blob: 3d3c06cbf6f281b3747415b0319ead35a741c8d3 [file] [log] [blame]
Constantin Kaplinsky729598c2006-05-25 05:12:25 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18#ifndef WINVNCCONF_CONNECTIONS
19#define WINVNCCONF_CONNECTIONS
20
21#include <vector>
22
23#include <rfb_win32/Registry.h>
24#include <rfb_win32/Dialog.h>
25#include <rfb_win32/ModuleFileName.h>
26#include <rfb/Configuration.h>
27#include <rfb/Blacklist.h>
28#include <network/TcpSocket.h>
29
30static rfb::IntParameter http_port("HTTPPortNumber",
31 "TCP/IP port on which the server will serve the Java applet VNC Viewer ", 5800);
32static rfb::IntParameter port_number("PortNumber",
33 "TCP/IP port on which the server will accept connections", 5900);
34static rfb::StringParameter hosts("Hosts",
35 "Filter describing which hosts are allowed access to this server", "+");
36static rfb::BoolParameter localHost("LocalHost",
37 "Only accept connections from via the local loop-back network interface", false);
38
39namespace rfb {
40
41 namespace win32 {
42
43 class ConnHostDialog : public Dialog {
44 public:
45 ConnHostDialog() : Dialog(GetModuleHandle(0)) {}
46 bool showDialog(const TCHAR* pat) {
47 pattern.replaceBuf(tstrDup(pat));
48 return Dialog::showDialog(MAKEINTRESOURCE(IDD_CONN_HOST));
49 }
50 void initDialog() {
51 if (_tcslen(pattern.buf) == 0)
52 pattern.replaceBuf(tstrDup("+"));
53
54 if (pattern.buf[0] == _T('+'))
55 setItemChecked(IDC_ALLOW, true);
56 else if (pattern.buf[0] == _T('?'))
57 setItemChecked(IDC_QUERY, true);
58 else
59 setItemChecked(IDC_DENY, true);
60
61 setItemString(IDC_HOST_PATTERN, &pattern.buf[1]);
62 pattern.replaceBuf(0);
63 }
64 bool onOk() {
Adam Tkac934f63c2009-10-12 15:54:59 +000065 TCharArray host(getItemString(IDC_HOST_PATTERN));
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000066 TCharArray newPat(_tcslen(host.buf)+2);
67 if (isItemChecked(IDC_ALLOW))
68 newPat.buf[0] = _T('+');
69 else if (isItemChecked(IDC_QUERY))
70 newPat.buf[0] = _T('?');
71 else
72 newPat.buf[0] = _T('-');
73 newPat.buf[1] = 0;
74 _tcscat(newPat.buf, host.buf);
75
Pierre Ossmancd873172015-08-10 14:03:16 +020076 try {
77 network::TcpFilter::Pattern pat(network::TcpFilter::parsePattern(CStr(newPat.buf)));
78 pattern.replaceBuf(TCharArray(network::TcpFilter::patternToStr(pat)).takeBuf());
79 } catch(rdr::Exception e) {
80 MsgBox(NULL, TStr(e.str()), MB_ICONEXCLAMATION | MB_OK);
81 return false;
82 }
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000083 return true;
84 }
85 const TCHAR* getPattern() {return pattern.buf;}
86 protected:
87 TCharArray pattern;
88 };
89
90 class ConnectionsPage : public PropSheetPage {
91 public:
92 ConnectionsPage(const RegKey& rk)
93 : PropSheetPage(GetModuleHandle(0), MAKEINTRESOURCE(IDD_CONNECTIONS)), regKey(rk) {}
94 void initDialog() {
95 vlog.debug("set IDC_PORT %d", (int)port_number);
96 setItemInt(IDC_PORT, port_number ? port_number : 5900);
97 setItemChecked(IDC_RFB_ENABLE, port_number != 0);
98 setItemInt(IDC_IDLE_TIMEOUT, rfb::Server::idleTimeout);
99 vlog.debug("set IDC_HTTP_PORT %d", (int)http_port);
100 setItemInt(IDC_HTTP_PORT, http_port ? http_port : 5800);
101 setItemChecked(IDC_HTTP_ENABLE, http_port != 0);
102 enableItem(IDC_HTTP_PORT, http_port != 0);
103 setItemChecked(IDC_LOCALHOST, localHost);
104
105 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
106 while (SendMessage(listBox, LB_GETCOUNT, 0, 0))
107 SendMessage(listBox, LB_DELETESTRING, 0, 0);
108
109 CharArray tmp;
110 tmp.buf = hosts.getData();
111 while (tmp.buf) {
112 CharArray first;
113 strSplit(tmp.buf, ',', &first.buf, &tmp.buf);
114 if (strlen(first.buf))
115 SendMessage(listBox, LB_ADDSTRING, 0, (LPARAM)(const TCHAR*)TStr(first.buf));
116 }
117
118 onCommand(IDC_RFB_ENABLE, EN_CHANGE);
119 }
120 bool onCommand(int id, int cmd) {
121 switch (id) {
122 case IDC_HOSTS:
123 {
124 DWORD selected = SendMessage(GetDlgItem(handle, IDC_HOSTS), LB_GETCURSEL, 0, 0);
Pierre Ossman5c23b9e2015-03-03 16:26:03 +0100125 DWORD count = SendMessage(GetDlgItem(handle, IDC_HOSTS), LB_GETCOUNT, 0, 0);
126 bool enable = selected != (DWORD)LB_ERR;
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000127 enableItem(IDC_HOST_REMOVE, enable);
128 enableItem(IDC_HOST_UP, enable && (selected > 0));
Pierre Ossman5c23b9e2015-03-03 16:26:03 +0100129 enableItem(IDC_HOST_DOWN, enable && (selected+1 < count));
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000130 enableItem(IDC_HOST_EDIT, enable);
131 setChanged(isChanged());
132 }
133 return true;
134
135 case IDC_PORT:
136 if (cmd == EN_CHANGE) {
137 try {
138 setItemInt(IDC_HTTP_PORT, rfbPortToHTTP(getItemInt(IDC_PORT)));
139 } catch (...) {
140 }
141 }
142 case IDC_HTTP_PORT:
143 case IDC_IDLE_TIMEOUT:
144 if (cmd == EN_CHANGE)
145 setChanged(isChanged());
146 return false;
147
148 case IDC_HTTP_ENABLE:
149 case IDC_RFB_ENABLE:
150 case IDC_LOCALHOST:
151 {
152 // HTTP port
153 enableItem(IDC_HTTP_PORT, isItemChecked(IDC_HTTP_ENABLE) && isItemChecked(IDC_RFB_ENABLE));
154 enableItem(IDC_HTTP_ENABLE, isItemChecked(IDC_RFB_ENABLE));
155
156 // RFB port
157 enableItem(IDC_PORT, isItemChecked(IDC_RFB_ENABLE));
158
159 // Hosts
160 enableItem(IDC_LOCALHOST, isItemChecked(IDC_RFB_ENABLE));
161
162 bool enableHosts = !isItemChecked(IDC_LOCALHOST) && isItemChecked(IDC_RFB_ENABLE);
163 enableItem(IDC_HOSTS, enableHosts);
164 enableItem(IDC_HOST_ADD, enableHosts);
165 if (!enableHosts) {
166 enableItem(IDC_HOST_REMOVE, enableHosts);
167 enableItem(IDC_HOST_UP, enableHosts);
168 enableItem(IDC_HOST_DOWN, enableHosts);
169 enableItem(IDC_HOST_EDIT, enableHosts);
170 } else {
171 onCommand(IDC_HOSTS, EN_CHANGE);
172 }
173 setChanged(isChanged());
174 return false;
175 }
176
177 case IDC_HOST_ADD:
178 if (hostDialog.showDialog(_T("")))
179 {
180 const TCHAR* pattern = hostDialog.getPattern();
181 if (pattern)
182 SendMessage(GetDlgItem(handle, IDC_HOSTS), LB_ADDSTRING, 0, (LPARAM)pattern);
183 }
184 return true;
185
186 case IDC_HOST_EDIT:
187 {
188 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
189 int item = SendMessage(listBox, LB_GETCURSEL, 0, 0);
190 TCharArray pattern(SendMessage(listBox, LB_GETTEXTLEN, item, 0)+1);
191 SendMessage(listBox, LB_GETTEXT, item, (LPARAM)pattern.buf);
192
193 if (hostDialog.showDialog(pattern.buf)) {
194 const TCHAR* newPat = hostDialog.getPattern();
195 if (newPat) {
196 item = SendMessage(listBox, LB_FINDSTRINGEXACT, item, (LPARAM)pattern.buf);
197 if (item != LB_ERR) {
198 SendMessage(listBox, LB_DELETESTRING, item, 0);
199 SendMessage(listBox, LB_INSERTSTRING, item, (LPARAM)newPat);
200 SendMessage(listBox, LB_SETCURSEL, item, 0);
201 onCommand(IDC_HOSTS, EN_CHANGE);
202 }
203 }
204 }
205 }
206 return true;
207
208 case IDC_HOST_UP:
209 {
210 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
211 int item = SendMessage(listBox, LB_GETCURSEL, 0, 0);
212 TCharArray pattern(SendMessage(listBox, LB_GETTEXTLEN, item, 0)+1);
213 SendMessage(listBox, LB_GETTEXT, item, (LPARAM)pattern.buf);
214 SendMessage(listBox, LB_DELETESTRING, item, 0);
215 SendMessage(listBox, LB_INSERTSTRING, item-1, (LPARAM)pattern.buf);
216 SendMessage(listBox, LB_SETCURSEL, item-1, 0);
217 onCommand(IDC_HOSTS, EN_CHANGE);
218 }
219 return true;
220
221 case IDC_HOST_DOWN:
222 {
223 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
224 int item = SendMessage(listBox, LB_GETCURSEL, 0, 0);
225 TCharArray pattern(SendMessage(listBox, LB_GETTEXTLEN, item, 0)+1);
226 SendMessage(listBox, LB_GETTEXT, item, (LPARAM)pattern.buf);
227 SendMessage(listBox, LB_DELETESTRING, item, 0);
228 SendMessage(listBox, LB_INSERTSTRING, item+1, (LPARAM)pattern.buf);
229 SendMessage(listBox, LB_SETCURSEL, item+1, 0);
230 onCommand(IDC_HOSTS, EN_CHANGE);
231 }
232 return true;
233
234 case IDC_HOST_REMOVE:
235 {
236 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
237 int item = SendMessage(listBox, LB_GETCURSEL, 0, 0);
238 SendMessage(listBox, LB_DELETESTRING, item, 0);
239 onCommand(IDC_HOSTS, EN_CHANGE);
240 }
241
242 }
243 return false;
244 }
245 bool onOk() {
246 regKey.setInt(_T("PortNumber"), isItemChecked(IDC_RFB_ENABLE) ? getItemInt(IDC_PORT) : 0);
247 regKey.setInt(_T("IdleTimeout"), getItemInt(IDC_IDLE_TIMEOUT));
248 regKey.setInt(_T("HTTPPortNumber"), isItemChecked(IDC_HTTP_ENABLE) && isItemChecked(IDC_RFB_ENABLE)
249 ? getItemInt(IDC_HTTP_PORT) : 0);
250 regKey.setInt(_T("LocalHost"), isItemChecked(IDC_LOCALHOST));
251 regKey.setString(_T("Hosts"), TCharArray(getHosts()).buf);
252 return true;
253 }
254 bool isChanged() {
255 try {
Adam Tkac934f63c2009-10-12 15:54:59 +0000256 CharArray new_hosts(getHosts());
257 CharArray old_hosts(hosts.getData());
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000258 return (strcmp(new_hosts.buf, old_hosts.buf) != 0) ||
259 (localHost != isItemChecked(IDC_LOCALHOST)) ||
260 (port_number != getItemInt(IDC_PORT)) ||
261 (http_port != getItemInt(IDC_HTTP_PORT)) ||
262 ((http_port!=0) != (isItemChecked(IDC_HTTP_ENABLE)!=0)) ||
263 (rfb::Server::idleTimeout != getItemInt(IDC_IDLE_TIMEOUT));
264 } catch (rdr::Exception) {
265 return false;
266 }
267 }
268 char* getHosts() {
269 int bufLen = 1, i;
270 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
271 for (i=0; i<SendMessage(listBox, LB_GETCOUNT, 0, 0); i++)
272 bufLen+=SendMessage(listBox, LB_GETTEXTLEN, i, 0)+1;
273 TCharArray hosts_str(bufLen);
274 hosts_str.buf[0] = 0;
275 TCHAR* outPos = hosts_str.buf;
276 for (i=0; i<SendMessage(listBox, LB_GETCOUNT, 0, 0); i++) {
277 outPos += SendMessage(listBox, LB_GETTEXT, i, (LPARAM)outPos);
278 outPos[0] = ',';
279 outPos[1] = 0;
280 outPos++;
281 }
282 return strDup(hosts_str.buf);
283 }
284 int rfbPortToHTTP(int rfbPort) {
285 int offset = -100;
286 if (http_port)
287 offset = http_port - port_number;
288 int httpPort = rfbPort + offset;
289 if (httpPort <= 0)
290 httpPort = rfbPort;
291 return httpPort;
292 }
293
294 protected:
295 RegKey regKey;
296 ConnHostDialog hostDialog;
297 };
298
299 };
300
301};
302
303#endif