blob: 62ea50e6ed9ae668ea604e4721889a610acde74d [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>
Adam Tkacc210e8a2010-04-23 14:09:16 +000027#include <rfb/CSecurityNone.h>
Adam Tkac707d3612010-07-20 15:16:10 +000028#include <rfb/CSecurityStack.h>
Adam Tkacb10489b2010-04-23 14:16:04 +000029#include <rfb/CSecurityVeNCrypt.h>
Adam Tkacc210e8a2010-04-23 14:09:16 +000030#include <rfb/CSecurityVncAuth.h>
Adam Tkac8c048382010-09-02 12:37:00 +000031#include <rfb/CSecurityPlain.h>
Adam Tkac1d15e2d2010-04-23 14:06:38 +000032#include <rdr/Exception.h>
33#include <rfb/LogWriter.h>
Adam Tkacb6eb3992010-04-23 14:05:00 +000034#include <rfb/Security.h>
Adam Tkac1d15e2d2010-04-23 14:06:38 +000035#include <rfb/SSecurityNone.h>
Adam Tkac707d3612010-07-20 15:16:10 +000036#include <rfb/SSecurityStack.h>
Adam Tkac520fc412010-09-02 14:13:24 +000037#include <rfb/SSecurityPlain.h>
Adam Tkac1d15e2d2010-04-23 14:06:38 +000038#include <rfb/SSecurityVncAuth.h>
Adam Tkacdfe19cf2010-04-23 14:14:11 +000039#include <rfb/SSecurityVeNCrypt.h>
Adam Tkac707d3612010-07-20 15:16:10 +000040#ifdef HAVE_GNUTLS
Adam Tkac3c5be392010-07-21 09:27:34 +000041#include <rfb/CSecurityTLS.h>
Adam Tkac21b61a52010-07-21 09:19:00 +000042#include <rfb/SSecurityTLS.h>
Adam Tkacdf799702010-04-28 15:45:53 +000043#endif
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000044#include <rfb/util.h>
45
Adam Tkac1d15e2d2010-04-23 14:06:38 +000046using namespace rdr;
47using namespace rfb;
48using namespace std;
49
50static LogWriter vlog("Security");
51
Pierre Ossmane5fe0702011-05-16 12:46:16 +000052Security::Security()
53{
54}
55
Adam Tkacbfd66c12010-10-01 08:33:29 +000056Security::Security(StringParameter &secTypes)
Adam Tkac1d15e2d2010-04-23 14:06:38 +000057{
Adam Tkacfb993152010-08-12 14:17:28 +000058 char *secTypesStr;
59
Adam Tkacbfd66c12010-10-01 08:33:29 +000060 secTypesStr = secTypes.getData();
Adam Tkac1d15e2d2010-04-23 14:06:38 +000061 enabledSecTypes = parseSecTypes(secTypesStr);
62
Pierre Ossman5e04c262011-11-09 11:31:12 +000063 delete [] secTypesStr;
Adam Tkac1d15e2d2010-04-23 14:06:38 +000064}
65
Adam Tkac0c77e512010-07-20 15:10:16 +000066const std::list<rdr::U8> Security::GetEnabledSecTypes(void)
Adam Tkac1d15e2d2010-04-23 14:06:38 +000067{
Adam Tkac0c77e512010-07-20 15:10:16 +000068 list<rdr::U8> result;
69 list<U32>::iterator i;
70
DRC674bf062011-02-21 13:14:16 +000071 result.push_back(secTypeVeNCrypt);
Adam Tkac0c77e512010-07-20 15:10:16 +000072 for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
73 if (*i < 0x100)
74 result.push_back(*i);
75
76 return result;
77}
78
79const std::list<rdr::U32> Security::GetEnabledExtSecTypes(void)
80{
81 list<rdr::U32> result;
82 list<U32>::iterator i;
83
84 for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
Adam Tkac95e2fe82010-08-12 13:54:59 +000085 if (*i != secTypeVeNCrypt) /* Do not include VeNCrypt type to avoid loops */
Adam Tkac0c77e512010-07-20 15:10:16 +000086 result.push_back(*i);
87
88 return result;
89}
90
91void Security::EnableSecType(U32 secType)
92{
93 list<U32>::iterator i;
Adam Tkac1d15e2d2010-04-23 14:06:38 +000094
95 for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
96 if (*i == secType)
97 return;
98
99 enabledSecTypes.push_back(secType);
100}
101
Adam Tkac0c77e512010-07-20 15:10:16 +0000102bool Security::IsSupported(U32 secType)
Adam Tkac1d15e2d2010-04-23 14:06:38 +0000103{
Adam Tkac0c77e512010-07-20 15:10:16 +0000104 list<U32>::iterator i;
Adam Tkac1d15e2d2010-04-23 14:06:38 +0000105
106 for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
107 if (*i == secType)
108 return true;
DRC674bf062011-02-21 13:14:16 +0000109 if (secType == secTypeVeNCrypt)
110 return true;
Adam Tkac1d15e2d2010-04-23 14:06:38 +0000111
112 return false;
113}
114
Adam Tkaca9a7b4b2011-02-01 14:34:55 +0000115char *Security::ToString(void)
116{
117 list<U32>::iterator i;
118 static char out[128]; /* Should be enough */
119 bool firstpass = true;
120 const char *name;
121
122 memset(out, 0, sizeof(out));
123
124 for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++) {
125 name = secTypeName(*i);
126 if (name[0] == '[') /* Unknown security type */
127 continue;
128
129 if (!firstpass)
130 strncat(out, ",", sizeof(out) - 1);
131 else
132 firstpass = false;
133 strncat(out, name, sizeof(out) - 1);
134 }
135
136 return out;
137}
138
Adam Tkac0c77e512010-07-20 15:10:16 +0000139rdr::U32 rfb::secTypeNum(const char* name)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000140{
141 if (strcasecmp(name, "None") == 0) return secTypeNone;
142 if (strcasecmp(name, "VncAuth") == 0) return secTypeVncAuth;
143 if (strcasecmp(name, "Tight") == 0) return secTypeTight;
144 if (strcasecmp(name, "RA2") == 0) return secTypeRA2;
145 if (strcasecmp(name, "RA2ne") == 0) return secTypeRA2ne;
146 if (strcasecmp(name, "SSPI") == 0) return secTypeSSPI;
Adam Tkacdfe19cf2010-04-23 14:14:11 +0000147 if (strcasecmp(name, "SSPIne") == 0) return secTypeSSPIne;
148 if (strcasecmp(name, "VeNCrypt") == 0) return secTypeVeNCrypt;
Adam Tkacb3e60c62010-07-20 15:10:59 +0000149
150 /* VeNCrypt subtypes */
Adam Tkac957a5ae2010-07-20 15:12:41 +0000151 if (strcasecmp(name, "Plain") == 0) return secTypePlain;
Adam Tkacb3e60c62010-07-20 15:10:59 +0000152 if (strcasecmp(name, "TLSNone") == 0) return secTypeTLSNone;
153 if (strcasecmp(name, "TLSVnc") == 0) return secTypeTLSVnc;
Adam Tkac957a5ae2010-07-20 15:12:41 +0000154 if (strcasecmp(name, "TLSPlain") == 0) return secTypeTLSPlain;
Adam Tkacb3e60c62010-07-20 15:10:59 +0000155 if (strcasecmp(name, "X509None") == 0) return secTypeX509None;
156 if (strcasecmp(name, "X509Vnc") == 0) return secTypeX509Vnc;
Adam Tkacb3e60c62010-07-20 15:10:59 +0000157 if (strcasecmp(name, "X509Plain") == 0) return secTypeX509Plain;
Adam Tkacb3e60c62010-07-20 15:10:59 +0000158
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000159 return secTypeInvalid;
160}
161
Adam Tkac0c77e512010-07-20 15:10:16 +0000162const char* rfb::secTypeName(rdr::U32 num)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000163{
164 switch (num) {
165 case secTypeNone: return "None";
166 case secTypeVncAuth: return "VncAuth";
167 case secTypeTight: return "Tight";
168 case secTypeRA2: return "RA2";
169 case secTypeRA2ne: return "RA2ne";
170 case secTypeSSPI: return "SSPI";
171 case secTypeSSPIne: return "SSPIne";
Adam Tkacdfe19cf2010-04-23 14:14:11 +0000172 case secTypeVeNCrypt: return "VeNCrypt";
Adam Tkacb3e60c62010-07-20 15:10:59 +0000173
174 /* VeNCrypt subtypes */
Adam Tkac957a5ae2010-07-20 15:12:41 +0000175 case secTypePlain: return "Plain";
Adam Tkacb3e60c62010-07-20 15:10:59 +0000176 case secTypeTLSNone: return "TLSNone";
177 case secTypeTLSVnc: return "TLSVnc";
Adam Tkacb3e60c62010-07-20 15:10:59 +0000178 case secTypeTLSPlain: return "TLSPlain";
179 case secTypeX509None: return "X509None";
180 case secTypeX509Vnc: return "X509Vnc";
181 case secTypeX509Plain: return "X509Plain";
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000182 default: return "[unknown secType]";
183 }
184}
185
Adam Tkac0c77e512010-07-20 15:10:16 +0000186std::list<rdr::U32> rfb::parseSecTypes(const char* types_)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000187{
Adam Tkac0c77e512010-07-20 15:10:16 +0000188 std::list<rdr::U32> result;
Adam Tkacd36b6262009-09-04 10:57:20 +0000189 CharArray types(strDup(types_)), type;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000190 while (types.buf) {
191 strSplit(types.buf, ',', &type.buf, &types.buf);
Adam Tkac0c77e512010-07-20 15:10:16 +0000192 rdr::U32 typeNum = secTypeNum(type.buf);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000193 if (typeNum != secTypeInvalid)
194 result.push_back(typeNum);
195 }
196 return result;
197}