blob: e6a51bcc6183cfc6be4b3880ca63d3aafac99222 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Adam Tkacdf799702010-04-28 15:45:53 +00002 * Copyright (C) 2010 TigerVNC Team
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00003 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this software; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
Adam Tkacdf799702010-04-28 15:45:53 +000019
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
Adam Tkac1d15e2d2010-04-23 14:06:38 +000024#include <assert.h>
25#include <stdlib.h>
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000026#include <string.h>
27#ifdef _WIN32
28#define strcasecmp _stricmp
29#endif
Adam Tkacc210e8a2010-04-23 14:09:16 +000030#include <rfb/CSecurityNone.h>
Adam Tkac707d3612010-07-20 15:16:10 +000031#include <rfb/CSecurityStack.h>
Adam Tkacb10489b2010-04-23 14:16:04 +000032#include <rfb/CSecurityVeNCrypt.h>
Adam Tkacc210e8a2010-04-23 14:09:16 +000033#include <rfb/CSecurityVncAuth.h>
Adam Tkac1d15e2d2010-04-23 14:06:38 +000034#include <rdr/Exception.h>
35#include <rfb/LogWriter.h>
Adam Tkacb6eb3992010-04-23 14:05:00 +000036#include <rfb/Security.h>
Adam Tkac1d15e2d2010-04-23 14:06:38 +000037#include <rfb/SSecurityNone.h>
Adam Tkac707d3612010-07-20 15:16:10 +000038#include <rfb/SSecurityStack.h>
Adam Tkac1d15e2d2010-04-23 14:06:38 +000039#include <rfb/SSecurityVncAuth.h>
Adam Tkacdfe19cf2010-04-23 14:14:11 +000040#include <rfb/SSecurityVeNCrypt.h>
Adam Tkac707d3612010-07-20 15:16:10 +000041#ifdef HAVE_GNUTLS
42#include <rfb/CSecurityTLS.h>
43#include <rfb/SSecurityTLS.h>
Adam Tkacdf799702010-04-28 15:45:53 +000044#endif
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000045#include <rfb/util.h>
46
Adam Tkac1d15e2d2010-04-23 14:06:38 +000047using namespace rdr;
48using namespace rfb;
49using namespace std;
50
51static LogWriter vlog("Security");
52
Adam Tkacb10489b2010-04-23 14:16:04 +000053UserPasswdGetter *CSecurity::upg = NULL;
54
Adam Tkaca6578bf2010-04-23 14:07:41 +000055StringParameter Security::secTypes
56("SecurityTypes",
57 "Specify which security scheme to use (None, VncAuth)",
Adam Tkacb10489b2010-04-23 14:16:04 +000058 "VncAuth");
Adam Tkaca6578bf2010-04-23 14:07:41 +000059
Adam Tkacb10489b2010-04-23 14:16:04 +000060Security::Security(void)
Adam Tkac1d15e2d2010-04-23 14:06:38 +000061{
Adam Tkaca6578bf2010-04-23 14:07:41 +000062 char *secTypesStr = secTypes.getData();
Adam Tkac1d15e2d2010-04-23 14:06:38 +000063
64 enabledSecTypes = parseSecTypes(secTypesStr);
65
66 delete secTypesStr;
67}
68
Adam Tkac0c77e512010-07-20 15:10:16 +000069const std::list<rdr::U8> Security::GetEnabledSecTypes(void)
Adam Tkac1d15e2d2010-04-23 14:06:38 +000070{
Adam Tkac0c77e512010-07-20 15:10:16 +000071 list<rdr::U8> result;
72 list<U32>::iterator i;
73
74 for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
75 if (*i < 0x100)
76 result.push_back(*i);
77
78 return result;
79}
80
81const std::list<rdr::U32> Security::GetEnabledExtSecTypes(void)
82{
83 list<rdr::U32> result;
84 list<U32>::iterator i;
85
86 for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
87 if (*i >= 0x100)
88 result.push_back(*i);
89
90 return result;
91}
92
93void Security::EnableSecType(U32 secType)
94{
95 list<U32>::iterator i;
Adam Tkac1d15e2d2010-04-23 14:06:38 +000096
97 for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
98 if (*i == secType)
99 return;
100
101 enabledSecTypes.push_back(secType);
102}
103
Adam Tkac0c77e512010-07-20 15:10:16 +0000104bool Security::IsSupported(U32 secType)
Adam Tkac1d15e2d2010-04-23 14:06:38 +0000105{
Adam Tkac0c77e512010-07-20 15:10:16 +0000106 list<U32>::iterator i;
Adam Tkac1d15e2d2010-04-23 14:06:38 +0000107
108 for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
109 if (*i == secType)
110 return true;
111
112 return false;
113}
114
Adam Tkac0c77e512010-07-20 15:10:16 +0000115SSecurity* Security::GetSSecurity(U32 secType)
Adam Tkac1d15e2d2010-04-23 14:06:38 +0000116{
117 if (!IsSupported(secType))
118 goto bail;
119
120 switch (secType) {
121 case secTypeNone: return new SSecurityNone();
122 case secTypeVncAuth: return new SSecurityVncAuth();
Adam Tkaca0325932010-07-20 15:14:08 +0000123 case secTypeVeNCrypt: return new SSecurityVeNCrypt(this);
Adam Tkac707d3612010-07-20 15:16:10 +0000124#ifdef HAVE_GNUTLS
125 case secTypeTLSNone:
126 return new SSecurityStack(secTypeTLSNone, new SSecurityTLS());
127 case secTypeTLSVnc:
128 return new SSecurityStack(secTypeTLSVnc, new SSecurityTLS(), new SSecurityVncAuth());
Adam Tkacdf799702010-04-28 15:45:53 +0000129#endif
Adam Tkacc210e8a2010-04-23 14:09:16 +0000130 }
131
132bail:
133 throw Exception("Security type not supported");
134}
135
Adam Tkac0c77e512010-07-20 15:10:16 +0000136CSecurity* Security::GetCSecurity(U32 secType)
Adam Tkacc210e8a2010-04-23 14:09:16 +0000137{
Adam Tkacb10489b2010-04-23 14:16:04 +0000138 assert (CSecurity::upg != NULL); /* (upg == NULL) means bug in the viewer */
Adam Tkacc210e8a2010-04-23 14:09:16 +0000139
140 if (!IsSupported(secType))
141 goto bail;
142
143 switch (secType) {
144 case secTypeNone: return new CSecurityNone();
Adam Tkacb10489b2010-04-23 14:16:04 +0000145 case secTypeVncAuth: return new CSecurityVncAuth();
Adam Tkaca0325932010-07-20 15:14:08 +0000146 case secTypeVeNCrypt: return new CSecurityVeNCrypt(this);
Adam Tkac707d3612010-07-20 15:16:10 +0000147#ifdef HAVE_GNUTLS
148 case secTypeTLSNone:
149 return new CSecurityStack(secTypeTLSNone, "TLS with no password",
150 new CSecurityTLS());
151 case secTypeTLSVnc:
152 return new CSecurityStack(secTypeTLSVnc, "TLS with VNCAuth",
153 new CSecurityTLS(), new CSecurityVncAuth());
Adam Tkacdf799702010-04-28 15:45:53 +0000154#endif
Adam Tkac1d15e2d2010-04-23 14:06:38 +0000155 }
156
157bail:
158 throw Exception("Security type not supported");
159}
160
Adam Tkac0c77e512010-07-20 15:10:16 +0000161rdr::U32 rfb::secTypeNum(const char* name)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000162{
163 if (strcasecmp(name, "None") == 0) return secTypeNone;
164 if (strcasecmp(name, "VncAuth") == 0) return secTypeVncAuth;
165 if (strcasecmp(name, "Tight") == 0) return secTypeTight;
166 if (strcasecmp(name, "RA2") == 0) return secTypeRA2;
167 if (strcasecmp(name, "RA2ne") == 0) return secTypeRA2ne;
168 if (strcasecmp(name, "SSPI") == 0) return secTypeSSPI;
Adam Tkacdfe19cf2010-04-23 14:14:11 +0000169 if (strcasecmp(name, "SSPIne") == 0) return secTypeSSPIne;
170 if (strcasecmp(name, "VeNCrypt") == 0) return secTypeVeNCrypt;
Adam Tkacb3e60c62010-07-20 15:10:59 +0000171
172 /* VeNCrypt subtypes */
Adam Tkac957a5ae2010-07-20 15:12:41 +0000173 if (strcasecmp(name, "Plain") == 0) return secTypePlain;
Adam Tkacb3e60c62010-07-20 15:10:59 +0000174 if (strcasecmp(name, "TLSNone") == 0) return secTypeTLSNone;
175 if (strcasecmp(name, "TLSVnc") == 0) return secTypeTLSVnc;
Adam Tkac957a5ae2010-07-20 15:12:41 +0000176 if (strcasecmp(name, "TLSPlain") == 0) return secTypeTLSPlain;
Adam Tkacb3e60c62010-07-20 15:10:59 +0000177 if (strcasecmp(name, "X509None") == 0) return secTypeX509None;
178 if (strcasecmp(name, "X509Vnc") == 0) return secTypeX509Vnc;
Adam Tkacb3e60c62010-07-20 15:10:59 +0000179 if (strcasecmp(name, "X509Plain") == 0) return secTypeX509Plain;
Adam Tkacb3e60c62010-07-20 15:10:59 +0000180
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000181 return secTypeInvalid;
182}
183
Adam Tkac0c77e512010-07-20 15:10:16 +0000184const char* rfb::secTypeName(rdr::U32 num)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000185{
186 switch (num) {
187 case secTypeNone: return "None";
188 case secTypeVncAuth: return "VncAuth";
189 case secTypeTight: return "Tight";
190 case secTypeRA2: return "RA2";
191 case secTypeRA2ne: return "RA2ne";
192 case secTypeSSPI: return "SSPI";
193 case secTypeSSPIne: return "SSPIne";
Adam Tkacdfe19cf2010-04-23 14:14:11 +0000194 case secTypeVeNCrypt: return "VeNCrypt";
Adam Tkacb3e60c62010-07-20 15:10:59 +0000195
196 /* VeNCrypt subtypes */
Adam Tkac957a5ae2010-07-20 15:12:41 +0000197 case secTypePlain: return "Plain";
Adam Tkacb3e60c62010-07-20 15:10:59 +0000198 case secTypeTLSNone: return "TLSNone";
199 case secTypeTLSVnc: return "TLSVnc";
Adam Tkacb3e60c62010-07-20 15:10:59 +0000200 case secTypeTLSPlain: return "TLSPlain";
201 case secTypeX509None: return "X509None";
202 case secTypeX509Vnc: return "X509Vnc";
203 case secTypeX509Plain: return "X509Plain";
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000204 default: return "[unknown secType]";
205 }
206}
207
Adam Tkac0c77e512010-07-20 15:10:16 +0000208std::list<rdr::U32> rfb::parseSecTypes(const char* types_)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000209{
Adam Tkac0c77e512010-07-20 15:10:16 +0000210 std::list<rdr::U32> result;
Adam Tkacd36b6262009-09-04 10:57:20 +0000211 CharArray types(strDup(types_)), type;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000212 while (types.buf) {
213 strSplit(types.buf, ',', &type.buf, &types.buf);
Adam Tkac0c77e512010-07-20 15:10:16 +0000214 rdr::U32 typeNum = secTypeNum(type.buf);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000215 if (typeNum != secTypeInvalid)
216 result.push_back(typeNum);
217 }
218 return result;
219}