SessionData.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "SessionData.h"
  5. #include "Common.h"
  6. #include "Configuration.h"
  7. #include "Exceptions.h"
  8. #include "FileBuffer.h"
  9. #include "ScpMain.h"
  10. #include "Security.h"
  11. #include "TextsCore.h"
  12. #include "PuttyIntf.h"
  13. //---------------------------------------------------------------------------
  14. #pragma package(smart_init)
  15. //---------------------------------------------------------------------------
  16. const char * DefaultSessionName = "Default Settings";
  17. const char CipherNames[CIPHER_COUNT][10] = {"WARN", "3des", "blowfish", "aes", "des"};
  18. const char SshProtList[][10] = {"1 only", "1", "2", "2 only"};
  19. const char ProxyMethodList[][10] = {"none", "SOCKS4", "SOCKS5", "HTTP", "Telnet", "Cmd" };
  20. const TCipher DefaultCipherList[CIPHER_COUNT] =
  21. { cipAES, cipBlowfish, cip3DES, cipWarn, cipDES };
  22. const char FSProtocolNames[FSPROTOCOL_COUNT][11] = { "SCP", "SFTP (SCP)", "SFTP" };
  23. //--- TSessionData ----------------------------------------------------
  24. __fastcall TSessionData::TSessionData(AnsiString aName):
  25. TNamedObject(aName)
  26. {
  27. Default();
  28. FModified = true;
  29. }
  30. //---------------------------------------------------------------------
  31. void __fastcall TSessionData::Default()
  32. {
  33. HostName = "";
  34. PortNumber = default_port;
  35. UserName = "";
  36. Password = "";
  37. PingInterval = 30;
  38. PingType = ptOff;
  39. Timeout = 15;
  40. AgentFwd = false;
  41. AuthTIS = false;
  42. AuthKI = true;
  43. Compression = false;
  44. SshProt = ssh2;
  45. Ssh2DES = false;
  46. for (int Index = 0; Index < CIPHER_COUNT; Index++)
  47. {
  48. Cipher[Index] = DefaultCipherList[Index];
  49. }
  50. PublicKeyFile = "";
  51. FProtocol = ptSSH;
  52. TcpNoDelay = true;
  53. ProxyMethod = pmNone;
  54. ProxyHost = "proxy";
  55. ProxyPort = 80;
  56. ProxyUsername = "";
  57. ProxyPassword = "";
  58. ProxyTelnetCommand = "connect %host %port\\n";
  59. //ProxySOCKSVersion = 5;
  60. ProxyDNS = asAuto;
  61. ProxyLocalhost = false;
  62. for (int Index = 0; Index < LENOF(FBugs); Index++)
  63. {
  64. Bug[(TSshBug)Index] = asAuto;
  65. }
  66. Special = false;
  67. FSProtocol = fsSFTP;
  68. // FS common
  69. LocalDirectory = "";
  70. RemoteDirectory = "";
  71. UpdateDirectories = false;
  72. CacheDirectories = true;
  73. CacheDirectoryChanges = true;
  74. PreserveDirectoryChanges = true;
  75. LockInHome = false;
  76. ResolveSymlinks = true;
  77. // SCP
  78. ReturnVar = "";
  79. LookupUserGroups = true;
  80. EOLType = eolLF;
  81. Shell = ""; //default shell
  82. ReturnVar = "";
  83. ClearAliases = true;
  84. UnsetNationalVars = true;
  85. AliasGroupList = false;
  86. IgnoreLsWarnings = true;
  87. Scp1Compatibility = false;
  88. TimeDifference = 0;
  89. // SFTP
  90. SFTPDownloadQueue = 4;
  91. SFTPUploadQueue = 4;
  92. SFTPListingQueue = 2;
  93. CustomParam1 = "";
  94. CustomParam2 = "";
  95. Selected = false;
  96. FModified = false;
  97. // add also to TSessionLog::AddStartupInfo()
  98. }
  99. //---------------------------------------------------------------------
  100. void __fastcall TSessionData::Assign(TPersistent * Source)
  101. {
  102. if (Source && Source->InheritsFrom(__classid(TSessionData)))
  103. {
  104. #define DUPL(P) P = ((TSessionData *)Source)->P
  105. DUPL(Name);
  106. DUPL(HostName);
  107. DUPL(PortNumber);
  108. DUPL(UserName);
  109. DUPL(Password);
  110. DUPL(PingInterval);
  111. DUPL(PingType);
  112. DUPL(Timeout);
  113. DUPL(AgentFwd);
  114. DUPL(AuthTIS);
  115. DUPL(Compression);
  116. DUPL(SshProt);
  117. DUPL(Ssh2DES);
  118. DUPL(CipherList);
  119. DUPL(PublicKeyFile);
  120. DUPL(FSProtocol);
  121. DUPL(LocalDirectory);
  122. DUPL(RemoteDirectory);
  123. DUPL(UpdateDirectories);
  124. DUPL(CacheDirectories);
  125. DUPL(CacheDirectoryChanges);
  126. DUPL(PreserveDirectoryChanges);
  127. DUPL(ResolveSymlinks);
  128. DUPL(LockInHome);
  129. DUPL(Special);
  130. DUPL(Selected);
  131. DUPL(ReturnVar);
  132. DUPL(LookupUserGroups);
  133. DUPL(EOLType);
  134. DUPL(Shell);
  135. DUPL(ClearAliases);
  136. DUPL(Scp1Compatibility);
  137. DUPL(UnsetNationalVars);
  138. DUPL(AliasGroupList);
  139. DUPL(IgnoreLsWarnings);
  140. DUPL(TimeDifference);
  141. // new in 53b
  142. DUPL(TcpNoDelay);
  143. DUPL(AuthKI);
  144. DUPL(ProxyMethod);
  145. DUPL(ProxyHost);
  146. DUPL(ProxyPort);
  147. DUPL(ProxyUsername);
  148. DUPL(ProxyPassword);
  149. DUPL(ProxyTelnetCommand);
  150. DUPL(ProxyDNS);
  151. DUPL(ProxyLocalhost);
  152. for (int Index = 0; Index < LENOF(FBugs); Index++)
  153. {
  154. DUPL(Bug[(TSshBug)Index]);
  155. }
  156. DUPL(CustomParam1);
  157. DUPL(CustomParam2);
  158. #undef DUPL
  159. FModified = ((TSessionData *)Source)->Modified;
  160. }
  161. else
  162. {
  163. TNamedObject::Assign(Source);
  164. }
  165. }
  166. //---------------------------------------------------------------------
  167. void __fastcall TSessionData::StoreToConfig(void * config)
  168. {
  169. Config * cfg = (Config *)config;
  170. // clear all (parameters not set below)
  171. memset(cfg, 0, sizeof(*cfg));
  172. // user-configurable settings
  173. ASCOPY(cfg->host, HostName);
  174. ASCOPY(cfg->username, UserName);
  175. cfg->port = PortNumber;
  176. cfg->protocol = PROT_SSH;
  177. // ping_interval is not used anyway
  178. cfg->ping_interval = (PingType == ptNullPacket) ? PingInterval : 0;
  179. cfg->compression = Compression;
  180. cfg->agentfwd = AgentFwd;
  181. for (int c = 0; c < CIPHER_COUNT; c++)
  182. {
  183. int pcipher;
  184. switch (Cipher[c]) {
  185. case cipWarn: pcipher = CIPHER_WARN; break;
  186. case cip3DES: pcipher = CIPHER_3DES; break;
  187. case cipBlowfish: pcipher = CIPHER_BLOWFISH; break;
  188. case cipAES: pcipher = CIPHER_AES; break;
  189. case cipDES: pcipher = CIPHER_DES; break;
  190. default: assert(false);
  191. }
  192. cfg->ssh_cipherlist[c] = pcipher;
  193. }
  194. AnsiString SPublicKeyFile = PublicKeyFile;
  195. if (SPublicKeyFile.IsEmpty()) SPublicKeyFile = Configuration->DefaultKeyFile;
  196. SPublicKeyFile = StripPathQuotes(SPublicKeyFile);
  197. ASCOPY(cfg->keyfile.path, SPublicKeyFile);
  198. cfg->sshprot = SshProt;
  199. cfg->ssh2_des_cbc = Ssh2DES;
  200. cfg->try_tis_auth = AuthTIS;
  201. cfg->try_ki_auth = AuthKI;
  202. cfg->proxy_type = ProxyMethod;
  203. ASCOPY(cfg->proxy_host, ProxyHost);
  204. cfg->proxy_port = ProxyPort;
  205. ASCOPY(cfg->proxy_username, ProxyUsername);
  206. ASCOPY(cfg->proxy_password, ProxyPassword);
  207. ASCOPY(cfg->proxy_telnet_command, ProxyTelnetCommand);
  208. cfg->proxy_dns = ProxyDNS;
  209. cfg->even_proxy_localhost = ProxyLocalhost;
  210. #pragma option push -w-eas
  211. // after 0.53b values were reversed, however putty still stores
  212. // settings to registry in save way as before
  213. cfg->sshbug_ignore1 = Bug[sbIgnore1];
  214. cfg->sshbug_plainpw1 = Bug[sbPlainPW1];
  215. cfg->sshbug_rsa1 = Bug[sbRSA1];
  216. cfg->sshbug_hmac2 = Bug[sbHMAC2];
  217. cfg->sshbug_derivekey2 = Bug[sbDeriveKey2];
  218. cfg->sshbug_rsapad2 = Bug[sbRSAPad2];
  219. cfg->sshbug_dhgex2 = Bug[sbDHGEx2];
  220. // new after 0.53b
  221. cfg->sshbug_pksessid2 = Bug[sbPKSessID2];
  222. #pragma option pop
  223. if (FSProtocol == fsSCPonly)
  224. {
  225. cfg->ssh_subsys = FALSE;
  226. if (Shell.IsEmpty())
  227. {
  228. // Following forces Putty to open default shell
  229. // see ssh.c: do_ssh2_authconn() and ssh1_protocol()
  230. cfg->remote_cmd[0] = '\0';
  231. }
  232. else
  233. {
  234. ASCOPY(cfg->remote_cmd, Shell);
  235. }
  236. cfg->remote_cmd_ptr = &cfg->remote_cmd[0];
  237. cfg->remote_cmd_ptr2 = NULL; // no second attempt for SCPonly
  238. }
  239. else
  240. {
  241. cfg->ssh_subsys = TRUE;
  242. strcpy(cfg->remote_cmd, "sftp");
  243. cfg->remote_cmd_ptr = &cfg->remote_cmd[0];
  244. if (FSProtocol != fsSFTPonly)
  245. {
  246. cfg->ssh_subsys2 = FALSE;
  247. if (Shell.IsEmpty())
  248. {
  249. cfg->remote_cmd2[0] = '\0';
  250. }
  251. else
  252. {
  253. ASCOPY(cfg->remote_cmd2, Shell);
  254. }
  255. cfg->remote_cmd_ptr2 = &cfg->remote_cmd2[0];
  256. }
  257. else
  258. {
  259. // see psftp_connect() from psftp.c
  260. cfg->ssh_subsys2 = FALSE;
  261. cfg->remote_cmd_ptr2 =
  262. "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n"
  263. "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n"
  264. "exec sftp-server";
  265. }
  266. }
  267. // permanent settings
  268. cfg->nopty = TRUE;
  269. }
  270. //---------------------------------------------------------------------
  271. void __fastcall TSessionData::Load(THierarchicalStorage * Storage)
  272. {
  273. if (Storage->OpenSubKey(StorageKey, False))
  274. {
  275. PortNumber = Storage->ReadInteger("PortNumber", PortNumber);
  276. UserName = Storage->ReadString("UserName", UserName);
  277. // must be loaded after UserName, because HostName may be in format user@host
  278. HostName = Storage->ReadString("HostName", HostName);
  279. if (!Configuration->DisablePasswordStoring)
  280. {
  281. FPassword = Storage->ReadString("Password", FPassword);
  282. }
  283. PingInterval =
  284. Storage->ReadInteger("PingInterval", PingInterval/60)*60 +
  285. Storage->ReadInteger("PingIntervalSec", PingInterval%60);
  286. PingType = static_cast<TPingType>
  287. (Storage->ReadInteger("PingType", PingInterval > 0 ? ptNullPacket : ptOff));
  288. if (PingInterval == 0)
  289. {
  290. PingInterval = 60;
  291. }
  292. Timeout = Storage->ReadInteger("Timeout", Timeout);
  293. AgentFwd = Storage->ReadBool("AgentFwd", AgentFwd);
  294. AuthTIS = Storage->ReadBool("AuthTIS", AuthTIS);
  295. AuthKI = Storage->ReadBool("AuthKI", AuthKI);
  296. Compression = Storage->ReadBool("Compression", Compression);
  297. SshProt = (TSshProt)Storage->ReadInteger("SshProt", SshProt);
  298. Ssh2DES = Storage->ReadBool("Ssh2DES", Ssh2DES);
  299. CipherList = Storage->ReadString("Cipher", CipherList);
  300. PublicKeyFile = Storage->ReadString("PublicKeyFile", PublicKeyFile);
  301. FSProtocol = (TFSProtocol)Storage->ReadInteger("FSProtocol", FSProtocol);
  302. LocalDirectory = Storage->ReadString("LocalDirectory", LocalDirectory);
  303. RemoteDirectory = Storage->ReadString("RemoteDirectory", RemoteDirectory);
  304. UpdateDirectories = Storage->ReadBool("UpdateDirectories", UpdateDirectories);
  305. CacheDirectories = Storage->ReadBool("CacheDirectories", CacheDirectories);
  306. CacheDirectoryChanges = Storage->ReadBool("CacheDirectoryChanges", CacheDirectoryChanges);
  307. PreserveDirectoryChanges = Storage->ReadBool("PreserveDirectoryChanges", PreserveDirectoryChanges);
  308. ResolveSymlinks = Storage->ReadBool("ResolveSymlinks", ResolveSymlinks);
  309. LockInHome = Storage->ReadBool("LockInHome", LockInHome);
  310. Special = Storage->ReadBool("Special", Special);
  311. Shell = Storage->ReadString("Shell", Shell);
  312. ClearAliases = Storage->ReadBool("ClearAliases", ClearAliases);
  313. UnsetNationalVars = Storage->ReadBool("UnsetNationalVars", UnsetNationalVars);
  314. AliasGroupList = Storage->ReadBool("AliasGroupList", AliasGroupList);
  315. IgnoreLsWarnings = Storage->ReadBool("IgnoreLsWarnings", IgnoreLsWarnings);
  316. Scp1Compatibility = Storage->ReadBool("Scp1Compatibility", Scp1Compatibility);
  317. TimeDifference = Storage->ReadFloat("TimeDifference", TimeDifference);
  318. ReturnVar = Storage->ReadString("ReturnVar", ReturnVar);
  319. LookupUserGroups = Storage->ReadBool("LookupUserGroups", LookupUserGroups);
  320. EOLType = (TEOLType)Storage->ReadInteger("EOLType", EOLType);
  321. // new in 53b
  322. TcpNoDelay = Storage->ReadBool("TcpNoDelay", TcpNoDelay);
  323. ProxyMethod = (TProxyMethod)Storage->ReadInteger("ProxyMethod", -1);
  324. if (ProxyMethod < 0)
  325. {
  326. int ProxyType = Storage->ReadInteger("ProxyType", pxNone);
  327. int ProxySOCKSVersion;
  328. switch (ProxyType) {
  329. case pxHTTP:
  330. ProxyMethod = pmHTTP;
  331. break;
  332. case pxTelnet:
  333. ProxyMethod = pmTelnet;
  334. break;
  335. case pxSocks:
  336. ProxySOCKSVersion = Storage->ReadInteger("ProxySOCKSVersion", 5);
  337. ProxyMethod = ProxySOCKSVersion == 5 ? pmSocks5 : pmSocks4;
  338. break;
  339. default:
  340. case pxNone:
  341. ProxyMethod = pmNone;
  342. break;
  343. }
  344. }
  345. ProxyHost = Storage->ReadString("ProxyHost", ProxyHost);
  346. ProxyPort = Storage->ReadInteger("ProxyPort", ProxyPort);
  347. ProxyUsername = Storage->ReadString("ProxyUsername", ProxyUsername);
  348. FProxyPassword = Storage->ReadString("ProxyPassword", FProxyPassword);
  349. ProxyTelnetCommand = Storage->ReadStringRaw("ProxyTelnetCommand", ProxyTelnetCommand);
  350. ProxyDNS = TAutoSwitch((Storage->ReadInteger("ProxyDNS", ProxyDNS) + 1) % 3);
  351. ProxyLocalhost = Storage->ReadBool("ProxyLocalhost", ProxyLocalhost);
  352. #define READ_BUG(BUG) \
  353. Bug[sb##BUG] = TAutoSwitch(2 - Storage->ReadInteger("Bug"#BUG, \
  354. 2 - Bug[sb##BUG]));
  355. READ_BUG(Ignore1);
  356. READ_BUG(PlainPW1);
  357. READ_BUG(RSA1);
  358. READ_BUG(HMAC2);
  359. READ_BUG(DeriveKey2);
  360. READ_BUG(RSAPad2);
  361. READ_BUG(DHGEx2);
  362. READ_BUG(PKSessID2);
  363. #undef READ_BUG
  364. if ((Bug[sbHMAC2] == asAuto) &&
  365. Storage->ReadBool("BuggyMAC", false))
  366. {
  367. Bug[sbHMAC2] = asOn;
  368. }
  369. // read only (used only on Import from Putty dialog)
  370. ProtocolStr = Storage->ReadString("Protocol", ProtocolStr);
  371. CustomParam1 = Storage->ReadString("CustomParam1", CustomParam1);
  372. CustomParam2 = Storage->ReadString("CustomParam2", CustomParam2);
  373. Storage->CloseSubKey();
  374. };
  375. FModified = false;
  376. }
  377. //---------------------------------------------------------------------
  378. void __fastcall TSessionData::Save(THierarchicalStorage * Storage, bool PuttyExport)
  379. {
  380. if (Modified && Storage->OpenSubKey(StorageKey, true))
  381. {
  382. Storage->WriteString("HostName", HostName);
  383. Storage->WriteInteger("PortNumber", PortNumber);
  384. Storage->WriteString("UserName", UserName);
  385. if (!Configuration->DisablePasswordStoring && !PuttyExport)
  386. {
  387. Storage->WriteString("Password", FPassword);
  388. }
  389. Storage->WriteInteger("PingInterval", PingInterval/60);
  390. Storage->WriteInteger("PingIntervalSec", PingInterval%60);
  391. Storage->WriteInteger("PingType", PingType);
  392. Storage->WriteInteger("Timeout", Timeout);
  393. Storage->WriteBool("AgentFwd", AgentFwd);
  394. Storage->WriteBool("AuthTIS", AuthTIS);
  395. Storage->WriteBool("AuthKI", AuthKI);
  396. Storage->WriteBool("Compression", Compression);
  397. Storage->WriteInteger("SshProt", SshProt);
  398. Storage->WriteBool("Ssh2DES", Ssh2DES);
  399. Storage->WriteString("Cipher", CipherList);
  400. Storage->WriteBool("TcpNoDelay", TcpNoDelay);
  401. if (PuttyExport)
  402. {
  403. Storage->WriteStringRaw("PublicKeyFile", PublicKeyFile);
  404. }
  405. else
  406. {
  407. Storage->WriteString("PublicKeyFile", PublicKeyFile);
  408. Storage->WriteInteger("FSProtocol", FSProtocol);
  409. Storage->WriteString("LocalDirectory", LocalDirectory);
  410. Storage->WriteString("RemoteDirectory", RemoteDirectory);
  411. Storage->WriteBool("UpdateDirectories", UpdateDirectories);
  412. Storage->WriteBool("CacheDirectories", CacheDirectories);
  413. Storage->WriteBool("CacheDirectoryChanges", CacheDirectoryChanges);
  414. Storage->WriteBool("PreserveDirectoryChanges", PreserveDirectoryChanges);
  415. Storage->WriteBool("ResolveSymlinks", ResolveSymlinks);
  416. Storage->WriteBool("LockInHome", LockInHome);
  417. // Special is never stored (if it would, login dialog must be modified not to
  418. // duplicate Special parameter when Special session is loaded and then stored
  419. // under different name)
  420. // Storage->WriteBool("Special", Special);
  421. Storage->WriteString("Shell", Shell);
  422. Storage->WriteBool("ClearAliases", ClearAliases);
  423. Storage->WriteBool("UnsetNationalVars", UnsetNationalVars);
  424. Storage->WriteBool("AliasGroupList", AliasGroupList);
  425. Storage->WriteBool("IgnoreLsWarnings", IgnoreLsWarnings);
  426. Storage->WriteBool("Scp1Compatibility", Scp1Compatibility);
  427. Storage->WriteFloat("TimeDifference", TimeDifference);
  428. Storage->WriteString("ReturnVar", ReturnVar);
  429. Storage->WriteBool("LookupUserGroups", LookupUserGroups);
  430. Storage->WriteInteger("EOLType", EOLType);
  431. }
  432. Storage->WriteInteger("ProxyMethod", ProxyMethod);
  433. if (PuttyExport)
  434. {
  435. // support for Putty 0.53b and older
  436. int ProxyType;
  437. int ProxySOCKSVersion = 5;
  438. switch (ProxyMethod) {
  439. case pmHTTP:
  440. ProxyType = pxHTTP;
  441. break;
  442. case pmTelnet:
  443. ProxyType = pxTelnet;
  444. break;
  445. case pmSocks5:
  446. ProxyType = pxSocks;
  447. ProxySOCKSVersion = 5;
  448. break;
  449. case pmSocks4:
  450. ProxyType = pxSocks;
  451. ProxySOCKSVersion = 4;
  452. break;
  453. default:
  454. case pmNone:
  455. ProxyType = pxNone;
  456. break;
  457. }
  458. Storage->WriteInteger("ProxyType", ProxyType);
  459. Storage->WriteInteger("ProxySOCKSVersion", ProxySOCKSVersion);
  460. }
  461. Storage->WriteString("ProxyHost", ProxyHost);
  462. Storage->WriteInteger("ProxyPort", ProxyPort);
  463. Storage->WriteString("ProxyUsername", ProxyUsername);
  464. Storage->WriteString("ProxyPassword", FProxyPassword);
  465. Storage->WriteStringRaw("ProxyTelnetCommand", ProxyTelnetCommand);
  466. Storage->WriteInteger("ProxyDNS", (ProxyDNS+2) % 3);
  467. Storage->WriteBool("ProxyLocalhost", ProxyLocalhost);
  468. #define WRITE_BUG(BUG) Storage->WriteInteger("Bug"#BUG, 2 - Bug[sb##BUG]);
  469. WRITE_BUG(Ignore1);
  470. WRITE_BUG(PlainPW1);
  471. WRITE_BUG(RSA1);
  472. WRITE_BUG(HMAC2);
  473. WRITE_BUG(DeriveKey2);
  474. WRITE_BUG(RSAPad2);
  475. WRITE_BUG(DHGEx2);
  476. WRITE_BUG(PKSessID2);
  477. #undef WRITE_BUG
  478. if (PuttyExport)
  479. {
  480. Storage->WriteString("Protocol", ProtocolStr);
  481. }
  482. if (!PuttyExport)
  483. {
  484. Storage->WriteString("CustomParam1", CustomParam1);
  485. Storage->WriteString("CustomParam2", CustomParam2);
  486. }
  487. Storage->CloseSubKey();
  488. FModified = false;
  489. }
  490. }
  491. //---------------------------------------------------------------------
  492. void __fastcall TSessionData::Remove()
  493. {
  494. THierarchicalStorage * Storage = Configuration->CreateScpStorage(true);
  495. try
  496. {
  497. if (Storage->OpenSubKey(Configuration->StoredSessionsSubKey, false))
  498. {
  499. Storage->RecursiveDeleteSubKey(StorageKey);
  500. }
  501. }
  502. __finally
  503. {
  504. delete Storage;
  505. }
  506. }
  507. //---------------------------------------------------------------------
  508. bool __fastcall TSessionData::ParseUrl(AnsiString Url, int Params,
  509. AnsiString * ConnectInfo, AnsiString * HostName, int * PortNumber,
  510. AnsiString * UserName, AnsiString * Password, AnsiString * Path)
  511. {
  512. int PSlash = Url.Pos("/");
  513. if (PSlash == 0)
  514. {
  515. PSlash = Url.Length() + 1;
  516. }
  517. AnsiString AConnectInfo;
  518. AConnectInfo = Url.SubString(1, PSlash - 1);
  519. int P = AConnectInfo.Pos("@");
  520. bool Result = (P > 0) || ((Params & puRequireUsername) == 0);
  521. if (Result)
  522. {
  523. if (Path != NULL)
  524. {
  525. bool ExcludeLeadingSlash = (Params & puExcludeLeadingSlash) != 0;
  526. int Delta = ExcludeLeadingSlash ? 1 : 0;
  527. AnsiString APath = Url.SubString(PSlash + Delta,
  528. Url.Length() - PSlash - Delta + 1);
  529. if (ExcludeLeadingSlash || (APath != "/"))
  530. {
  531. *Path = APath;
  532. }
  533. }
  534. if (ConnectInfo != NULL)
  535. {
  536. *ConnectInfo = AConnectInfo;
  537. }
  538. AnsiString UserInfo;
  539. AnsiString HostInfo;
  540. if (P > 0)
  541. {
  542. UserInfo = AConnectInfo.SubString(1, P - 1);
  543. HostInfo = AConnectInfo.SubString(P + 1, AConnectInfo.Length() - P);
  544. }
  545. else
  546. {
  547. HostInfo = AConnectInfo;
  548. }
  549. if (HostName != NULL)
  550. {
  551. *HostName = CutToChar(HostInfo, ':', true);
  552. }
  553. else
  554. {
  555. CutToChar(HostInfo, ':', true);
  556. }
  557. if (PortNumber != NULL)
  558. {
  559. *PortNumber = HostInfo.IsEmpty() ? -1 : StrToIntDef(HostInfo, -1);
  560. }
  561. if (UserName != NULL)
  562. {
  563. *UserName = CutToChar(UserInfo, ':', false);
  564. }
  565. else
  566. {
  567. CutToChar(UserInfo, ':', false);
  568. }
  569. if (Password != NULL)
  570. {
  571. *Password = UserInfo;
  572. }
  573. }
  574. return Result;
  575. }
  576. //---------------------------------------------------------------------
  577. bool __fastcall TSessionData::ParseUrl(AnsiString Url, int Params)
  578. {
  579. AnsiString AHostName = HostName;
  580. int APortNumber = PortNumber;
  581. AnsiString AUserName = UserName;
  582. AnsiString APassword = Password;
  583. AnsiString ARemoteDirectory = RemoteDirectory;
  584. bool Result = ParseUrl(Url, Params, NULL, &AHostName, &APortNumber,
  585. &AUserName, &APassword, &ARemoteDirectory);
  586. if (Result)
  587. {
  588. HostName = AHostName;
  589. if (APortNumber >= 0)
  590. {
  591. PortNumber = APortNumber;
  592. }
  593. UserName = AUserName;
  594. Password = APassword;
  595. RemoteDirectory = ARemoteDirectory;
  596. }
  597. return Result;
  598. }
  599. //---------------------------------------------------------------------
  600. bool __fastcall TSessionData::GetCanLogin()
  601. {
  602. return !FHostName.IsEmpty() && !FUserName.IsEmpty();
  603. }
  604. //---------------------------------------------------------------------------
  605. AnsiString __fastcall TSessionData::GetSessionKey()
  606. {
  607. return FORMAT("%s@%s", (UserName, HostName));
  608. }
  609. //---------------------------------------------------------------------
  610. AnsiString __fastcall TSessionData::GetStorageKey()
  611. {
  612. return MungeStr(Name);
  613. }
  614. //---------------------------------------------------------------------
  615. void __fastcall TSessionData::SetHostName(AnsiString value)
  616. {
  617. if (FHostName != value)
  618. {
  619. // HostName is key for password encryption
  620. AnsiString XPassword = Password;
  621. int P = value.LastDelimiter("@");
  622. if (P > 0)
  623. {
  624. UserName = value.SubString(1, P - 1);
  625. value = value.SubString(P + 1, value.Length() - P);
  626. }
  627. FHostName = value;
  628. FModified = true;
  629. Password = XPassword;
  630. if (!XPassword.IsEmpty())
  631. {
  632. memset(XPassword.c_str(), 0, XPassword.Length());
  633. }
  634. }
  635. }
  636. //---------------------------------------------------------------------
  637. void __fastcall TSessionData::SetPortNumber(int value)
  638. {
  639. SET_SESSION_PROPERTY(PortNumber);
  640. }
  641. //---------------------------------------------------------------------------
  642. void __fastcall TSessionData::SetShell(AnsiString value)
  643. {
  644. SET_SESSION_PROPERTY(Shell);
  645. }
  646. //---------------------------------------------------------------------------
  647. void __fastcall TSessionData::SetClearAliases(bool value)
  648. {
  649. SET_SESSION_PROPERTY(ClearAliases);
  650. }
  651. //---------------------------------------------------------------------------
  652. void __fastcall TSessionData::SetAliasGroupList(bool value)
  653. {
  654. SET_SESSION_PROPERTY(AliasGroupList);
  655. }
  656. //---------------------------------------------------------------------------
  657. void __fastcall TSessionData::SetIgnoreLsWarnings(bool value)
  658. {
  659. SET_SESSION_PROPERTY(IgnoreLsWarnings);
  660. }
  661. //---------------------------------------------------------------------------
  662. void __fastcall TSessionData::SetUnsetNationalVars(bool value)
  663. {
  664. SET_SESSION_PROPERTY(UnsetNationalVars);
  665. }
  666. //---------------------------------------------------------------------
  667. void __fastcall TSessionData::SetUserName(AnsiString value)
  668. {
  669. // UserName is key for password encryption
  670. AnsiString XPassword = Password;
  671. SET_SESSION_PROPERTY(UserName);
  672. Password = XPassword;
  673. if (!XPassword.IsEmpty())
  674. {
  675. memset(XPassword.c_str(), 0, XPassword.Length());
  676. }
  677. }
  678. //---------------------------------------------------------------------
  679. void __fastcall TSessionData::SetPassword(AnsiString value)
  680. {
  681. value = EncryptPassword(value, UserName+HostName);
  682. SET_SESSION_PROPERTY(Password);
  683. }
  684. //---------------------------------------------------------------------
  685. AnsiString __fastcall TSessionData::GetPassword()
  686. {
  687. return DecryptPassword(FPassword, UserName+HostName);
  688. }
  689. //---------------------------------------------------------------------
  690. void __fastcall TSessionData::SetPingInterval(int value)
  691. {
  692. SET_SESSION_PROPERTY(PingInterval);
  693. }
  694. //---------------------------------------------------------------------
  695. void __fastcall TSessionData::SetAgentFwd(bool value)
  696. {
  697. SET_SESSION_PROPERTY(AgentFwd);
  698. }
  699. //---------------------------------------------------------------------
  700. void __fastcall TSessionData::SetAuthTIS(bool value)
  701. {
  702. SET_SESSION_PROPERTY(AuthTIS);
  703. }
  704. //---------------------------------------------------------------------
  705. void __fastcall TSessionData::SetAuthKI(bool value)
  706. {
  707. SET_SESSION_PROPERTY(AuthKI);
  708. }
  709. //---------------------------------------------------------------------
  710. void __fastcall TSessionData::SetCompression(bool value)
  711. {
  712. SET_SESSION_PROPERTY(Compression);
  713. }
  714. //---------------------------------------------------------------------
  715. void __fastcall TSessionData::SetSshProt(TSshProt value)
  716. {
  717. SET_SESSION_PROPERTY(SshProt);
  718. }
  719. //---------------------------------------------------------------------
  720. void __fastcall TSessionData::SetSsh2DES(bool value)
  721. {
  722. SET_SESSION_PROPERTY(Ssh2DES);
  723. }
  724. //---------------------------------------------------------------------
  725. AnsiString __fastcall TSessionData::GetSshProtStr()
  726. {
  727. return SshProtList[FSshProt];
  728. }
  729. //---------------------------------------------------------------------
  730. void __fastcall TSessionData::SetCipher(int Index, TCipher value)
  731. {
  732. assert(Index >= 0 && Index < CIPHER_COUNT);
  733. SET_SESSION_PROPERTY(Ciphers[Index]);
  734. }
  735. //---------------------------------------------------------------------
  736. TCipher __fastcall TSessionData::GetCipher(int Index)
  737. {
  738. assert(Index >= 0 && Index < CIPHER_COUNT);
  739. return FCiphers[Index];
  740. }
  741. //---------------------------------------------------------------------
  742. void __fastcall TSessionData::SetCipherList(AnsiString value)
  743. {
  744. bool Used[CIPHER_COUNT];
  745. for (int C = 0; C < CIPHER_COUNT; C++) Used[C] = false;
  746. AnsiString CipherStr;
  747. int Index = 0;
  748. while (!value.IsEmpty() && (Index < CIPHER_COUNT))
  749. {
  750. CipherStr = CutToChar(value, ',', true);
  751. for (int C = 0; C < CIPHER_COUNT; C++)
  752. {
  753. if (!CipherStr.AnsiCompareIC(CipherNames[C]))
  754. {
  755. Cipher[Index] = (TCipher)C;
  756. Used[C] = true;
  757. Index++;
  758. break;
  759. }
  760. }
  761. }
  762. for (int C = 0; C < CIPHER_COUNT && Index < CIPHER_COUNT; C++)
  763. {
  764. if (!Used[DefaultCipherList[C]]) Cipher[Index++] = DefaultCipherList[C];
  765. }
  766. }
  767. //---------------------------------------------------------------------
  768. AnsiString __fastcall TSessionData::GetCipherList()
  769. {
  770. AnsiString Result;
  771. for (int Index = 0; Index < CIPHER_COUNT; Index++)
  772. {
  773. Result += AnsiString(Index ? "," : "") + CipherNames[Cipher[Index]];
  774. }
  775. return Result;
  776. }
  777. //---------------------------------------------------------------------
  778. void __fastcall TSessionData::SetPublicKeyFile(AnsiString value)
  779. {
  780. SET_SESSION_PROPERTY(PublicKeyFile);
  781. }
  782. //---------------------------------------------------------------------
  783. AnsiString __fastcall TSessionData::GetDefaultLogFileName()
  784. {
  785. return GetTemporaryPath() + MakeValidFileName(SessionName) + ".log";
  786. }
  787. //---------------------------------------------------------------------
  788. void __fastcall TSessionData::SetReturnVar(AnsiString value)
  789. {
  790. SET_SESSION_PROPERTY(ReturnVar);
  791. }
  792. //---------------------------------------------------------------------------
  793. void __fastcall TSessionData::SetLookupUserGroups(bool value)
  794. {
  795. SET_SESSION_PROPERTY(LookupUserGroups);
  796. }
  797. //---------------------------------------------------------------------------
  798. void __fastcall TSessionData::SetEOLType(TEOLType value)
  799. {
  800. SET_SESSION_PROPERTY(EOLType);
  801. }
  802. //---------------------------------------------------------------------------
  803. void __fastcall TSessionData::SetTimeout(int value)
  804. {
  805. SET_SESSION_PROPERTY(Timeout);
  806. }
  807. //---------------------------------------------------------------------------
  808. void __fastcall TSessionData::SetFSProtocol(TFSProtocol value)
  809. {
  810. SET_SESSION_PROPERTY(FSProtocol);
  811. }
  812. //---------------------------------------------------------------------
  813. AnsiString __fastcall TSessionData::GetFSProtocolStr()
  814. {
  815. assert(FSProtocol >= 0 && FSProtocol < FSPROTOCOL_COUNT);
  816. return FSProtocolNames[FSProtocol];
  817. }
  818. //---------------------------------------------------------------------------
  819. void __fastcall TSessionData::SetDetectReturnVar(bool value)
  820. {
  821. if (value != DetectReturnVar)
  822. {
  823. ReturnVar = value ? "" : "$?";
  824. }
  825. }
  826. //---------------------------------------------------------------------------
  827. bool __fastcall TSessionData::GetDetectReturnVar()
  828. {
  829. return ReturnVar.IsEmpty();
  830. }
  831. //---------------------------------------------------------------------------
  832. void __fastcall TSessionData::SetDefaultShell(bool value)
  833. {
  834. if (value != DefaultShell)
  835. {
  836. Shell = value ? "" : "/bin/bash";
  837. }
  838. }
  839. //---------------------------------------------------------------------------
  840. bool __fastcall TSessionData::GetDefaultShell()
  841. {
  842. return Shell.IsEmpty();
  843. }
  844. //---------------------------------------------------------------------------
  845. void __fastcall TSessionData::SetProtocolStr(AnsiString value)
  846. {
  847. for (int Index = 0; backends[Index].name != NULL; Index++)
  848. {
  849. if (!value.AnsiCompareIC(backends[Index].name))
  850. {
  851. FProtocol = (TProtocol)backends[Index].protocol;
  852. break;
  853. }
  854. }
  855. }
  856. //---------------------------------------------------------------------
  857. AnsiString __fastcall TSessionData::GetProtocolStr()
  858. {
  859. for (int Index = 0; backends[Index].name != NULL; Index++)
  860. {
  861. if ((TProtocol)backends[Index].protocol == Protocol)
  862. {
  863. return backends[Index].name;
  864. }
  865. }
  866. return "raw";
  867. }
  868. //---------------------------------------------------------------------
  869. void __fastcall TSessionData::SetPingIntervalDT(TDateTime value)
  870. {
  871. unsigned short hour, min, sec, msec;
  872. value.DecodeTime(&hour, &min, &sec, &msec);
  873. PingInterval = ((int)hour)*60*60 + ((int)min)*60 + sec;
  874. }
  875. //---------------------------------------------------------------------------
  876. TDateTime __fastcall TSessionData::GetPingIntervalDT()
  877. {
  878. return TDateTime((unsigned short)(PingInterval/60/60),
  879. (unsigned short)(PingInterval/60%60), (unsigned short)(PingInterval%60), 0);
  880. }
  881. //---------------------------------------------------------------------------
  882. void __fastcall TSessionData::SetPingType(TPingType value)
  883. {
  884. SET_SESSION_PROPERTY(PingType);
  885. }
  886. //---------------------------------------------------------------------
  887. AnsiString __fastcall TSessionData::GetSessionName()
  888. {
  889. if (!Name.IsEmpty() && !TNamedObjectList::IsHidden(this) &&
  890. (Name != DefaultSessionName))
  891. {
  892. return Name;
  893. }
  894. else if (!HostName.IsEmpty() && !UserName.IsEmpty())
  895. {
  896. return FORMAT("%s@%s", (UserName, HostName));
  897. }
  898. else if (!HostName.IsEmpty())
  899. {
  900. return HostName;
  901. }
  902. else
  903. {
  904. return "session";
  905. }
  906. }
  907. //---------------------------------------------------------------------
  908. void __fastcall TSessionData::SetTimeDifference(TDateTime value)
  909. {
  910. SET_SESSION_PROPERTY(TimeDifference);
  911. }
  912. //---------------------------------------------------------------------
  913. void __fastcall TSessionData::SetLocalDirectory(AnsiString value)
  914. {
  915. SET_SESSION_PROPERTY(LocalDirectory);
  916. }
  917. //---------------------------------------------------------------------
  918. void __fastcall TSessionData::SetRemoteDirectory(AnsiString value)
  919. {
  920. SET_SESSION_PROPERTY(RemoteDirectory);
  921. }
  922. //---------------------------------------------------------------------
  923. void __fastcall TSessionData::SetUpdateDirectories(bool value)
  924. {
  925. SET_SESSION_PROPERTY(UpdateDirectories);
  926. }
  927. //---------------------------------------------------------------------
  928. void __fastcall TSessionData::SetCacheDirectories(bool value)
  929. {
  930. SET_SESSION_PROPERTY(CacheDirectories);
  931. }
  932. //---------------------------------------------------------------------
  933. void __fastcall TSessionData::SetCacheDirectoryChanges(bool value)
  934. {
  935. SET_SESSION_PROPERTY(CacheDirectoryChanges);
  936. }
  937. //---------------------------------------------------------------------
  938. void __fastcall TSessionData::SetPreserveDirectoryChanges(bool value)
  939. {
  940. SET_SESSION_PROPERTY(PreserveDirectoryChanges);
  941. }
  942. //---------------------------------------------------------------------
  943. void __fastcall TSessionData::SetResolveSymlinks(bool value)
  944. {
  945. SET_SESSION_PROPERTY(ResolveSymlinks);
  946. }
  947. //---------------------------------------------------------------------
  948. void __fastcall TSessionData::SetLockInHome(bool value)
  949. {
  950. SET_SESSION_PROPERTY(LockInHome);
  951. }
  952. //---------------------------------------------------------------------
  953. void __fastcall TSessionData::SetSpecial(bool value)
  954. {
  955. SET_SESSION_PROPERTY(Special);
  956. }
  957. //---------------------------------------------------------------------------
  958. void __fastcall TSessionData::SetScp1Compatibility(bool value)
  959. {
  960. SET_SESSION_PROPERTY(Scp1Compatibility);
  961. }
  962. //---------------------------------------------------------------------
  963. void __fastcall TSessionData::SetTcpNoDelay(bool value)
  964. {
  965. SET_SESSION_PROPERTY(TcpNoDelay);
  966. }
  967. //---------------------------------------------------------------------
  968. void __fastcall TSessionData::SetProxyMethod(TProxyMethod value)
  969. {
  970. SET_SESSION_PROPERTY(ProxyMethod);
  971. }
  972. //---------------------------------------------------------------------
  973. void __fastcall TSessionData::SetProxyHost(AnsiString value)
  974. {
  975. SET_SESSION_PROPERTY(ProxyHost);
  976. }
  977. //---------------------------------------------------------------------
  978. void __fastcall TSessionData::SetProxyPort(int value)
  979. {
  980. SET_SESSION_PROPERTY(ProxyPort);
  981. }
  982. //---------------------------------------------------------------------
  983. void __fastcall TSessionData::SetProxyUsername(AnsiString value)
  984. {
  985. SET_SESSION_PROPERTY(ProxyUsername);
  986. }
  987. //---------------------------------------------------------------------
  988. void __fastcall TSessionData::SetProxyPassword(AnsiString value)
  989. {
  990. // proxy password unencrypted to maintain compatibility with Putty
  991. SET_SESSION_PROPERTY(ProxyPassword);
  992. }
  993. //---------------------------------------------------------------------
  994. AnsiString __fastcall TSessionData::GetProxyPassword()
  995. {
  996. return FProxyPassword;
  997. }
  998. //---------------------------------------------------------------------
  999. void __fastcall TSessionData::SetProxyTelnetCommand(AnsiString value)
  1000. {
  1001. SET_SESSION_PROPERTY(ProxyTelnetCommand);
  1002. }
  1003. //---------------------------------------------------------------------
  1004. void __fastcall TSessionData::SetProxyDNS(TAutoSwitch value)
  1005. {
  1006. SET_SESSION_PROPERTY(ProxyDNS);
  1007. }
  1008. //---------------------------------------------------------------------
  1009. void __fastcall TSessionData::SetProxyLocalhost(bool value)
  1010. {
  1011. SET_SESSION_PROPERTY(ProxyLocalhost);
  1012. }
  1013. //---------------------------------------------------------------------
  1014. void __fastcall TSessionData::SetBug(TSshBug Bug, TAutoSwitch value)
  1015. {
  1016. assert(Bug >= 0 && Bug < LENOF(FBugs));
  1017. SET_SESSION_PROPERTY(Bugs[Bug]);
  1018. }
  1019. //---------------------------------------------------------------------
  1020. TAutoSwitch __fastcall TSessionData::GetBug(TSshBug Bug)
  1021. {
  1022. assert(Bug >= 0 && Bug < LENOF(FBugs));
  1023. return FBugs[Bug];
  1024. }
  1025. //---------------------------------------------------------------------
  1026. void __fastcall TSessionData::SetCustomParam1(AnsiString value)
  1027. {
  1028. SET_SESSION_PROPERTY(CustomParam1);
  1029. }
  1030. //---------------------------------------------------------------------
  1031. void __fastcall TSessionData::SetCustomParam2(AnsiString value)
  1032. {
  1033. SET_SESSION_PROPERTY(CustomParam2);
  1034. }
  1035. //---------------------------------------------------------------------
  1036. void __fastcall TSessionData::SetSFTPDownloadQueue(int value)
  1037. {
  1038. SET_SESSION_PROPERTY(SFTPDownloadQueue);
  1039. }
  1040. //---------------------------------------------------------------------
  1041. void __fastcall TSessionData::SetSFTPUploadQueue(int value)
  1042. {
  1043. SET_SESSION_PROPERTY(SFTPUploadQueue);
  1044. }
  1045. //---------------------------------------------------------------------
  1046. void __fastcall TSessionData::SetSFTPListingQueue(int value)
  1047. {
  1048. SET_SESSION_PROPERTY(SFTPListingQueue);
  1049. }
  1050. //---------------------------------------------------------------------
  1051. AnsiString __fastcall TSessionData::GetInfoTip()
  1052. {
  1053. return FmtLoadStr(SESSION_INFO_TIP,
  1054. ARRAYOFCONST((
  1055. (HostName.IsEmpty() ? AnsiString() : HostName),
  1056. (UserName.IsEmpty() ? AnsiString() : UserName),
  1057. (PublicKeyFile.IsEmpty() ? LoadStr(NO_STR) : LoadStr(YES_STR)),
  1058. SshProtStr,
  1059. FSProtocolStr)));
  1060. }
  1061. //=== TStoredSessionList ----------------------------------------------
  1062. __fastcall TStoredSessionList::TStoredSessionList(bool aReadOnly):
  1063. TNamedObjectList(), FReadOnly(aReadOnly)
  1064. {
  1065. assert(Configuration);
  1066. LastStorage = Configuration->Storage;
  1067. FDefaultSettings = new TSessionData(DefaultSessionName);
  1068. }
  1069. //---------------------------------------------------------------------
  1070. __fastcall TStoredSessionList::~TStoredSessionList()
  1071. {
  1072. assert(Configuration);
  1073. if (!FReadOnly && (Configuration->Storage != LastStorage)) Save();
  1074. delete FDefaultSettings;
  1075. }
  1076. //---------------------------------------------------------------------
  1077. void __fastcall TStoredSessionList::Load(THierarchicalStorage * Storage, bool AsModified)
  1078. {
  1079. TStringList *SubKeys = new TStringList();
  1080. try {
  1081. Storage->GetSubKeyNames(SubKeys);
  1082. for (int Index = 0; Index < SubKeys->Count; Index++)
  1083. {
  1084. TSessionData *SessionData;
  1085. AnsiString SessionName = UnMungeStr(SubKeys->Strings[Index]);
  1086. if (SessionName == FDefaultSettings->Name) SessionData = FDefaultSettings;
  1087. else SessionData = (TSessionData*)FindByName(SessionName);
  1088. if (!SessionData)
  1089. {
  1090. SessionData = new TSessionData(SessionName);
  1091. Add(SessionData);
  1092. }
  1093. SessionData->Load(Storage);
  1094. if (AsModified)
  1095. {
  1096. SessionData->Modified = true;
  1097. }
  1098. }
  1099. } __finally {
  1100. delete SubKeys;
  1101. }
  1102. }
  1103. //---------------------------------------------------------------------
  1104. void __fastcall TStoredSessionList::Load(AnsiString aKey)
  1105. {
  1106. TRegistryStorage * Storage = new TRegistryStorage(aKey);
  1107. try {
  1108. LastStorage = stRegistry;
  1109. if (Storage->OpenRootKey(False)) Load(Storage);
  1110. } __finally {
  1111. delete Storage;
  1112. }
  1113. }
  1114. //---------------------------------------------------------------------
  1115. void __fastcall TStoredSessionList::Load()
  1116. {
  1117. THierarchicalStorage * Storage = Configuration->CreateScpStorage(true);
  1118. try {
  1119. LastStorage = Configuration->Storage;
  1120. if (Storage->OpenSubKey(Configuration->StoredSessionsSubKey, False))
  1121. Load(Storage);
  1122. } __finally {
  1123. delete Storage;
  1124. }
  1125. }
  1126. //---------------------------------------------------------------------
  1127. void __fastcall TStoredSessionList::Save(THierarchicalStorage * Storage)
  1128. {
  1129. for (int Index = 0; Index < Count+HiddenCount; Index++)
  1130. {
  1131. TSessionData *SessionData = (TSessionData *)Items[Index];
  1132. if (SessionData->Modified)
  1133. SessionData->Save(Storage);
  1134. }
  1135. if (FDefaultSettings->Modified)
  1136. FDefaultSettings->Save(Storage);
  1137. }
  1138. //---------------------------------------------------------------------
  1139. void __fastcall TStoredSessionList::Save(AnsiString aKey)
  1140. {
  1141. TRegistryStorage * Storage = new TRegistryStorage(aKey);
  1142. try
  1143. {
  1144. LastStorage = stRegistry;
  1145. Storage->AccessMode = smReadWrite;
  1146. if (Storage->OpenRootKey(True)) Save(Storage);
  1147. }
  1148. __finally
  1149. {
  1150. delete Storage;
  1151. }
  1152. }
  1153. //---------------------------------------------------------------------
  1154. void __fastcall TStoredSessionList::Save()
  1155. {
  1156. if (LastStorage != Configuration->Storage)
  1157. {
  1158. // make sure, that all data will be stored, when saving to new storage
  1159. for (int Index = 0; Index < Count+HiddenCount; Index++)
  1160. ((TSessionData*)Items[Index])->Modified = true;
  1161. FDefaultSettings->Modified = true;
  1162. LastStorage = Configuration->Storage;
  1163. }
  1164. THierarchicalStorage * Storage = Configuration->CreateScpStorage(true);
  1165. try {
  1166. Storage->AccessMode = smReadWrite;
  1167. if (Storage->OpenSubKey(Configuration->StoredSessionsSubKey, True))
  1168. Save(Storage);
  1169. } __finally {
  1170. delete Storage;
  1171. }
  1172. }
  1173. //---------------------------------------------------------------------
  1174. void __fastcall TStoredSessionList::SelectAll(bool Select)
  1175. {
  1176. for (int Index = 0; Index < Count; Index++)
  1177. Sessions[Index]->Selected = Select;
  1178. }
  1179. //---------------------------------------------------------------------
  1180. void __fastcall TStoredSessionList::Import(TStoredSessionList * From,
  1181. bool OnlySelected)
  1182. {
  1183. for (int Index = 0; Index < From->Count; Index++)
  1184. {
  1185. if (!OnlySelected || From->Sessions[Index]->Selected)
  1186. {
  1187. TSessionData *Session = new TSessionData("");
  1188. Session->Assign(From->Sessions[Index]);
  1189. Session->Modified = true;
  1190. Session->MakeUniqueIn(this);
  1191. Add(Session);
  1192. }
  1193. }
  1194. Save();
  1195. }
  1196. //---------------------------------------------------------------------
  1197. void __fastcall TStoredSessionList::SelectSessionsToImport
  1198. (TStoredSessionList * Dest, bool SSHOnly)
  1199. {
  1200. for (int Index = 0; Index < Count; Index++)
  1201. {
  1202. Sessions[Index]->Selected =
  1203. (!SSHOnly || (Sessions[Index]->Protocol == ptSSH)) &&
  1204. !Dest->FindByName(Sessions[Index]->Name);
  1205. }
  1206. }
  1207. //---------------------------------------------------------------------
  1208. void __fastcall TStoredSessionList::Cleanup()
  1209. {
  1210. try {
  1211. if (Configuration->Storage == stRegistry) Clear();
  1212. TRegistryStorage * Storage = new TRegistryStorage(Configuration->RegistryStorageKey);
  1213. try {
  1214. Storage->AccessMode = smReadWrite;
  1215. if (Storage->OpenRootKey(False))
  1216. Storage->RecursiveDeleteSubKey(Configuration->StoredSessionsSubKey);
  1217. } __finally {
  1218. delete Storage;
  1219. }
  1220. } catch (Exception &E) {
  1221. throw ExtException(&E, CLEANUP_SESSIONS_ERROR);
  1222. }
  1223. }
  1224. //---------------------------------------------------------------------------
  1225. int __fastcall TStoredSessionList::IndexOf(TSessionData * Data)
  1226. {
  1227. for (int Index = 0; Index < Count; Index++)
  1228. if (Data == Sessions[Index]) return Index;
  1229. return -1;
  1230. }
  1231. //---------------------------------------------------------------------------
  1232. TSessionData * __fastcall TStoredSessionList::NewSession(
  1233. AnsiString SessionName, TSessionData * Session)
  1234. {
  1235. TSessionData * DuplicateSession = (TSessionData*)FindByName(SessionName);
  1236. if (!DuplicateSession)
  1237. {
  1238. DuplicateSession = new TSessionData("");
  1239. DuplicateSession->Assign(Session);
  1240. DuplicateSession->Name = SessionName;
  1241. // make sure, that new stored session is saved to registry
  1242. DuplicateSession->Modified = true;
  1243. Add(DuplicateSession);
  1244. }
  1245. else
  1246. {
  1247. DuplicateSession->Assign(Session);
  1248. DuplicateSession->Name = SessionName;
  1249. DuplicateSession->Modified = true;
  1250. }
  1251. // list was saved here before to default storage, but it would not allow
  1252. // to work with special lists (export/import) not using default storage
  1253. return DuplicateSession;
  1254. }
  1255. //---------------------------------------------------------------------------
  1256. void __fastcall TStoredSessionList::SetDefaultSettings(TSessionData * value)
  1257. {
  1258. assert(FDefaultSettings);
  1259. if (FDefaultSettings != value)
  1260. {
  1261. FDefaultSettings->Assign(value);
  1262. FDefaultSettings->Name = DefaultSessionName;
  1263. Save();
  1264. }
  1265. }