SessionData.cpp 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902
  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. #include "RemoteFiles.h"
  14. //---------------------------------------------------------------------------
  15. #pragma package(smart_init)
  16. //---------------------------------------------------------------------------
  17. const char * DefaultSessionName = "Default Settings";
  18. const char CipherNames[CIPHER_COUNT][10] = {"WARN", "3des", "blowfish", "aes", "des"};
  19. const char KexNames[KEX_COUNT][20] = {"WARN", "dh-group1-sha1", "dh-group14-sha1", "dh-gex-sha1" };
  20. const char SshProtList[][10] = {"1 only", "1", "2", "2 only"};
  21. const char ProxyMethodList[][10] = {"none", "SOCKS4", "SOCKS5", "HTTP", "Telnet", "Cmd" };
  22. const TCipher DefaultCipherList[CIPHER_COUNT] =
  23. { cipAES, cipBlowfish, cip3DES, cipWarn, cipDES };
  24. const TKex DefaultKexList[KEX_COUNT] =
  25. { kexDHGEx, kexDHGroup14, kexDHGroup1, kexWarn };
  26. const char FSProtocolNames[FSPROTOCOL_COUNT][11] = { "SCP", "SFTP (SCP)", "SFTP", "SSH", "SFTP" };
  27. //--- TSessionData ----------------------------------------------------
  28. AnsiString TSessionData::FInvalidChars("/\\[]");
  29. //---------------------------------------------------------------------
  30. __fastcall TSessionData::TSessionData(AnsiString aName):
  31. TNamedObject(aName)
  32. {
  33. Default();
  34. FModified = true;
  35. }
  36. //---------------------------------------------------------------------
  37. void __fastcall TSessionData::Default()
  38. {
  39. HostName = "";
  40. PortNumber = default_port;
  41. UserName = "";
  42. Password = "";
  43. PingInterval = 30;
  44. PingType = ptOff;
  45. Timeout = 15;
  46. AgentFwd = false;
  47. AuthTIS = false;
  48. AuthKI = true;
  49. AuthKIPassword = true;
  50. AuthGSSAPI = false;
  51. ChangeUsername = false;
  52. Compression = false;
  53. SshProt = ssh2;
  54. Ssh2DES = false;
  55. for (int Index = 0; Index < CIPHER_COUNT; Index++)
  56. {
  57. Cipher[Index] = DefaultCipherList[Index];
  58. }
  59. for (int Index = 0; Index < KEX_COUNT; Index++)
  60. {
  61. Kex[Index] = DefaultKexList[Index];
  62. }
  63. PublicKeyFile = "";
  64. FProtocol = ptSSH;
  65. TcpNoDelay = true;
  66. ProxyMethod = pmNone;
  67. ProxyHost = "proxy";
  68. ProxyPort = 80;
  69. ProxyUsername = "";
  70. ProxyPassword = "";
  71. ProxyTelnetCommand = "connect %host %port\\n";
  72. ProxyDNS = asAuto;
  73. ProxyLocalhost = false;
  74. for (int Index = 0; Index < LENOF(FBugs); Index++)
  75. {
  76. Bug[(TSshBug)Index] = asAuto;
  77. }
  78. Special = false;
  79. FSProtocol = fsSFTP;
  80. AddressFamily = afAuto;
  81. RekeyData = "1G";
  82. RekeyTime = 60;
  83. // FS common
  84. LocalDirectory = "";
  85. RemoteDirectory = "";
  86. UpdateDirectories = false;
  87. CacheDirectories = true;
  88. CacheDirectoryChanges = true;
  89. PreserveDirectoryChanges = true;
  90. LockInHome = false;
  91. ResolveSymlinks = true;
  92. ConsiderDST = true;
  93. DeleteToRecycleBin = false;
  94. OverwrittenToRecycleBin = false;
  95. RecycleBinPath = "/tmp";
  96. Color = 0;
  97. // SCP
  98. ReturnVar = "";
  99. LookupUserGroups = true;
  100. EOLType = eolLF;
  101. Shell = ""; //default shell
  102. ReturnVar = "";
  103. ClearAliases = true;
  104. UnsetNationalVars = true;
  105. AliasGroupList = false;
  106. IgnoreLsWarnings = true;
  107. Scp1Compatibility = false;
  108. TimeDifference = 0;
  109. SCPLsFullTime = asAuto;
  110. // SFTP
  111. SFTPDownloadQueue = 4;
  112. SFTPUploadQueue = 4;
  113. SFTPListingQueue = 2;
  114. SFTPMaxVersion = 5;
  115. SFTPMaxPacketSize = 0;
  116. for (int Index = 0; Index < LENOF(FSFTPBugs); Index++)
  117. {
  118. SFTPBug[(TSftpBug)Index] = asAuto;
  119. }
  120. CustomParam1 = "";
  121. CustomParam2 = "";
  122. Selected = false;
  123. FModified = false;
  124. // add also to TSessionLog::AddStartupInfo()
  125. }
  126. //---------------------------------------------------------------------
  127. void __fastcall TSessionData::NonPersistant()
  128. {
  129. UpdateDirectories = false;
  130. PreserveDirectoryChanges = false;
  131. }
  132. //---------------------------------------------------------------------
  133. void __fastcall TSessionData::Assign(TPersistent * Source)
  134. {
  135. if (Source && Source->InheritsFrom(__classid(TSessionData)))
  136. {
  137. #define DUPL(P) P = ((TSessionData *)Source)->P
  138. DUPL(Name);
  139. DUPL(HostName);
  140. DUPL(PortNumber);
  141. DUPL(UserName);
  142. DUPL(Password);
  143. DUPL(PingInterval);
  144. DUPL(PingType);
  145. DUPL(Timeout);
  146. DUPL(AgentFwd);
  147. DUPL(AuthTIS);
  148. DUPL(ChangeUsername);
  149. DUPL(Compression);
  150. DUPL(SshProt);
  151. DUPL(Ssh2DES);
  152. DUPL(CipherList);
  153. DUPL(KexList);
  154. DUPL(PublicKeyFile);
  155. DUPL(AddressFamily);
  156. DUPL(RekeyData);
  157. DUPL(RekeyTime);
  158. DUPL(FSProtocol);
  159. DUPL(LocalDirectory);
  160. DUPL(RemoteDirectory);
  161. DUPL(UpdateDirectories);
  162. DUPL(CacheDirectories);
  163. DUPL(CacheDirectoryChanges);
  164. DUPL(PreserveDirectoryChanges);
  165. DUPL(ResolveSymlinks);
  166. DUPL(ConsiderDST);
  167. DUPL(LockInHome);
  168. DUPL(Special);
  169. DUPL(Selected);
  170. DUPL(ReturnVar);
  171. DUPL(LookupUserGroups);
  172. DUPL(EOLType);
  173. DUPL(Shell);
  174. DUPL(ClearAliases);
  175. DUPL(Scp1Compatibility);
  176. DUPL(UnsetNationalVars);
  177. DUPL(AliasGroupList);
  178. DUPL(IgnoreLsWarnings);
  179. DUPL(SCPLsFullTime);
  180. DUPL(TimeDifference);
  181. // new in 53b
  182. DUPL(TcpNoDelay);
  183. DUPL(AuthKI);
  184. DUPL(AuthKIPassword);
  185. DUPL(AuthGSSAPI);
  186. DUPL(DeleteToRecycleBin);
  187. DUPL(OverwrittenToRecycleBin);
  188. DUPL(RecycleBinPath);
  189. DUPL(ProxyMethod);
  190. DUPL(ProxyHost);
  191. DUPL(ProxyPort);
  192. DUPL(ProxyUsername);
  193. DUPL(ProxyPassword);
  194. DUPL(ProxyTelnetCommand);
  195. DUPL(ProxyDNS);
  196. DUPL(ProxyLocalhost);
  197. for (int Index = 0; Index < LENOF(FBugs); Index++)
  198. {
  199. DUPL(Bug[(TSshBug)Index]);
  200. }
  201. // SFTP
  202. DUPL(SFTPDownloadQueue);
  203. DUPL(SFTPUploadQueue);
  204. DUPL(SFTPListingQueue);
  205. DUPL(SFTPMaxVersion);
  206. DUPL(SFTPMaxPacketSize);
  207. for (int Index = 0; Index < LENOF(FSFTPBugs); Index++)
  208. {
  209. DUPL(SFTPBug[(TSftpBug)Index]);
  210. }
  211. DUPL(Color);
  212. DUPL(CustomParam1);
  213. DUPL(CustomParam2);
  214. #undef DUPL
  215. FModified = ((TSessionData *)Source)->Modified;
  216. }
  217. else
  218. {
  219. TNamedObject::Assign(Source);
  220. }
  221. }
  222. //---------------------------------------------------------------------
  223. void __fastcall TSessionData::StoreToConfig(void * config)
  224. {
  225. Config * cfg = (Config *)config;
  226. // clear all (parameters not set below)
  227. memset(cfg, 0, sizeof(*cfg));
  228. // user-configurable settings
  229. ASCOPY(cfg->host, HostName);
  230. ASCOPY(cfg->username, UserName);
  231. cfg->port = PortNumber;
  232. cfg->protocol = PROT_SSH;
  233. // always set 0, as we will handle keepalives ourselves to avoid
  234. // multi-threaded issues in putty timer list
  235. cfg->ping_interval = 0;
  236. cfg->compression = Compression;
  237. cfg->agentfwd = AgentFwd;
  238. cfg->addressfamily = AddressFamily;
  239. ASCOPY(cfg->ssh_rekey_data, RekeyData);
  240. cfg->ssh_rekey_time = RekeyTime;
  241. for (int c = 0; c < CIPHER_COUNT; c++)
  242. {
  243. int pcipher;
  244. switch (Cipher[c]) {
  245. case cipWarn: pcipher = CIPHER_WARN; break;
  246. case cip3DES: pcipher = CIPHER_3DES; break;
  247. case cipBlowfish: pcipher = CIPHER_BLOWFISH; break;
  248. case cipAES: pcipher = CIPHER_AES; break;
  249. case cipDES: pcipher = CIPHER_DES; break;
  250. default: assert(false);
  251. }
  252. cfg->ssh_cipherlist[c] = pcipher;
  253. }
  254. for (int k = 0; k < KEX_COUNT; k++)
  255. {
  256. int pkex;
  257. switch (Kex[k]) {
  258. case kexWarn: pkex = KEX_WARN; break;
  259. case kexDHGroup1: pkex = KEX_DHGROUP1; break;
  260. case kexDHGroup14: pkex = KEX_DHGROUP14; break;
  261. case kexDHGEx: pkex = KEX_DHGEX; break;
  262. default: assert(false);
  263. }
  264. cfg->ssh_kexlist[k] = pkex;
  265. }
  266. AnsiString SPublicKeyFile = PublicKeyFile;
  267. if (SPublicKeyFile.IsEmpty()) SPublicKeyFile = Configuration->DefaultKeyFile;
  268. SPublicKeyFile = StripPathQuotes(SPublicKeyFile);
  269. ASCOPY(cfg->keyfile.path, SPublicKeyFile);
  270. cfg->sshprot = SshProt;
  271. cfg->ssh2_des_cbc = Ssh2DES;
  272. cfg->try_tis_auth = AuthTIS;
  273. cfg->try_ki_auth = AuthKI;
  274. cfg->try_gssapi_auth = AuthGSSAPI;
  275. cfg->change_username = ChangeUsername;
  276. cfg->proxy_type = ProxyMethod;
  277. ASCOPY(cfg->proxy_host, ProxyHost);
  278. cfg->proxy_port = ProxyPort;
  279. ASCOPY(cfg->proxy_username, ProxyUsername);
  280. ASCOPY(cfg->proxy_password, ProxyPassword);
  281. ASCOPY(cfg->proxy_telnet_command, ProxyTelnetCommand);
  282. cfg->proxy_dns = ProxyDNS;
  283. cfg->even_proxy_localhost = ProxyLocalhost;
  284. #pragma option push -w-eas
  285. // after 0.53b values were reversed, however putty still stores
  286. // settings to registry in save way as before
  287. cfg->sshbug_ignore1 = Bug[sbIgnore1];
  288. cfg->sshbug_plainpw1 = Bug[sbPlainPW1];
  289. cfg->sshbug_rsa1 = Bug[sbRSA1];
  290. cfg->sshbug_hmac2 = Bug[sbHMAC2];
  291. cfg->sshbug_derivekey2 = Bug[sbDeriveKey2];
  292. cfg->sshbug_rsapad2 = Bug[sbRSAPad2];
  293. cfg->sshbug_rekey2 = Bug[sbRekey2];
  294. // new after 0.53b
  295. cfg->sshbug_pksessid2 = Bug[sbPKSessID2];
  296. #pragma option pop
  297. if (FSProtocol == fsSCPonly)
  298. {
  299. cfg->ssh_subsys = FALSE;
  300. if (Shell.IsEmpty())
  301. {
  302. // Following forces Putty to open default shell
  303. // see ssh.c: do_ssh2_authconn() and ssh1_protocol()
  304. cfg->remote_cmd[0] = '\0';
  305. }
  306. else
  307. {
  308. ASCOPY(cfg->remote_cmd, Shell);
  309. }
  310. }
  311. else
  312. {
  313. cfg->ssh_subsys = TRUE;
  314. strcpy(cfg->remote_cmd, "sftp");
  315. if (FSProtocol != fsSFTPonly)
  316. {
  317. cfg->ssh_subsys2 = FALSE;
  318. if (Shell.IsEmpty())
  319. {
  320. // Following forces Putty to open default shell
  321. // see ssh.c: do_ssh2_authconn() and ssh1_protocol()
  322. cfg->remote_cmd2[0] = '\0';
  323. }
  324. else
  325. {
  326. ASCOPY(cfg->remote_cmd2, Shell);
  327. }
  328. // Putty reads only "ptr" member for fallback
  329. cfg->remote_cmd_ptr2 = cfg->remote_cmd2;
  330. }
  331. else
  332. {
  333. // see psftp_connect() from psftp.c
  334. cfg->ssh_subsys2 = FALSE;
  335. cfg->remote_cmd_ptr2 =
  336. "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n"
  337. "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n"
  338. "exec sftp-server";
  339. }
  340. }
  341. // permanent settings
  342. cfg->nopty = TRUE;
  343. cfg->tcp_keepalives = 0;
  344. }
  345. //---------------------------------------------------------------------
  346. void __fastcall TSessionData::Load(THierarchicalStorage * Storage)
  347. {
  348. bool RewritePassword = false;
  349. if (Storage->OpenSubKey(StorageKey, False))
  350. {
  351. PortNumber = Storage->ReadInteger("PortNumber", PortNumber);
  352. UserName = Storage->ReadString("UserName", UserName);
  353. // must be loaded after UserName, because HostName may be in format user@host
  354. HostName = Storage->ReadString("HostName", HostName);
  355. if (!Configuration->DisablePasswordStoring)
  356. {
  357. if (Storage->ValueExists("PasswordPlain"))
  358. {
  359. Password = Storage->ReadString("PasswordPlain", Password);
  360. RewritePassword = true;
  361. }
  362. else
  363. {
  364. FPassword = Storage->ReadString("Password", FPassword);
  365. }
  366. }
  367. // Putty uses PingIntervalSecs
  368. int PingIntervalSecs = Storage->ReadInteger("PingIntervalSecs", -1);
  369. if (PingIntervalSecs < 0)
  370. {
  371. PingIntervalSecs = Storage->ReadInteger("PingIntervalSec", PingInterval%60);
  372. }
  373. PingInterval =
  374. Storage->ReadInteger("PingInterval", PingInterval/60)*60 +
  375. PingIntervalSecs;
  376. PingType = static_cast<TPingType>
  377. (Storage->ReadInteger("PingType", PingInterval > 0 ? ptNullPacket : ptOff));
  378. if (PingInterval == 0)
  379. {
  380. PingInterval = 30;
  381. }
  382. Timeout = Storage->ReadInteger("Timeout", Timeout);
  383. AgentFwd = Storage->ReadBool("AgentFwd", AgentFwd);
  384. AuthTIS = Storage->ReadBool("AuthTIS", AuthTIS);
  385. AuthKI = Storage->ReadBool("AuthKI", AuthKI);
  386. AuthKIPassword = Storage->ReadBool("AuthKIPassword", AuthKIPassword);
  387. AuthGSSAPI = Storage->ReadBool("AuthGSSAPI", AuthGSSAPI);
  388. ChangeUsername = Storage->ReadBool("ChangeUsername", ChangeUsername);
  389. Compression = Storage->ReadBool("Compression", Compression);
  390. SshProt = (TSshProt)Storage->ReadInteger("SshProt", SshProt);
  391. Ssh2DES = Storage->ReadBool("Ssh2DES", Ssh2DES);
  392. CipherList = Storage->ReadString("Cipher", CipherList);
  393. KexList = Storage->ReadString("KEX", KexList);
  394. PublicKeyFile = Storage->ReadString("PublicKeyFile", PublicKeyFile);
  395. AddressFamily = static_cast<TAddressFamily>
  396. (Storage->ReadInteger("AddressFamily", AddressFamily));
  397. RekeyData = Storage->ReadString("RekeyBytes", RekeyData);
  398. RekeyTime = Storage->ReadInteger("RekeyTime", RekeyTime);
  399. FSProtocol = (TFSProtocol)Storage->ReadInteger("FSProtocol", FSProtocol);
  400. LocalDirectory = Storage->ReadString("LocalDirectory", LocalDirectory);
  401. RemoteDirectory = Storage->ReadString("RemoteDirectory", RemoteDirectory);
  402. UpdateDirectories = Storage->ReadBool("UpdateDirectories", UpdateDirectories);
  403. CacheDirectories = Storage->ReadBool("CacheDirectories", CacheDirectories);
  404. CacheDirectoryChanges = Storage->ReadBool("CacheDirectoryChanges", CacheDirectoryChanges);
  405. PreserveDirectoryChanges = Storage->ReadBool("PreserveDirectoryChanges", PreserveDirectoryChanges);
  406. ResolveSymlinks = Storage->ReadBool("ResolveSymlinks", ResolveSymlinks);
  407. ConsiderDST = Storage->ReadBool("ConsiderDST", ConsiderDST);
  408. LockInHome = Storage->ReadBool("LockInHome", LockInHome);
  409. Special = Storage->ReadBool("Special", Special);
  410. Shell = Storage->ReadString("Shell", Shell);
  411. ClearAliases = Storage->ReadBool("ClearAliases", ClearAliases);
  412. UnsetNationalVars = Storage->ReadBool("UnsetNationalVars", UnsetNationalVars);
  413. AliasGroupList = Storage->ReadBool("AliasGroupList", AliasGroupList);
  414. IgnoreLsWarnings = Storage->ReadBool("IgnoreLsWarnings", IgnoreLsWarnings);
  415. SCPLsFullTime = TAutoSwitch(Storage->ReadInteger("SCPLsFullTime", SCPLsFullTime));
  416. Scp1Compatibility = Storage->ReadBool("Scp1Compatibility", Scp1Compatibility);
  417. TimeDifference = Storage->ReadFloat("TimeDifference", TimeDifference);
  418. DeleteToRecycleBin = Storage->ReadBool("DeleteToRecycleBin", DeleteToRecycleBin);
  419. OverwrittenToRecycleBin = Storage->ReadBool("OverwrittenToRecycleBin", OverwrittenToRecycleBin);
  420. RecycleBinPath = Storage->ReadString("RecycleBinPath", RecycleBinPath);
  421. ReturnVar = Storage->ReadString("ReturnVar", ReturnVar);
  422. LookupUserGroups = Storage->ReadBool("LookupUserGroups", LookupUserGroups);
  423. EOLType = (TEOLType)Storage->ReadInteger("EOLType", EOLType);
  424. // new in 53b
  425. TcpNoDelay = Storage->ReadBool("TcpNoDelay", TcpNoDelay);
  426. ProxyMethod = (TProxyMethod)Storage->ReadInteger("ProxyMethod", -1);
  427. if (ProxyMethod < 0)
  428. {
  429. int ProxyType = Storage->ReadInteger("ProxyType", pxNone);
  430. int ProxySOCKSVersion;
  431. switch (ProxyType) {
  432. case pxHTTP:
  433. ProxyMethod = pmHTTP;
  434. break;
  435. case pxTelnet:
  436. ProxyMethod = pmTelnet;
  437. break;
  438. case pxSocks:
  439. ProxySOCKSVersion = Storage->ReadInteger("ProxySOCKSVersion", 5);
  440. ProxyMethod = ProxySOCKSVersion == 5 ? pmSocks5 : pmSocks4;
  441. break;
  442. default:
  443. case pxNone:
  444. ProxyMethod = pmNone;
  445. break;
  446. }
  447. }
  448. ProxyHost = Storage->ReadString("ProxyHost", ProxyHost);
  449. ProxyPort = Storage->ReadInteger("ProxyPort", ProxyPort);
  450. ProxyUsername = Storage->ReadString("ProxyUsername", ProxyUsername);
  451. if (Storage->ValueExists("ProxyPassword"))
  452. {
  453. // encrypt unencrypted password
  454. ProxyPassword = Storage->ReadString("ProxyPassword", "");
  455. }
  456. else
  457. {
  458. // load encrypted password
  459. FProxyPassword = Storage->ReadString("ProxyPasswordEnc", FProxyPassword);
  460. }
  461. ProxyTelnetCommand = Storage->ReadStringRaw("ProxyTelnetCommand", ProxyTelnetCommand);
  462. ProxyDNS = TAutoSwitch((Storage->ReadInteger("ProxyDNS", (ProxyDNS + 2) % 3) + 1) % 3);
  463. ProxyLocalhost = Storage->ReadBool("ProxyLocalhost", ProxyLocalhost);
  464. #define READ_BUG(BUG) \
  465. Bug[sb##BUG] = TAutoSwitch(2 - Storage->ReadInteger("Bug"#BUG, \
  466. 2 - Bug[sb##BUG]));
  467. READ_BUG(Ignore1);
  468. READ_BUG(PlainPW1);
  469. READ_BUG(RSA1);
  470. READ_BUG(HMAC2);
  471. READ_BUG(DeriveKey2);
  472. READ_BUG(RSAPad2);
  473. READ_BUG(Rekey2);
  474. READ_BUG(PKSessID2);
  475. #undef READ_BUG
  476. if ((Bug[sbHMAC2] == asAuto) &&
  477. Storage->ReadBool("BuggyMAC", false))
  478. {
  479. Bug[sbHMAC2] = asOn;
  480. }
  481. #define READ_SFTP_BUG(BUG) \
  482. SFTPBug[sb##BUG] = TAutoSwitch(Storage->ReadInteger("SFTP" #BUG "Bug", SFTPBug[sb##BUG]));
  483. READ_SFTP_BUG(Symlink);
  484. READ_SFTP_BUG(Utf);
  485. READ_SFTP_BUG(SignedTS);
  486. #undef READ_SFTP_BUG
  487. SFTPMaxVersion = Storage->ReadInteger("SFTPMaxVersion", SFTPMaxVersion);
  488. SFTPMaxPacketSize = Storage->ReadInteger("SFTPMaxPacketSize", SFTPMaxPacketSize);
  489. Color = Storage->ReadInteger("Color", Color);
  490. // read only (used only on Import from Putty dialog)
  491. ProtocolStr = Storage->ReadString("Protocol", ProtocolStr);
  492. CustomParam1 = Storage->ReadString("CustomParam1", CustomParam1);
  493. CustomParam2 = Storage->ReadString("CustomParam2", CustomParam2);
  494. Storage->CloseSubKey();
  495. };
  496. if (RewritePassword)
  497. {
  498. TStorageAccessMode AccessMode = Storage->AccessMode;
  499. Storage->AccessMode = smReadWrite;
  500. try
  501. {
  502. if (Storage->OpenSubKey(StorageKey, true))
  503. {
  504. Storage->DeleteValue("PasswordPlain");
  505. if (!Password.IsEmpty())
  506. {
  507. Storage->WriteString("Password", FPassword);
  508. }
  509. Storage->CloseSubKey();
  510. }
  511. }
  512. catch(...)
  513. {
  514. // ignore errors (like read-only INI file)
  515. }
  516. Storage->AccessMode = AccessMode;
  517. }
  518. FModified = false;
  519. }
  520. //---------------------------------------------------------------------
  521. void __fastcall TSessionData::Save(THierarchicalStorage * Storage,
  522. bool PuttyExport, const TSessionData * Default)
  523. {
  524. if (Modified && Storage->OpenSubKey(StorageKey, true))
  525. {
  526. #define WRITE_DATA_EX(TYPE, NAME, PROPERTY, CONV) \
  527. if ((Default != NULL) && (CONV(Default->PROPERTY) == CONV(PROPERTY))) \
  528. { \
  529. Storage->DeleteValue(NAME); \
  530. } \
  531. else \
  532. { \
  533. Storage->Write ## TYPE(NAME, CONV(PROPERTY)); \
  534. }
  535. #define WRITE_DATA_CONV(TYPE, NAME, PROPERTY) WRITE_DATA_EX(TYPE, NAME, PROPERTY, WRITE_DATA_CONV_FUNC)
  536. #define WRITE_DATA(TYPE, PROPERTY) WRITE_DATA_EX(TYPE, #PROPERTY, PROPERTY, )
  537. WRITE_DATA(String, HostName);
  538. WRITE_DATA(Integer, PortNumber);
  539. if (!Configuration->DisablePasswordStoring && !PuttyExport && !Password.IsEmpty())
  540. {
  541. WRITE_DATA_EX(String, "Password", FPassword, );
  542. }
  543. else
  544. {
  545. Storage->DeleteValue("Password");
  546. }
  547. Storage->DeleteValue("PasswordPlain");
  548. WRITE_DATA_EX(Integer, "PingInterval", PingInterval / 60, );
  549. WRITE_DATA_EX(Integer, "PingIntervalSecs", PingInterval % 60, );
  550. Storage->DeleteValue("PingIntervalSec"); // obsolete
  551. // store PingType always as it does not have fixed default
  552. Storage->WriteInteger("PingType", PingType);
  553. WRITE_DATA(Integer, Timeout);
  554. WRITE_DATA(Bool, AgentFwd);
  555. WRITE_DATA(Bool, AuthTIS);
  556. WRITE_DATA(Bool, AuthKI);
  557. WRITE_DATA(Bool, AuthKIPassword);
  558. WRITE_DATA(Bool, ChangeUsername);
  559. WRITE_DATA(Bool, Compression);
  560. WRITE_DATA(Integer, SshProt);
  561. WRITE_DATA(Bool, Ssh2DES);
  562. WRITE_DATA_EX(String, "Cipher", CipherList, );
  563. WRITE_DATA_EX(String, "KEX", KexList, );
  564. WRITE_DATA(Integer, AddressFamily);
  565. WRITE_DATA_EX(String, "RekeyBytes", RekeyData, );
  566. WRITE_DATA(Integer, RekeyTime);
  567. WRITE_DATA(Bool, TcpNoDelay);
  568. if (PuttyExport)
  569. {
  570. WRITE_DATA(StringRaw, UserName);
  571. WRITE_DATA(StringRaw, PublicKeyFile);
  572. }
  573. else
  574. {
  575. WRITE_DATA(String, UserName);
  576. WRITE_DATA(Bool, AuthGSSAPI);
  577. WRITE_DATA(String, PublicKeyFile);
  578. WRITE_DATA(Integer, FSProtocol);
  579. WRITE_DATA(String, LocalDirectory);
  580. WRITE_DATA(String, RemoteDirectory);
  581. WRITE_DATA(Bool, UpdateDirectories);
  582. WRITE_DATA(Bool, CacheDirectories);
  583. WRITE_DATA(Bool, CacheDirectoryChanges);
  584. WRITE_DATA(Bool, PreserveDirectoryChanges);
  585. WRITE_DATA(Bool, ResolveSymlinks);
  586. WRITE_DATA(Bool, ConsiderDST);
  587. WRITE_DATA(Bool, LockInHome);
  588. // Special is never stored (if it would, login dialog must be modified not to
  589. // duplicate Special parameter when Special session is loaded and then stored
  590. // under different name)
  591. // WRITE_DATA(Bool, Special);
  592. WRITE_DATA(String, Shell);
  593. WRITE_DATA(Bool, ClearAliases);
  594. WRITE_DATA(Bool, UnsetNationalVars);
  595. WRITE_DATA(Bool, AliasGroupList);
  596. WRITE_DATA(Bool, IgnoreLsWarnings);
  597. WRITE_DATA(Integer, SCPLsFullTime);
  598. WRITE_DATA(Bool, Scp1Compatibility);
  599. WRITE_DATA(Float, TimeDifference);
  600. WRITE_DATA(Bool, DeleteToRecycleBin);
  601. WRITE_DATA(Bool, OverwrittenToRecycleBin);
  602. WRITE_DATA(String, RecycleBinPath);
  603. WRITE_DATA(String, ReturnVar);
  604. WRITE_DATA(Bool, LookupUserGroups);
  605. WRITE_DATA(Integer, EOLType);
  606. }
  607. WRITE_DATA(Integer, ProxyMethod);
  608. if (PuttyExport)
  609. {
  610. // support for Putty 0.53b and older
  611. int ProxyType;
  612. int ProxySOCKSVersion = 5;
  613. switch (ProxyMethod) {
  614. case pmHTTP:
  615. ProxyType = pxHTTP;
  616. break;
  617. case pmTelnet:
  618. ProxyType = pxTelnet;
  619. break;
  620. case pmSocks5:
  621. ProxyType = pxSocks;
  622. ProxySOCKSVersion = 5;
  623. break;
  624. case pmSocks4:
  625. ProxyType = pxSocks;
  626. ProxySOCKSVersion = 4;
  627. break;
  628. default:
  629. case pmNone:
  630. ProxyType = pxNone;
  631. break;
  632. }
  633. Storage->WriteInteger("ProxyType", ProxyType);
  634. Storage->WriteInteger("ProxySOCKSVersion", ProxySOCKSVersion);
  635. }
  636. else
  637. {
  638. Storage->DeleteValue("ProxyType");
  639. Storage->DeleteValue("ProxySOCKSVersion");
  640. }
  641. WRITE_DATA(String, ProxyHost);
  642. WRITE_DATA(Integer, ProxyPort);
  643. WRITE_DATA(String, ProxyUsername);
  644. if (PuttyExport)
  645. {
  646. // save password unencrypted
  647. WRITE_DATA(String, ProxyPassword);
  648. }
  649. else
  650. {
  651. // save password encrypted
  652. if (!ProxyPassword.IsEmpty())
  653. {
  654. WRITE_DATA_EX(String, "ProxyPasswordEnc", FProxyPassword, );
  655. }
  656. else
  657. {
  658. Storage->DeleteValue("ProxyPasswordEnc");
  659. }
  660. Storage->DeleteValue("ProxyPassword");
  661. }
  662. WRITE_DATA(StringRaw, ProxyTelnetCommand);
  663. #define WRITE_DATA_CONV_FUNC(X) (((X) + 2) % 3)
  664. WRITE_DATA_CONV(Integer, "ProxyDNS", ProxyDNS);
  665. #undef WRITE_DATA_CONV_FUNC
  666. WRITE_DATA(Bool, ProxyLocalhost);
  667. #define WRITE_DATA_CONV_FUNC(X) (2 - (X))
  668. #define WRITE_BUG(BUG) WRITE_DATA_CONV(Integer, "Bug" #BUG, Bug[sb##BUG]);
  669. WRITE_BUG(Ignore1);
  670. WRITE_BUG(PlainPW1);
  671. WRITE_BUG(RSA1);
  672. WRITE_BUG(HMAC2);
  673. WRITE_BUG(DeriveKey2);
  674. WRITE_BUG(RSAPad2);
  675. WRITE_BUG(Rekey2);
  676. WRITE_BUG(PKSessID2);
  677. #undef WRITE_BUG
  678. #undef WRITE_DATA_CONV_FUNC
  679. Storage->DeleteValue("BuggyMAC");
  680. if (PuttyExport)
  681. {
  682. WRITE_DATA_EX(String, "Protocol", ProtocolStr, );
  683. }
  684. if (!PuttyExport)
  685. {
  686. #define WRITE_SFTP_BUG(BUG) WRITE_DATA_EX(Integer, "SFTP" #BUG "Bug", SFTPBug[sb##BUG], );
  687. WRITE_SFTP_BUG(Symlink);
  688. WRITE_SFTP_BUG(Utf);
  689. WRITE_SFTP_BUG(SignedTS);
  690. #undef WRITE_SFTP_BUG
  691. WRITE_DATA(Integer, SFTPMaxVersion);
  692. WRITE_DATA(Integer, SFTPMaxPacketSize);
  693. WRITE_DATA(Integer, Color);
  694. WRITE_DATA(String, CustomParam1);
  695. WRITE_DATA(String, CustomParam2);
  696. }
  697. Storage->CloseSubKey();
  698. FModified = false;
  699. }
  700. }
  701. //---------------------------------------------------------------------
  702. void __fastcall TSessionData::Remove()
  703. {
  704. THierarchicalStorage * Storage = Configuration->CreateScpStorage(true);
  705. try
  706. {
  707. if (Storage->OpenSubKey(Configuration->StoredSessionsSubKey, false))
  708. {
  709. Storage->RecursiveDeleteSubKey(StorageKey);
  710. }
  711. }
  712. __finally
  713. {
  714. delete Storage;
  715. }
  716. }
  717. //---------------------------------------------------------------------
  718. bool __fastcall TSessionData::ParseUrl(AnsiString Url, int Params,
  719. AnsiString * ConnectInfo, AnsiString * HostName, int * PortNumber,
  720. AnsiString * UserName, AnsiString * Password, AnsiString * Path,
  721. AnsiString * FileName)
  722. {
  723. #define DECODE(S) (FLAGSET(Params, puDecodeUrlChars) ? DecodeUrlChars(S) : S)
  724. int PSlash = Url.Pos("/");
  725. if (PSlash == 0)
  726. {
  727. PSlash = Url.Length() + 1;
  728. }
  729. AnsiString AConnectInfo;
  730. AConnectInfo = Url.SubString(1, PSlash - 1);
  731. int P = AConnectInfo.LastDelimiter("@");
  732. bool Result = (P > 0) || ((Params & puRequireUsername) == 0);
  733. if (Result)
  734. {
  735. if ((Path != NULL) || (FileName != NULL))
  736. {
  737. bool ExcludeLeadingSlash = (Params & puExcludeLeadingSlash) != 0;
  738. int Delta = ExcludeLeadingSlash ? 1 : 0;
  739. AnsiString APath = Url.SubString(PSlash + Delta,
  740. Url.Length() - PSlash - Delta + 1);
  741. if (ExcludeLeadingSlash || (APath != "/"))
  742. {
  743. if ((APath.Length() > 0) && (APath[APath.Length()] != '/'))
  744. {
  745. if (FileName != NULL)
  746. {
  747. *FileName = DECODE(UnixExtractFileName(APath));
  748. }
  749. if (FLAGSET(Params, puExtractFileName))
  750. {
  751. APath = UnixExtractFilePath(APath);
  752. }
  753. }
  754. if (Path != NULL)
  755. {
  756. *Path = DECODE(APath);
  757. }
  758. }
  759. }
  760. if (ConnectInfo != NULL)
  761. {
  762. *ConnectInfo = DECODE(AConnectInfo);
  763. }
  764. AnsiString UserInfo;
  765. AnsiString HostInfo;
  766. if (P > 0)
  767. {
  768. UserInfo = AConnectInfo.SubString(1, P - 1);
  769. HostInfo = AConnectInfo.SubString(P + 1, AConnectInfo.Length() - P);
  770. }
  771. else
  772. {
  773. HostInfo = AConnectInfo;
  774. }
  775. if (HostName != NULL)
  776. {
  777. *HostName = DECODE(CutToChar(HostInfo, ':', true));
  778. }
  779. else
  780. {
  781. CutToChar(HostInfo, ':', true);
  782. }
  783. if (PortNumber != NULL)
  784. {
  785. // expanded from ?: operator, as it caused strange "access violation" errors
  786. if (HostInfo.IsEmpty())
  787. {
  788. *PortNumber = -1;
  789. }
  790. else
  791. {
  792. *PortNumber = StrToIntDef(DECODE(HostInfo), -1);
  793. }
  794. }
  795. if (UserName != NULL)
  796. {
  797. *UserName = DECODE(CutToChar(UserInfo, ':', false));
  798. }
  799. else
  800. {
  801. CutToChar(UserInfo, ':', false);
  802. }
  803. if (Password != NULL)
  804. {
  805. *Password = DECODE(UserInfo);
  806. }
  807. }
  808. return Result;
  809. #undef DECODE
  810. }
  811. //---------------------------------------------------------------------
  812. bool __fastcall TSessionData::ParseUrl(AnsiString Url, int Params,
  813. AnsiString * FileName)
  814. {
  815. AnsiString AHostName = HostName;
  816. int APortNumber = PortNumber;
  817. AnsiString AUserName = UserName;
  818. AnsiString APassword = Password;
  819. AnsiString ARemoteDirectory = RemoteDirectory;
  820. bool Result = ParseUrl(Url, Params, NULL, &AHostName, &APortNumber,
  821. &AUserName, &APassword, &ARemoteDirectory, FileName);
  822. if (Result)
  823. {
  824. HostName = AHostName;
  825. if (APortNumber >= 0)
  826. {
  827. PortNumber = APortNumber;
  828. }
  829. UserName = AUserName;
  830. Password = APassword;
  831. RemoteDirectory = ARemoteDirectory;
  832. }
  833. return Result;
  834. }
  835. //---------------------------------------------------------------------
  836. void __fastcall TSessionData::ValidateName(const AnsiString Name)
  837. {
  838. if (Name.LastDelimiter(FInvalidChars) > 0)
  839. {
  840. throw Exception(FMTLOAD(ITEM_NAME_INVALID, (Name, FInvalidChars)));
  841. }
  842. }
  843. //---------------------------------------------------------------------
  844. bool __fastcall TSessionData::GetCanLogin()
  845. {
  846. return !FHostName.IsEmpty() && !FUserName.IsEmpty();
  847. }
  848. //---------------------------------------------------------------------------
  849. AnsiString __fastcall TSessionData::GetSessionKey()
  850. {
  851. return FORMAT("%s@%s", (UserName, HostName));
  852. }
  853. //---------------------------------------------------------------------
  854. AnsiString __fastcall TSessionData::GetStorageKey()
  855. {
  856. // particularly OpenSessionInPutty expect that StorageKey always returns something
  857. return MungeStr(Name.IsEmpty() ? SessionKey : Name);
  858. }
  859. //---------------------------------------------------------------------
  860. void __fastcall TSessionData::SetHostName(AnsiString value)
  861. {
  862. if (FHostName != value)
  863. {
  864. // HostName is key for password encryption
  865. AnsiString XPassword = Password;
  866. int P = value.LastDelimiter("@");
  867. if (P > 0)
  868. {
  869. UserName = value.SubString(1, P - 1);
  870. value = value.SubString(P + 1, value.Length() - P);
  871. }
  872. FHostName = value;
  873. FModified = true;
  874. Password = XPassword;
  875. if (!XPassword.IsEmpty())
  876. {
  877. memset(XPassword.c_str(), 0, XPassword.Length());
  878. }
  879. }
  880. }
  881. //---------------------------------------------------------------------
  882. void __fastcall TSessionData::SetPortNumber(int value)
  883. {
  884. SET_SESSION_PROPERTY(PortNumber);
  885. }
  886. //---------------------------------------------------------------------------
  887. void __fastcall TSessionData::SetShell(AnsiString value)
  888. {
  889. SET_SESSION_PROPERTY(Shell);
  890. }
  891. //---------------------------------------------------------------------------
  892. void __fastcall TSessionData::SetClearAliases(bool value)
  893. {
  894. SET_SESSION_PROPERTY(ClearAliases);
  895. }
  896. //---------------------------------------------------------------------------
  897. void __fastcall TSessionData::SetAliasGroupList(bool value)
  898. {
  899. SET_SESSION_PROPERTY(AliasGroupList);
  900. }
  901. //---------------------------------------------------------------------------
  902. void __fastcall TSessionData::SetIgnoreLsWarnings(bool value)
  903. {
  904. SET_SESSION_PROPERTY(IgnoreLsWarnings);
  905. }
  906. //---------------------------------------------------------------------------
  907. void __fastcall TSessionData::SetUnsetNationalVars(bool value)
  908. {
  909. SET_SESSION_PROPERTY(UnsetNationalVars);
  910. }
  911. //---------------------------------------------------------------------
  912. void __fastcall TSessionData::SetUserName(AnsiString value)
  913. {
  914. // UserName is key for password encryption
  915. AnsiString XPassword = Password;
  916. SET_SESSION_PROPERTY(UserName);
  917. Password = XPassword;
  918. if (!XPassword.IsEmpty())
  919. {
  920. memset(XPassword.c_str(), 0, XPassword.Length());
  921. }
  922. }
  923. //---------------------------------------------------------------------
  924. void __fastcall TSessionData::SetPassword(AnsiString value)
  925. {
  926. value = EncryptPassword(value, UserName+HostName);
  927. SET_SESSION_PROPERTY(Password);
  928. }
  929. //---------------------------------------------------------------------
  930. AnsiString __fastcall TSessionData::GetPassword()
  931. {
  932. return DecryptPassword(FPassword, UserName+HostName);
  933. }
  934. //---------------------------------------------------------------------
  935. void __fastcall TSessionData::SetPingInterval(int value)
  936. {
  937. SET_SESSION_PROPERTY(PingInterval);
  938. }
  939. //---------------------------------------------------------------------
  940. void __fastcall TSessionData::SetAgentFwd(bool value)
  941. {
  942. SET_SESSION_PROPERTY(AgentFwd);
  943. }
  944. //---------------------------------------------------------------------
  945. void __fastcall TSessionData::SetAuthTIS(bool value)
  946. {
  947. SET_SESSION_PROPERTY(AuthTIS);
  948. }
  949. //---------------------------------------------------------------------
  950. void __fastcall TSessionData::SetAuthKI(bool value)
  951. {
  952. SET_SESSION_PROPERTY(AuthKI);
  953. }
  954. //---------------------------------------------------------------------
  955. void __fastcall TSessionData::SetAuthKIPassword(bool value)
  956. {
  957. SET_SESSION_PROPERTY(AuthKIPassword);
  958. }
  959. //---------------------------------------------------------------------
  960. void __fastcall TSessionData::SetAuthGSSAPI(bool value)
  961. {
  962. SET_SESSION_PROPERTY(AuthGSSAPI);
  963. }
  964. //---------------------------------------------------------------------
  965. void __fastcall TSessionData::SetChangeUsername(bool value)
  966. {
  967. SET_SESSION_PROPERTY(ChangeUsername);
  968. }
  969. //---------------------------------------------------------------------
  970. void __fastcall TSessionData::SetCompression(bool value)
  971. {
  972. SET_SESSION_PROPERTY(Compression);
  973. }
  974. //---------------------------------------------------------------------
  975. void __fastcall TSessionData::SetSshProt(TSshProt value)
  976. {
  977. SET_SESSION_PROPERTY(SshProt);
  978. }
  979. //---------------------------------------------------------------------
  980. void __fastcall TSessionData::SetSsh2DES(bool value)
  981. {
  982. SET_SESSION_PROPERTY(Ssh2DES);
  983. }
  984. //---------------------------------------------------------------------
  985. AnsiString __fastcall TSessionData::GetSshProtStr()
  986. {
  987. return SshProtList[FSshProt];
  988. }
  989. //---------------------------------------------------------------------
  990. void __fastcall TSessionData::SetCipher(int Index, TCipher value)
  991. {
  992. assert(Index >= 0 && Index < CIPHER_COUNT);
  993. SET_SESSION_PROPERTY(Ciphers[Index]);
  994. }
  995. //---------------------------------------------------------------------
  996. TCipher __fastcall TSessionData::GetCipher(int Index) const
  997. {
  998. assert(Index >= 0 && Index < CIPHER_COUNT);
  999. return FCiphers[Index];
  1000. }
  1001. //---------------------------------------------------------------------
  1002. void __fastcall TSessionData::SetCipherList(AnsiString value)
  1003. {
  1004. bool Used[CIPHER_COUNT];
  1005. for (int C = 0; C < CIPHER_COUNT; C++) Used[C] = false;
  1006. AnsiString CipherStr;
  1007. int Index = 0;
  1008. while (!value.IsEmpty() && (Index < CIPHER_COUNT))
  1009. {
  1010. CipherStr = CutToChar(value, ',', true);
  1011. for (int C = 0; C < CIPHER_COUNT; C++)
  1012. {
  1013. if (!CipherStr.AnsiCompareIC(CipherNames[C]))
  1014. {
  1015. Cipher[Index] = (TCipher)C;
  1016. Used[C] = true;
  1017. Index++;
  1018. break;
  1019. }
  1020. }
  1021. }
  1022. for (int C = 0; C < CIPHER_COUNT && Index < CIPHER_COUNT; C++)
  1023. {
  1024. if (!Used[DefaultCipherList[C]]) Cipher[Index++] = DefaultCipherList[C];
  1025. }
  1026. }
  1027. //---------------------------------------------------------------------
  1028. AnsiString __fastcall TSessionData::GetCipherList() const
  1029. {
  1030. AnsiString Result;
  1031. for (int Index = 0; Index < CIPHER_COUNT; Index++)
  1032. {
  1033. Result += AnsiString(Index ? "," : "") + CipherNames[Cipher[Index]];
  1034. }
  1035. return Result;
  1036. }
  1037. //---------------------------------------------------------------------
  1038. void __fastcall TSessionData::SetKex(int Index, TKex value)
  1039. {
  1040. assert(Index >= 0 && Index < KEX_COUNT);
  1041. SET_SESSION_PROPERTY(Kex[Index]);
  1042. }
  1043. //---------------------------------------------------------------------
  1044. TKex __fastcall TSessionData::GetKex(int Index) const
  1045. {
  1046. assert(Index >= 0 && Index < KEX_COUNT);
  1047. return FKex[Index];
  1048. }
  1049. //---------------------------------------------------------------------
  1050. void __fastcall TSessionData::SetKexList(AnsiString value)
  1051. {
  1052. bool Used[KEX_COUNT];
  1053. for (int K = 0; K < KEX_COUNT; K++) Used[K] = false;
  1054. AnsiString KexStr;
  1055. int Index = 0;
  1056. while (!value.IsEmpty() && (Index < KEX_COUNT))
  1057. {
  1058. KexStr = CutToChar(value, ',', true);
  1059. for (int K = 0; K < KEX_COUNT; K++)
  1060. {
  1061. if (!KexStr.AnsiCompareIC(KexNames[K]))
  1062. {
  1063. Kex[Index] = (TKex)K;
  1064. Used[K] = true;
  1065. Index++;
  1066. break;
  1067. }
  1068. }
  1069. }
  1070. for (int K = 0; K < KEX_COUNT && Index < KEX_COUNT; K++)
  1071. {
  1072. if (!Used[DefaultKexList[K]]) Kex[Index++] = DefaultKexList[K];
  1073. }
  1074. }
  1075. //---------------------------------------------------------------------
  1076. AnsiString __fastcall TSessionData::GetKexList() const
  1077. {
  1078. AnsiString Result;
  1079. for (int Index = 0; Index < KEX_COUNT; Index++)
  1080. {
  1081. Result += AnsiString(Index ? "," : "") + KexNames[Kex[Index]];
  1082. }
  1083. return Result;
  1084. }
  1085. //---------------------------------------------------------------------
  1086. void __fastcall TSessionData::SetPublicKeyFile(AnsiString value)
  1087. {
  1088. if (FPublicKeyFile != value)
  1089. {
  1090. FPublicKeyFile = StripPathQuotes(value);
  1091. FModified = true;
  1092. }
  1093. }
  1094. //---------------------------------------------------------------------
  1095. AnsiString __fastcall TSessionData::GetDefaultLogFileName()
  1096. {
  1097. // not used anymore
  1098. return IncludeTrailingBackslash(SystemTemporaryDirectory()) +
  1099. MakeValidFileName(SessionName) + ".log";
  1100. }
  1101. //---------------------------------------------------------------------
  1102. void __fastcall TSessionData::SetReturnVar(AnsiString value)
  1103. {
  1104. SET_SESSION_PROPERTY(ReturnVar);
  1105. }
  1106. //---------------------------------------------------------------------------
  1107. void __fastcall TSessionData::SetLookupUserGroups(bool value)
  1108. {
  1109. SET_SESSION_PROPERTY(LookupUserGroups);
  1110. }
  1111. //---------------------------------------------------------------------------
  1112. void __fastcall TSessionData::SetEOLType(TEOLType value)
  1113. {
  1114. SET_SESSION_PROPERTY(EOLType);
  1115. }
  1116. //---------------------------------------------------------------------------
  1117. void __fastcall TSessionData::SetTimeout(int value)
  1118. {
  1119. SET_SESSION_PROPERTY(Timeout);
  1120. }
  1121. //---------------------------------------------------------------------------
  1122. void __fastcall TSessionData::SetFSProtocol(TFSProtocol value)
  1123. {
  1124. SET_SESSION_PROPERTY(FSProtocol);
  1125. }
  1126. //---------------------------------------------------------------------
  1127. AnsiString __fastcall TSessionData::GetFSProtocolStr()
  1128. {
  1129. assert(FSProtocol >= 0 && FSProtocol < FSPROTOCOL_COUNT);
  1130. return FSProtocolNames[FSProtocol];
  1131. }
  1132. //---------------------------------------------------------------------------
  1133. void __fastcall TSessionData::SetDetectReturnVar(bool value)
  1134. {
  1135. if (value != DetectReturnVar)
  1136. {
  1137. ReturnVar = value ? "" : "$?";
  1138. }
  1139. }
  1140. //---------------------------------------------------------------------------
  1141. bool __fastcall TSessionData::GetDetectReturnVar()
  1142. {
  1143. return ReturnVar.IsEmpty();
  1144. }
  1145. //---------------------------------------------------------------------------
  1146. void __fastcall TSessionData::SetDefaultShell(bool value)
  1147. {
  1148. if (value != DefaultShell)
  1149. {
  1150. Shell = value ? "" : "/bin/bash";
  1151. }
  1152. }
  1153. //---------------------------------------------------------------------------
  1154. bool __fastcall TSessionData::GetDefaultShell()
  1155. {
  1156. return Shell.IsEmpty();
  1157. }
  1158. //---------------------------------------------------------------------------
  1159. void __fastcall TSessionData::SetProtocolStr(AnsiString value)
  1160. {
  1161. for (int Index = 0; backends[Index].name != NULL; Index++)
  1162. {
  1163. if (!value.AnsiCompareIC(backends[Index].name))
  1164. {
  1165. FProtocol = (TProtocol)backends[Index].protocol;
  1166. break;
  1167. }
  1168. }
  1169. }
  1170. //---------------------------------------------------------------------
  1171. AnsiString __fastcall TSessionData::GetProtocolStr() const
  1172. {
  1173. for (int Index = 0; backends[Index].name != NULL; Index++)
  1174. {
  1175. if ((TProtocol)backends[Index].protocol == Protocol)
  1176. {
  1177. return backends[Index].name;
  1178. }
  1179. }
  1180. return "raw";
  1181. }
  1182. //---------------------------------------------------------------------
  1183. void __fastcall TSessionData::SetPingIntervalDT(TDateTime value)
  1184. {
  1185. unsigned short hour, min, sec, msec;
  1186. value.DecodeTime(&hour, &min, &sec, &msec);
  1187. PingInterval = ((int)hour)*60*60 + ((int)min)*60 + sec;
  1188. }
  1189. //---------------------------------------------------------------------------
  1190. TDateTime __fastcall TSessionData::GetPingIntervalDT()
  1191. {
  1192. return TDateTime((unsigned short)(PingInterval/60/60),
  1193. (unsigned short)(PingInterval/60%60), (unsigned short)(PingInterval%60), 0);
  1194. }
  1195. //---------------------------------------------------------------------------
  1196. void __fastcall TSessionData::SetPingType(TPingType value)
  1197. {
  1198. SET_SESSION_PROPERTY(PingType);
  1199. }
  1200. //---------------------------------------------------------------------------
  1201. void __fastcall TSessionData::SetAddressFamily(TAddressFamily value)
  1202. {
  1203. SET_SESSION_PROPERTY(AddressFamily);
  1204. }
  1205. //---------------------------------------------------------------------------
  1206. void __fastcall TSessionData::SetRekeyData(AnsiString value)
  1207. {
  1208. SET_SESSION_PROPERTY(RekeyData);
  1209. }
  1210. //---------------------------------------------------------------------------
  1211. void __fastcall TSessionData::SetRekeyTime(unsigned int value)
  1212. {
  1213. SET_SESSION_PROPERTY(RekeyTime);
  1214. }
  1215. //---------------------------------------------------------------------
  1216. AnsiString __fastcall TSessionData::GetSessionName()
  1217. {
  1218. if (!Name.IsEmpty() && !TNamedObjectList::IsHidden(this) &&
  1219. (Name != DefaultSessionName))
  1220. {
  1221. return Name;
  1222. }
  1223. else if (!HostName.IsEmpty() && !UserName.IsEmpty())
  1224. {
  1225. return FORMAT("%s@%s", (UserName, HostName));
  1226. }
  1227. else if (!HostName.IsEmpty())
  1228. {
  1229. return HostName;
  1230. }
  1231. else
  1232. {
  1233. return "session";
  1234. }
  1235. }
  1236. //---------------------------------------------------------------------
  1237. void __fastcall TSessionData::SetTimeDifference(TDateTime value)
  1238. {
  1239. SET_SESSION_PROPERTY(TimeDifference);
  1240. }
  1241. //---------------------------------------------------------------------
  1242. void __fastcall TSessionData::SetLocalDirectory(AnsiString value)
  1243. {
  1244. SET_SESSION_PROPERTY(LocalDirectory);
  1245. }
  1246. //---------------------------------------------------------------------
  1247. void __fastcall TSessionData::SetRemoteDirectory(AnsiString value)
  1248. {
  1249. SET_SESSION_PROPERTY(RemoteDirectory);
  1250. }
  1251. //---------------------------------------------------------------------
  1252. void __fastcall TSessionData::SetUpdateDirectories(bool value)
  1253. {
  1254. SET_SESSION_PROPERTY(UpdateDirectories);
  1255. }
  1256. //---------------------------------------------------------------------
  1257. void __fastcall TSessionData::SetCacheDirectories(bool value)
  1258. {
  1259. SET_SESSION_PROPERTY(CacheDirectories);
  1260. }
  1261. //---------------------------------------------------------------------
  1262. void __fastcall TSessionData::SetCacheDirectoryChanges(bool value)
  1263. {
  1264. SET_SESSION_PROPERTY(CacheDirectoryChanges);
  1265. }
  1266. //---------------------------------------------------------------------
  1267. void __fastcall TSessionData::SetPreserveDirectoryChanges(bool value)
  1268. {
  1269. SET_SESSION_PROPERTY(PreserveDirectoryChanges);
  1270. }
  1271. //---------------------------------------------------------------------
  1272. void __fastcall TSessionData::SetResolveSymlinks(bool value)
  1273. {
  1274. SET_SESSION_PROPERTY(ResolveSymlinks);
  1275. }
  1276. //---------------------------------------------------------------------------
  1277. void __fastcall TSessionData::SetConsiderDST(bool value)
  1278. {
  1279. SET_SESSION_PROPERTY(ConsiderDST);
  1280. }
  1281. //---------------------------------------------------------------------------
  1282. void __fastcall TSessionData::SetDeleteToRecycleBin(bool value)
  1283. {
  1284. SET_SESSION_PROPERTY(DeleteToRecycleBin);
  1285. }
  1286. //---------------------------------------------------------------------------
  1287. void __fastcall TSessionData::SetOverwrittenToRecycleBin(bool value)
  1288. {
  1289. SET_SESSION_PROPERTY(OverwrittenToRecycleBin);
  1290. }
  1291. //---------------------------------------------------------------------------
  1292. void __fastcall TSessionData::SetRecycleBinPath(AnsiString value)
  1293. {
  1294. SET_SESSION_PROPERTY(RecycleBinPath);
  1295. }
  1296. //---------------------------------------------------------------------
  1297. void __fastcall TSessionData::SetLockInHome(bool value)
  1298. {
  1299. SET_SESSION_PROPERTY(LockInHome);
  1300. }
  1301. //---------------------------------------------------------------------
  1302. void __fastcall TSessionData::SetSpecial(bool value)
  1303. {
  1304. SET_SESSION_PROPERTY(Special);
  1305. }
  1306. //---------------------------------------------------------------------------
  1307. void __fastcall TSessionData::SetScp1Compatibility(bool value)
  1308. {
  1309. SET_SESSION_PROPERTY(Scp1Compatibility);
  1310. }
  1311. //---------------------------------------------------------------------
  1312. void __fastcall TSessionData::SetTcpNoDelay(bool value)
  1313. {
  1314. SET_SESSION_PROPERTY(TcpNoDelay);
  1315. }
  1316. //---------------------------------------------------------------------
  1317. void __fastcall TSessionData::SetProxyMethod(TProxyMethod value)
  1318. {
  1319. SET_SESSION_PROPERTY(ProxyMethod);
  1320. }
  1321. //---------------------------------------------------------------------
  1322. void __fastcall TSessionData::SetProxyHost(AnsiString value)
  1323. {
  1324. SET_SESSION_PROPERTY(ProxyHost);
  1325. }
  1326. //---------------------------------------------------------------------
  1327. void __fastcall TSessionData::SetProxyPort(int value)
  1328. {
  1329. SET_SESSION_PROPERTY(ProxyPort);
  1330. }
  1331. //---------------------------------------------------------------------
  1332. void __fastcall TSessionData::SetProxyUsername(AnsiString value)
  1333. {
  1334. SET_SESSION_PROPERTY(ProxyUsername);
  1335. }
  1336. //---------------------------------------------------------------------
  1337. void __fastcall TSessionData::SetProxyPassword(AnsiString value)
  1338. {
  1339. value = EncryptPassword(value, ProxyUsername+ProxyHost);
  1340. SET_SESSION_PROPERTY(ProxyPassword);
  1341. }
  1342. //---------------------------------------------------------------------
  1343. AnsiString __fastcall TSessionData::GetProxyPassword() const
  1344. {
  1345. return DecryptPassword(FProxyPassword, ProxyUsername+ProxyHost);
  1346. }
  1347. //---------------------------------------------------------------------
  1348. void __fastcall TSessionData::SetProxyTelnetCommand(AnsiString value)
  1349. {
  1350. SET_SESSION_PROPERTY(ProxyTelnetCommand);
  1351. }
  1352. //---------------------------------------------------------------------
  1353. void __fastcall TSessionData::SetProxyDNS(TAutoSwitch value)
  1354. {
  1355. SET_SESSION_PROPERTY(ProxyDNS);
  1356. }
  1357. //---------------------------------------------------------------------
  1358. void __fastcall TSessionData::SetProxyLocalhost(bool value)
  1359. {
  1360. SET_SESSION_PROPERTY(ProxyLocalhost);
  1361. }
  1362. //---------------------------------------------------------------------
  1363. void __fastcall TSessionData::SetBug(TSshBug Bug, TAutoSwitch value)
  1364. {
  1365. assert(Bug >= 0 && Bug < LENOF(FBugs));
  1366. SET_SESSION_PROPERTY(Bugs[Bug]);
  1367. }
  1368. //---------------------------------------------------------------------
  1369. TAutoSwitch __fastcall TSessionData::GetBug(TSshBug Bug) const
  1370. {
  1371. assert(Bug >= 0 && Bug < LENOF(FBugs));
  1372. return FBugs[Bug];
  1373. }
  1374. //---------------------------------------------------------------------
  1375. void __fastcall TSessionData::SetCustomParam1(AnsiString value)
  1376. {
  1377. SET_SESSION_PROPERTY(CustomParam1);
  1378. }
  1379. //---------------------------------------------------------------------
  1380. void __fastcall TSessionData::SetCustomParam2(AnsiString value)
  1381. {
  1382. SET_SESSION_PROPERTY(CustomParam2);
  1383. }
  1384. //---------------------------------------------------------------------
  1385. void __fastcall TSessionData::SetSFTPDownloadQueue(int value)
  1386. {
  1387. SET_SESSION_PROPERTY(SFTPDownloadQueue);
  1388. }
  1389. //---------------------------------------------------------------------
  1390. void __fastcall TSessionData::SetSFTPUploadQueue(int value)
  1391. {
  1392. SET_SESSION_PROPERTY(SFTPUploadQueue);
  1393. }
  1394. //---------------------------------------------------------------------
  1395. void __fastcall TSessionData::SetSFTPListingQueue(int value)
  1396. {
  1397. SET_SESSION_PROPERTY(SFTPListingQueue);
  1398. }
  1399. //---------------------------------------------------------------------
  1400. void __fastcall TSessionData::SetSFTPMaxVersion(int value)
  1401. {
  1402. SET_SESSION_PROPERTY(SFTPMaxVersion);
  1403. }
  1404. //---------------------------------------------------------------------
  1405. void __fastcall TSessionData::SetSFTPMaxPacketSize(unsigned long value)
  1406. {
  1407. SET_SESSION_PROPERTY(SFTPMaxPacketSize);
  1408. }
  1409. //---------------------------------------------------------------------
  1410. void __fastcall TSessionData::SetSFTPBug(TSftpBug Bug, TAutoSwitch value)
  1411. {
  1412. assert(Bug >= 0 && Bug < LENOF(FSFTPBugs));
  1413. SET_SESSION_PROPERTY(SFTPBugs[Bug]);
  1414. }
  1415. //---------------------------------------------------------------------
  1416. TAutoSwitch __fastcall TSessionData::GetSFTPBug(TSftpBug Bug) const
  1417. {
  1418. assert(Bug >= 0 && Bug < LENOF(FSFTPBugs));
  1419. return FSFTPBugs[Bug];
  1420. }
  1421. //---------------------------------------------------------------------
  1422. void __fastcall TSessionData::SetSCPLsFullTime(TAutoSwitch value)
  1423. {
  1424. SET_SESSION_PROPERTY(SCPLsFullTime);
  1425. }
  1426. //---------------------------------------------------------------------------
  1427. void __fastcall TSessionData::SetColor(int value)
  1428. {
  1429. SET_SESSION_PROPERTY(Color);
  1430. }
  1431. //---------------------------------------------------------------------
  1432. AnsiString __fastcall TSessionData::GetInfoTip()
  1433. {
  1434. return FmtLoadStr(SESSION_INFO_TIP,
  1435. ARRAYOFCONST((
  1436. (HostName.IsEmpty() ? AnsiString() : HostName),
  1437. (UserName.IsEmpty() ? AnsiString() : UserName),
  1438. (PublicKeyFile.IsEmpty() ? LoadStr(NO_STR) : LoadStr(YES_STR)),
  1439. SshProtStr,
  1440. FSProtocolStr)));
  1441. }
  1442. //=== TStoredSessionList ----------------------------------------------
  1443. __fastcall TStoredSessionList::TStoredSessionList(bool aReadOnly):
  1444. TNamedObjectList(), FReadOnly(aReadOnly)
  1445. {
  1446. assert(Configuration);
  1447. LastStorage = Configuration->Storage;
  1448. FDefaultSettings = new TSessionData(DefaultSessionName);
  1449. }
  1450. //---------------------------------------------------------------------
  1451. __fastcall TStoredSessionList::~TStoredSessionList()
  1452. {
  1453. assert(Configuration);
  1454. if (!FReadOnly && (Configuration->Storage != LastStorage)) Save();
  1455. delete FDefaultSettings;
  1456. }
  1457. //---------------------------------------------------------------------
  1458. void __fastcall TStoredSessionList::Load(THierarchicalStorage * Storage,
  1459. bool AsModified, bool UseDefaults)
  1460. {
  1461. TStringList *SubKeys = new TStringList();
  1462. try {
  1463. Storage->GetSubKeyNames(SubKeys);
  1464. for (int Index = 0; Index < SubKeys->Count; Index++)
  1465. {
  1466. TSessionData *SessionData;
  1467. AnsiString SessionName = UnMungeStr(SubKeys->Strings[Index]);
  1468. bool ValidName = true;
  1469. try
  1470. {
  1471. TSessionData::ValidateName(SessionName);
  1472. }
  1473. catch(...)
  1474. {
  1475. ValidName = false;
  1476. }
  1477. if (ValidName)
  1478. {
  1479. if (SessionName == FDefaultSettings->Name) SessionData = FDefaultSettings;
  1480. else SessionData = (TSessionData*)FindByName(SessionName);
  1481. if ((SessionData != FDefaultSettings) || !UseDefaults)
  1482. {
  1483. if (!SessionData)
  1484. {
  1485. SessionData = new TSessionData("");
  1486. if (UseDefaults)
  1487. {
  1488. SessionData->Assign(DefaultSettings);
  1489. }
  1490. SessionData->Name = SessionName;
  1491. Add(SessionData);
  1492. }
  1493. SessionData->Load(Storage);
  1494. if (AsModified)
  1495. {
  1496. SessionData->Modified = true;
  1497. }
  1498. }
  1499. }
  1500. }
  1501. } __finally {
  1502. delete SubKeys;
  1503. }
  1504. }
  1505. //---------------------------------------------------------------------
  1506. void __fastcall TStoredSessionList::Load(AnsiString aKey, bool UseDefaults)
  1507. {
  1508. TRegistryStorage * Storage = new TRegistryStorage(aKey);
  1509. try {
  1510. LastStorage = stRegistry;
  1511. if (Storage->OpenRootKey(False)) Load(Storage, false, UseDefaults);
  1512. } __finally {
  1513. delete Storage;
  1514. }
  1515. }
  1516. //---------------------------------------------------------------------
  1517. void __fastcall TStoredSessionList::Load()
  1518. {
  1519. THierarchicalStorage * Storage = Configuration->CreateScpStorage(true);
  1520. try {
  1521. LastStorage = Configuration->Storage;
  1522. if (Storage->OpenSubKey(Configuration->StoredSessionsSubKey, False))
  1523. Load(Storage);
  1524. } __finally {
  1525. delete Storage;
  1526. }
  1527. }
  1528. //---------------------------------------------------------------------
  1529. void __fastcall TStoredSessionList::Save(THierarchicalStorage * Storage)
  1530. {
  1531. TSessionData * FactoryDefaults = new TSessionData("");
  1532. try
  1533. {
  1534. for (int Index = 0; Index < Count+HiddenCount; Index++)
  1535. {
  1536. TSessionData *SessionData = (TSessionData *)Items[Index];
  1537. if (SessionData->Modified)
  1538. SessionData->Save(Storage, false, FactoryDefaults);
  1539. }
  1540. if (FDefaultSettings->Modified)
  1541. FDefaultSettings->Save(Storage, false, FactoryDefaults);
  1542. }
  1543. __finally
  1544. {
  1545. delete FactoryDefaults;
  1546. }
  1547. }
  1548. //---------------------------------------------------------------------
  1549. void __fastcall TStoredSessionList::Save(AnsiString aKey)
  1550. {
  1551. TRegistryStorage * Storage = new TRegistryStorage(aKey);
  1552. try
  1553. {
  1554. LastStorage = stRegistry;
  1555. Storage->AccessMode = smReadWrite;
  1556. if (Storage->OpenRootKey(True)) Save(Storage);
  1557. }
  1558. __finally
  1559. {
  1560. delete Storage;
  1561. }
  1562. }
  1563. //---------------------------------------------------------------------
  1564. void __fastcall TStoredSessionList::Save()
  1565. {
  1566. if (LastStorage != Configuration->Storage)
  1567. {
  1568. // make sure, that all data will be stored, when saving to new storage
  1569. for (int Index = 0; Index < Count+HiddenCount; Index++)
  1570. ((TSessionData*)Items[Index])->Modified = true;
  1571. FDefaultSettings->Modified = true;
  1572. LastStorage = Configuration->Storage;
  1573. }
  1574. THierarchicalStorage * Storage = Configuration->CreateScpStorage(true);
  1575. try {
  1576. Storage->AccessMode = smReadWrite;
  1577. if (Storage->OpenSubKey(Configuration->StoredSessionsSubKey, True))
  1578. Save(Storage);
  1579. } __finally {
  1580. delete Storage;
  1581. }
  1582. }
  1583. //---------------------------------------------------------------------
  1584. void __fastcall TStoredSessionList::SelectAll(bool Select)
  1585. {
  1586. for (int Index = 0; Index < Count; Index++)
  1587. Sessions[Index]->Selected = Select;
  1588. }
  1589. //---------------------------------------------------------------------
  1590. void __fastcall TStoredSessionList::Import(TStoredSessionList * From,
  1591. bool OnlySelected)
  1592. {
  1593. for (int Index = 0; Index < From->Count; Index++)
  1594. {
  1595. if (!OnlySelected || From->Sessions[Index]->Selected)
  1596. {
  1597. TSessionData *Session = new TSessionData("");
  1598. Session->Assign(From->Sessions[Index]);
  1599. Session->Modified = true;
  1600. Session->MakeUniqueIn(this);
  1601. Add(Session);
  1602. }
  1603. }
  1604. Save();
  1605. }
  1606. //---------------------------------------------------------------------
  1607. void __fastcall TStoredSessionList::SelectSessionsToImport
  1608. (TStoredSessionList * Dest, bool SSHOnly)
  1609. {
  1610. for (int Index = 0; Index < Count; Index++)
  1611. {
  1612. Sessions[Index]->Selected =
  1613. (!SSHOnly || (Sessions[Index]->Protocol == ptSSH)) &&
  1614. !Dest->FindByName(Sessions[Index]->Name);
  1615. }
  1616. }
  1617. //---------------------------------------------------------------------
  1618. void __fastcall TStoredSessionList::Cleanup()
  1619. {
  1620. try {
  1621. if (Configuration->Storage == stRegistry) Clear();
  1622. TRegistryStorage * Storage = new TRegistryStorage(Configuration->RegistryStorageKey);
  1623. try {
  1624. Storage->AccessMode = smReadWrite;
  1625. if (Storage->OpenRootKey(False))
  1626. Storage->RecursiveDeleteSubKey(Configuration->StoredSessionsSubKey);
  1627. } __finally {
  1628. delete Storage;
  1629. }
  1630. } catch (Exception &E) {
  1631. throw ExtException(&E, CLEANUP_SESSIONS_ERROR);
  1632. }
  1633. }
  1634. //---------------------------------------------------------------------------
  1635. int __fastcall TStoredSessionList::IndexOf(TSessionData * Data)
  1636. {
  1637. for (int Index = 0; Index < Count; Index++)
  1638. if (Data == Sessions[Index]) return Index;
  1639. return -1;
  1640. }
  1641. //---------------------------------------------------------------------------
  1642. TSessionData * __fastcall TStoredSessionList::NewSession(
  1643. AnsiString SessionName, TSessionData * Session)
  1644. {
  1645. TSessionData * DuplicateSession = (TSessionData*)FindByName(SessionName);
  1646. if (!DuplicateSession)
  1647. {
  1648. DuplicateSession = new TSessionData("");
  1649. DuplicateSession->Assign(Session);
  1650. DuplicateSession->Name = SessionName;
  1651. // make sure, that new stored session is saved to registry
  1652. DuplicateSession->Modified = true;
  1653. Add(DuplicateSession);
  1654. }
  1655. else
  1656. {
  1657. DuplicateSession->Assign(Session);
  1658. DuplicateSession->Name = SessionName;
  1659. DuplicateSession->Modified = true;
  1660. }
  1661. // list was saved here before to default storage, but it would not allow
  1662. // to work with special lists (export/import) not using default storage
  1663. return DuplicateSession;
  1664. }
  1665. //---------------------------------------------------------------------------
  1666. void __fastcall TStoredSessionList::SetDefaultSettings(TSessionData * value)
  1667. {
  1668. assert(FDefaultSettings);
  1669. if (FDefaultSettings != value)
  1670. {
  1671. FDefaultSettings->Assign(value);
  1672. FDefaultSettings->Name = DefaultSessionName;
  1673. if (!FReadOnly)
  1674. {
  1675. Save();
  1676. }
  1677. }
  1678. }
  1679. //---------------------------------------------------------------------------
  1680. void __fastcall TStoredSessionList::ImportHostKeys(const AnsiString TargetKey,
  1681. const AnsiString SourceKey, TStoredSessionList * Sessions,
  1682. bool OnlySelected)
  1683. {
  1684. TRegistryStorage * SourceStorage = NULL;
  1685. TRegistryStorage * TargetStorage = NULL;
  1686. TStringList * KeyList = NULL;
  1687. try
  1688. {
  1689. SourceStorage = new TRegistryStorage(SourceKey);
  1690. TargetStorage = new TRegistryStorage(TargetKey);
  1691. TargetStorage->AccessMode = smReadWrite;
  1692. KeyList = new TStringList();
  1693. if (SourceStorage->OpenRootKey(false) &&
  1694. TargetStorage->OpenRootKey(true))
  1695. {
  1696. SourceStorage->GetValueNames(KeyList);
  1697. TSessionData * Session;
  1698. AnsiString HostKeyName;
  1699. assert(Sessions != NULL);
  1700. for (int Index = 0; Index < Sessions->Count; Index++)
  1701. {
  1702. Session = Sessions->Sessions[Index];
  1703. if (!OnlySelected || Session->Selected)
  1704. {
  1705. HostKeyName = MungeStr(FORMAT("@%d:%s", (Session->PortNumber, Session->HostName)));
  1706. AnsiString KeyName;
  1707. for (int KeyIndex = 0; KeyIndex < KeyList->Count; KeyIndex++)
  1708. {
  1709. KeyName = KeyList->Strings[KeyIndex];
  1710. int P = KeyName.Pos(HostKeyName);
  1711. if ((P > 0) && (P == KeyName.Length() - HostKeyName.Length() + 1))
  1712. {
  1713. TargetStorage->WriteStringRaw(KeyName,
  1714. SourceStorage->ReadStringRaw(KeyName, ""));
  1715. }
  1716. }
  1717. }
  1718. }
  1719. }
  1720. }
  1721. __finally
  1722. {
  1723. delete SourceStorage;
  1724. delete TargetStorage;
  1725. delete KeyList;
  1726. }
  1727. }
  1728. //---------------------------------------------------------------------------
  1729. TSessionData * __fastcall TStoredSessionList::ParseUrl(AnsiString Url,
  1730. bool & DefaultsOnly, int Params, AnsiString * FileName,
  1731. bool * AProtocolDefined)
  1732. {
  1733. bool ProtocolDefined = false;
  1734. TFSProtocol Protocol;
  1735. if (Url.SubString(1, 6).LowerCase() == "scp://")
  1736. {
  1737. Protocol = fsSCPonly;
  1738. Url.Delete(1, 6);
  1739. ProtocolDefined = true;
  1740. }
  1741. else if (Url.SubString(1, 7).LowerCase() == "sftp://")
  1742. {
  1743. Protocol = fsSFTPonly;
  1744. Url.Delete(1, 7);
  1745. ProtocolDefined = true;
  1746. }
  1747. if (AProtocolDefined != NULL)
  1748. {
  1749. *AProtocolDefined = ProtocolDefined;
  1750. }
  1751. DefaultsOnly = true;
  1752. TSessionData * Data = new TSessionData("");
  1753. try
  1754. {
  1755. if (!Url.IsEmpty())
  1756. {
  1757. TSessionData * AData = NULL;
  1758. // lookup stored session session even if protocol was defined
  1759. // (this allows setting for example default username for host
  1760. // by creating stored session named by host)
  1761. AnsiString ConnectInfo;
  1762. AnsiString RemoteDirectory;
  1763. if (TSessionData::ParseUrl(Url, Params, &ConnectInfo, NULL, NULL, NULL,
  1764. NULL, &RemoteDirectory, FileName))
  1765. {
  1766. AData = dynamic_cast<TSessionData *>(FindByName(ConnectInfo, false));
  1767. }
  1768. if (AData == NULL)
  1769. {
  1770. Data->Assign(DefaultSettings);
  1771. if (Data->ParseUrl(Url, Params, FileName))
  1772. {
  1773. Data->Name = "";
  1774. DefaultsOnly = false;
  1775. }
  1776. else
  1777. {
  1778. throw Exception(FMTLOAD(SESSION_NOT_EXISTS_ERROR, (Url)));
  1779. }
  1780. }
  1781. else
  1782. {
  1783. DefaultsOnly = false;
  1784. Data->Assign(AData);
  1785. if (!RemoteDirectory.IsEmpty())
  1786. {
  1787. Data->RemoteDirectory = RemoteDirectory;
  1788. }
  1789. if (IsHidden(AData))
  1790. {
  1791. AData->Remove();
  1792. Remove(AData);
  1793. Save();
  1794. }
  1795. }
  1796. }
  1797. else
  1798. {
  1799. Data->Assign(DefaultSettings);
  1800. }
  1801. if (ProtocolDefined)
  1802. {
  1803. Data->FSProtocol = Protocol;
  1804. }
  1805. }
  1806. catch(...)
  1807. {
  1808. delete Data;
  1809. throw;
  1810. }
  1811. return Data;
  1812. }