1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * auth.c - deal with authentication. 3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This file implements the VNC authentication protocol when setting up an RFB 5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * connection. 6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin 10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>. 11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. 12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * All Rights Reserved. 13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This is free software; you can redistribute it and/or modify 15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * it under the terms of the GNU General Public License as published by 16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the Free Software Foundation; either version 2 of the License, or 17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (at your option) any later version. 18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This software is distributed in the hope that it will be useful, 20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * but WITHOUT ANY WARRANTY; without even the implied warranty of 21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * GNU General Public License for more details. 23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * You should have received a copy of the GNU General Public License 25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * along with this software; if not, write to the Free Software 26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * USA. 28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfb.h> 31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* RFB 3.8 clients are well informed */ 33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbClientSendString(rfbClientPtr cl, const char *reason); 34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Handle security types 38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbSecurityHandler* securityHandlers = NULL; 41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This method registers a list of new security types. 44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * It avoids same security type getting registered multiple times. 45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The order is not preserved if multiple security types are 46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * registered at one-go. 47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbRegisterSecurityHandler(rfbSecurityHandler* handler) 50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSecurityHandler *head = securityHandlers, *next = NULL; 52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(handler == NULL) 54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat next = handler->next; 57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(head != NULL) { 59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(head == handler) { 60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbRegisterSecurityHandler(next); 61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat head = head->next; 65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat handler->next = securityHandlers; 68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat securityHandlers = handler; 69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbRegisterSecurityHandler(next); 71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This method unregisters a list of security types. 75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * These security types won't be available for any new 76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * client connection. 77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbUnregisterSecurityHandler(rfbSecurityHandler* handler) 80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSecurityHandler *cur = NULL, *pre = NULL; 82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(handler == NULL) 84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(securityHandlers == handler) { 87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat securityHandlers = securityHandlers->next; 88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbUnregisterSecurityHandler(handler->next); 89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cur = pre = securityHandlers; 93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(cur) { 95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cur == handler) { 96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat pre->next = cur->next; 97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat pre = cur; 100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cur = cur->next; 101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbUnregisterSecurityHandler(handler->next); 103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send the authentication challenge. 107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void 110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbVncAuthSendChallenge(rfbClientPtr cl) 111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 4 byte header is alreay sent. Which is rfbSecTypeVncAuth 114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (same as rfbVncAuth). Just send the challenge. */ 115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbRandomBytes(cl->authChallenge); 116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)cl->authChallenge, CHALLENGESIZE) < 0) { 117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbAuthNewClient: write"); 118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Dispatch client input to rfbVncAuthProcessResponse. */ 123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->state = RFB_AUTHENTICATION; 124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send the NO AUTHENTICATION. SCARR 128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The rfbVncAuthNone function is currently the only function that contains 132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * special logic for the built-in Mac OS X VNC client which is activated by 133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * a protocolMinorVersion == 889 coming from the Mac OS X VNC client. 134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The rfbProcessClientInitMessage function does understand how to handle the 135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * RFB_INITIALISATION_SHARED state which was introduced to support the built-in 136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Mac OS X VNC client, but rfbProcessClientInitMessage does not examine the 137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * protocolMinorVersion version field and so its support for the 138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * RFB_INITIALISATION_SHARED state is not restricted to just the OS X client. 139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void 142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbVncAuthNone(rfbClientPtr cl) 143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* The built-in Mac OS X VNC client behaves in a non-conforming fashion 145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * when the server version is 3.7 or later AND the list of security types 146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * sent to the OS X client contains the 'None' authentication type AND 147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the OS X client sends back the 'None' type as its choice. In this case, 148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and this case ONLY, the built-in Mac OS X VNC client will NOT send the 149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ClientInit message and instead will behave as though an implicit 150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ClientInit message containing a shared-flag of true has been sent. 151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The special state RFB_INITIALISATION_SHARED represents this case. 152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The Mac OS X VNC client can be detected by checking protocolMinorVersion 153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * for a value of 889. No other VNC client is known to use this value 154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * for protocolMinorVersion. */ 155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t authResult; 156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* The built-in Mac OS X VNC client expects to NOT receive a SecurityResult 158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * message for authentication type 'None'. Since its protocolMinorVersion 159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * is greater than 7 (it is 889) this case must be tested for specially. */ 160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion > 7 && cl->protocolMinorVersion != 889) { 161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessClientSecurityType: returning securityResult for client rfb version >= 3.8\n"); 162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat authResult = Swap32IfLE(rfbVncAuthOK); 163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) { 164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbAuthProcessClientMessage: write"); 165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->state = cl->protocolMinorVersion == 889 ? RFB_INITIALISATION_SHARED : RFB_INITIALISATION; 170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->state == RFB_INITIALISATION_SHARED) 171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* In this case we must call rfbProcessClientMessage now because 172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * otherwise we would hang waiting for data to be received from the 173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * client (the ClientInit message which will never come). */ 174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProcessClientMessage(cl); 175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Advertise the supported security types (protocol 3.7). Here before sending 181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the list of security types to the client one more security type is added 182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * to the list if primaryType is not set to rfbSecTypeInvalid. This security 183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * type is the standard vnc security type which does the vnc authentication 184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * or it will be security type for no authentication. 185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Different security types will be added by applications using this library. 186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbSecurityHandler VncSecurityHandlerVncAuth = { 189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSecTypeVncAuth, 190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbVncAuthSendChallenge, 191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat NULL 192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}; 193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbSecurityHandler VncSecurityHandlerNone = { 195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSecTypeNone, 196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbVncAuthNone, 197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat NULL 198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}; 199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void 202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendSecurityTypeList(rfbClientPtr cl, int primaryType) 203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* The size of the message is the count of security types +1, 205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * since the first byte is the number of types. */ 206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int size = 1; 207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSecurityHandler* handler; 208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define MAX_SECURITY_TYPES 255 209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t buffer[MAX_SECURITY_TYPES+1]; 210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Fill in the list of security types in the client structure. (NOTE: Not really in the client structure) */ 213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (primaryType) { 214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbSecTypeNone: 215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbRegisterSecurityHandler(&VncSecurityHandlerNone); 216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbSecTypeVncAuth: 218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbRegisterSecurityHandler(&VncSecurityHandlerVncAuth); 219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (handler = securityHandlers; 223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat handler && size<MAX_SECURITY_TYPES; handler = handler->next) { 224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer[size] = handler->type; 225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat size++; 226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer[0] = (unsigned char)size-1; 228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Send the list. */ 230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)buffer, size) < 0) { 231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendSecurityTypeList: write"); 232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * if count is 0, we need to send the reason and close the connection. 238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(size <= 1) { 240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* This means total count is Zero and so reason msg should be sent */ 241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* The execution should never reach here */ 242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char* reason = "No authentication mode is registered!"; 243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientSendString(cl, reason); 245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Dispatch client input to rfbProcessClientSecurityType. */ 249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->state = RFB_SECURITY_TYPE; 250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Tell the client what security type will be used (protocol 3.3). 257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void 259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendSecurityType(rfbClientPtr cl, int32_t securityType) 260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t value32; 262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Send the value. */ 264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat value32 = Swap32IfLE(securityType); 265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)&value32, 4) < 0) { 266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendSecurityType: write"); 267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Decide what to do next. */ 272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (securityType) { 273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbSecTypeNone: 274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Dispatch client input to rfbProcessClientInitMessage. */ 275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->state = RFB_INITIALISATION; 276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbSecTypeVncAuth: 278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Begin the standard VNC authentication procedure. */ 279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbVncAuthSendChallenge(cl); 280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Impossible case (hopefully). */ 283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendSecurityType: assertion failed"); 284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbAuthNewClient is called right after negotiating the protocol 292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * version. Depending on the protocol version, we send either a code 293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * for authentication scheme to be used (protocol 3.3), or a list of 294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * possible "security types" (protocol 3.7). 295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbAuthNewClient(rfbClientPtr cl) 299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int32_t securityType = rfbSecTypeInvalid; 301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->screen->authPasswdData || cl->reverseConnection) { 303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* chk if this condition is valid or not. */ 304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat securityType = rfbSecTypeNone; 305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (cl->screen->authPasswdData) { 306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat securityType = rfbSecTypeVncAuth; 307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion < 7) 310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Make sure we use only RFB 3.3 compatible security types. */ 312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (securityType == rfbSecTypeInvalid) { 313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("VNC authentication disabled - RFB 3.3 client rejected\n"); 314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientConnFailed(cl, "Your viewer cannot handle required " 315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "authentication methods"); 316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSendSecurityType(cl, securityType); 319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Here it's ok when securityType is set to rfbSecTypeInvalid. */ 321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSendSecurityTypeList(cl, securityType); 322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Read the security type chosen by the client (protocol 3.7). 327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbProcessClientSecurityType(rfbClientPtr cl) 331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n; 333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t chosenType; 334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSecurityHandler* handler; 335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Read the security type. */ 337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat n = rfbReadExact(cl, (char *)&chosenType, 1); 338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n <= 0) { 339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n == 0) 340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessClientSecurityType: client gone\n"); 341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientSecurityType: read"); 343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Make sure it was present in the list sent by the server. */ 348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (handler = securityHandlers; handler; handler = handler->next) { 349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (chosenType == handler->type) { 350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessClientSecurityType: executing handler for type %d\n", chosenType); 351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat handler->handler(cl); 352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessClientSecurityType: wrong security type (%d) requested\n", chosenType); 357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbAuthProcessClientMessage is called when the client sends its 364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * authentication response. 365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbAuthProcessClientMessage(rfbClientPtr cl) 369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n; 371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t response[CHALLENGESIZE]; 372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t authResult; 373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, (char *)response, CHALLENGESIZE)) <= 0) { 375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbAuthProcessClientMessage: read"); 377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!cl->screen->passwordCheck(cl,(const char*)response,CHALLENGESIZE)) { 382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbErr("rfbAuthProcessClientMessage: password check failed\n"); 383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat authResult = Swap32IfLE(rfbVncAuthFailed); 384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) { 385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbAuthProcessClientMessage: write"); 386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* support RFB 3.8 clients, they expect a reason *why* it was disconnected */ 388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->protocolMinorVersion > 7) { 389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientSendString(cl, "password check failed!"); 390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat authResult = Swap32IfLE(rfbVncAuthOK); 397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) { 399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbAuthProcessClientMessage: write"); 400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->state = RFB_INITIALISATION; 405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 406