diff options
Diffstat (limited to 'java/com/tigervnc/rfb/CSecurityVeNCrypt.java')
-rw-r--r-- | java/com/tigervnc/rfb/CSecurityVeNCrypt.java | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/java/com/tigervnc/rfb/CSecurityVeNCrypt.java b/java/com/tigervnc/rfb/CSecurityVeNCrypt.java new file mode 100644 index 00000000..ae758e7f --- /dev/null +++ b/java/com/tigervnc/rfb/CSecurityVeNCrypt.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2003 Sun Microsystems, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +package com.tigervnc.rfb; + +import java.util.*; + +import com.tigervnc.rdr.*; + +public class CSecurityVeNCrypt extends CSecurity { + + public CSecurityVeNCrypt(SecurityClient sec) + { + haveRecvdMajorVersion = false; + haveRecvdMinorVersion = false; + haveSentVersion = false; + haveAgreedVersion = false; + haveListOfTypes = false; + haveNumberOfTypes = false; + haveChosenType = false; + majorVersion = 0; + minorVersion = 0; + chosenType = Security.secTypeVeNCrypt; + nAvailableTypes = 0; + availableTypes = null; + iAvailableType = 0; + security = sec; + } + + public boolean processMsg(CConnection cc) { + InStream is = cc.getInStream(); + OutStream os = cc.getOutStream(); + + /* get major, minor versions, send what we can support (or 0.0 for can't support it) */ + if (!haveRecvdMinorVersion) { + minorVersion = is.readU8(); + haveRecvdMinorVersion = true; + + return false; + } + + if (!haveRecvdMajorVersion) { + majorVersion = is.readU8(); + haveRecvdMajorVersion = true; + } + + /* major version in upper 8 bits and minor version in lower 8 bits */ + int Version = (majorVersion << 8) | minorVersion; + + if (!haveSentVersion) { + /* Currently we don't support former VeNCrypt 0.1 */ + if (Version >= 0x0002) { + majorVersion = 0; + minorVersion = 2; + os.writeU8(majorVersion); + os.writeU8(minorVersion); + os.flush(); + } else { + /* Send 0.0 to indicate no support */ + majorVersion = 0; + minorVersion = 0; + os.writeU8(majorVersion); + os.writeU8(minorVersion); + os.flush(); + throw new Exception("Server reported an unsupported VeNCrypt version"); + } + + haveSentVersion = true; + return false; + } + + /* Check that the server is OK */ + if (!haveAgreedVersion) { + if (is.readU8() != 0) + throw new Exception("Server reported it could not support the VeNCrypt version"); + + haveAgreedVersion = true; + return false; + } + + /* get a number of types */ + if (!haveNumberOfTypes) { + nAvailableTypes = is.readU8(); + iAvailableType = 0; + + if (nAvailableTypes <= 0) + throw new Exception("The server reported no VeNCrypt sub-types"); + + availableTypes = new int[nAvailableTypes]; + haveNumberOfTypes = true; + return false; + } + + if (nAvailableTypes > 0) { + /* read in the types possible */ + if (!haveListOfTypes) { + if (is.checkNoWait(4)) { + availableTypes[iAvailableType++] = is.readU32(); + haveListOfTypes = (iAvailableType >= nAvailableTypes); + vlog.debug("Server offers security type "+ + Security.secTypeName(availableTypes[iAvailableType - 1])+" ("+ + availableTypes[iAvailableType - 1]+")"); + + if (!haveListOfTypes) + return false; + + } else + return false; + } + + /* make a choice and send it to the server, meanwhile set up the stack */ + if (!haveChosenType) { + chosenType = Security.secTypeInvalid; + int i; + Iterator j; + List<Integer> secTypes = new ArrayList<Integer>(); + + secTypes = security.GetEnabledExtSecTypes(); + + /* Honor server's security type order */ + for (i = 0; i < nAvailableTypes; i++) { + for (j = secTypes.iterator(); j.hasNext(); ) { + int refType = (Integer)j.next(); + if (refType == availableTypes[i]) { + chosenType = refType; + break; + } + } + + if (chosenType != Security.secTypeInvalid) + break; + } + + vlog.debug("Choosing security type "+Security.secTypeName(chosenType)+ + " ("+chosenType+")"); + + /* Set up the stack according to the chosen type: */ + if (chosenType == Security.secTypeInvalid || chosenType == Security.secTypeVeNCrypt) + throw new AuthFailureException("No valid VeNCrypt sub-type"); + + csecurity = security.GetCSecurity(chosenType); + + /* send chosen type to server */ + os.writeU32(chosenType); + os.flush(); + + haveChosenType = true; + } + } else { + /* + * Server told us that there are 0 types it can support - this should not + * happen, since if the server supports 0 sub-types, it doesn't support + * this security type + */ + throw new AuthFailureException("The server reported 0 VeNCrypt sub-types"); + } + + return csecurity.processMsg(cc); + } + + public final int getType() { return chosenType; } + public final String description() { return Security.secTypeName(chosenType); } + + public static StringParameter secTypesStr; + + private CSecurity csecurity; + SecurityClient security; + private boolean haveRecvdMajorVersion; + private boolean haveRecvdMinorVersion; + private boolean haveSentVersion; + private boolean haveAgreedVersion; + private boolean haveListOfTypes; + private boolean haveNumberOfTypes; + private boolean haveChosenType; + private int majorVersion, minorVersion; + private int chosenType; + private int nAvailableTypes; + private int[] availableTypes; + private int iAvailableType; + //private final String desc; + + static LogWriter vlog = new LogWriter("CSecurityVeNCrypt"); +} |