Net.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "Net.h"
  5. #include "PuttyIntf.h"
  6. #include "Interface.h"
  7. #include "SecureShell.h"
  8. #include "TextsCore.h"
  9. #include "Common.h"
  10. //---------------------------------------------------------------------------
  11. #pragma package(smart_init)
  12. //---------------------------------------------------------------------------
  13. int SessionsCount = 0;
  14. TSecureShell * CurrentSSH = NULL;
  15. //---------------------------------------------------------------------------
  16. void __fastcall InitWinsock();
  17. static int get_line(const char * prompt, char * str, int maxlen, int is_pw);
  18. //---------------------------------------------------------------------------
  19. void __fastcall NetInitialize()
  20. {
  21. ssh_get_line = get_line;
  22. ssh_getline_pw_only = TRUE;
  23. InitWinsock();
  24. sk_init();
  25. AnsiString VersionString = SshVersionString();
  26. assert(!VersionString.IsEmpty() && VersionString.Length() < 40);
  27. strcpy(sshver, VersionString.c_str());
  28. }
  29. //---------------------------------------------------------------------------
  30. void __fastcall NetFinalize()
  31. {
  32. WSACleanup();
  33. }
  34. //---------------------------------------------------------------------------
  35. void __fastcall InitWinsock(void)
  36. {
  37. // see scp.c init_winsock()
  38. WORD winsock_ver;
  39. WSADATA wsadata;
  40. #pragma option push -w-prc
  41. winsock_ver = MAKEWORD(1, 1);
  42. #pragma option pop
  43. if (WSAStartup(winsock_ver, &wsadata))
  44. {
  45. SSH_FATAL_ERROR("Unable to initialise WinSock");
  46. }
  47. if (LOBYTE(wsadata.wVersion) != 1 ||
  48. HIBYTE(wsadata.wVersion) != 1)
  49. {
  50. SSH_FATAL_ERROR("WinSock version is incompatible with 1.1");
  51. }
  52. }
  53. //---------------------------------------------------------------------------
  54. extern "C" char * do_select(SOCKET skt, int startup)
  55. {
  56. assert(CurrentSSH);
  57. if (CurrentSSH)
  58. {
  59. if (!startup)
  60. {
  61. skt = INVALID_SOCKET;
  62. }
  63. CurrentSSH->SetSocket(&skt);
  64. }
  65. return NULL;
  66. }
  67. //---------------------------------------------------------------------------
  68. int from_backend(void * frontend, int is_stderr, char * data, int datalen)
  69. {
  70. assert(frontend);
  71. ((TSecureShell *)frontend)->FromBackend((is_stderr == 1), data, datalen);
  72. return 0;
  73. }
  74. //---------------------------------------------------------------------------
  75. static int get_line(const char * prompt, char * str, int maxlen, int is_pw)
  76. {
  77. assert(is_pw);
  78. assert(CurrentSSH);
  79. AnsiString Password, Prompt(prompt);
  80. int Result;
  81. if (Prompt.Pos("Passphrase for key ") == 1)
  82. {
  83. AnsiString Key(Prompt);
  84. int P = Prompt.Pos("\"");
  85. if (P > 0)
  86. {
  87. Key.Delete(1, P);
  88. P = Key.LastDelimiter("\"");
  89. if (P > 0)
  90. {
  91. Key.SetLength(P - 1);
  92. }
  93. }
  94. CurrentSSH->LogEvent(FORMAT("Passphrase prompt (%s)", (Prompt)));
  95. Result = GetSessionPassword(FMTLOAD(PROMPT_KEY_PASSPHRASE, (Key)),
  96. pkPassphrase, Password);
  97. }
  98. else if (Prompt.Pos("'s password: "))
  99. {
  100. CurrentSSH->LogEvent(FORMAT("Session password prompt (%s)", (Prompt)));
  101. assert(CurrentSSH);
  102. Result = CurrentSSH->GetPassword(Password);
  103. }
  104. else
  105. {
  106. CurrentSSH->LogEvent(FORMAT("Server prompt (%s)", (Prompt)));
  107. // in other cases we assume TIS/Cryptocard/keyboard-interactive authentification prompt
  108. Result = GetSessionPassword(AnsiString(prompt), pkServerPrompt, Password);
  109. };
  110. if (Result)
  111. {
  112. strcpy(str, Password.SubString(1, maxlen).c_str());
  113. }
  114. return Result;
  115. }
  116. //---------------------------------------------------------------------------
  117. void SSHLogEvent(void * frontend, char * string)
  118. {
  119. // Frontend maybe NULL here
  120. if (frontend != NULL)
  121. {
  122. ((TSecureShell *)frontend)->LogEvent(string);
  123. }
  124. }
  125. //---------------------------------------------------------------------------
  126. void SSHFatalError(char * string)
  127. {
  128. // Only few calls from putty\winnet.c might be connected with specific
  129. // TSecureShell. Otherwise called only for really fatal errors
  130. // like 'out of memory' from putty\ssh.c.
  131. SSH_FATAL_ERROR_EXT(NULL, string);
  132. }
  133. //---------------------------------------------------------------------------
  134. void SSHConnectionFatal(void * frontend, char * string)
  135. {
  136. assert(frontend);
  137. ((TSecureShell *)frontend)->FatalError(string);
  138. }
  139. //---------------------------------------------------------------------------
  140. void SSHVerifyHostKey(void * frontend, char * Host, int Port, char * KeyType,
  141. char * KeyStr, char * Fingerprint)
  142. {
  143. assert(frontend);
  144. ((TSecureShell *)frontend)->VerifyHostKey(Host, Port, KeyType, KeyStr, Fingerprint);
  145. }
  146. //---------------------------------------------------------------------------
  147. void SSHAskCipher(void * frontend, char * CipherName, int CipherType)
  148. {
  149. assert(frontend);
  150. ((TSecureShell *)frontend)->AskCipher(CipherName, CipherType);
  151. }
  152. //---------------------------------------------------------------------------
  153. void SSHOldKeyfileWarning(void)
  154. {
  155. assert(CurrentSSH);
  156. CurrentSSH->OldKeyfileWarning();
  157. }