1 // $Id: MyXmlConfig.cpp 704 2012-03-14 14:55:15Z felfert $
2 //
3 // Copyright (C) 2006 The OpenNX Team
4 // Author: Fritz Elfert
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU Library General Public License as
8 // published by the Free Software Foundation; either version 2 of the
9 // License, or (at your option) any later version.
10 //
11 // This program 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 Library General Public
17 // License along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 //
21
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #if defined(__GNUG__) && !defined(__APPLE__)
27 #pragma implementation "MyXmlConfig.h"
28 #endif
29
30 // For compilers that support precompilation, includes "wx/wx.h".
31 #include "wx/wxprec.h"
32
33 #ifdef __BORLANDC__
34 #pragma hdrstop
35 #endif
36
37 #ifndef WX_PRECOMP
38 #include "wx/wx.h"
39 #endif
40
41 #include <wx/filename.h>
42 #include <wx/xml/xml.h>
43 #include <wx/arrimpl.cpp>
44 #include <wx/file.h>
45 #include <wx/mstream.h>
46 #include <wx/wfstream.h>
47 #include <wx/regex.h>
48 #include <wx/url.h>
49 #include <wx/config.h>
50 #include <wx/display.h>
51
52 class wxConfigBase;
53
54 #include "LibUSB.h"
55 #include "MyXmlConfig.h"
56 #include "WinShare.h"
57
58 #ifdef APP_OPENNX
59 # include "opennxApp.h"
60 #endif
61 #ifdef APP_WATCHUSBIP
62 # include "watchUsbIpApp.h"
63 #endif
64
65 #include "pwcrypt.h"
66 #include "osdep.h"
67
68 #ifdef APP_OPENNX
69 # ifdef HAVE_LIBCURL
70 # include <curl/curl.h>
71 # endif
72 #endif
73
74 #include "trace.h"
75 ENABLE_TRACE;
76
77 #define STR_TRUE wxT("true")
78 #define STR_FALSE wxT("false");
79 #define STR_ONE wxT("1")
80 #define STR_ZERO wxT("0")
81
82 // We use something the user cannot type here!
83 #define DUMMY_MD5_PASSWORD wxT("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b")
84 #define DUMMY_CLR_PASSWORD wxT("\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r")
85 #define DEFAULT_GUEST_USER wxT("NX guest user")
86
87 IMPLEMENT_DYNAMIC_CLASS(ShareGroup, wxObject);
88 IMPLEMENT_DYNAMIC_CLASS(SharedUsbDevice, wxObject);
89
90 WX_DEFINE_OBJARRAY(ArrayOfShareGroups);
91 WX_DEFINE_OBJARRAY(ArrayOfUsbForwards);
92
toString()93 wxString ShareGroup::toString()
94 {
95 wxString ret = wxT("Name: '");
96 ret.Append(m_sGroupName);
97 ret.Append(wxT("', Type: "));
98 switch (m_eType) {
99 case SharedResource::SHARE_UNKNOWN:
100 ret.Append(wxT("unknown"));
101 break;
102 case SharedResource::SHARE_SMB_DISK:
103 ret.Append(wxT("SMBdisk, Share: '"));
104 ret.Append(m_sShareName);
105 ret.Append(wxT("', Alias: '"));
106 ret.Append(m_sAlias);
107 ret.Append(wxT("'"));
108 break;
109 case SharedResource::SHARE_SMB_PRINTER:
110 ret.Append(wxT("SMBprinter, Share: '"));
111 ret.Append(m_sShareName);
112 ret.Append(wxT("', Alias: '"));
113 ret.Append(m_sAlias);
114 ret.Append(wxT("'"));
115 break;
116 case SharedResource::SHARE_CUPS_PRINTER:
117 ret.Append(wxT("CUPSprinter, Share: '"));
118 ret.Append(m_sShareName);
119 ret.Append(wxT("', Driver: '"));
120 ret.Append(m_sDriver);
121 ret.Append(wxT("', Public: "));
122 ret.Append(m_bPublic ? wxT("true") : wxT("false"));
123 ret.Append(wxT(", Default: "));
124 ret.Append(m_bDefault ? wxT("true") : wxT("false"));
125 break;
126 }
127 return ret;
128 }
129
operator ==(const ShareGroup & other)130 bool ShareGroup::operator ==(const ShareGroup &other)
131 {
132 if (m_eType != other.m_eType) return false;
133 if (m_sGroupName != other.m_sGroupName) return false;
134 if (m_sUsername != other.m_sUsername) return false;
135 if (m_sPassword != other.m_sPassword) return false;
136 if (m_sShareName != other.m_sShareName) return false;
137 switch (m_eType) {
138 case SharedResource::SHARE_UNKNOWN:
139 break;
140 case SharedResource::SHARE_SMB_DISK:
141 if (m_sAlias != other.m_sAlias) return false;
142 break;
143 case SharedResource::SHARE_SMB_PRINTER:
144 case SharedResource::SHARE_CUPS_PRINTER:
145 if (m_sDriver != other.m_sDriver) return false;
146 if (m_bPublic != other.m_bPublic) return false;
147 if (m_bDefault != other.m_bDefault) return false;
148 break;
149 }
150 return true;
151 }
152
operator !=(const ShareGroup & other)153 bool ShareGroup::operator !=(const ShareGroup &other)
154 {
155 return (!(*this == other));
156 }
157
operator ==(const SharedUsbDevice & other)158 bool SharedUsbDevice::operator ==(const SharedUsbDevice &other)
159 {
160 if (m_eMode != other.m_eMode) return false;
161 if (m_sVendor != other.m_sVendor) return false;
162 if (m_sProduct != other.m_sProduct) return false;
163 if (m_sSerial != other.m_sSerial) return false;
164 if (m_iVendorID != other.m_iVendorID) return false;
165 if (m_iProductID != other.m_iProductID) return false;
166 if (m_iClass != other.m_iClass) return false;
167 return true;
168 }
169
cmpNoMode(const SharedUsbDevice & other)170 bool SharedUsbDevice::cmpNoMode(const SharedUsbDevice &other)
171 {
172 if (m_sVendor != other.m_sVendor) return false;
173 if (m_sProduct != other.m_sProduct) return false;
174 if (m_sSerial != other.m_sSerial) return false;
175 if (m_iVendorID != other.m_iVendorID) return false;
176 if (m_iProductID != other.m_iProductID) return false;
177 if (m_iClass != other.m_iClass) return false;
178 return true;
179 }
180
operator !=(const SharedUsbDevice & other)181 bool SharedUsbDevice::operator !=(const SharedUsbDevice &other)
182 {
183 return (!(*this == other));
184 }
185
MatchHotplug(const USBDevice & udev)186 bool SharedUsbDevice::MatchHotplug(const USBDevice &udev)
187 {
188 if (m_iVendorID >= 0) {
189 if (m_iVendorID != udev.GetVendorID())
190 return false;
191 }
192 if (m_iProductID >= 0) {
193 if (m_iProductID != udev.GetProductID())
194 return false;
195 }
196 if (m_iClass >= 0) {
197 if (m_iClass != udev.GetDeviceClass())
198 return false;
199 }
200 if (!m_sVendor.IsEmpty()) {
201 if (!udev.GetVendor().StartsWith(m_sVendor))
202 return false;
203 }
204 if (!m_sProduct.IsEmpty()) {
205 if (!udev.GetProduct().StartsWith(m_sProduct))
206 return false;
207 }
208 if (!m_sSerial.IsEmpty()) {
209 if (!udev.GetSerial().StartsWith(m_sSerial))
210 return false;
211 }
212 return true;
213 }
214
toShortString()215 wxString SharedUsbDevice::toShortString()
216 {
217 wxString ret = m_sVendor.Strip(wxString::both);
218 if ((!ret.IsEmpty()) && (!m_sProduct.IsEmpty()))
219 ret.Append(wxT(" "));
220 ret.Append(m_sProduct.Strip(wxString::both));
221 return ret;
222 }
223
224 void
init()225 MyXmlConfig::init()
226 {
227 saved = NULL;
228 m_bDisableBackingstore = false;
229 m_bDisableComposite = false;
230 m_bDisableRender = false;
231 m_bDisableShmem = false;
232 m_bDisableShpix = false;
233 m_bDisableTaint = false;
234 m_bDisableTcpNoDelay = false;
235 m_bDisableXagent = false;
236 m_bDisableZlibCompression = false;
237 m_bEnableMultimedia = false;
238 m_bEnableSmbSharing = false;
239 m_bEnableSSL = true;
240 m_bEnableUSBIP = false;
241 m_bExternalProxy = false;
242 m_bGuestMode = false;
243 m_bKbdLayoutOther = false;
244 m_bOldConfig = false;
245 m_bProxyPassRemember = false;
246 m_bRdpCache = true;
247 m_bRdpRememberPassword = false;
248 m_bRdpRunApplication = false;
249 m_bRememberPassword = false;
250 m_bRemoveOldSessionFiles = true;
251 m_bRunConsole = false;
252 m_bRunXclients = false;
253 m_bUseCups = false;
254 m_bUseCustomImageEncoding = false;
255 m_bUseProxy = false;
256 m_bUseSmartCard = false;
257 m_bValid = false;
258 m_bWritable = true;
259 m_bVirtualDesktop = false;
260 m_bVncRememberPassword = false;
261 m_bVncUseNxAuth = false;
262 m_bDisableDirectDraw = false;
263 m_bDisableDeferredUpdates = false;
264 m_bGrabKeyboard = false;
265
266 m_iClipFilter = 2;
267 m_iCupsPort = 631;
268 m_iDisplayHeight = 480;
269 m_iDisplayWidth = 640;
270 m_iImageEncoding = 3;
271 m_iJpegQuality = 6;
272 m_iProxyPort = 3128;
273 m_iRdpAuthType = 1;
274 m_iRdpColors = 8;
275 m_iRdpImageEncoding = 3;
276 m_iRdpJpegQuality = 6;
277 m_iServerPort = 22;
278 m_iSmbPort = 445;
279 m_iUsedShareGroups = 0;
280 m_iVncDisplayNumber = 0;
281 m_iVncImageEncoding = 3;
282 m_iVncJpegQuality = 6;
283 m_iXdmBroadcastPort = 177;
284 m_iXdmListPort = 177;
285 m_iXdmQueryPort = 177;
286
287 m_eCacheDisk = CACHEDISK_32MB;
288 m_eCacheMemory = CACHEMEM_8MB;
289 m_eConnectionSpeed = SPEED_ADSL;
290 m_eDesktopType = DTYPE_KDE;
291 m_eDisplayType = DPTYPE_AVAILABLE;
292 m_eSessionType = STYPE_UNIX;
293 m_eXdmMode = XDM_MODE_SERVER;
294
295 m_sCommandLine = wxEmptyString;
296 wxConfigBase::Get()->Read(wxT("Config/CupsPath"), &m_sCupsPath);
297 if (m_sCupsPath.IsEmpty())
298 m_sCupsPath = wxT(CUPS_DEFAULT_PATH);
299 m_sFileName = wxEmptyString;
300 m_sGuestUser = wxEmptyString;
301 m_sGuestPassword = wxEmptyString;
302 m_sKbdLayoutLanguage = wxString(wxConvLocal.cMB2WX(x11_keyboard_type)).AfterFirst(wxT('/')).BeforeFirst(wxT(','));
303 m_sName = wxEmptyString;
304 m_sPassword = wxEmptyString;
305 m_sProxyCommand = wxEmptyString;
306 m_sProxyHost = wxEmptyString;
307 m_sProxyPass = wxEmptyString;
308 m_sProxyUser = wxEmptyString;
309 m_sRdpApplication = wxEmptyString;
310 m_sRdpDomain = wxEmptyString;
311 m_sRdpHostName = wxEmptyString;
312 m_sRdpPassword = wxEmptyString;
313 m_sRdpUsername = wxEmptyString;
314 m_sServerHost = wxEmptyString;
315 m_sSshKey = wxEmptyString;
316 m_sUsername = wxEmptyString;
317 m_sVncHostName = wxEmptyString;
318 m_sVncPassword = wxEmptyString;
319 m_sXdmListHost = wxT("localhost");
320 m_sXdmQueryHost = wxT("localhost");
321
322 m_pMd5Password = NULL;
323 m_pClrPassword = NULL;
324 }
325
MyXmlConfig()326 MyXmlConfig::MyXmlConfig()
327 {
328 init();
329 }
330
MyXmlConfig(const wxString & filename)331 MyXmlConfig::MyXmlConfig(const wxString &filename)
332 {
333 init();
334 if (filename.StartsWith(wxT("http://")) ||
335 filename.StartsWith(wxT("https://")) ||
336 filename.StartsWith(wxT("ftp://")) ||
337 filename.StartsWith(wxT("file://")))
338 LoadFromURL(filename);
339 else
340 LoadFromFile(filename);
341 }
342
~MyXmlConfig()343 MyXmlConfig::~MyXmlConfig()
344 {
345 if (saved)
346 delete saved;
347 if (m_pMd5Password)
348 delete m_pMd5Password;
349 if (m_pClrPassword)
350 delete m_pClrPassword;
351 }
352
353 MyXmlConfig &
operator =(const MyXmlConfig & other)354 MyXmlConfig::operator =(const MyXmlConfig &other)
355 {
356 saved = NULL;
357
358 m_bDisableBackingstore = other.m_bDisableBackingstore;
359 m_bDisableComposite = other.m_bDisableComposite;
360 m_bDisableRender = other.m_bDisableRender;
361 m_bDisableShmem = other.m_bDisableShmem;
362 m_bDisableShpix = other.m_bDisableShpix;
363 m_bDisableTaint = other.m_bDisableTaint;
364 m_bDisableTcpNoDelay = other.m_bDisableTcpNoDelay;
365 m_bDisableXagent = other.m_bDisableXagent;
366 m_bDisableZlibCompression = other.m_bDisableZlibCompression;
367 m_bEnableMultimedia = other.m_bEnableMultimedia;
368 m_bEnableSmbSharing = other.m_bEnableSmbSharing;
369 m_bEnableSSL = other.m_bEnableSSL;
370 m_bEnableUSBIP = other.m_bEnableUSBIP;
371 m_bExternalProxy = other.m_bExternalProxy;
372 m_bGuestMode = other.m_bGuestMode;
373 m_bKbdLayoutOther = other.m_bKbdLayoutOther;
374 m_bProxyPassRemember = other.m_bProxyPassRemember;
375 m_bRdpCache = other.m_bRdpCache;
376 m_bRdpRememberPassword = other.m_bRdpRememberPassword;
377 m_bRdpRunApplication = other.m_bRdpRunApplication;
378 m_bRememberPassword = other.m_bRememberPassword;
379 m_bRemoveOldSessionFiles = other.m_bRemoveOldSessionFiles;
380 m_bRunConsole = other.m_bRunConsole;
381 m_bRunXclients = other.m_bRunXclients;
382 m_bUseCups = other.m_bUseCups;
383 m_bUseCustomImageEncoding = other.m_bUseCustomImageEncoding;
384 m_bUseProxy = other.m_bUseProxy;
385 m_bUseSmartCard = other.m_bUseSmartCard;
386 m_bValid = other.m_bValid;
387 // Don't copy readonly flag
388 m_bVirtualDesktop = other.m_bVirtualDesktop;
389 m_bVncRememberPassword = other.m_bVncRememberPassword;
390 m_bVncUseNxAuth = other.m_bVncUseNxAuth;
391 m_bDisableDirectDraw = other.m_bDisableDirectDraw;
392 m_bDisableDeferredUpdates = other.m_bDisableDeferredUpdates;
393 m_bGrabKeyboard = other.m_bGrabKeyboard;
394
395 m_iClipFilter = other.m_iClipFilter;
396 m_iCupsPort = other.m_iCupsPort;
397 m_iDisplayHeight = other.m_iDisplayHeight;
398 m_iDisplayWidth = other.m_iDisplayWidth;
399 m_iImageEncoding = other.m_iImageEncoding;
400 m_iJpegQuality = other.m_iJpegQuality;
401 m_sKbdLayoutLanguage = other.m_sKbdLayoutLanguage;
402 m_iProxyPort = other.m_iProxyPort;
403 m_iRdpAuthType = other.m_iRdpAuthType;
404 m_iRdpColors = other.m_iRdpColors;
405 m_iRdpImageEncoding = other.m_iRdpImageEncoding;
406 m_iRdpJpegQuality = other.m_iRdpJpegQuality;
407 m_iServerPort = other.m_iServerPort;
408 m_iSmbPort = other.m_iSmbPort;
409 m_iUsedShareGroups = other.m_iUsedShareGroups;
410 m_iVncDisplayNumber = other.m_iVncDisplayNumber;
411 m_iVncImageEncoding = other.m_iVncImageEncoding;
412 m_iVncJpegQuality = other.m_iVncJpegQuality;
413 m_iXdmBroadcastPort = other.m_iXdmBroadcastPort;
414 m_iXdmListPort = other.m_iXdmListPort;
415 m_iXdmQueryPort = other.m_iXdmQueryPort;
416
417 m_eCacheDisk = other.m_eCacheDisk;
418 m_eCacheMemory = other.m_eCacheMemory;
419 m_eConnectionSpeed = other.m_eConnectionSpeed;
420 m_eDesktopType = other.m_eDesktopType;
421 m_eDisplayType = other.m_eDisplayType;
422 m_eSessionType = other.m_eSessionType;
423 m_eXdmMode = other.m_eXdmMode;
424
425 m_sCommandLine = other.m_sCommandLine;
426 m_sCupsPath = other.m_sCupsPath;
427 m_sGuestPassword = other.m_sGuestPassword;
428 m_sGuestUser = other.m_sGuestUser;
429 m_sName = other.m_sName;
430 m_sPassword = other.m_sPassword;
431 m_sProxyCommand = other.m_sProxyCommand;
432 m_sProxyHost = other.m_sProxyHost;
433 m_sProxyPass = other.m_sProxyPass;
434 m_sProxyUser = other.m_sProxyUser;
435 m_sRdpApplication = other.m_sRdpApplication;
436 m_sRdpDomain = other.m_sRdpDomain;
437 m_sRdpHostName = other.m_sRdpHostName;
438 m_sRdpPassword = other.m_sRdpPassword;
439 m_sRdpUsername = other.m_sRdpUsername;
440 m_sServerHost = other.m_sServerHost;
441 m_sSshKey = other.m_sSshKey;
442 m_sUsername = other.m_sUsername;
443 m_sVncHostName = other.m_sVncHostName;
444 m_sVncPassword = other.m_sVncPassword;
445 m_sXdmListHost = other.m_sXdmListHost;
446 m_sXdmQueryHost = other.m_sXdmQueryHost;
447
448 m_aShareGroups = other.m_aShareGroups;
449 m_aUsedShareGroups = other.m_aUsedShareGroups;
450 m_aUsbForwards = other.m_aUsbForwards;
451
452 if (other.m_pMd5Password) {
453 if (m_pMd5Password)
454 delete m_pMd5Password;
455 m_pMd5Password = new wxString(*other.m_pMd5Password);
456 }
457 if (other.m_pClrPassword) {
458 if (m_pClrPassword)
459 delete m_pClrPassword;
460 m_pClrPassword = new wxString(*other.m_pClrPassword);
461 }
462 return *this;
463 }
464
465 // Retrieve parameters for proxy otion file
466 wxString
sGetProxyParams(const long protocolVersion)467 MyXmlConfig::sGetProxyParams(const long protocolVersion)
468 {
469 wxUnusedVar(protocolVersion);
470 wxString ret = wxEmptyString;
471 ret << wxT(",shmem=") << (m_bDisableShmem ? 0 : 1)
472 << wxT(",shpix=") << (m_bDisableShpix ? 0 : 1)
473 ;
474 // FIXME: use real settings
475 ret << wxT(",font=1");
476 return ret;
477 }
478
479 // Retrieve parameters for listsession command
480 wxString
sGetListParams(const long protocolVersion)481 MyXmlConfig::sGetListParams(const long protocolVersion)
482 {
483 wxUnusedVar(protocolVersion);
484 wxString ret = wxT(" --user=\"");
485 if (m_eSessionType == STYPE_SHADOW) {
486 ret = wxT(" --type=\"shadow\"");
487 return ret;
488 }
489 if (m_bGuestMode) {
490 if (m_sGuestUser.IsEmpty())
491 ret << DEFAULT_GUEST_USER;
492 else
493 ret << m_sGuestUser;
494 } else
495 ret << m_sUsername;
496 if (protocolVersion >= 0x00040000)
497 ret << wxT("\" --status=\"disconnected,connected\"");
498 else
499 ret << wxT("\" --status=\"suspended,running\"");
500 ret << wxT(" --type=\"");
501 switch (m_eSessionType) {
502 case STYPE_SHADOW:
503 break;
504 case STYPE_UNIX:
505 ret << wxT("unix-");
506 switch (m_eDesktopType) {
507 case DTYPE_ANY:
508 case DTYPE_RDP:
509 case DTYPE_RFB:
510 break;
511 case DTYPE_KDE:
512 ret << wxT("kde\"");
513 break;
514 case DTYPE_GNOME:
515 ret << wxT("gnome\"");
516 break;
517 case DTYPE_CDE:
518 ret << wxT("cde\"");
519 break;
520 case DTYPE_XFCE:
521 ret << wxT("xfce\"");
522 break;
523 case DTYPE_XDM:
524 ret << wxT("xdm\"");
525 break;
526 case DTYPE_CUSTOM:
527 if (m_bRunConsole)
528 ret << wxT("console\"");
529 else if (m_bRunXclients)
530 ret << wxT("default\"");
531 else
532 ret << wxT("application\"");
533 break;
534 }
535 break;
536 case STYPE_WINDOWS:
537 ret << wxT("windows\"");
538 break;
539 case STYPE_VNC:
540 ret << wxT("vnc\"");
541 break;
542 }
543 int w, h;
544 ::wxDisplaySize(&w, &h);
545 ret << wxT(" --geometry=\"") << w << wxT("x") << h << wxT("x")
546 << ::wxDisplayDepth() << (m_bDisableRender ? wxEmptyString : wxT("+render"))
547 << ((m_eDisplayType == DPTYPE_FULLSCREEN) ? wxT("+fullscreen") : wxEmptyString)
548 << wxT("\"");
549 return ret;
550 }
551
552 wxString
UrlEsc(const wxString & s)553 MyXmlConfig::UrlEsc(const wxString &s)
554 {
555 size_t len = s.Length();
556 wxString ret;
557 for (size_t i = 0; i < len; i++) {
558 switch (s[i]) {
559 case wxT(' '):
560 case wxT(':'):
561 case wxT('"'):
562 case wxT('&'):
563 case wxT('$'):
564 case wxT('`'):
565 case wxT('\''):
566 case wxT('\\'):
567 ret << wxString::Format(wxT("%%%02X"), s[i]);
568 break;
569 default:
570 ret << s[i];
571 }
572 }
573 return ret;
574 }
575
576 void
getDesktopSize(int & dw,int & dh,int & ww,int & wh)577 MyXmlConfig::getDesktopSize(int &dw, int &dh, int &ww, int &wh)
578 {
579 // Fetch the size of the display and the workarea
580 // (workarea == display size reduced by the size of the taskbar and window
581 // decorations) where our toplevel dialog are shown.
582 wxWindow *tlw = ::wxGetApp().GetTopWindow();
583 if (NULL == tlw) {
584 ::wxLogError(_("Could not find application window"));
585 return;
586 }
587 int dspidx = wxDisplay::GetFromWindow(tlw);
588 wxDisplay dsp(dspidx);
589 wxRect r = dsp.GetGeometry();
590 dw = r.GetWidth();
591 dh = r.GetHeight();
592 r = dsp.GetClientArea();
593 wxSize sz = tlw->GetSize();
594 wxSize clsz = tlw->GetClientSize();
595 ww = r.GetWidth() - (sz.GetWidth() - clsz.GetWidth());
596 wh = r.GetHeight() - (sz.GetHeight() - clsz.GetHeight());
597 ::myLogTrace(MYTRACETAG, wxT("Display: %dx%d, Workarea: %dx%d (netto: %d,%d)"),
598 dw, dh, r.GetWidth(), r.GetHeight(), ww, wh);
599 }
600
601 // Retrieve parameters for startsession command
602 wxString
sGetSessionParams(const long protocolVersion,bool bNew,const wxString & clrpass)603 MyXmlConfig::sGetSessionParams(const long protocolVersion, bool bNew, const wxString &clrpass)
604 {
605 wxUnusedVar(protocolVersion);
606 wxString ret = wxEmptyString;
607 bool bNeedGeometry = true;
608 int dspw, dsph, clientw, clienth;
609
610 getDesktopSize(dspw, dsph, clientw, clienth);
611 ret << wxString::Format(wxT(" --session=\"%s\""), m_sName.c_str());
612 ret << wxT(" --type=\"");
613 switch (m_eSessionType) {
614 case STYPE_SHADOW:
615 ret << wxT("shadow\"");
616 if (m_bUseCustomImageEncoding) {
617 ret << wxT(" --imagecompressionmethod=\"") << m_iImageEncoding << wxT("\"")
618 << wxT(" --imagecompressionlevel=\"")
619 << (((-1 == m_iImageEncoding) || (4 == m_iImageEncoding)) ? m_iJpegQuality : -1) << wxT("\"");
620 }
621 break;
622 case STYPE_UNIX:
623 ret << wxT("unix-");
624 switch (m_eDesktopType) {
625 case DTYPE_ANY:
626 case DTYPE_RDP:
627 case DTYPE_RFB:
628 break;
629 case DTYPE_KDE:
630 ret << wxT("kde\"");
631 break;
632 case DTYPE_GNOME:
633 ret << wxT("gnome\"");
634 break;
635 case DTYPE_CDE:
636 ret << wxT("cde\"");
637 break;
638 case DTYPE_XFCE:
639 ret << wxT("xfce\"");
640 break;
641 case DTYPE_XDM:
642 ret << wxT("xdm\"");
643 switch (m_eXdmMode) {
644 case XDM_MODE_SERVER:
645 ret << wxT(" --xdm_port=\"-1\"");
646 break;
647 case XDM_MODE_QUERY:
648 ret << wxT(" --xdm_type=\"query\"")
649 << wxT(" --xdm_host=\"") << m_sXdmQueryHost << wxT("\"")
650 << wxT(" --xdm_port=\"") << m_iXdmQueryPort << wxT("\"");
651 break;
652 case XDM_MODE_BROADCAST:
653 ret << wxT(" --xdm_type=\"broadcast\"")
654 << wxT(" --xdm_port=\"") << m_iXdmBroadcastPort << wxT("\"");
655 break;
656 case XDM_MODE_LIST:
657 ret << wxT(" --xdm_type=\"list\"")
658 << wxT(" --xdm_host=\"") << m_sXdmListHost << wxT("\"")
659 << wxT(" --xdm_port=\"") << m_iXdmListPort << wxT("\"");
660 break;
661 }
662 break;
663 case DTYPE_CUSTOM:
664 if (m_bRunConsole)
665 ret << wxT("console\"");
666 else if (m_bRunXclients)
667 ret << wxT("default\"");
668 else {
669 bNeedGeometry = false;
670 ret << wxT("application\"");
671 ret << wxT(" --rootless=\"")
672 << (m_bVirtualDesktop ? 0 : 1)
673 << wxT("\" --virtualdesktop=\"")
674 << (m_bVirtualDesktop ? 1 : 0)
675 << wxT("\" --application=\"")
676 << UrlEsc(m_sCommandLine) << wxT("\"");
677 }
678 break;
679 }
680 if (m_bUseCustomImageEncoding) {
681 ret << wxT(" --imagecompressionmethod=\"") << m_iImageEncoding << wxT("\"")
682 << wxT(" --imagecompressionlevel=\"")
683 << (((-1 == m_iImageEncoding) || (4 == m_iImageEncoding)) ? m_iJpegQuality : -1) << wxT("\"");
684 }
685 break;
686 case STYPE_WINDOWS:
687 ret << wxT("windows\"")
688 << wxT(" --agent_server=\"") << UrlEsc(m_sRdpHostName)
689 << wxT("\" --agent_domain=\"") << UrlEsc(m_sRdpDomain)
690 << wxT("\"");
691 switch (m_iRdpAuthType) {
692 case 0:
693 // use specified user/passwd
694 ret << wxT(" --agent_user=\"") << UrlEsc(m_sRdpUsername)
695 << wxT("\" --agent_password=\"") << UrlEsc(m_sRdpPassword)
696 << wxT("\"");
697 break;
698 case 1:
699 // show winlogon (empty username and password)
700 break;
701 case 2:
702 // use NX credentials
703 ret << wxT(" --agent_user=\"") << UrlEsc(sGetSessionUser())
704 << wxT("\" --agent_password=\"")
705 << UrlEsc(m_bRememberPassword ? sGetSessionPassword() : clrpass)
706 << wxT("\"");
707 break;
708 break;
709 }
710 if (m_bRdpRunApplication)
711 ret << wxT(" --application=\"") << UrlEsc(m_sRdpApplication) << wxT("\"");
712 if (m_bUseCustomImageEncoding) {
713 ret << wxT(" --rdpcolors=\"");
714 switch (m_iRdpColors) {
715 case 0:
716 ret << wxT("256\"");
717 break;
718 case 1:
719 ret << wxT("32K\"");
720 break;
721 case 2:
722 ret << wxT("64K\"");
723 break;
724 case 3:
725 ret << wxT("16M\"");
726 break;
727 }
728 ret << wxT(" --rdpcache=\"") << (m_bRdpCache ? 1 : 0) << wxT("\"")
729 << wxT(" --imagecompressionmethod=\"") << m_iRdpImageEncoding << wxT("\"")
730 << wxT(" --imagecompressionlevel=\"")
731 << (((-1 == m_iRdpImageEncoding) || (4 == m_iRdpImageEncoding)) ? m_iRdpJpegQuality : -1)
732 << wxT("\"");
733 }
734 break;
735 case STYPE_VNC:
736 ret << wxT("vnc\"")
737 << wxT(" --agent_server=\"")
738 << UrlEsc(m_sVncHostName) << wxT("%3A") << m_iVncDisplayNumber
739 << wxT("\" --agent_password=\"") << UrlEsc(m_sVncPassword) << wxT("\"");
740 if (m_bUseCustomImageEncoding) {
741 ret << wxT(" --imagecompressionmethod=\"") << m_iVncImageEncoding << wxT("\"")
742 << wxT(" --imagecompressionlevel=\"")
743 << (((-1 == m_iVncImageEncoding) || (4 == m_iVncImageEncoding)) ? m_iVncJpegQuality : -1)
744 << wxT("\"");
745 }
746 break;
747 }
748 ret << wxT(" --cache=\"");
749 switch (m_eCacheMemory) {
750 case CACHEMEM_0MB:
751 ret << wxT("0M\"");
752 break;
753 case CACHEMEM_1MB:
754 ret << wxT("1M\"");
755 break;
756 case CACHEMEM_2MB:
757 ret << wxT("2M\"");
758 break;
759 case CACHEMEM_4MB:
760 ret << wxT("4M\"");
761 break;
762 case CACHEMEM_8MB:
763 ret << wxT("8M\"");
764 break;
765 case CACHEMEM_16MB:
766 ret << wxT("16M\"");
767 break;
768 case CACHEMEM_32MB:
769 ret << wxT("32M\"");
770 break;
771 case CACHEMEM_64MB:
772 ret << wxT("64M\"");
773 break;
774 case CACHEMEM_128MB:
775 ret << wxT("128M\"");
776 break;
777 }
778 ret << wxT(" --images=\"");
779 switch (m_eCacheDisk) {
780 case CACHEDISK_0MB:
781 ret << wxT("0M\"");
782 break;
783 case CACHEDISK_4MB:
784 ret << wxT("4M\"");
785 break;
786 case CACHEDISK_8MB:
787 ret << wxT("8M\"");
788 break;
789 case CACHEDISK_16MB:
790 ret << wxT("16M\"");
791 break;
792 case CACHEDISK_32MB:
793 ret << wxT("32M\"");
794 break;
795 case CACHEDISK_64MB:
796 ret << wxT("64M\"");
797 break;
798 case CACHEDISK_128MB:
799 ret << wxT("128M\"");
800 break;
801 case CACHEDISK_256MB:
802 ret << wxT("256M\"");
803 break;
804 case CACHEDISK_512MB:
805 ret << wxT("512M\"");
806 break;
807 }
808 ret << wxT(" --link=\"");
809 switch (m_eConnectionSpeed) {
810 case SPEED_MODEM:
811 ret << wxT("modem\"");
812 break;
813 case SPEED_ISDN:
814 ret << wxT("isdn\"");
815 break;
816 case SPEED_ADSL:
817 ret << wxT("adsl\"");
818 break;
819 case SPEED_WAN:
820 ret << wxT("wan\"");
821 break;
822 case SPEED_LAN:
823 ret << wxT("lan\"");
824 break;
825 }
826 if (bNeedGeometry) {
827 ret << wxT(" --geometry=\"");
828 switch (m_eDisplayType) {
829 case DPTYPE_640x480:
830 ret << wxT("640x480\"");
831 break;
832 case DPTYPE_800x600:
833 ret << wxT("800x600\"");
834 break;
835 case DPTYPE_1024x768:
836 ret << wxT("1024x768\"");
837 break;
838 case DPTYPE_AVAILABLE:
839 ret << wxString::Format(wxT("%dx%d\""), clientw, clienth);
840 break;
841 case DPTYPE_FULLSCREEN:
842 ret << wxString::Format(wxT("%dx%d\""), dspw, dsph)
843 << wxT(" --fullscreen=\"1\"");
844 break;
845 case DPTYPE_CUSTOM:
846 ret << wxString::Format(wxT("%dx%d\""), m_iDisplayWidth, m_iDisplayHeight);
847 break;
848 case DPTYPE_REMOTE:
849 ret << wxString::Format(wxT("%dx%d\""), dspw, dsph);
850 break;
851 }
852 }
853 if (m_eSessionType != STYPE_SHADOW) {
854 ret << wxT(" --screeninfo=\"") << dspw << wxT("x") << dsph << wxT("x")
855 << ::wxDisplayDepth() << (m_bDisableRender ? wxEmptyString : wxT("+render"))
856 << ((m_eDisplayType == DPTYPE_FULLSCREEN) ? wxT("+fullscreen") : wxEmptyString)
857 << wxT("\"");
858 }
859
860 wxString kbdLocal = wxString(wxConvLocal.cMB2WX(x11_keyboard_type)).BeforeFirst(wxT(','));
861 ret << wxT(" --keyboard=\"");
862 if (m_bKbdLayoutOther) {
863 if (wxNOT_FOUND != kbdLocal.Find(wxT('/')))
864 ret << kbdLocal.BeforeFirst(wxT('/')) << wxT("/");
865 ret << m_sKbdLayoutLanguage;
866 } else {
867 if (kbdLocal.IsEmpty())
868 kbdLocal = wxT("query");
869 ret << kbdLocal;
870 }
871 ret << wxT("\"")
872 << wxT(" --backingstore=\"") << (m_bDisableBackingstore ? 0 : 1) << wxT("\"")
873 << wxT(" --encryption=\"") << (m_bEnableSSL ? 1 : 0) << wxT("\"");
874 if (bNew) {
875 ret << wxT(" --render=\"") << (m_bDisableRender ? 0 : 1) << wxT("\"");
876 }
877 ret << wxT(" --composite=\"") << (m_bDisableComposite ? 0 : 1) << wxT("\"")
878 << wxT(" --shmem=\"") << (m_bDisableShmem ? 0 : 1) << wxT("\"")
879 << wxT(" --shpix=\"") << (m_bDisableShpix ? 0 : 1) << wxT("\"");
880 // deprecated << wxT(" --streaming=\"") << (m_bDisableStreaming ? 0 : 1) << wxT("\"")
881 if (bNew) {
882 ret << wxT(" --samba=\"") << (m_bEnableSmbSharing ? 1 : 0) << wxT("\"")
883 << wxT(" --cups=\"") << (m_bUseCups ? 1 : 0) << wxT("\"")
884 << wxT(" --nodelay=\"") << (m_bDisableTcpNoDelay ? 0 : 1) << wxT("\"")
885 << wxT(" --defer=\"") << (m_bDisableDeferredUpdates ? 1 : 0) << wxT("\"");
886 }
887 #ifdef __WXMAC__
888 ret << wxT(" --client=\"macosx\"");
889 #else
890 # ifdef __UNIX__
891 ret << wxT(" --client=\"linux\"");
892 # else
893 // << wxT(" --client=\"winnt\"")
894 ret << wxT(" --client=\"linux\"");
895 # endif
896 #endif
897 ret << wxT(" --media=\"") << (m_bEnableMultimedia ? 1 : 0) << wxT("\"");
898 if (m_bEnableMultimedia) {
899 ret << wxT(" --mediahelper=\"esd\"");
900 }
901 // Original always uses those?!
902 ret << wxT(" --strict=\"0\"");
903 if (bNew) {
904 // With this parameter set, attaching to shadow sessions fails, if the server's display base is >= 10000
905 // so we simply leave it out for shadow sessions.
906 ret << wxT(" --aux=\"1\"");
907 }
908 return ret;
909 }
910
911 #ifdef __WXMSW__
912 wxString
sGetXserverParams(bool forNXWin)913 MyXmlConfig::sGetXserverParams(bool forNXWin)
914 {
915 wxString ret;
916 int dspw, dsph, clientw, clienth;
917 getDesktopSize(dspw, dsph, clientw, clienth);
918
919 if (forNXWin) {
920 switch (m_eDisplayType) {
921 case MyXmlConfig::DPTYPE_640x480:
922 ret << wxT(" -screen 0 640x480");
923 break;
924 case MyXmlConfig::DPTYPE_800x600:
925 // fall thru
926 default:
927 ret << wxT(" -screen 0 800x600");
928 break;
929 case MyXmlConfig::DPTYPE_1024x768:
930 ret << wxT(" -screen 0 1024x768");
931 break;
932 case MyXmlConfig::DPTYPE_AVAILABLE:
933 ret << wxT(" -screen 0 ") << clientw << wxT("x") << clienth;
934 break;
935 case MyXmlConfig::DPTYPE_FULLSCREEN:
936 ret << wxT(" -fullscreen ");
937 break;
938 case MyXmlConfig::DPTYPE_CUSTOM:
939 // Fall thru
940 case MyXmlConfig::DPTYPE_REMOTE:
941 ret << wxT(" -screen 0 ") << m_iDisplayWidth << wxT("x") << m_iDisplayHeight;
942 break;
943 }
944 } else {
945 if (MyXmlConfig::DPTYPE_FULLSCREEN == m_eDisplayType) {
946 ret << wxT(" -terminate -fullscreen -hide");
947 } else {
948 ret << wxT(" -noreset -lesspointer -multiwindow");
949 }
950 }
951 if (m_bDisableDirectDraw)
952 ret << wxT(" -engine 1");
953 ret << wxT(" -") << (m_bGrabKeyboard ? wxT("") : wxT("no")) << wxT("keyhook");
954 return ret;
955 }
956 #endif
957
958 ShareGroup &
findShare(const wxString & name)959 MyXmlConfig::findShare(const wxString &name)
960 {
961 size_t cnt = m_aShareGroups.GetCount();
962 static ShareGroup ret;
963 for (size_t i = 0; i < cnt; i++) {
964 if (m_aShareGroups[i].m_sGroupName == name)
965 return m_aShareGroups[i];
966 }
967 return ret;
968 }
969
970 // Compare two arrays of ShareGroup where sequence of elements is irrelevant
971 // return true, if arrays are different.
972 bool
cmpShareGroups(ArrayOfShareGroups a1,ArrayOfShareGroups a2)973 MyXmlConfig::cmpShareGroups(ArrayOfShareGroups a1, ArrayOfShareGroups a2)
974 {
975 size_t cnt = a1.GetCount();
976 if (cnt != a2.GetCount())
977 return true;
978 ArrayOfShareGroups ca = a2;
979 for (size_t i = 0; i < cnt; i++) {
980 size_t cnt2 = ca.GetCount();
981 int idx = wxNOT_FOUND;
982 for (size_t j = 0; j < cnt2; j++) {
983 if (a1[i] == ca[j]) {
984 idx = j;
985 break;
986 }
987 }
988 if (idx == wxNOT_FOUND)
989 return true;
990 ca.RemoveAt(idx);
991 }
992 return (ca.GetCount() != 0);
993 }
994
995 // Compare two arrays of UsbForwards where sequence of elements is irrelevant
996 // return true, if arrays are different.
997 bool
cmpUsbForwards(ArrayOfUsbForwards a1,ArrayOfUsbForwards a2)998 MyXmlConfig::cmpUsbForwards(ArrayOfUsbForwards a1, ArrayOfUsbForwards a2)
999 {
1000 size_t cnt = a1.GetCount();
1001 if (cnt != a2.GetCount())
1002 return true;
1003 ArrayOfUsbForwards ca = a2;
1004 for (size_t i = 0; i < cnt; i++) {
1005 size_t cnt2 = ca.GetCount();
1006 int idx = wxNOT_FOUND;
1007 for (size_t j = 0; j < cnt2; j++) {
1008 if (a1[i] == ca[j]) {
1009 idx = j;
1010 break;
1011 }
1012 }
1013 if (idx == wxNOT_FOUND)
1014 return true;
1015 ca.RemoveAt(idx);
1016 }
1017 return (ca.GetCount() != 0);
1018 }
1019
1020 // Compare two wxArrayString where sequence of elements is irrelevant
1021 // return true, if arrays are different.
1022 bool
cmpUsedShareGroups(wxArrayString a1,wxArrayString a2)1023 MyXmlConfig::cmpUsedShareGroups(wxArrayString a1, wxArrayString a2)
1024 {
1025 size_t cnt = a1.GetCount();
1026 if (cnt != a2.GetCount())
1027 return true;
1028 wxArrayString ca = a2;
1029 for (size_t i = 0; i < cnt; i++) {
1030 int idx = ca.Index(a1.Item(i));
1031 if (idx == wxNOT_FOUND)
1032 return true;
1033 ca.RemoveAt(idx);
1034 }
1035 return (ca.GetCount() != 0);
1036 }
1037
1038 bool
operator ==(const MyXmlConfig & other)1039 MyXmlConfig::operator ==(const MyXmlConfig &other)
1040 {
1041 if (m_bDisableBackingstore != other.m_bDisableBackingstore) return false;
1042 if (m_bDisableComposite != other.m_bDisableComposite) return false;
1043 if (m_bDisableRender != other.m_bDisableRender) return false;
1044 if (m_bDisableShmem != other.m_bDisableShmem) return false;
1045 if (m_bDisableShpix != other.m_bDisableShpix) return false;
1046 if (m_bDisableTaint != other.m_bDisableTaint) return false;
1047 if (m_bDisableTcpNoDelay != other.m_bDisableTcpNoDelay) return false;
1048 if (m_bDisableXagent != other.m_bDisableXagent) return false;
1049 if (m_bDisableZlibCompression != other.m_bDisableZlibCompression) return false;
1050 if (m_bEnableMultimedia != other.m_bEnableMultimedia) return false;
1051 if (m_bEnableSmbSharing != other.m_bEnableSmbSharing) return false;
1052 if (m_bEnableSSL != other.m_bEnableSSL) return false;
1053 if (m_bEnableUSBIP != other.m_bEnableUSBIP) return false;
1054 if (m_bExternalProxy != other.m_bExternalProxy) return false;
1055 if (m_bGuestMode != other.m_bGuestMode) return false;
1056 if (m_bKbdLayoutOther != other.m_bKbdLayoutOther) return false;
1057 if (m_bProxyPassRemember != other.m_bProxyPassRemember) return false;
1058 if (m_bRdpCache != other.m_bRdpCache) return false;
1059 if (m_bRdpRememberPassword != other.m_bRdpRememberPassword) return false;
1060 if (m_bRdpRunApplication != other.m_bRdpRunApplication) return false;
1061 if (m_bRememberPassword != other.m_bRememberPassword) return false;
1062 if (m_bRemoveOldSessionFiles != other.m_bRemoveOldSessionFiles) return false;
1063 if (m_bRunConsole != other.m_bRunConsole) return false;
1064 if (m_bRunXclients != other.m_bRunXclients) return false;
1065 if (m_bUseCups != other.m_bUseCups) return false;
1066 if (m_bUseCustomImageEncoding != other.m_bUseCustomImageEncoding) return false;
1067 if (m_bUseProxy != other.m_bUseProxy) return false;
1068 if (m_bUseSmartCard != other.m_bUseSmartCard) return false;
1069 if (m_bValid != other.m_bValid) return false;
1070 // Don't compare readonly flag
1071 if (m_bVirtualDesktop != other.m_bVirtualDesktop) return false;
1072 if (m_bVncRememberPassword != other.m_bVncRememberPassword) return false;
1073 if (m_bVncUseNxAuth != other.m_bVncUseNxAuth) return false;
1074 if (m_bDisableDirectDraw != other.m_bDisableDirectDraw) return false;
1075 if (m_bDisableDeferredUpdates != other.m_bDisableDeferredUpdates) return false;
1076 if (m_bGrabKeyboard != other.m_bGrabKeyboard) return false;
1077
1078 if (m_iClipFilter != other.m_iClipFilter) return false;
1079 if (m_iCupsPort != other.m_iCupsPort) return false;
1080 if (m_iDisplayHeight != other.m_iDisplayHeight) return false;
1081 if (m_iDisplayWidth != other.m_iDisplayWidth) return false;
1082 if (m_iImageEncoding != other.m_iImageEncoding) return false;
1083 if (m_iJpegQuality != other.m_iJpegQuality) return false;
1084 if (m_iProxyPort != other.m_iProxyPort) return false;
1085 if (m_iRdpAuthType != other.m_iRdpAuthType) return false;
1086 if (m_iRdpColors != other.m_iRdpColors) return false;
1087 if (m_iRdpImageEncoding != other.m_iRdpImageEncoding) return false;
1088 if (m_iRdpJpegQuality != other.m_iRdpJpegQuality) return false;
1089 if (m_iServerPort != other.m_iServerPort) return false;
1090 if (m_iSmbPort != other.m_iSmbPort) return false;
1091 if (m_iUsedShareGroups != other.m_iUsedShareGroups) return false;
1092 if (m_iVncDisplayNumber != other.m_iVncDisplayNumber) return false;
1093 if (m_iVncImageEncoding != other.m_iVncImageEncoding) return false;
1094 if (m_iVncJpegQuality != other.m_iVncJpegQuality) return false;
1095 if (m_iXdmBroadcastPort != other.m_iXdmBroadcastPort) return false;
1096 if (m_iXdmListPort != other.m_iXdmListPort) return false;
1097 if (m_iXdmQueryPort != other.m_iXdmQueryPort) return false;
1098
1099 if (m_eCacheDisk != other.m_eCacheDisk) return false;
1100 if (m_eCacheMemory != other.m_eCacheMemory) return false;
1101 if (m_eConnectionSpeed != other.m_eConnectionSpeed) return false;
1102 if (m_eDesktopType != other.m_eDesktopType) return false;
1103 if (m_eDisplayType != other.m_eDisplayType) return false;
1104 if (m_eSessionType != other.m_eSessionType) return false;
1105 if (m_eXdmMode != other.m_eXdmMode) return false;
1106
1107 if (m_sCommandLine != other.m_sCommandLine) return false;
1108 if (m_sCupsPath != other.m_sCupsPath) return false;
1109 // if (m_sFileName != other.m_sFileName) return false;
1110 if (m_sKbdLayoutLanguage != other.m_sKbdLayoutLanguage) return false;
1111 if (m_sName != other.m_sName) return false;
1112 if (m_sPassword != other.m_sPassword) return false;
1113 if (m_sProxyCommand != other.m_sProxyCommand) return false;
1114 if (m_sProxyHost != other.m_sProxyHost) return false;
1115 if (m_sProxyPass != other.m_sProxyPass) return false;
1116 if (m_sProxyUser != other.m_sProxyUser) return false;
1117 if (m_sRdpApplication != other.m_sRdpApplication) return false;
1118 if (m_sRdpDomain != other.m_sRdpDomain) return false;
1119 if (m_sRdpHostName != other.m_sRdpHostName) return false;
1120 if (m_sRdpPassword != other.m_sRdpPassword) return false;
1121 if (m_sRdpUsername != other.m_sRdpUsername) return false;
1122 if (m_sServerHost != other.m_sServerHost) return false;
1123 if (m_sSshKey != other.m_sSshKey) return false;
1124 if (m_sUsername != other.m_sUsername) return false;
1125 if (m_sVncHostName != other.m_sVncHostName) return false;
1126 if (m_sVncPassword != other.m_sVncPassword) return false;
1127 if (m_sXdmListHost != other.m_sXdmListHost) return false;
1128 if (m_sXdmQueryHost != other.m_sXdmQueryHost) return false;
1129
1130 if (cmpUsedShareGroups(m_aUsedShareGroups, other.m_aUsedShareGroups)) return false;
1131 if (cmpShareGroups(m_aShareGroups, other.m_aShareGroups)) return false;
1132 if (cmpUsbForwards(m_aUsbForwards, other.m_aUsbForwards)) return false;
1133 return true;
1134 }
1135
1136 bool
LoadFromString(const wxString & content,bool isPush)1137 MyXmlConfig::LoadFromString(const wxString &content, bool isPush)
1138 {
1139 char *cnt = strdup(content.mb_str());
1140 wxMemoryInputStream mis(cnt, strlen(cnt));
1141 bool ret = loadFromStream(mis, isPush);
1142 free(cnt);
1143 return ret;
1144 }
1145
1146 bool
LoadFromFile(const wxString & filename)1147 MyXmlConfig::LoadFromFile(const wxString &filename)
1148 {
1149 {
1150 wxLogNull dummy;
1151 wxFile *f = new wxFile(filename);
1152 if ((!f->IsOpened()) || f->Eof()) {
1153 delete f;
1154 return false;
1155 }
1156 delete f;
1157 }
1158 ::myLogTrace(MYTRACETAG, wxT("Reading %s"), filename.c_str());
1159 wxFileInputStream fis(filename);
1160 if (loadFromStream(fis, false)) {
1161 m_sName = wxFileName(filename).GetName();
1162 m_sFileName = wxFileName(filename).GetFullPath();
1163 m_bWritable = wxFileName::IsFileWritable(m_sFileName);
1164 return true;
1165 }
1166 return false;
1167 }
1168
CurlWriteCallback(void * buffer,size_t size,size_t nmemb,void * userp)1169 size_t MyXmlConfig::CurlWriteCallback(void *buffer, size_t size, size_t nmemb, void *userp)
1170 {
1171 #ifdef APP_OPENNX
1172 # ifdef HAVE_LIBCURL
1173 if (userp) {
1174 wxMemoryOutputStream *mos = (wxMemoryOutputStream *)userp;
1175 return mos->GetOutputStreamBuffer()->Write(buffer, size * nmemb);
1176 // return size * nmemb;
1177 }
1178 # endif
1179 #else
1180 wxUnusedVar(buffer);
1181 wxUnusedVar(size);
1182 wxUnusedVar(nmemb);
1183 wxUnusedVar(userp);
1184 #endif
1185 return -1;
1186 }
1187
1188 bool
LoadFromURL(const wxString & filename)1189 MyXmlConfig::LoadFromURL(const wxString &filename)
1190 {
1191 bool ret = false;
1192 #ifdef APP_OPENNX
1193 # ifdef HAVE_LIBCURL
1194 wxMemoryOutputStream mos;
1195 char ebuf[CURL_ERROR_SIZE];
1196 CURL *c = curl_easy_init();
1197 // curl_easy_setopt(c, CURLOPT_FAILONERROR, 1);
1198 // curl_easy_setopt(c, CURLOPT_VERBOSE, 1);
1199 curl_easy_setopt(c, CURLOPT_NOPROGRESS, 1);
1200 curl_easy_setopt(c, CURLOPT_NOSIGNAL, 1);
1201 curl_easy_setopt(c, CURLOPT_URL, (const char *)filename.mb_str());
1202 curl_easy_setopt(c, CURLOPT_FOLLOWLOCATION, 1);
1203 curl_easy_setopt(c, CURLOPT_MAXREDIRS, 10);
1204 // curl_easy_setopt(c, CURLOPT_COOKIE, "foo=bar");
1205 curl_easy_setopt(c, CURLOPT_TIMEOUT, 10);
1206 curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 1);
1207 curl_easy_setopt(c, CURLOPT_SSL_VERIFYHOST, 2);
1208 if (!::wxGetApp().GetCaCert().IsEmpty())
1209 curl_easy_setopt(c, CURLOPT_CAINFO, (const char *)::wxGetApp().GetCaCert().mb_str());
1210 curl_easy_setopt(c, CURLOPT_WRITEDATA, &mos);
1211 curl_easy_setopt(c, CURLOPT_ERRORBUFFER, ebuf);
1212 curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, CurlWriteCallback);
1213 ::myLogTrace(MYTRACETAG, wxT("Fetching %s"), filename.c_str());
1214 CURLcode r = curl_easy_perform(c);
1215 if (0 == r) {
1216 off_t len = mos.TellO();
1217 if (len > 0) {
1218 int rcode = 200;
1219 if (filename.StartsWith(wxT("http"))) {
1220 curl_easy_getinfo(c, CURLINFO_RESPONSE_CODE, &rcode);
1221 }
1222 if (200 == rcode) {
1223 ::myLogTrace(MYTRACETAG, wxT("Fetching %s"), filename.c_str());
1224 char * const data = new char[len];
1225 mos.CopyTo(data, len);
1226 wxMemoryInputStream mis(data, len);
1227 if (loadFromStream(mis, false)) {
1228 wxURI uri(filename);
1229 m_sName = wxFileName(uri.GetPath()).GetName();
1230 if (0 == uri.GetScheme().CmpNoCase(wxT("file"))) {
1231 m_sFileName = wxFileName(uri.GetPath()).GetFullPath();
1232 m_bWritable = wxFileName::IsFileWritable(m_sFileName);
1233 } else {
1234 wxURL url(filename);
1235 m_sFileName = url.BuildUnescapedURI();
1236 m_bWritable = false;
1237 }
1238 ret = true;
1239 }
1240 delete data;
1241 } else {
1242 ::wxLogError(_("Error %d while fetching session configuration"), rcode);
1243 }
1244 }
1245 } else {
1246 wxString msg(ebuf, *wxConvCurrent);
1247 ::wxLogError(_("Error while fetching session configuration:\n%s"), msg.c_str());
1248 }
1249 curl_easy_cleanup(c);
1250 # else
1251 wxURL url(filename);
1252 {
1253 wxLogNull dummy;
1254 if (!url.IsOk())
1255 return false;
1256 }
1257 ::myLogTrace(MYTRACETAG, wxT("Fetching %s"), filename.c_str());
1258 wxInputStream *is = url.GetInputStream();
1259 if (is && loadFromStream(*is, false)) {
1260 wxURI uri(filename);
1261 m_sName = wxFileName(uri.GetPath()).GetName();
1262 if (0 == uri.GetScheme().CmpNoCase(wxT("file"))) {
1263 m_sFileName = wxFileName(uri.GetPath()).GetFullPath();
1264 m_bWritable = wxFileName::IsFileWritable(m_sFileName);
1265 } else {
1266 m_sFileName = url.BuildUnescapedURI();
1267 m_bWritable = false;
1268 }
1269 ret = true;
1270 }
1271 # endif
1272 #else
1273 wxUnusedVar(filename);
1274 #endif
1275 return ret;
1276 }
1277
1278 bool
loadFromStream(wxInputStream & is,bool isPush)1279 MyXmlConfig::loadFromStream(wxInputStream &is, bool isPush)
1280 {
1281 wxString tmp;
1282 int itmp;
1283 wxXmlDocument cfg(is);
1284
1285 wxXmlNode *cfgnode = cfg.GetRoot();
1286 if (cfgnode && (cfgnode->GetName() == wxT("NXClientSettings"))) {
1287 if (!(cfgnode->GetPropVal(wxT("application"), wxEmptyString) == wxT("nxclient")))
1288 return false;
1289 if (!(cfgnode->GetPropVal(wxT("version"), wxEmptyString) == wxT("1.3")))
1290 return false;
1291 cfgnode = cfgnode->GetChildren();
1292 while (cfgnode) {
1293 if (cfgnode->GetName() == wxT("group")) {
1294
1295 // Tab "Advanced"
1296 if (cfgnode->GetPropVal(wxT("name"), wxEmptyString) == wxT("Advanced")) {
1297 wxXmlNode *opt = cfgnode->GetChildren();
1298 while (opt) {
1299
1300 itmp = getLong(opt, wxT("Cache size"), -1);
1301 switch (itmp) {
1302 case 0:
1303 m_eCacheMemory = CACHEMEM_0MB;
1304 break;
1305 case 1:
1306 m_eCacheMemory = CACHEMEM_1MB;
1307 break;
1308 case 2:
1309 m_eCacheMemory = CACHEMEM_2MB;
1310 break;
1311 case 4:
1312 m_eCacheMemory = CACHEMEM_4MB;
1313 break;
1314 case 8:
1315 m_eCacheMemory = CACHEMEM_8MB;
1316 break;
1317 case 16:
1318 m_eCacheMemory = CACHEMEM_16MB;
1319 break;
1320 case 32:
1321 m_eCacheMemory = CACHEMEM_32MB;
1322 break;
1323 case 64:
1324 m_eCacheMemory = CACHEMEM_64MB;
1325 break;
1326 case 128:
1327 m_eCacheMemory = CACHEMEM_128MB;
1328 break;
1329 }
1330 itmp = getLong(opt, wxT("Cache size on disk"), -1);
1331 switch (itmp) {
1332 case 0:
1333 m_eCacheDisk = CACHEDISK_0MB;
1334 break;
1335 case 4:
1336 m_eCacheDisk = CACHEDISK_4MB;
1337 break;
1338 case 8:
1339 m_eCacheDisk = CACHEDISK_8MB;
1340 break;
1341 case 16:
1342 m_eCacheDisk = CACHEDISK_16MB;
1343 break;
1344 case 32:
1345 m_eCacheDisk = CACHEDISK_32MB;
1346 break;
1347 case 64:
1348 m_eCacheDisk = CACHEDISK_64MB;
1349 break;
1350 case 128:
1351 m_eCacheDisk = CACHEDISK_128MB;
1352 break;
1353 case 256:
1354 m_eCacheDisk = CACHEDISK_256MB;
1355 break;
1356 case 512:
1357 m_eCacheDisk = CACHEDISK_512MB;
1358 break;
1359 }
1360 #if 0
1361 if (wxGetEnv(wxT("THINCLIENT"), NULL))
1362 m_eCacheDisk = CACHEDISK_0MB;
1363 #endif
1364 m_bKbdLayoutOther = !getBool(opt, wxT("Current keyboard"),
1365 !m_bKbdLayoutOther);
1366 m_sKbdLayoutLanguage = getString(opt,
1367 wxT("Custom keyboard layout"), m_sKbdLayoutLanguage);
1368 m_bDisableTcpNoDelay = getBool(opt, wxT("Disable TCP no-delay"),
1369 m_bDisableTcpNoDelay);
1370 m_bDisableZlibCompression = getBool(opt,
1371 wxT("Disable ZLIB stream compression"),
1372 m_bDisableZlibCompression);
1373 m_bGrabKeyboard = getBool(opt, wxT("Grab keyboard"),
1374 m_bGrabKeyboard);
1375 m_bDisableDirectDraw = getBool(opt, wxT("Disable DirectDraw"),
1376 m_bDisableDirectDraw);
1377 m_bDisableDeferredUpdates = getBool(opt, wxT("Disable deferred updates"),
1378 m_bDisableDeferredUpdates);
1379
1380 tmp = getString(opt, wxT("Clipboard filter"), wxEmptyString);
1381 if (!tmp.IsEmpty()) {
1382 ::myLogTrace(MYTRACETAG, wxT("read: Clipboard filter '%s'"), tmp.c_str());
1383 if (tmp.CmpNoCase(wxT("primary")) == 0) {
1384 m_iClipFilter = 0;
1385 }
1386 if (tmp.CmpNoCase(wxT("clipboard")) == 0) {
1387 m_iClipFilter = 1;
1388 }
1389 if (tmp.CmpNoCase(wxT("both")) == 0) {
1390 m_iClipFilter = 2;
1391 }
1392 ::myLogTrace(MYTRACETAG, wxT("read: m_iClipFilter=%d"), m_iClipFilter);
1393 }
1394 m_bUseProxy = getBool(opt, wxT("Enable HTTP proxy"), m_bUseProxy);
1395 m_bExternalProxy = getBool(opt, wxT("Enable external proxy"), m_bExternalProxy);
1396 m_bEnableSSL = getBool(opt, wxT("Enable SSL encryption"), m_bEnableSSL);
1397 m_bEnableUSBIP = getBool(opt, wxT("Enable USBIP"), m_bEnableUSBIP);
1398 // Enable response time optimizations false
1399 m_sProxyCommand = getString(opt, wxT("Proxy command"), m_sProxyCommand);
1400 m_sProxyHost = getString(opt, wxT("HTTP proxy host"), m_sProxyHost);
1401 m_iProxyPort = getLong(opt, wxT("HTTP proxy port"), m_iProxyPort);
1402 m_sProxyUser = getString(opt, wxT("HTTP proxy username"), m_sProxyUser);
1403 m_bProxyPassRemember = getBool(opt, wxT("Remember HTTP proxy password"), m_bProxyPassRemember);
1404 if (m_bProxyPassRemember)
1405 m_sProxyPass = getPassword(opt, wxT("HTTP proxy password"), m_sProxyPass);
1406 else
1407 m_sProxyPass = wxEmptyString;
1408 // Restore cache true
1409 // StreamCompression ""
1410
1411 opt = opt->GetNext();
1412 }
1413 cfgnode = cfgnode->GetNext();
1414 continue;
1415 }
1416
1417 // Tab "Environment"
1418 if (cfgnode->GetPropVal(wxT("name"), wxEmptyString) == wxT("Environment")) {
1419 wxXmlNode *opt = cfgnode->GetChildren();
1420 while (opt) {
1421 m_sCupsPath = getString(opt, wxT("CUPSD path"), m_sCupsPath);
1422 opt = opt->GetNext();
1423 }
1424 cfgnode = cfgnode->GetNext();
1425 continue;
1426 }
1427
1428 // Tab "General"
1429 if (cfgnode->GetPropVal(wxT("name"), wxEmptyString) == wxT("General")) {
1430 wxXmlNode *opt = cfgnode->GetChildren();
1431 while (opt) {
1432
1433 // Automatic reconnect true
1434 m_sCommandLine = getString(opt, wxT("Command line"), m_sCommandLine);
1435 tmp = getString(opt,
1436 wxT("Custom Unix Desktop"), wxEmptyString);
1437 if (!tmp.IsEmpty()) {
1438 if (tmp.CmpNoCase(wxT("application")) == 0) {
1439 m_bRunConsole = false;
1440 m_bRunXclients = false;
1441 }
1442 if (tmp.CmpNoCase(wxT("console")) == 0) {
1443 m_bRunConsole = true;
1444 m_bRunXclients = false;
1445 }
1446 if (tmp.CmpNoCase(wxT("default")) == 0) {
1447 m_bRunConsole = false;
1448 m_bRunXclients = true;
1449 }
1450 }
1451 tmp = getString(opt, wxT("Desktop"));
1452 if (tmp.CmpNoCase(wxT("RDP")) == 0)
1453 m_eDesktopType = DTYPE_RDP;
1454 if (tmp.CmpNoCase(wxT("RFB")) == 0)
1455 m_eDesktopType = DTYPE_RFB;
1456 if (tmp.CmpNoCase(wxT("KDE")) == 0)
1457 m_eDesktopType = DTYPE_KDE;
1458 if (tmp.CmpNoCase(wxT("Gnome")) == 0)
1459 m_eDesktopType = DTYPE_GNOME;
1460 if (tmp.CmpNoCase(wxT("CDE")) == 0)
1461 m_eDesktopType = DTYPE_CDE;
1462 if (tmp.CmpNoCase(wxT("XFCE")) == 0)
1463 m_eDesktopType = DTYPE_XFCE;
1464 if (tmp.CmpNoCase(wxT("XDM")) == 0)
1465 m_eDesktopType = DTYPE_XDM;
1466 if (tmp.CmpNoCase(wxT("Console")) == 0)
1467 m_eDesktopType = DTYPE_CUSTOM;
1468 m_bDisableShmem = getBool(opt, wxT("Disable SHM"), m_bDisableShmem);
1469 m_bDisableShpix = getBool(opt, wxT("Disable emulate shared pixmaps"), m_bDisableShpix);
1470 tmp = getString(opt, wxT("Link speed"));
1471 if (tmp == wxT("modem"))
1472 m_eConnectionSpeed = SPEED_MODEM;
1473 if (tmp == wxT("isdn"))
1474 m_eConnectionSpeed = SPEED_ISDN;
1475 if (tmp == wxT("adsl"))
1476 m_eConnectionSpeed = SPEED_ADSL;
1477 if (tmp == wxT("wan"))
1478 m_eConnectionSpeed = SPEED_WAN;
1479 if (tmp == wxT("lan"))
1480 m_eConnectionSpeed = SPEED_LAN;
1481
1482 m_bRememberPassword = getBool(opt, wxT("Remember password"),
1483 m_bRememberPassword);
1484
1485 tmp = getString(opt, wxT("Resolution"));
1486 if (!tmp.IsEmpty())
1487 m_eDisplayType = DPTYPE_CUSTOM;
1488 if (tmp == wxT("640x480"))
1489 m_eDisplayType = DPTYPE_640x480;
1490 if (tmp == wxT("800x600"))
1491 m_eDisplayType = DPTYPE_800x600;
1492 if (tmp == wxT("1024x768"))
1493 m_eDisplayType = DPTYPE_1024x768;
1494 if (tmp == wxT("available"))
1495 m_eDisplayType = DPTYPE_AVAILABLE;
1496 if (tmp == wxT("fullscreen"))
1497 m_eDisplayType = DPTYPE_FULLSCREEN;
1498 if (tmp == wxT("remote"))
1499 m_eDisplayType = DPTYPE_REMOTE;
1500
1501 m_iDisplayHeight = getLong(opt, wxT("Resolution height"),
1502 m_iDisplayHeight);
1503 m_iDisplayWidth = getLong(opt, wxT("Resolution width"),
1504 m_iDisplayWidth);
1505 m_sServerHost = getString(opt, wxT("Server host"), m_sServerHost);
1506 m_iServerPort = getLong(opt, wxT("Server port"), m_iServerPort);
1507
1508 tmp = getString(opt, wxT("Session"));
1509 if (tmp.CmpNoCase(wxT("application")) == 0) {
1510 m_eSessionType = STYPE_UNIX;
1511 m_bValid = true;
1512 }
1513 if (tmp.CmpNoCase(wxT("unix")) == 0) {
1514 m_eSessionType = STYPE_UNIX;
1515 m_bValid = true;
1516 }
1517 if (tmp.CmpNoCase(wxT("windows")) == 0) {
1518 m_eSessionType = STYPE_WINDOWS;
1519 m_bValid = true;
1520 }
1521 if (tmp.CmpNoCase(wxT("vnc")) == 0) {
1522 m_eSessionType = STYPE_VNC;
1523 m_bValid = true;
1524 }
1525 if (tmp.CmpNoCase(wxT("shadow")) == 0) {
1526 m_eSessionType = STYPE_SHADOW;
1527 m_bValid = true;
1528 }
1529 // this is 0/1 in NX but getBool can handle that
1530 m_bUseCustomImageEncoding = getBool(opt,
1531 wxT("Use default image encoding"), m_bUseCustomImageEncoding);
1532 m_bDisableRender = !getBool(opt, wxT("Use render"), !m_bDisableRender);
1533 m_bUseSmartCard = getBool(opt, wxT("Use smartcard"), m_bUseSmartCard);
1534 m_bDisableTaint = !getBool(opt, wxT("Use taint"), !m_bDisableTaint);
1535 m_bVirtualDesktop = getBool(opt, wxT("Virtual desktop"),
1536 m_bVirtualDesktop);
1537 m_bDisableXagent = !getBool(opt, wxT("XAgent encoding"),
1538 !m_bDisableXagent);
1539 // displaySaveOnExit = true
1540
1541 tmp = getString(opt, wxT("xdm mode"));
1542 if (tmp.CmpNoCase(wxT("server decide")) == 0) {
1543 m_eXdmMode = XDM_MODE_SERVER;
1544 }
1545 if (tmp.CmpNoCase(wxT("server_decide")) == 0) {
1546 m_eXdmMode = XDM_MODE_SERVER;
1547 }
1548 if (tmp.CmpNoCase(wxT("query")) == 0) {
1549 m_eXdmMode = XDM_MODE_QUERY;
1550 }
1551 if (tmp.CmpNoCase(wxT("broadcast")) == 0) {
1552 m_eXdmMode = XDM_MODE_BROADCAST;
1553 }
1554 if (tmp.CmpNoCase(wxT("list")) == 0) {
1555 m_eXdmMode = XDM_MODE_LIST;
1556 }
1557 m_sXdmListHost = getString(opt, wxT("xdm list host"), m_sXdmListHost);
1558 m_sXdmQueryHost = getString(opt, wxT("xdm query host"), m_sXdmQueryHost);
1559 m_iXdmBroadcastPort = getLong(opt, wxT("xdm broadcast port"), m_iXdmBroadcastPort);
1560 m_iXdmListPort = getLong(opt, wxT("xdm list port"), m_iXdmListPort);
1561 m_iXdmQueryPort = getLong(opt, wxT("xdm query port"), m_iXdmQueryPort);
1562
1563 opt = opt->GetNext();
1564 }
1565 cfgnode = cfgnode->GetNext();
1566 continue;
1567 }
1568
1569 // Sub-Dialog Custom image compresion
1570 if (cfgnode->GetPropVal(wxT("name"), wxEmptyString) == wxT("Images")) {
1571 // First, determine, if we have an old (pre 0.16.173) config file
1572 wxXmlNode *opt = cfgnode->GetChildren();
1573 m_bOldConfig = false;
1574 while (opt) {
1575 wxString key = opt->GetPropVal(wxT("key"), wxEmptyString);
1576 if (key == wxT("Windows Image Compression")) {
1577 m_bOldConfig = true;
1578 break;
1579 }
1580 opt = opt->GetNext();
1581 }
1582 opt = cfgnode->GetChildren();
1583 while (opt) {
1584 m_bDisableBackingstore = getBool(opt, wxT("Disable backingstore"),
1585 m_bDisableBackingstore);
1586 m_bDisableComposite = getBool(opt, wxT("Disable coposite"),
1587 m_bDisableComposite);
1588
1589 m_iImageEncoding = getLong(opt, wxT("Image Compression Type"), m_iImageEncoding);
1590 m_iJpegQuality = getLong(opt, wxT("JPEG Quality"), m_iJpegQuality);
1591 // RDP optimization for low-bandwidth link = false
1592 // Reduce colors to = ""
1593 m_iVncImageEncoding = getLong(opt, wxT("VNC images compression"),
1594 m_iVncImageEncoding);
1595 m_iVncJpegQuality = getLong(opt, wxT("VNC JPEG Quality"), m_iVncJpegQuality);
1596 m_iRdpImageEncoding = getLong(opt, wxT("RDP Image Encoding"),
1597 m_iRdpImageEncoding);
1598 m_iRdpJpegQuality = getLong(opt, wxT("RDP JPEG Quality"), m_iRdpJpegQuality);
1599 opt = opt->GetNext();
1600 }
1601 if (m_bOldConfig) {
1602 if (m_bUseCustomImageEncoding) {
1603 // Convert from old settings format
1604 switch (m_iImageEncoding) {
1605 case 0:
1606 m_iImageEncoding = 3;
1607 break;
1608 case 1:
1609 m_iImageEncoding = 4;
1610 break;
1611 case 2:
1612 m_iImageEncoding = 2;
1613 break;
1614 }
1615 m_iRdpJpegQuality = m_iVncJpegQuality = m_iJpegQuality;
1616
1617 opt = cfgnode->GetChildren();
1618 int oldvncenc = 0;
1619 int oldrdpenc = 0;
1620 while (opt) {
1621 oldvncenc = getLong(opt, wxT("Image Encoding Type"), oldvncenc);
1622 oldrdpenc = getLong(opt, wxT("Windows Image Compression"), oldrdpenc);
1623 opt = opt->GetNext();
1624 }
1625 m_iVncImageEncoding = (oldvncenc + 1) % 3;
1626 switch (oldrdpenc) {
1627 case 0:
1628 m_iRdpImageEncoding = 3;
1629 break;
1630 case 1:
1631 m_iRdpImageEncoding = 1;
1632 break;
1633 case 2:
1634 m_iRdpImageEncoding = 2;
1635 break;
1636 case 3:
1637 m_iRdpImageEncoding = 0;
1638 break;
1639 }
1640 } else {
1641 // Custom settings are disabled, so simply set defaults ...
1642 m_iImageEncoding = m_iRdpImageEncoding = m_iVncImageEncoding = 3;
1643 m_iJpegQuality = m_iRdpJpegQuality = m_iVncJpegQuality = 6;
1644 // ... and shut up (no need to bother the user)
1645 m_bOldConfig = false;
1646 }
1647 }
1648 cfgnode = cfgnode->GetNext();
1649 continue;
1650 }
1651
1652 // Main login params
1653 if (cfgnode->GetPropVal(wxT("name"), wxEmptyString) == wxT("Login")) {
1654 wxXmlNode *opt = cfgnode->GetChildren();
1655 while (opt) {
1656 m_bGuestMode = getBool(opt, wxT("Guest Mode"), m_bGuestMode);
1657 if (m_bGuestMode && isPush) {
1658 m_sGuestUser = getString(opt, wxT("User"), m_sGuestUser);
1659 tmp = getString(opt, wxT("Auth"), wxEmptyString);
1660 if (!tmp.IsEmpty())
1661 m_sGuestPassword = cryptString(tmp);
1662 } else {
1663 m_pMd5Password = getStringNew(opt, wxT("Auth"), m_pMd5Password);
1664 m_sUsername = getString(opt, wxT("User"), m_sUsername);
1665 m_sGuestPassword = getString(opt, wxT("Guest password"),
1666 m_sGuestPassword);
1667 m_sGuestUser = getString(opt, wxT("Guest username"), m_sGuestUser);
1668 }
1669 // Login method = "nx"
1670 tmp = m_sSshKey;
1671 m_sSshKey = getString(opt, wxT("Public Key"), m_sSshKey);
1672 if (tmp != m_sSshKey) {
1673 if (!m_sSshKey.IsEmpty()) {
1674 wxRegEx r(wxT("^(-----BEGIN .SA PRIVATE KEY-----)\\s+(.*)(-----END .SA PRIVATE KEY-----)\\s*$"), wxRE_ADVANCED);
1675 if (r.Matches(m_sSshKey)) {
1676 tmp = r.GetMatch(m_sSshKey, 2);
1677 tmp.Replace(wxT(" "), wxT("\n"));
1678 m_sSshKey = r.GetMatch(m_sSshKey, 1) + wxT("\n")
1679 + tmp + r.GetMatch(m_sSshKey, 3) + wxT("\n");
1680 }
1681 }
1682 }
1683 m_pClrPassword = getStringNew(opt, wxT("Password"), m_pClrPassword);
1684
1685 opt = opt->GetNext();
1686 }
1687 cfgnode = cfgnode->GetNext();
1688 continue;
1689 }
1690
1691 // Tab "Services"
1692 if (cfgnode->GetPropVal(wxT("name"), wxEmptyString) == wxT("Services")) {
1693 wxXmlNode *opt = cfgnode->GetChildren();
1694 while (opt) {
1695 m_bEnableMultimedia = getBool(opt, wxT("Audio"), m_bEnableMultimedia);
1696 m_iCupsPort = getLong(opt, wxT("IPPPort"), m_iCupsPort);
1697 m_iSmbPort = getLong(opt, wxT("SmbDefaultPort"), m_iSmbPort);
1698 m_bUseCups = getBool(opt, wxT("IPPPrinting"), m_bUseCups);
1699 m_bEnableSmbSharing = getBool(opt, wxT("Shares"), m_bEnableSmbSharing);
1700 opt = opt->GetNext();
1701 }
1702 cfgnode = cfgnode->GetNext();
1703 continue;
1704 }
1705
1706 if (cfgnode->GetPropVal(wxT("name"), wxEmptyString) == wxT("VNC Session")) {
1707 wxXmlNode *opt = cfgnode->GetChildren();
1708 while (opt) {
1709 tmp = getString(opt, wxT("Display"));
1710 if (tmp.Left(1) == wxT(":")) {
1711 tmp = tmp.Mid(1);
1712 if (tmp.IsNumber()) {
1713 long l;
1714 tmp.ToLong(&l, 0);
1715 m_iVncDisplayNumber = l;
1716 }
1717 }
1718 m_sVncPassword = getPassword(opt, wxT("Password"), m_sVncPassword);
1719 m_bVncRememberPassword = getBool(opt, wxT("Remember"),
1720 m_bVncRememberPassword);
1721 m_sVncHostName = getString(opt, wxT("Server"), m_sVncHostName);
1722 opt = opt->GetNext();
1723 }
1724 cfgnode = cfgnode->GetNext();
1725 continue;
1726 }
1727
1728 if (cfgnode->GetPropVal(wxT("name"), wxEmptyString) == wxT("Windows Session")) {
1729 wxXmlNode *opt = cfgnode->GetChildren();
1730 while (opt) {
1731 m_sRdpApplication = getString(opt, wxT("Application"),
1732 m_sRdpApplication);
1733 m_iRdpAuthType = getLong(opt, wxT("Authentication"), m_iRdpAuthType);
1734 itmp = -1;
1735 switch (getLong(opt, wxT("Color Depth"), itmp)) {
1736 case 8:
1737 m_iRdpColors = 0;
1738 break;
1739 case 15:
1740 m_iRdpColors = 1;
1741 break;
1742 case 16:
1743 m_iRdpColors = 2;
1744 break;
1745 case 24:
1746 m_iRdpColors = 3;
1747 break;
1748 }
1749 m_sRdpDomain = getString(opt, wxT("Domain"), m_sRdpDomain);
1750 m_bRdpCache = getBool(opt, wxT("Image Cache"), m_bRdpCache);
1751 m_sRdpPassword = getPassword(opt, wxT("Password"), m_sRdpPassword);
1752 m_bRdpRememberPassword = getBool(opt, wxT("Remember"),
1753 m_bRdpRememberPassword);
1754 m_bRdpRunApplication = getBool(opt, wxT("Run application"),
1755 m_bRdpRunApplication);
1756 m_sRdpHostName = getString(opt, wxT("Server"), m_sRdpHostName);
1757 m_sRdpUsername = getString(opt, wxT("User"), m_sRdpUsername);
1758 opt = opt->GetNext();
1759 }
1760 cfgnode = cfgnode->GetNext();
1761 continue;
1762 }
1763
1764 if (cfgnode->GetPropVal(wxT("name"), wxEmptyString) == wxT("share chosen")) {
1765 wxXmlNode *opt = cfgnode->GetChildren();
1766 while (opt) {
1767 wxString key = opt->GetPropVal(wxT("key"), wxEmptyString);
1768 if (key == wxT("Share number")) {
1769 m_iUsedShareGroups = getLong(opt, wxT("Share number"),
1770 m_iUsedShareGroups);
1771 } else if (key == wxT("default printer")) {
1772 // Ignoring this key, because it is set in the share as well.
1773 } else
1774 m_aUsedShareGroups.Add(opt->GetPropVal(wxT("value"), wxEmptyString));
1775 opt = opt->GetNext();
1776 }
1777 cfgnode = cfgnode->GetNext();
1778 continue;
1779 }
1780
1781 // When we reach here, we got an "unknown" group name. This is usually
1782 // either a mounted share description or an UsbForward entry.
1783 if (cfgnode->GetPropVal(wxT("name"), wxEmptyString).StartsWith(wxT("UsbForward"))) {
1784 SharedUsbDevice dev;
1785 wxXmlNode *opt = cfgnode->GetChildren();
1786 int optcount = 0;
1787 while (opt) {
1788 wxString key = opt->GetPropVal(wxT("key"), wxEmptyString);
1789 if (key == wxT("Vendor")) {
1790 optcount++;
1791 dev.m_sVendor = getString(opt, wxT("Vendor"), wxEmptyString);
1792 opt = opt->GetNext();
1793 continue;
1794 }
1795 if (key == wxT("Product")) {
1796 optcount++;
1797 dev.m_sProduct = getString(opt, wxT("Product"), wxEmptyString);
1798 opt = opt->GetNext();
1799 continue;
1800 }
1801 if (key == wxT("Serial")) {
1802 optcount++;
1803 dev.m_sSerial = getString(opt, wxT("Serial"), wxEmptyString);
1804 opt = opt->GetNext();
1805 continue;
1806 }
1807 if (key == wxT("VendorID")) {
1808 optcount++;
1809 dev.m_iVendorID = getLong(opt, wxT("VendorID"), 0);
1810 opt = opt->GetNext();
1811 continue;
1812 }
1813 if (key == wxT("ProductID")) {
1814 optcount++;
1815 dev.m_iProductID = getLong(opt, wxT("ProductID"), 0);
1816 opt = opt->GetNext();
1817 continue;
1818 }
1819 if (key == wxT("Class")) {
1820 optcount++;
1821 dev.m_iClass = getLong(opt, wxT("Class"), 0);
1822 opt = opt->GetNext();
1823 continue;
1824 }
1825 if (key == wxT("Mode")) {
1826 optcount++;
1827 wxString tmp = getString(opt, wxT("Mode"), wxEmptyString);
1828 if (tmp.IsSameAs(wxT("local")))
1829 dev.m_eMode = SharedUsbDevice::MODE_LOCAL;
1830 if (tmp.IsSameAs(wxT("remote")))
1831 dev.m_eMode = SharedUsbDevice::MODE_REMOTE;
1832 opt = opt->GetNext();
1833 continue;
1834 }
1835 opt = opt->GetNext();
1836 }
1837 if ((7 == optcount) && (dev.m_eMode != SharedUsbDevice::MODE_UNKNOWN))
1838 m_aUsbForwards.Add(dev);
1839 cfgnode = cfgnode->GetNext();
1840 continue;
1841 }
1842
1843 // When we reach here, we got an "unknown" group name. This is usually
1844 // a mounted share description.
1845 {
1846 int shareOptions = 0;
1847 ShareGroup s;
1848 s.m_sGroupName = cfgnode->GetPropVal(wxT("name"), wxEmptyString);
1849 s.m_eType = SharedResource::SHARE_UNKNOWN;
1850 wxXmlNode *opt = cfgnode->GetChildren();
1851 while (opt) {
1852 wxString key = opt->GetPropVal(wxT("key"), wxEmptyString);
1853 if (key == wxT("Alias")) {
1854 shareOptions++;
1855 s.m_sAlias = getString(opt, wxT("Alias"), wxEmptyString);
1856 }
1857 if (key == wxT("Default")) {
1858 shareOptions++;
1859 s.m_bDefault = getBool(opt, wxT("Default"), false);
1860 }
1861 if (key == wxT("Driver")) {
1862 shareOptions++;
1863 s.m_sDriver = getString(opt, wxT("Driver"), wxEmptyString);
1864 }
1865 if (key == wxT("Password")) {
1866 shareOptions++;
1867 s.m_sPassword = getPassword(opt, wxT("Password"), wxEmptyString);
1868 }
1869 if (key == wxT("Public")) {
1870 shareOptions++;
1871 s.m_bPublic = getBool(opt, wxT("Public"), false);
1872 }
1873 if (key == wxT("Sharename")) {
1874 shareOptions++;
1875 s.m_sShareName = getString(opt, wxT("Sharename"), wxEmptyString);
1876 }
1877 if (key == wxT("Type")) {
1878 shareOptions++;
1879 wxString tmp = getString(opt, wxT("Type"), wxEmptyString);
1880 if (tmp.CmpNoCase(wxT("cupsprinter")) == 0)
1881 s.m_eType = SharedResource::SHARE_CUPS_PRINTER;
1882 if (tmp.CmpNoCase(wxT("disk")) == 0)
1883 s.m_eType = SharedResource::SHARE_SMB_DISK;
1884 if (tmp.CmpNoCase(wxT("smbprinter")) == 0)
1885 s.m_eType = SharedResource::SHARE_SMB_PRINTER;
1886 }
1887 if (key == wxT("Username")) {
1888 shareOptions++;
1889 s.m_sUsername = getString(opt, wxT("Username"), wxEmptyString);
1890 }
1891 opt = opt->GetNext();
1892 }
1893 if (shareOptions >= 5)
1894 m_aShareGroups.Add(s);
1895 }
1896
1897 }
1898 cfgnode = cfgnode->GetNext();
1899 }
1900 }
1901 if (m_bValid) {
1902 if (m_pMd5Password) {
1903 m_sPassword = DUMMY_MD5_PASSWORD;
1904 } else if (m_pClrPassword) {
1905 m_sPassword = DUMMY_CLR_PASSWORD;
1906 }
1907 if (STYPE_SHADOW == m_eSessionType)
1908 m_eDesktopType = DTYPE_ANY;
1909 } else {
1910 m_sUsername = wxEmptyString;
1911 m_sPassword = wxEmptyString;
1912 }
1913 return m_bValid;
1914 }
1915
1916 wxString
sGetSessionUser()1917 MyXmlConfig::sGetSessionUser()
1918 {
1919 if (m_bGuestMode) {
1920 if (m_sGuestUser.IsEmpty())
1921 return wxT("NX guest user");
1922 else
1923 return m_sGuestUser;
1924 } else
1925 return m_sUsername;
1926 }
1927
1928 wxString
sGetSessionPassword()1929 MyXmlConfig::sGetSessionPassword()
1930 {
1931 wxString ret;
1932 if (m_bGuestMode) {
1933 ret = decryptString(m_sGuestPassword);
1934 } else {
1935 if ((m_sPassword == DUMMY_MD5_PASSWORD) && m_pMd5Password)
1936 ret = decryptString(*m_pMd5Password);
1937 else
1938 ret = m_sPassword;
1939 }
1940 return ret;
1941 }
1942
1943 void
sSetUsername(const wxString & s)1944 MyXmlConfig::sSetUsername(const wxString &s)
1945 {
1946 bool b;
1947 wxConfigBase::Get()->Read(wxT("Config/LowercaseLogin"), &b, false);
1948 if (b) {
1949 m_sUsername = s.Lower();
1950 } else {
1951 m_sUsername = s;
1952 }
1953 }
1954
1955 void
bAddOption(wxXmlNode * group,const wxString & name,const bool val)1956 MyXmlConfig::bAddOption(wxXmlNode *group, const wxString &name, const bool val)
1957 {
1958 wxXmlNode *n = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("option"));
1959 n->AddProperty(new wxXmlProperty(wxT("key"), name, NULL));
1960 n->AddProperty(new wxXmlProperty(wxT("value"), val ? wxT("true") : wxT("false"), NULL));
1961 group->AddChild(n);
1962 }
1963
1964 void
iAddOptionBool(wxXmlNode * group,const wxString & name,const bool val)1965 MyXmlConfig::iAddOptionBool(wxXmlNode *group, const wxString &name, const bool val)
1966 {
1967 wxXmlNode *n = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("option"));
1968 n->AddProperty(new wxXmlProperty(wxT("key"), name, NULL));
1969 n->AddProperty(new wxXmlProperty(wxT("value"), wxString::Format(wxT("%d"), val ? 1 : 0), NULL));
1970 group->AddChild(n);
1971 }
1972
1973 void
iAddOption(wxXmlNode * group,const wxString & name,const long val)1974 MyXmlConfig::iAddOption(wxXmlNode *group, const wxString &name, const long val)
1975 {
1976 wxXmlNode *n = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("option"));
1977 n->AddProperty(new wxXmlProperty(wxT("key"), name, NULL));
1978 n->AddProperty(new wxXmlProperty(wxT("value"), wxString::Format(wxT("%d"), val), NULL));
1979 group->AddChild(n);
1980 }
1981
1982 void
sAddOption(wxXmlNode * group,const wxString & name,const wxString & val)1983 MyXmlConfig::sAddOption(wxXmlNode *group, const wxString &name, const wxString &val)
1984 {
1985 wxXmlNode *n = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("option"));
1986 n->AddProperty(new wxXmlProperty(wxT("key"), name, NULL));
1987 n->AddProperty(new wxXmlProperty(wxT("value"), val, NULL));
1988 group->AddChild(n);
1989 }
1990
1991 wxXmlNode *
AddGroup(wxXmlNode * parent,const wxString & name)1992 MyXmlConfig::AddGroup(wxXmlNode *parent, const wxString &name)
1993 {
1994 wxXmlNode *n = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("group"));
1995 n->AddProperty(new wxXmlProperty(wxT("name"), name, NULL));
1996 parent->AddChild(n);
1997 return n;
1998 }
1999
2000 bool
SaveToFile()2001 MyXmlConfig::SaveToFile()
2002 {
2003 wxXmlDocument cfg;
2004 wxXmlNode *r;
2005 wxXmlNode *g;
2006 wxString optval;
2007 size_t i;
2008
2009 if (m_sFileName.StartsWith(wxT("http://"))
2010 || m_sFileName.StartsWith(wxT("https://"))
2011 || m_sFileName.StartsWith(wxT("ftp://"))
2012 )
2013 return false;
2014 r = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("NXClientSettings"));
2015 r->AddProperty(new wxXmlProperty(wxT("application"), wxT("nxclient"), NULL));
2016 r->AddProperty(new wxXmlProperty(wxT("version"), wxT("1.3"), NULL));
2017 cfg.SetRoot(r);
2018
2019 // SessionProperties, Tab "General"
2020 g = AddGroup(r, wxT("General"));
2021 bAddOption(g, wxT("Automatic reconnect"), true); // Not (yet?) configurable
2022 sAddOption(g, wxT("Command line"), m_sCommandLine);
2023 optval = wxT("application");
2024 if (m_bRunConsole)
2025 optval = wxT("console");
2026 if (m_bRunXclients)
2027 optval = wxT("default");
2028 sAddOption(g, wxT("Custom Unix Desktop"), optval);
2029 switch (m_eDesktopType) {
2030 case DTYPE_ANY:
2031 optval = wxT("any");
2032 break;
2033 case DTYPE_RDP:
2034 optval = wxT("rdp");
2035 break;
2036 case DTYPE_RFB:
2037 optval = wxT("rfb");
2038 break;
2039 case DTYPE_KDE:
2040 optval = wxT("kde");
2041 break;
2042 case DTYPE_GNOME:
2043 optval = wxT("gnome");
2044 break;
2045 case DTYPE_CDE:
2046 optval = wxT("cde");
2047 break;
2048 case DTYPE_XFCE:
2049 optval = wxT("xfce");
2050 break;
2051 case DTYPE_XDM:
2052 optval = wxT("xdm");
2053 break;
2054 case DTYPE_CUSTOM:
2055 optval = wxT("console");
2056 break;
2057 }
2058 sAddOption(g, wxT("Desktop"), optval);
2059 bAddOption(g, wxT("Disable SHM"), m_bDisableShmem); // Not in original GUI but in config ?!
2060 bAddOption(g, wxT("Disable emulate shared pixmaps"), m_bDisableShpix); // Not in original GUI but in config ?!
2061 switch (m_eConnectionSpeed) {
2062 case SPEED_MODEM:
2063 optval = wxT("modem");
2064 break;
2065 case SPEED_ISDN:
2066 optval = wxT("isdn");
2067 break;
2068 case SPEED_ADSL:
2069 optval = wxT("adsl");
2070 break;
2071 case SPEED_WAN:
2072 optval = wxT("wan");
2073 break;
2074 case SPEED_LAN:
2075 optval = wxT("lan");
2076 break;
2077 }
2078 sAddOption(g, wxT("Link speed"), optval);
2079 bAddOption(g, wxT("Remember password"), m_bRememberPassword);
2080 switch (m_eDisplayType) {
2081 case DPTYPE_CUSTOM:
2082 optval = wxString::Format(wxT("%dx%d"),
2083 m_iDisplayWidth, m_iDisplayHeight);
2084 break;
2085 case DPTYPE_640x480:
2086 optval = wxT("640x480");
2087 break;
2088 case DPTYPE_800x600:
2089 optval = wxT("800x600");
2090 break;
2091 case DPTYPE_1024x768:
2092 optval = wxT("1024x768");
2093 break;
2094 case DPTYPE_AVAILABLE:
2095 optval = wxT("available");
2096 break;
2097 case DPTYPE_FULLSCREEN:
2098 optval = wxT("fullscreen");
2099 break;
2100 case DPTYPE_REMOTE:
2101 optval = wxT("remote");
2102 break;
2103 }
2104 sAddOption(g, wxT("Resolution"), optval);
2105 iAddOption(g, wxT("Resolution height"), m_iDisplayHeight);
2106 iAddOption(g, wxT("Resolution width"), m_iDisplayWidth);
2107 sAddOption(g, wxT("Server host"), m_sServerHost);
2108 iAddOption(g, wxT("Server port"), m_iServerPort);
2109 switch (m_eSessionType) {
2110 case STYPE_UNIX:
2111 optval = wxT("unix");
2112 break;
2113 case STYPE_WINDOWS:
2114 optval = wxT("windows");
2115 break;
2116 case STYPE_VNC:
2117 optval = wxT("vnc");
2118 break;
2119 case STYPE_SHADOW:
2120 optval = wxT("shadow");
2121 break;
2122 }
2123 sAddOption(g, wxT("Session"), optval);
2124 iAddOption(g, wxT("Use default image encoding"), m_bUseCustomImageEncoding);
2125 bAddOption(g, wxT("Use render"), !m_bDisableRender);
2126 bAddOption(g, wxT("Use taint"), !m_bDisableTaint);
2127 bAddOption(g, wxT("Virtual desktop"), m_bVirtualDesktop);
2128 bAddOption(g, wxT("XAgent encoding"), !m_bDisableXagent);
2129 bAddOption(g, wxT("displaySaveOnExit"), true); // Not in original GUI but in config ?!
2130 iAddOption(g, wxT("xdm broadcast port"), m_iXdmBroadcastPort);
2131 sAddOption(g, wxT("xdm list host"), m_sXdmListHost);
2132 iAddOption(g, wxT("xdm list port"), m_iXdmListPort);
2133 switch (m_eXdmMode) {
2134 case XDM_MODE_SERVER:
2135 optval = wxT("server decide");
2136 break;
2137 case XDM_MODE_QUERY:
2138 optval = wxT("query");
2139 break;
2140 case XDM_MODE_BROADCAST:
2141 optval = wxT("broadcast");
2142 break;
2143 case XDM_MODE_LIST:
2144 optval = wxT("list");
2145 break;
2146 }
2147 sAddOption(g, wxT("xdm mode"), optval);
2148 sAddOption(g, wxT("xdm query host"), m_sXdmQueryHost);
2149 iAddOption(g, wxT("xdm query port"), m_iXdmQueryPort);
2150 bAddOption(g, wxT("Use smartcard"), m_bUseSmartCard); // Not in original
2151
2152 // == UnixImageSettingsDialog, RdpImageSettingsDialog, VncImageSettingsDialog
2153 g = AddGroup(r, wxT("Images"));
2154
2155 // deprecated but written by NX client, m_bDisableJpeg
2156 iAddOption(g, wxT("Disable JPEG Compression"), 0);
2157
2158 // deprecated but written by NX client, m_bDisableImageCompression
2159 bAddOption(g, wxT("Disable all image optimisations"), false);
2160
2161 bAddOption(g, wxT("Disable backingstore"), m_bDisableBackingstore);
2162 bAddOption(g, wxT("Disable coposite"), m_bDisableComposite);
2163
2164 // deprecated bAddOption(g, wxT("Disable image streaming"), m_bDisableStreaming);
2165
2166 iAddOption(g, wxT("Image Compression Type"), m_iImageEncoding);
2167
2168 // deprecated but written by NX client
2169 iAddOption(g, wxT("Image Encoding Type"), 0);
2170
2171 // deprecated but written by NX client, m_bUseTightJpeg
2172 bAddOption(g, wxT("Image JPEG Encoding"), false);
2173
2174 iAddOption(g, wxT("JPEG Quality"), m_iJpegQuality);
2175 iAddOption(g, wxT("RDP Image Encoding"), m_iRdpImageEncoding);
2176 iAddOption(g, wxT("RDP JPEG Quality"), m_iRdpJpegQuality);
2177
2178 // Written by NX client, unknown purpose
2179 bAddOption(g, wxT("RDP optimization for low-bandwidth link"), false);
2180
2181 // Written by NX client, unknown purpose
2182 sAddOption(g, wxT("Reduce colors to"), wxEmptyString);
2183
2184 // deprecated but written by NX client, m_bImageEncodingPNG
2185 bAddOption(g, wxT("Use PNG Compression"), true);
2186
2187 iAddOption(g, wxT("VNC images compression"), m_iVncImageEncoding);
2188 iAddOption(g, wxT("VNC JPEG Quality"), m_iVncJpegQuality);
2189
2190 // deprecated - If this exists, we consider it an "old" config file during read
2191 // iAddOption(g, wxT("Windows Image Compression"), m_iRdpImageCompression);
2192
2193 g = AddGroup(r, wxT("Login"));
2194 if (m_bRememberPassword) {
2195 if ((m_sPassword != DUMMY_MD5_PASSWORD) &&
2196 (m_sPassword != DUMMY_CLR_PASSWORD) ) {
2197 optval = cryptString(m_sPassword);
2198 sAddOption(g, wxT("Auth"), optval);
2199 } else {
2200 if (m_pMd5Password)
2201 sAddOption(g, wxT("Auth"), *m_pMd5Password);
2202 if (m_pClrPassword)
2203 sAddOption(g, wxT("Password"), *m_pClrPassword);
2204 }
2205 } else {
2206 optval = wxEmptyString;
2207 sAddOption(g, wxT("Auth"), optval);
2208 sAddOption(g, wxT("Password"), optval);
2209 }
2210 bAddOption(g, wxT("Guest Mode"), m_bGuestMode);
2211 sAddOption(g, wxT("Guest password"), m_sGuestPassword);
2212 sAddOption(g, wxT("Guest username"), m_sGuestUser);
2213 sAddOption(g, wxT("Login Method"), wxT("nx"));
2214 sAddOption(g, wxT("Public Key"), m_sSshKey);
2215 sAddOption(g, wxT("User"), m_sUsername);
2216
2217 g = AddGroup(r, wxT("Environment"));
2218 sAddOption(g, wxT("CUPSD path"), m_sCupsPath);
2219
2220 g = AddGroup(r, wxT("Services"));
2221 bAddOption(g, wxT("Audio"), m_bEnableMultimedia);
2222 bAddOption(g, wxT("Shares"), m_bEnableSmbSharing);
2223 bAddOption(g, wxT("IPPPrinting"), m_bUseCups);
2224 iAddOption(g, wxT("IPPPort"), m_iCupsPort);
2225 iAddOption(g, wxT("SmbDefaultPort"), m_iSmbPort);
2226
2227 if (m_aUsedShareGroups.GetCount()) {
2228 g = AddGroup(r, wxT("share chosen"));
2229 iAddOption(g, wxT("Share number"), m_iUsedShareGroups);
2230 wxString sDefaultPrinter = wxEmptyString;
2231 for (i = 0; i < m_aUsedShareGroups.GetCount(); i++) {
2232 optval = wxString::Format(wxT("Share%d"), i);
2233 sAddOption(g, optval, m_aUsedShareGroups[i]);
2234 switch (findShare(optval).m_eType) {
2235 case SharedResource::SHARE_UNKNOWN:
2236 case SharedResource::SHARE_SMB_DISK:
2237 break;
2238 case SharedResource::SHARE_CUPS_PRINTER:
2239 case SharedResource::SHARE_SMB_PRINTER:
2240 if (findShare(optval).m_bDefault)
2241 sDefaultPrinter = optval;
2242 }
2243 }
2244 if (!sDefaultPrinter.IsEmpty())
2245 sAddOption(g, wxT("default printer"), sDefaultPrinter);
2246 }
2247
2248 g = AddGroup(r, wxT("Advanced"));
2249 switch (m_eCacheMemory) {
2250 case CACHEMEM_0MB:
2251 optval = wxT("0");
2252 break;
2253 case CACHEMEM_1MB:
2254 optval = wxT("1");
2255 break;
2256 case CACHEMEM_2MB:
2257 optval = wxT("2");
2258 break;
2259 case CACHEMEM_4MB:
2260 optval = wxT("4");
2261 break;
2262 case CACHEMEM_8MB:
2263 optval = wxT("8");
2264 break;
2265 case CACHEMEM_16MB:
2266 optval = wxT("16");
2267 break;
2268 case CACHEMEM_32MB:
2269 optval = wxT("32");
2270 break;
2271 case CACHEMEM_64MB:
2272 optval = wxT("64");
2273 break;
2274 case CACHEMEM_128MB:
2275 optval = wxT("128");
2276 break;
2277 }
2278 sAddOption(g, wxT("Cache size"), optval);
2279 switch (m_eCacheDisk) {
2280 case CACHEDISK_0MB:
2281 optval = wxT("0");
2282 break;
2283 case CACHEDISK_4MB:
2284 optval = wxT("4");
2285 break;
2286 case CACHEDISK_8MB:
2287 optval = wxT("8");
2288 break;
2289 case CACHEDISK_16MB:
2290 optval = wxT("16");
2291 break;
2292 case CACHEDISK_32MB:
2293 optval = wxT("32");
2294 break;
2295 case CACHEDISK_64MB:
2296 optval = wxT("64");
2297 break;
2298 case CACHEDISK_128MB:
2299 optval = wxT("128");
2300 break;
2301 case CACHEDISK_256MB:
2302 optval = wxT("256");
2303 break;
2304 case CACHEDISK_512MB:
2305 optval = wxT("512");
2306 break;
2307 }
2308 sAddOption(g, wxT("Cache size on disk"), optval);
2309 bAddOption(g, wxT("Current keyboard"), !m_bKbdLayoutOther);
2310 sAddOption(g, wxT("Custom keyboard layout"), m_sKbdLayoutLanguage);
2311 bAddOption(g, wxT("Disable TCP no-delay"), m_bDisableTcpNoDelay);
2312 bAddOption(g, wxT("Disable ZLIB stream compression"), m_bDisableZlibCompression);
2313 bAddOption(g, wxT("Enable SSL encryption"), m_bEnableSSL);
2314 switch (m_iClipFilter) {
2315 case 0:
2316 optval = wxT("primary");
2317 break;
2318 case 1:
2319 optval = wxT("clipboard");
2320 break;
2321 default:
2322 optval = wxT("both");
2323 break;
2324 }
2325 sAddOption(g, wxT("Clipboard filter"), optval);
2326 bAddOption(g, wxT("Enable HTTP proxy"), m_bUseProxy);
2327 bAddOption(g, wxT("Enable external proxy"), m_bExternalProxy);
2328 bAddOption(g, wxT("Enable USBIP"), m_bEnableUSBIP);
2329 bAddOption(g, wxT("Enable response time optimisations"), false); // ???
2330 bAddOption(g, wxT("Grab keyboard"), m_bGrabKeyboard);
2331 bAddOption(g, wxT("Disable DirectDraw"), m_bDisableDirectDraw);
2332 bAddOption(g, wxT("Disable deferred updates"), m_bDisableDeferredUpdates);
2333 sAddOption(g, wxT("Proxy command"), m_sProxyCommand);
2334 sAddOption(g, wxT("HTTP proxy host"), m_sProxyHost);
2335 optval = m_bProxyPassRemember ? encodeString(m_sProxyPass) : wxT("");
2336 sAddOption(g, wxT("HTTP proxy password"), optval);
2337 iAddOption(g, wxT("HTTP proxy port"), m_iProxyPort);
2338 sAddOption(g, wxT("HTTP proxy username"), m_sProxyUser);
2339 bAddOption(g, wxT("Remember HTTP proxy password"), m_bProxyPassRemember);
2340 bAddOption(g, wxT("Restore cache"), true); // ???
2341 sAddOption(g, wxT("StreamCompression"), wxEmptyString); // ???
2342
2343 g = AddGroup(r, wxT("Windows Session"));
2344 bAddOption(g, wxT("Remember"), m_bRdpRememberPassword);
2345 bAddOption(g, wxT("Run application"), m_bRdpRunApplication);
2346 iAddOption(g, wxT("Authentication"), m_iRdpAuthType);
2347 switch (m_iRdpColors) {
2348 default:
2349 optval = wxT("8");
2350 break;
2351 case 1:
2352 optval = wxT("15");
2353 break;
2354 case 2:
2355 optval = wxT("16");
2356 break;
2357 case 3:
2358 optval = wxT("24");
2359 break;
2360 }
2361 sAddOption(g, wxT("Color Depth"), optval);
2362 sAddOption(g, wxT("Domain"), m_sRdpDomain);
2363 bAddOption(g, wxT("Image Cache"), m_bRdpCache);
2364 sAddOption(g, wxT("Server"), m_sRdpHostName);
2365 sAddOption(g, wxT("User"), m_sRdpUsername);
2366 optval = m_bRdpRememberPassword ? encodeString(m_sRdpPassword) : wxT("");
2367 sAddOption(g, wxT("Password"), optval);
2368 sAddOption(g, wxT("Application"), m_sRdpApplication);
2369
2370 g = AddGroup(r, wxT("VNC Session"));
2371 bAddOption(g, wxT("Remember"), m_bVncRememberPassword);
2372 sAddOption(g, wxT("Server"), m_sVncHostName);
2373 optval = m_bVncRememberPassword ? encodeString(m_sVncPassword) : wxT("");
2374 sAddOption(g, wxT("Password"), optval);
2375 optval = wxString::Format(wxT(":%d"), m_iVncDisplayNumber);
2376 sAddOption(g, wxT("Display"), optval);
2377
2378 for (i = 0; i < m_aShareGroups.GetCount(); i++) {
2379 g = AddGroup(r, m_aShareGroups[i].m_sGroupName);
2380 sAddOption(g, wxT("Sharename"), m_aShareGroups[i].m_sShareName);
2381 sAddOption(g, wxT("Username"), m_aShareGroups[i].m_sUsername);
2382 optval = encodeString(m_aShareGroups[i].m_sPassword);
2383 sAddOption(g, wxT("Password"), optval);
2384 switch (m_aShareGroups[i].m_eType) {
2385 case SharedResource::SHARE_UNKNOWN:
2386 break;
2387 case SharedResource::SHARE_SMB_DISK:
2388 sAddOption(g, wxT("Alias"), m_aShareGroups[i].m_sAlias);
2389 sAddOption(g, wxT("Type"), wxT("disk"));
2390 break;
2391 case SharedResource::SHARE_SMB_PRINTER:
2392 bAddOption(g, wxT("Default"), m_aShareGroups[i].m_bDefault);
2393 sAddOption(g, wxT("Driver"), m_aShareGroups[i].m_sDriver);
2394 bAddOption(g, wxT("Public"), m_aShareGroups[i].m_bPublic);
2395 sAddOption(g, wxT("Type"), wxT("smbprinter"));
2396 break;
2397 case SharedResource::SHARE_CUPS_PRINTER:
2398 bAddOption(g, wxT("Default"), m_aShareGroups[i].m_bDefault);
2399 sAddOption(g, wxT("Driver"), m_aShareGroups[i].m_sDriver);
2400 bAddOption(g, wxT("Public"), m_aShareGroups[i].m_bPublic);
2401 sAddOption(g, wxT("Type"), wxT("cupsprinter"));
2402 break;
2403 }
2404 }
2405 for (i = 0; i < m_aUsbForwards.GetCount(); i++) {
2406 g = AddGroup(r, wxString::Format(wxT("UsbForward%d"), i));
2407 sAddOption(g, wxT("Vendor"), m_aUsbForwards[i].m_sVendor);
2408 sAddOption(g, wxT("Product"), m_aUsbForwards[i].m_sProduct);
2409 sAddOption(g, wxT("Serial"), m_aUsbForwards[i].m_sSerial);
2410 iAddOption(g, wxT("VendorID"), m_aUsbForwards[i].m_iVendorID);
2411 iAddOption(g, wxT("ProductID"), m_aUsbForwards[i].m_iProductID);
2412 iAddOption(g, wxT("Class"), m_aUsbForwards[i].m_iClass);
2413 switch (m_aUsbForwards[i].m_eMode) {
2414 case SharedUsbDevice::MODE_UNKNOWN:
2415 sAddOption(g, wxT("Mode"), wxT("unknown"));
2416 break;
2417 case SharedUsbDevice::MODE_LOCAL:
2418 sAddOption(g, wxT("Mode"), wxT("local"));
2419 break;
2420 case SharedUsbDevice::MODE_REMOTE:
2421 sAddOption(g, wxT("Mode"), wxT("remote"));
2422 break;
2423 }
2424 }
2425
2426 // Must write to memory first, to get rid of the standard XML
2427 // doctype header
2428 wxMemoryOutputStream mos;
2429 cfg.Save(mos);
2430 off_t len = mos.TellO();
2431 if (len > 0) {
2432 char *data = new char[len];
2433 mos.CopyTo(data, len);
2434 char *secondline = (char *)memchr(data, '\n', len);
2435 if (secondline++) {
2436 // Replace 1st line with non-standard NXclient doctype
2437 len -= (secondline - data);
2438 ::myLogTrace(MYTRACETAG, wxT("Writing '%s'"), m_sFileName.c_str());
2439 wxFile f;
2440 if (!f.Create(m_sFileName, true, wxS_IRUSR|wxS_IWUSR)) {
2441 delete data;
2442 return false;
2443 }
2444 wxFileOutputStream fos(f);
2445 if (!fos.Ok()) {
2446 delete data;
2447 return false;
2448 }
2449 // NO wxT() here!!
2450 fos.Write("<!DOCTYPE NXClientSettings>\n", 28);
2451 if (fos.LastWrite() != 28) {
2452 delete data;
2453 return false;
2454 }
2455 // Write out rest of file
2456 fos.Write(secondline, len);
2457 if (fos.LastWrite() != (size_t)len) {
2458 delete data;
2459 return false;
2460 }
2461 } else {
2462 delete data;
2463 return false;
2464 }
2465 delete data;
2466 }
2467 #ifdef __WXMAC__
2468 wxFileName fn(m_sFileName);
2469 fn.MacSetTypeAndCreator('TEXT', 'OPNX');
2470 #endif
2471 return true;
2472 }
2473
saveState()2474 void MyXmlConfig::saveState()
2475 {
2476 if (saved)
2477 delete saved;
2478 saved = new MyXmlConfig();
2479 *saved = *this;
2480 }
2481
checkChanged()2482 bool MyXmlConfig::checkChanged()
2483 {
2484 if (!saved)
2485 return true;
2486 return (!(*this == *saved));
2487 }
2488
getBool(wxXmlNode * opt,const wxString & key,bool defval)2489 bool MyXmlConfig::getBool(wxXmlNode *opt, const wxString &key, bool defval)
2490 {
2491 bool val = defval;
2492
2493 if (opt->GetName() == wxT("option")) {
2494 if (opt->GetPropVal(wxT("key"), wxEmptyString) == key) {
2495 wxString tmp = opt->GetPropVal(wxT("value"), wxEmptyString);
2496 if (!tmp.IsEmpty())
2497 val = ((tmp == STR_TRUE) || (tmp == STR_ONE));
2498 }
2499 }
2500 return val;
2501 }
2502
getLong(wxXmlNode * opt,const wxString & key,long defval)2503 long MyXmlConfig::getLong(wxXmlNode *opt, const wxString &key, long defval)
2504 {
2505 long val = defval;
2506
2507 if (opt->GetName() == wxT("option")) {
2508 if (opt->GetPropVal(wxT("key"), wxEmptyString) == key) {
2509 wxString tmp = opt->GetPropVal(wxT("value"), wxEmptyString);
2510 if (tmp.IsNumber())
2511 tmp.ToLong(&val, 0);
2512 }
2513 }
2514 return val;
2515 }
2516
getLongBool(wxXmlNode * opt,const wxString & key,bool defval)2517 bool MyXmlConfig::getLongBool(wxXmlNode *opt, const wxString &key, bool defval)
2518 {
2519 long val = defval ? 1 : 0;
2520
2521 if (opt->GetName() == wxT("option")) {
2522 if (opt->GetPropVal(wxT("key"), wxEmptyString) == key) {
2523 wxString tmp = opt->GetPropVal(wxT("value"), wxEmptyString);
2524 if (tmp.IsNumber())
2525 tmp.ToLong(&val, 0);
2526 }
2527 }
2528 return (val != 0);
2529 }
2530
getString(wxXmlNode * opt,const wxString & key,const wxString & defval)2531 wxString MyXmlConfig::getString(wxXmlNode *opt, const wxString &key, const wxString &defval)
2532 {
2533 wxString tmp = defval;
2534
2535 if (opt->GetName() == wxT("option")) {
2536 if (opt->GetPropVal(wxT("key"), wxEmptyString) == key)
2537 tmp = opt->GetPropVal(wxT("value"), defval);
2538 }
2539 return tmp;
2540 }
2541
getStringNew(wxXmlNode * opt,const wxString & key,wxString * defval)2542 wxString *MyXmlConfig::getStringNew(wxXmlNode *opt, const wxString &key, wxString *defval)
2543 {
2544 wxString *val = defval;
2545
2546 if (opt->GetName() == wxT("option")) {
2547 if (opt->GetPropVal(wxT("key"), wxEmptyString) == key) {
2548 if (opt->HasProp(wxT("value"))) {
2549 val = new wxString(opt->GetPropVal(wxT("value"), defval ? *defval : wxT("")));
2550 if (val && val->IsEmpty() && (!defval)) {
2551 delete val;
2552 val = NULL;
2553 }
2554 if (defval)
2555 delete defval;
2556 }
2557 }
2558 }
2559 return val;
2560 }
2561
getPassword(wxXmlNode * opt,const wxString & key,const wxString & defval)2562 wxString MyXmlConfig::getPassword(wxXmlNode *opt, const wxString &key, const wxString &defval)
2563 {
2564 wxString val = defval;
2565 wxString *enc = getStringNew(opt, key, NULL);
2566 if (enc && enc->Left(1) == wxT(":") && enc->Right(1) == wxT(":") && enc->Length() > 1) {
2567 int idx = 1;
2568 wxString newpw = wxEmptyString;
2569 enc->Remove(0, 1);
2570 while (enc->Length()) {
2571 int p = enc->Find(wxT(":"));
2572 if (p != -1) {
2573 long l;
2574 enc->Left(p).ToLong(&l);
2575 newpw += wxChar(l - idx++);
2576 } else
2577 break;
2578 enc->Remove(0, p+1);
2579 }
2580 val = newpw;
2581 }
2582 if (enc)
2583 delete enc;
2584 return val;
2585 }
2586