blob: 133e81c1f444b86dd98c168d849a88714b956c88 [file] [log] [blame]
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001/* Copyright (C) 2002-2004 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/Configuration.h>
26#include <rfb/Blacklist.h>
27#include <network/TcpSocket.h>
28
29static rfb::IntParameter http_port("HTTPPortNumber",
30 "TCP/IP port on which the server will serve the Java applet VNC Viewer ", 5800);
31static rfb::IntParameter port_number("PortNumber",
32 "TCP/IP port on which the server will accept connections", 5900);
33static rfb::StringParameter hosts("Hosts",
34 "Filter describing which hosts are allowed access to this server", "+");
35static rfb::BoolParameter localHost("LocalHost",
36 "Only accept connections from via the local loop-back network interface", false);
37
38namespace rfb {
39
40 namespace win32 {
41
42 class ConnHostDialog : public Dialog {
43 public:
44 ConnHostDialog() : Dialog(GetModuleHandle(0)) {}
45 bool showDialog(const TCHAR* pat) {
46 delete [] pattern.buf;
47 pattern.buf = tstrDup(pat);
48 return Dialog::showDialog(MAKEINTRESOURCE(IDD_CONN_HOST));
49 }
50 void initDialog() {
51 if (_tcslen(pattern.buf) == 0) {
52 delete [] pattern.buf;
53 pattern.buf = tstrDup(_T("+"));
54 }
55
56 if (pattern.buf[0] == _T('+'))
57 setItemChecked(IDC_ALLOW, true);
58 else
59 setItemChecked(IDC_DENY, true);
60
61 setItemString(IDC_HOST_PATTERN, &pattern.buf[1]);
62
63 delete [] pattern.buf;
64 pattern.buf = 0;
65 }
66 bool onOk() {
67 delete [] pattern.buf;
68 pattern.buf = 0;
69
70 TCharArray host = getItemString(IDC_HOST_PATTERN);
71
72 TCharArray newPat(_tcslen(host.buf)+2);
73 if (isItemChecked(IDC_ALLOW))
74 newPat.buf[0] = _T('+');
75 else
76 newPat.buf[0] = _T('-');
77 newPat.buf[1] = 0;
78 _tcscat(newPat.buf, host.buf);
79
80 network::TcpFilter::Pattern pat = network::TcpFilter::parsePattern(CStr(newPat.buf));
81 pattern.buf = TCharArray(network::TcpFilter::patternToStr(pat)).takeBuf();
82 return true;
83 }
84 const TCHAR* getPattern() {return pattern.buf;}
85 protected:
86 TCharArray pattern;
87 };
88
89 class ConnectionsPage : public PropSheetPage {
90 public:
91 ConnectionsPage(const RegKey& rk)
92 : PropSheetPage(GetModuleHandle(0), MAKEINTRESOURCE(IDD_CONNECTIONS)), regKey(rk) {}
93 void initDialog() {
94 vlog.debug("set IDC_PORT %d", (int)port_number);
95 setItemInt(IDC_PORT, port_number);
96 setItemInt(IDC_IDLE_TIMEOUT, rfb::Server::idleTimeout);
97 vlog.debug("set IDC_HTTP_PORT %d", (int)http_port);
98 setItemInt(IDC_HTTP_PORT, http_port);
99 setItemChecked(IDC_HTTP_ENABLE, http_port != 0);
100 enableItem(IDC_HTTP_PORT, http_port != 0);
101 setItemChecked(IDC_LOCALHOST, localHost);
102
103 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
104 while (SendMessage(listBox, LB_GETCOUNT, 0, 0))
105 SendMessage(listBox, LB_DELETESTRING, 0, 0);
106
107 CharArray tmp;
108 tmp.buf = hosts.getData();
109 while (tmp.buf) {
110 CharArray first;
111 strSplit(tmp.buf, ',', &first.buf, &tmp.buf);
112 if (strlen(first.buf))
113 SendMessage(listBox, LB_ADDSTRING, 0, (LPARAM)(const TCHAR*)TStr(first.buf));
114 }
115
116 onCommand(IDC_HOSTS, EN_CHANGE);
117 }
118 bool onCommand(int id, int cmd) {
119 switch (id) {
120 case IDC_HOSTS:
121 {
122 DWORD selected = SendMessage(GetDlgItem(handle, IDC_HOSTS), LB_GETCURSEL, 0, 0);
123 int count = SendMessage(GetDlgItem(handle, IDC_HOSTS), LB_GETCOUNT, 0, 0);
124 bool enable = selected != LB_ERR;
125 enableItem(IDC_HOST_REMOVE, enable);
126 enableItem(IDC_HOST_UP, enable && (selected > 0));
127 enableItem(IDC_HOST_DOWN, enable && (selected < count-1));
128 enableItem(IDC_HOST_EDIT, enable);
129 setChanged(isChanged());
130 }
131 return true;
132
133 case IDC_PORT:
134 if (cmd == EN_CHANGE) {
135 try {
136 if (getItemInt(IDC_PORT) > 100)
137 setItemInt(IDC_HTTP_PORT, getItemInt(IDC_PORT)-100);
138 } catch (...) {
139 }
140 }
141 case IDC_HTTP_PORT:
142 case IDC_IDLE_TIMEOUT:
143 if (cmd == EN_CHANGE)
144 setChanged(isChanged());
145 return false;
146
147 case IDC_HTTP_ENABLE:
148 enableItem(IDC_HTTP_PORT, isItemChecked(IDC_HTTP_ENABLE));
149 setChanged(isChanged());
150 return false;
151
152 case IDC_LOCALHOST:
153 enableItem(IDC_HOSTS, !isItemChecked(IDC_LOCALHOST));
154 enableItem(IDC_HOST_REMOVE, !isItemChecked(IDC_LOCALHOST));
155 enableItem(IDC_HOST_UP, !isItemChecked(IDC_LOCALHOST));
156 enableItem(IDC_HOST_DOWN, !isItemChecked(IDC_LOCALHOST));
157 enableItem(IDC_HOST_EDIT, !isItemChecked(IDC_LOCALHOST));
158 enableItem(IDC_HOST_ADD, !isItemChecked(IDC_LOCALHOST));
159 setChanged(isChanged());
160 return false;
161
162 case IDC_HOST_ADD:
163 if (hostDialog.showDialog(_T("")))
164 {
165 const TCHAR* pattern = hostDialog.getPattern();
166 if (pattern)
167 SendMessage(GetDlgItem(handle, IDC_HOSTS), LB_ADDSTRING, 0, (LPARAM)pattern);
168 }
169 return true;
170
171 case IDC_HOST_EDIT:
172 {
173 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
174 int item = SendMessage(listBox, LB_GETCURSEL, 0, 0);
175 TCharArray pattern(SendMessage(listBox, LB_GETTEXTLEN, item, 0)+1);
176 SendMessage(listBox, LB_GETTEXT, item, (LPARAM)pattern.buf);
177
178 if (hostDialog.showDialog(pattern.buf)) {
179 const TCHAR* newPat = hostDialog.getPattern();
180 if (newPat) {
181 item = SendMessage(listBox, LB_FINDSTRINGEXACT, item, (LPARAM)pattern.buf);
182 if (item != LB_ERR) {
183 SendMessage(listBox, LB_DELETESTRING, item, 0);
184 SendMessage(listBox, LB_INSERTSTRING, item, (LPARAM)newPat);
185 SendMessage(listBox, LB_SETCURSEL, item, 0);
186 onCommand(IDC_HOSTS, EN_CHANGE);
187 }
188 }
189 }
190 }
191 return true;
192
193 case IDC_HOST_UP:
194 {
195 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
196 int item = SendMessage(listBox, LB_GETCURSEL, 0, 0);
197 TCharArray pattern(SendMessage(listBox, LB_GETTEXTLEN, item, 0)+1);
198 SendMessage(listBox, LB_GETTEXT, item, (LPARAM)pattern.buf);
199 SendMessage(listBox, LB_DELETESTRING, item, 0);
200 SendMessage(listBox, LB_INSERTSTRING, item-1, (LPARAM)pattern.buf);
201 SendMessage(listBox, LB_SETCURSEL, item-1, 0);
202 onCommand(IDC_HOSTS, EN_CHANGE);
203 }
204 return true;
205
206 case IDC_HOST_DOWN:
207 {
208 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
209 int item = SendMessage(listBox, LB_GETCURSEL, 0, 0);
210 TCharArray pattern(SendMessage(listBox, LB_GETTEXTLEN, item, 0)+1);
211 SendMessage(listBox, LB_GETTEXT, item, (LPARAM)pattern.buf);
212 SendMessage(listBox, LB_DELETESTRING, item, 0);
213 SendMessage(listBox, LB_INSERTSTRING, item+1, (LPARAM)pattern.buf);
214 SendMessage(listBox, LB_SETCURSEL, item+1, 0);
215 onCommand(IDC_HOSTS, EN_CHANGE);
216 }
217 return true;
218
219 case IDC_HOST_REMOVE:
220 {
221 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
222 int item = SendMessage(listBox, LB_GETCURSEL, 0, 0);
223 SendMessage(listBox, LB_DELETESTRING, item, 0);
224 onCommand(IDC_HOSTS, EN_CHANGE);
225 }
226
227 }
228 return false;
229 }
230 bool onOk() {
231 regKey.setInt(_T("PortNumber"), getItemInt(IDC_PORT));
232 regKey.setInt(_T("LocalHost"), isItemChecked(IDC_LOCALHOST));
233 regKey.setInt(_T("IdleTimeout"), getItemInt(IDC_IDLE_TIMEOUT));
234 regKey.setInt(_T("HTTPPortNumber"), isItemChecked(IDC_HTTP_ENABLE) ? getItemInt(IDC_HTTP_PORT) : 0);
235
236 regKey.setString(_T("Hosts"), TCharArray(getHosts()).buf);
237 return true;
238 }
239 bool isChanged() {
240 try {
241 CharArray new_hosts = getHosts();
242 CharArray old_hosts = hosts.getData();
243 return (strcmp(new_hosts.buf, old_hosts.buf) != 0) ||
244 (localHost != isItemChecked(IDC_LOCALHOST)) ||
245 (port_number != getItemInt(IDC_PORT)) ||
246 (http_port != getItemInt(IDC_HTTP_PORT)) ||
247 ((http_port!=0) != (isItemChecked(IDC_HTTP_ENABLE)!=0)) ||
248 (rfb::Server::idleTimeout != getItemInt(IDC_IDLE_TIMEOUT));
249 } catch (rdr::Exception) {
250 return false;
251 }
252 }
253 char* getHosts() {
254 int bufLen = 1, i;
255 HWND listBox = GetDlgItem(handle, IDC_HOSTS);
256 for (i=0; i<SendMessage(listBox, LB_GETCOUNT, 0, 0); i++)
257 bufLen+=SendMessage(listBox, LB_GETTEXTLEN, i, 0)+1;
258 TCharArray hosts_str(bufLen);
259 hosts_str.buf[0] = 0;
260 TCHAR* outPos = hosts_str.buf;
261 for (i=0; i<SendMessage(listBox, LB_GETCOUNT, 0, 0); i++) {
262 outPos += SendMessage(listBox, LB_GETTEXT, i, (LPARAM)outPos);
263 outPos[0] = ',';
264 outPos[1] = 0;
265 outPos++;
266 }
267 return strDup(hosts_str.buf);
268 }
269 protected:
270 RegKey regKey;
271 ConnHostDialog hostDialog;
272 };
273
274 };
275
276};
277
278#endif