blob: ce6c71baf8cdde5451687d898737b7940d64c0cf [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
Adam Tkacbfd66c12010-10-01 08:33:29 +000041SSecurityVeNCrypt::SSecurityVeNCrypt(SecurityServer *sec) : security(sec)
Adam Tkac5522d612010-08-11 15:28:01 +000042{
43 ssecurity = NULL;
44 haveSentVersion = false;
45 haveRecvdMajorVersion = false;
46 haveRecvdMinorVersion = false;
47 majorVersion = 0;
48 minorVersion = 0;
49 haveSentTypes = false;
50 haveChosenType = false;
51 chosenType = secTypeVeNCrypt;
52 numTypes = 0;
53 subTypes = NULL;
54}
55
56SSecurityVeNCrypt::~SSecurityVeNCrypt()
57{
Michal Srb8f3e8662017-03-29 16:23:18 +030058 delete ssecurity;
59
Adam Tkac5522d612010-08-11 15:28:01 +000060 if (subTypes) {
61 delete [] subTypes;
62 subTypes = NULL;
63 }
64}
65
66bool SSecurityVeNCrypt::processMsg(SConnection* sc)
67{
68 rdr::InStream* is = sc->getInStream();
69 rdr::OutStream* os = sc->getOutStream();
70 rdr::U8 i;
71
72 /* VeNCrypt initialization */
73
74 /* Send the highest version we can support */
75 if (!haveSentVersion) {
76 os->writeU8(0);
77 os->writeU8(2);
78 haveSentVersion = true;
79 os->flush();
80
81 return false;
82 }
83
84 /* Receive back highest version that client can support (up to and including ours) */
85 if (!haveRecvdMajorVersion) {
86 majorVersion = is->readU8();
87 haveRecvdMajorVersion = true;
88
89 return false;
90 }
91
92 if (!haveRecvdMinorVersion) {
93 minorVersion = is->readU8();
94 haveRecvdMinorVersion = true;
95
96 /* WORD value with major version in upper 8 bits and minor version in lower 8 bits */
97 U16 Version = (((U16)majorVersion) << 8) | ((U16)minorVersion);
98
99 switch (Version) {
100 case 0x0000: /* 0.0 - The client cannot support us! */
101 case 0x0001: /* 0.1 Legacy VeNCrypt, not supported */
102 os->writeU8(0xFF); /* This is not OK */
103 os->flush();
104 throw AuthFailureException("The client cannot support the server's "
105 "VeNCrypt version");
106
107 case 0x0002: /* 0.2 */
108 os->writeU8(0); /* OK */
109 break;
110
111 default:
112 os->writeU8(0xFF); /* Not OK */
113 os->flush();
114 throw AuthFailureException("The client returned an unsupported VeNCrypt version");
115 }
116 }
117
118 /*
119 * send number of supported VeNCrypt authentication types (U8) followed
120 * by authentication types (U32s)
121 */
122 if (!haveSentTypes) {
123 list<U32> listSubTypes;
124
125 listSubTypes = security->GetEnabledExtSecTypes();
126
127 numTypes = listSubTypes.size();
128 subTypes = new U32[numTypes];
129
130 for (i = 0; i < numTypes; i++) {
131 subTypes[i] = listSubTypes.front();
132 listSubTypes.pop_front();
133 }
134
135 if (numTypes) {
136 os->writeU8(numTypes);
137 for (i = 0; i < numTypes; i++)
138 os->writeU32(subTypes[i]);
139
140 os->flush();
141 haveSentTypes = true;
142 return false;
143 } else
144 throw AuthFailureException("There are no VeNCrypt sub-types to send to the client");
145 }
146
147 /* get type back from client (must be one of the ones we sent) */
148 if (!haveChosenType) {
149 is->check(4);
150 chosenType = is->readU32();
151
152 for (i = 0; i < numTypes; i++) {
153 if (chosenType == subTypes[i]) {
154 haveChosenType = true;
155 break;
156 }
157 }
158
159 if (!haveChosenType)
160 chosenType = secTypeInvalid;
161
Pierre Ossman71d66662014-11-11 13:42:51 +0100162 vlog.info("Client requests security type %s (%d)", secTypeName(chosenType),
Adam Tkac5522d612010-08-11 15:28:01 +0000163 chosenType);
164
165 /* Set up the stack according to the chosen type */
166 if (chosenType == secTypeInvalid || chosenType == secTypeVeNCrypt)
167 throw AuthFailureException("No valid VeNCrypt sub-type");
168
169 ssecurity = security->GetSSecurity(chosenType);
170 }
171
172 /* continue processing the messages */
173 return ssecurity->processMsg(sc);
174}
175
Pierre Ossman555815a2014-12-02 15:13:22 +0100176const char* SSecurityVeNCrypt::getUserName() const
177{
178 if (ssecurity == NULL)
179 return NULL;
180 return ssecurity->getUserName();
181}
182
183SConnection::AccessRights SSecurityVeNCrypt::getAccessRights() const
184{
185 if (ssecurity == NULL)
186 return SSecurity::getAccessRights();
187 return ssecurity->getAccessRights();
188}