blob: d522ef6fc48ee94c63e82381e02d09ea53d4e776 [file] [log] [blame]
Adam Tkac5522d612010-08-11 15:28:01 +00001/*
2 * Copyright (C) 2005-2006 Martin Koegler
3 * Copyright (C) 2006 OCCAM Financial Technology
4 * Copyright (C) 2010 TigerVNC Team
5 *
6 * This is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This software is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this software; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * USA.
20 */
21/*
22 * SSecurityVeNCrypt
23 */
24
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28
29#include <rfb/SSecurityVeNCrypt.h>
30#include <rfb/Exception.h>
31#include <rfb/LogWriter.h>
32#include <rdr/InStream.h>
33#include <rdr/OutStream.h>
34
35using namespace rfb;
36using namespace rdr;
37using namespace std;
38
39static LogWriter vlog("SVeNCrypt");
40
Pierre Ossmanad2b3c42018-09-21 15:31:11 +020041SSecurityVeNCrypt::SSecurityVeNCrypt(SConnection* sc, SecurityServer *sec)
42 : SSecurity(sc), security(sec)
Adam Tkac5522d612010-08-11 15:28:01 +000043{
44 ssecurity = NULL;
45 haveSentVersion = false;
46 haveRecvdMajorVersion = false;
47 haveRecvdMinorVersion = false;
48 majorVersion = 0;
49 minorVersion = 0;
50 haveSentTypes = false;
51 haveChosenType = false;
52 chosenType = secTypeVeNCrypt;
53 numTypes = 0;
54 subTypes = NULL;
55}
56
57SSecurityVeNCrypt::~SSecurityVeNCrypt()
58{
Michal Srb8f3e8662017-03-29 16:23:18 +030059 delete ssecurity;
60
Adam Tkac5522d612010-08-11 15:28:01 +000061 if (subTypes) {
62 delete [] subTypes;
63 subTypes = NULL;
64 }
65}
66
Pierre Ossmanad2b3c42018-09-21 15:31:11 +020067bool SSecurityVeNCrypt::processMsg()
Adam Tkac5522d612010-08-11 15:28:01 +000068{
69 rdr::InStream* is = sc->getInStream();
70 rdr::OutStream* os = sc->getOutStream();
71 rdr::U8 i;
72
73 /* VeNCrypt initialization */
74
75 /* Send the highest version we can support */
76 if (!haveSentVersion) {
77 os->writeU8(0);
78 os->writeU8(2);
79 haveSentVersion = true;
80 os->flush();
81
82 return false;
83 }
84
85 /* Receive back highest version that client can support (up to and including ours) */
86 if (!haveRecvdMajorVersion) {
87 majorVersion = is->readU8();
88 haveRecvdMajorVersion = true;
89
90 return false;
91 }
92
93 if (!haveRecvdMinorVersion) {
94 minorVersion = is->readU8();
95 haveRecvdMinorVersion = true;
96
97 /* WORD value with major version in upper 8 bits and minor version in lower 8 bits */
98 U16 Version = (((U16)majorVersion) << 8) | ((U16)minorVersion);
99
100 switch (Version) {
101 case 0x0000: /* 0.0 - The client cannot support us! */
102 case 0x0001: /* 0.1 Legacy VeNCrypt, not supported */
103 os->writeU8(0xFF); /* This is not OK */
104 os->flush();
105 throw AuthFailureException("The client cannot support the server's "
106 "VeNCrypt version");
107
108 case 0x0002: /* 0.2 */
109 os->writeU8(0); /* OK */
110 break;
111
112 default:
113 os->writeU8(0xFF); /* Not OK */
114 os->flush();
115 throw AuthFailureException("The client returned an unsupported VeNCrypt version");
116 }
117 }
118
119 /*
120 * send number of supported VeNCrypt authentication types (U8) followed
121 * by authentication types (U32s)
122 */
123 if (!haveSentTypes) {
124 list<U32> listSubTypes;
125
126 listSubTypes = security->GetEnabledExtSecTypes();
127
128 numTypes = listSubTypes.size();
129 subTypes = new U32[numTypes];
130
131 for (i = 0; i < numTypes; i++) {
132 subTypes[i] = listSubTypes.front();
133 listSubTypes.pop_front();
134 }
135
136 if (numTypes) {
137 os->writeU8(numTypes);
138 for (i = 0; i < numTypes; i++)
139 os->writeU32(subTypes[i]);
140
141 os->flush();
142 haveSentTypes = true;
143 return false;
144 } else
145 throw AuthFailureException("There are no VeNCrypt sub-types to send to the client");
146 }
147
148 /* get type back from client (must be one of the ones we sent) */
149 if (!haveChosenType) {
150 is->check(4);
151 chosenType = is->readU32();
152
153 for (i = 0; i < numTypes; i++) {
154 if (chosenType == subTypes[i]) {
155 haveChosenType = true;
156 break;
157 }
158 }
159
160 if (!haveChosenType)
161 chosenType = secTypeInvalid;
162
Pierre Ossman71d66662014-11-11 13:42:51 +0100163 vlog.info("Client requests security type %s (%d)", secTypeName(chosenType),
Adam Tkac5522d612010-08-11 15:28:01 +0000164 chosenType);
165
166 /* Set up the stack according to the chosen type */
167 if (chosenType == secTypeInvalid || chosenType == secTypeVeNCrypt)
168 throw AuthFailureException("No valid VeNCrypt sub-type");
169
Pierre Ossmanad2b3c42018-09-21 15:31:11 +0200170 ssecurity = security->GetSSecurity(sc, chosenType);
Adam Tkac5522d612010-08-11 15:28:01 +0000171 }
172
173 /* continue processing the messages */
Pierre Ossmanad2b3c42018-09-21 15:31:11 +0200174 return ssecurity->processMsg();
Adam Tkac5522d612010-08-11 15:28:01 +0000175}
176
Pierre Ossman555815a2014-12-02 15:13:22 +0100177const char* SSecurityVeNCrypt::getUserName() const
178{
179 if (ssecurity == NULL)
180 return NULL;
181 return ssecurity->getUserName();
182}
183
184SConnection::AccessRights SSecurityVeNCrypt::getAccessRights() const
185{
186 if (ssecurity == NULL)
187 return SSecurity::getAccessRights();
188 return ssecurity->getAccessRights();
189}