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