ssh.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <assert.h>
  5. #include <winsock.h>
  6. #include "putty.h"
  7. #include "ssh.h"
  8. #include "scp.h"
  9. #ifndef FALSE
  10. #define FALSE 0
  11. #endif
  12. #ifndef TRUE
  13. #define TRUE 1
  14. #endif
  15. #define SSH_MSG_DISCONNECT 1
  16. #define SSH_SMSG_PUBLIC_KEY 2
  17. #define SSH_CMSG_SESSION_KEY 3
  18. #define SSH_CMSG_USER 4
  19. #define SSH_CMSG_AUTH_PASSWORD 9
  20. #define SSH_CMSG_REQUEST_PTY 10
  21. #define SSH_CMSG_WINDOW_SIZE 11
  22. #define SSH_CMSG_EXEC_SHELL 12
  23. #define SSH_CMSG_EXEC_CMD 13
  24. #define SSH_SMSG_SUCCESS 14
  25. #define SSH_SMSG_FAILURE 15
  26. #define SSH_CMSG_STDIN_DATA 16
  27. #define SSH_SMSG_STDOUT_DATA 17
  28. #define SSH_SMSG_STDERR_DATA 18
  29. #define SSH_CMSG_EOF 19
  30. #define SSH_SMSG_EXIT_STATUS 20
  31. #define SSH_CMSG_EXIT_CONFIRMATION 33
  32. #define SSH_MSG_IGNORE 32
  33. #define SSH_MSG_DEBUG 36
  34. #define SSH_CMSG_REQUEST_COMPRESSION 37
  35. #define SSH_CMSG_AUTH_TIS 39
  36. #define SSH_SMSG_AUTH_TIS_CHALLENGE 40
  37. #define SSH_CMSG_AUTH_TIS_RESPONSE 41
  38. #define SSH_AUTH_TIS 5
  39. #define COMPRESSION_LEVEL 5
  40. #define GET_32BIT(cp) \
  41. (((unsigned long)(unsigned char)(cp)[0] << 24) | \
  42. ((unsigned long)(unsigned char)(cp)[1] << 16) | \
  43. ((unsigned long)(unsigned char)(cp)[2] << 8) | \
  44. ((unsigned long)(unsigned char)(cp)[3]))
  45. #define PUT_32BIT(cp, value) { \
  46. (cp)[0] = (unsigned char)((value) >> 24); \
  47. (cp)[1] = (unsigned char)((value) >> 16); \
  48. (cp)[2] = (unsigned char)((value) >> 8); \
  49. (cp)[3] = (unsigned char)(value); }
  50. enum { PKT_END, PKT_INT, PKT_CHAR, PKT_DATA, PKT_STR };
  51. /* Coroutine mechanics for the sillier bits of the code */
  52. #define crBegin1 static int crLine = 0;
  53. #define crBegin2 switch(crLine) { case 0:;
  54. #define crBegin crBegin1; crBegin2;
  55. #define crFinish(z) } crLine = 0; return (z)
  56. #define crFinishV } crLine = 0; return
  57. #define crReturn(z) \
  58. do {\
  59. crLine=__LINE__; return (z); case __LINE__:;\
  60. } while (0)
  61. #define crReturnV \
  62. do {\
  63. crLine=__LINE__; return; case __LINE__:;\
  64. } while (0)
  65. #define crStop(z) do{ crLine = 0; return (z); }while(0)
  66. #define crStopV do{ crLine = 0; return; }while(0)
  67. #define crWaitUntil(c) do { crReturn(0); } while (!(c))
  68. static SOCKET s = INVALID_SOCKET;
  69. static unsigned char session_key[32];
  70. static struct ssh_cipher *cipher = NULL;
  71. static int use_compression = 0;
  72. void (*ssh_get_password)(const char *prompt, char *str, int maxlen) = NULL;
  73. static char *savedhost;
  74. static enum {
  75. SSH_STATE_BEFORE_SIZE,
  76. SSH_STATE_INTERMED,
  77. SSH_STATE_SESSION,
  78. SSH_STATE_CLOSED
  79. } ssh_state = SSH_STATE_BEFORE_SIZE;
  80. static int size_needed = FALSE;
  81. static void s_write (char *buf, int len) {
  82. while (len > 0) {
  83. int i = send (s, buf, len, 0);
  84. if (IS_SCP) {
  85. noise_ultralight(i);
  86. if (i <= 0)
  87. fatalbox("Lost connection while sending");
  88. }
  89. if (i > 0)
  90. len -= i, buf += i;
  91. }
  92. }
  93. static int s_read (char *buf, int len) {
  94. int ret = 0;
  95. while (len > 0) {
  96. int i = recv (s, buf, len, 0);
  97. if (IS_SCP)
  98. noise_ultralight(i);
  99. if (i > 0)
  100. len -= i, buf += i, ret += i;
  101. else
  102. return i;
  103. }
  104. return ret;
  105. }
  106. static void c_write (char *buf, int len) {
  107. if (IS_SCP) {
  108. if (len > 0 && buf[len-1] == '\n') len--;
  109. if (len > 0 && buf[len-1] == '\r') len--;
  110. if (len > 0) { fwrite(buf, len, 1, stderr); fputc('\n', stderr); }
  111. return;
  112. }
  113. while (len--) {
  114. int new_head = (inbuf_head + 1) & INBUF_MASK;
  115. if (new_head != inbuf_reap) {
  116. inbuf[inbuf_head] = *buf++;
  117. inbuf_head = new_head;
  118. } else {
  119. term_out();
  120. if( inbuf_head == inbuf_reap ) len++; else break;
  121. }
  122. }
  123. }
  124. struct Packet {
  125. long length;
  126. int type;
  127. unsigned char *data;
  128. unsigned char *body;
  129. long maxlen;
  130. };
  131. static struct Packet pktin = { 0, 0, NULL, NULL, 0 };
  132. static struct Packet pktout = { 0, 0, NULL, NULL, 0 };
  133. static void ssh_protocol(unsigned char *in, int inlen, int ispkt);
  134. static void ssh_size(void);
  135. static void pktalloc(struct Packet *pkt, long newlen)
  136. {
  137. if (pkt->maxlen < newlen) {
  138. pkt->maxlen = newlen;
  139. #ifdef MSCRYPTOAPI
  140. /* Allocate enough buffer space for extra block
  141. * for MS CryptEncrypt() */
  142. pkt->data = (pkt->data == NULL ? malloc(newlen+8) :
  143. realloc(pkt->data, newlen+8));
  144. #else
  145. pkt->data = (pkt->data == NULL ? malloc(newlen) :
  146. realloc(pkt->data, newlen));
  147. #endif
  148. if (!pkt->data)
  149. fatalbox("Out of memory");
  150. }
  151. }
  152. /*
  153. * Collect incoming data in the incoming packet buffer.
  154. * Decihper and verify the packet when it is completely read.
  155. * Drop SSH_MSG_DEBUG and SSH_MSG_IGNORE packets.
  156. * Update the *data and *datalen variables.
  157. * Return the additional nr of bytes needed, or 0 when
  158. * a complete packet is available.
  159. */
  160. static int s_rdpkt(unsigned char **data, int *datalen)
  161. {
  162. static long len, pad, biglen, to_read;
  163. static unsigned long realcrc, gotcrc;
  164. static unsigned char *p;
  165. static int i;
  166. crBegin;
  167. next_packet:
  168. pktin.type = 0;
  169. pktin.length = 0;
  170. for (i = len = 0; i < 4; i++) {
  171. while ((*datalen) == 0)
  172. crReturn(4-i);
  173. len = (len << 8) + **data;
  174. (*data)++, (*datalen)--;
  175. }
  176. #ifdef FWHACK
  177. if (len == 0x52656d6f) { /* "Remo"te server has closed ... */
  178. len = 0x300; /* big enough to carry to end */
  179. }
  180. #endif
  181. pad = 8 - (len % 8);
  182. biglen = len + pad;
  183. if (pktin.maxlen < biglen)
  184. pktalloc(&pktin, biglen);
  185. to_read = biglen;
  186. p = pktin.data;
  187. while (to_read > 0) {
  188. static int chunk;
  189. chunk = to_read;
  190. while ((*datalen) == 0)
  191. crReturn(to_read);
  192. if (chunk > (*datalen))
  193. chunk = (*datalen);
  194. memcpy(p, *data, chunk);
  195. *data += chunk;
  196. *datalen -= chunk;
  197. p += chunk;
  198. to_read -= chunk;
  199. }
  200. if (cipher)
  201. cipher->decrypt(pktin.data, biglen);
  202. realcrc = crc32(pktin.data, biglen-4);
  203. gotcrc = GET_32BIT(pktin.data+biglen-4);
  204. if (gotcrc != realcrc) {
  205. fatalbox("Incorrect CRC received on packet");
  206. }
  207. if (use_compression) {
  208. ssh_decompress(pktin.data + pad, len - 4, &p, &len);
  209. pktin.length = len - 1;
  210. pktin.type = p[0];
  211. pktin.body = p + 1;
  212. } else {
  213. pktin.length = len - 5;
  214. pktin.type = pktin.data[pad];
  215. pktin.body = pktin.data + pad + 1;
  216. }
  217. if (pktin.type == SSH_SMSG_STDOUT_DATA ||
  218. pktin.type == SSH_SMSG_STDERR_DATA ||
  219. pktin.type == SSH_MSG_DEBUG ||
  220. pktin.type == SSH_SMSG_AUTH_TIS_CHALLENGE) {
  221. long strlen = GET_32BIT(pktin.body);
  222. if (strlen + 4 != pktin.length)
  223. fatalbox("Received data packet with bogus string length");
  224. }
  225. if (pktin.type == SSH_MSG_DEBUG) {
  226. /* log debug message */
  227. char buf[80];
  228. int strlen = GET_32BIT(pktin.body);
  229. strcpy(buf, "Remote: ");
  230. if (strlen > 70) strlen = 70;
  231. memcpy(buf+8, pktin.body+4, strlen);
  232. buf[8+strlen] = '\0';
  233. logevent(buf);
  234. goto next_packet;
  235. } else if (pktin.type == SSH_MSG_IGNORE) {
  236. /* do nothing */
  237. goto next_packet;
  238. }
  239. crFinish(0);
  240. }
  241. static void ssh_gotdata(unsigned char *data, int datalen)
  242. {
  243. while (datalen > 0) {
  244. if ( s_rdpkt(&data, &datalen) == 0 )
  245. ssh_protocol(NULL, 0, 1);
  246. }
  247. }
  248. static void s_wrpkt_start(int type, int len) {
  249. int pad, biglen;
  250. len += 5; /* type and CRC */
  251. pad = 8 - (len%8);
  252. biglen = len + pad;
  253. pktout.length = len-5;
  254. if (pktout.maxlen < biglen + 4)
  255. pktalloc(&pktout, biglen + 4);
  256. pktout.type = type;
  257. pktout.body = pktout.data+4+pad+1;
  258. }
  259. static void s_wrpkt(void) {
  260. int pad, len, biglen, i;
  261. unsigned long crc;
  262. len = pktout.length + 5; /* type and CRC */
  263. pad = 8 - (len%8);
  264. biglen = len + pad;
  265. pktout.body[-1] = pktout.type;
  266. if (use_compression) {
  267. unsigned char *p;
  268. unsigned int n;
  269. pktout.body = NULL;
  270. ssh_compress(pktout.data + 4 + pad, pktout.length + 1, &p, &n);
  271. len = n + 4;
  272. pad = 8 - (len%8);
  273. biglen = len + pad;
  274. if (pktout.maxlen < biglen + 4)
  275. pktalloc(&pktout, biglen + 4);
  276. memcpy(pktout.data + 4 + pad, p, n);
  277. }
  278. for (i=0; i<pad; i++)
  279. pktout.data[i+4] = random_byte();
  280. crc = crc32(pktout.data+4, biglen-4);
  281. PUT_32BIT(pktout.data+biglen, crc);
  282. PUT_32BIT(pktout.data, len);
  283. if (cipher)
  284. cipher->encrypt(pktout.data+4, biglen);
  285. s_write(pktout.data, biglen+4);
  286. }
  287. /*
  288. * Construct a packet with the specified contents and
  289. * send it to the server.
  290. */
  291. static void send_packet(int pkttype, ...)
  292. {
  293. va_list args;
  294. unsigned char *p, *argp, argchar;
  295. unsigned long argint;
  296. int pktlen, argtype, arglen;
  297. pktlen = 0;
  298. va_start(args, pkttype);
  299. while ((argtype = va_arg(args, int)) != PKT_END) {
  300. switch (argtype) {
  301. case PKT_INT:
  302. (void) va_arg(args, int);
  303. pktlen += 4;
  304. break;
  305. case PKT_CHAR:
  306. (void) va_arg(args, char);
  307. pktlen++;
  308. break;
  309. case PKT_DATA:
  310. (void) va_arg(args, unsigned char *);
  311. arglen = va_arg(args, int);
  312. pktlen += arglen;
  313. break;
  314. case PKT_STR:
  315. argp = va_arg(args, unsigned char *);
  316. arglen = strlen(argp);
  317. pktlen += 4 + arglen;
  318. break;
  319. default:
  320. assert(0);
  321. }
  322. }
  323. va_end(args);
  324. s_wrpkt_start(pkttype, pktlen);
  325. p = pktout.body;
  326. va_start(args, pkttype);
  327. while ((argtype = va_arg(args, int)) != PKT_END) {
  328. switch (argtype) {
  329. case PKT_INT:
  330. argint = va_arg(args, int);
  331. PUT_32BIT(p, argint);
  332. p += 4;
  333. break;
  334. case PKT_CHAR:
  335. argchar = va_arg(args, unsigned char);
  336. *p = argchar;
  337. p++;
  338. break;
  339. case PKT_DATA:
  340. argp = va_arg(args, unsigned char *);
  341. arglen = va_arg(args, int);
  342. memcpy(p, argp, arglen);
  343. p += arglen;
  344. break;
  345. case PKT_STR:
  346. argp = va_arg(args, unsigned char *);
  347. arglen = strlen(argp);
  348. PUT_32BIT(p, arglen);
  349. memcpy(p + 4, argp, arglen);
  350. p += 4 + arglen;
  351. break;
  352. }
  353. }
  354. va_end(args);
  355. s_wrpkt();
  356. }
  357. /*
  358. * Connect to specified host and port.
  359. * Returns an error message, or NULL on success.
  360. * Also places the canonical host name into `realhost'.
  361. */
  362. static char *connect_to_host(char *host, int port, char **realhost)
  363. {
  364. SOCKADDR_IN addr;
  365. struct hostent *h;
  366. unsigned long a;
  367. #ifdef FWHACK
  368. char *FWhost;
  369. int FWport;
  370. #endif
  371. savedhost = malloc(1+strlen(host));
  372. if (!savedhost)
  373. fatalbox("Out of memory");
  374. strcpy(savedhost, host);
  375. if (port < 0)
  376. port = 22; /* default ssh port */
  377. #ifdef FWHACK
  378. FWhost = host;
  379. FWport = port;
  380. host = FWSTR;
  381. port = 23;
  382. #endif
  383. /*
  384. * Try to find host.
  385. */
  386. if ( (a = inet_addr(host)) == (unsigned long) INADDR_NONE) {
  387. if ( (h = gethostbyname(host)) == NULL)
  388. switch (WSAGetLastError()) {
  389. case WSAENETDOWN: return "Network is down";
  390. case WSAHOST_NOT_FOUND: case WSANO_DATA:
  391. return "Host does not exist";
  392. case WSATRY_AGAIN: return "Host not found";
  393. default: return "gethostbyname: unknown error";
  394. }
  395. memcpy (&a, h->h_addr, sizeof(a));
  396. *realhost = h->h_name;
  397. } else
  398. *realhost = host;
  399. #ifdef FWHACK
  400. *realhost = FWhost;
  401. #endif
  402. a = ntohl(a);
  403. /*
  404. * Open socket.
  405. */
  406. s = socket(AF_INET, SOCK_STREAM, 0);
  407. if (s == INVALID_SOCKET)
  408. switch (WSAGetLastError()) {
  409. case WSAENETDOWN: return "Network is down";
  410. case WSAEAFNOSUPPORT: return "TCP/IP support not present";
  411. default: return "socket(): unknown error";
  412. }
  413. /*
  414. * Bind to local address.
  415. */
  416. addr.sin_family = AF_INET;
  417. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  418. addr.sin_port = htons(0);
  419. if (bind (s, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR)
  420. switch (WSAGetLastError()) {
  421. case WSAENETDOWN: return "Network is down";
  422. default: return "bind(): unknown error";
  423. }
  424. /*
  425. * Connect to remote address.
  426. */
  427. addr.sin_addr.s_addr = htonl(a);
  428. addr.sin_port = htons((short)port);
  429. if (connect (s, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR)
  430. switch (WSAGetLastError()) {
  431. case WSAENETDOWN: return "Network is down";
  432. case WSAECONNREFUSED: return "Connection refused";
  433. case WSAENETUNREACH: return "Network is unreachable";
  434. case WSAEHOSTUNREACH: return "No route to host";
  435. default: return "connect(): unknown error";
  436. }
  437. #ifdef FWHACK
  438. send(s, "connect ", 8, 0);
  439. send(s, FWhost, strlen(FWhost), 0);
  440. {
  441. char buf[20];
  442. sprintf(buf, " %d\n", FWport);
  443. send (s, buf, strlen(buf), 0);
  444. }
  445. #endif
  446. return NULL;
  447. }
  448. static int ssh_versioncmp(char *a, char *b) {
  449. char *ae, *be;
  450. unsigned long av, bv;
  451. av = strtoul(a, &ae, 10);
  452. bv = strtoul(b, &be, 10);
  453. if (av != bv) return (av < bv ? -1 : +1);
  454. if (*ae == '.') ae++;
  455. if (*be == '.') be++;
  456. av = strtoul(ae, &ae, 10);
  457. bv = strtoul(be, &be, 10);
  458. if (av != bv) return (av < bv ? -1 : +1);
  459. return 0;
  460. }
  461. static int do_ssh_init(void) {
  462. char c, *vsp;
  463. char version[10];
  464. char vstring[80];
  465. char vlog[sizeof(vstring)+20];
  466. int i;
  467. #ifdef FWHACK
  468. i = 0;
  469. while (s_read(&c, 1) == 1) {
  470. if (c == 'S' && i < 2) i++;
  471. else if (c == 'S' && i == 2) i = 2;
  472. else if (c == 'H' && i == 2) break;
  473. else i = 0;
  474. }
  475. #else
  476. if (s_read(&c,1) != 1 || c != 'S') return 0;
  477. if (s_read(&c,1) != 1 || c != 'S') return 0;
  478. if (s_read(&c,1) != 1 || c != 'H') return 0;
  479. #endif
  480. strcpy(vstring, "SSH-");
  481. vsp = vstring+4;
  482. if (s_read(&c,1) != 1 || c != '-') return 0;
  483. i = 0;
  484. while (1) {
  485. if (s_read(&c,1) != 1)
  486. return 0;
  487. if (vsp < vstring+sizeof(vstring)-1)
  488. *vsp++ = c;
  489. if (i >= 0) {
  490. if (c == '-') {
  491. version[i] = '\0';
  492. i = -1;
  493. } else if (i < sizeof(version)-1)
  494. version[i++] = c;
  495. }
  496. else if (c == '\n')
  497. break;
  498. }
  499. *vsp = 0;
  500. sprintf(vlog, "Server version: %s", vstring);
  501. vlog[strcspn(vlog, "\r\n")] = '\0';
  502. logevent(vlog);
  503. sprintf(vstring, "SSH-%s-PuTTY\n",
  504. (ssh_versioncmp(version, "1.5") <= 0 ? version : "1.5"));
  505. sprintf(vlog, "We claim version: %s", vstring);
  506. vlog[strcspn(vlog, "\r\n")] = '\0';
  507. logevent(vlog);
  508. s_write(vstring, strlen(vstring));
  509. return 1;
  510. }
  511. /*
  512. * Handle the key exchange and user authentication phases.
  513. */
  514. static int do_ssh_login(unsigned char *in, int inlen, int ispkt)
  515. {
  516. int i, j, len;
  517. unsigned char session_id[16];
  518. unsigned char *rsabuf, *keystr1, *keystr2;
  519. unsigned char cookie[8];
  520. struct RSAKey servkey, hostkey;
  521. struct MD5Context md5c;
  522. static unsigned long supported_ciphers_mask, supported_auths_mask;
  523. int cipher_type;
  524. extern struct ssh_cipher ssh_3des;
  525. extern struct ssh_cipher ssh_des;
  526. extern struct ssh_cipher ssh_blowfish;
  527. crBegin;
  528. if (!ispkt) crWaitUntil(ispkt);
  529. if (pktin.type != SSH_SMSG_PUBLIC_KEY)
  530. fatalbox("Public key packet not received");
  531. logevent("Received public keys");
  532. memcpy(cookie, pktin.body, 8);
  533. i = makekey(pktin.body+8, &servkey, &keystr1);
  534. j = makekey(pktin.body+8+i, &hostkey, &keystr2);
  535. /*
  536. * Hash the host key and print the hash in the log box. Just as
  537. * a last resort in case the registry's host key checking is
  538. * compromised, we'll allow the user some ability to verify
  539. * host keys by eye.
  540. */
  541. MD5Init(&md5c);
  542. MD5Update(&md5c, keystr2, hostkey.bytes);
  543. MD5Final(session_id, &md5c);
  544. {
  545. char logmsg[80];
  546. int i;
  547. logevent("Host key MD5 is:");
  548. strcpy(logmsg, " ");
  549. for (i = 0; i < 16; i++)
  550. sprintf(logmsg+strlen(logmsg), "%02x", session_id[i]);
  551. logevent(logmsg);
  552. }
  553. supported_ciphers_mask = GET_32BIT(pktin.body+12+i+j);
  554. supported_auths_mask = GET_32BIT(pktin.body+16+i+j);
  555. MD5Init(&md5c);
  556. MD5Update(&md5c, keystr2, hostkey.bytes);
  557. MD5Update(&md5c, keystr1, servkey.bytes);
  558. MD5Update(&md5c, pktin.body, 8);
  559. MD5Final(session_id, &md5c);
  560. for (i=0; i<32; i++)
  561. session_key[i] = random_byte();
  562. len = (hostkey.bytes > servkey.bytes ? hostkey.bytes : servkey.bytes);
  563. rsabuf = malloc(len);
  564. if (!rsabuf)
  565. fatalbox("Out of memory");
  566. /*
  567. * Verify the host key.
  568. */
  569. {
  570. /*
  571. * First format the key into a string.
  572. */
  573. int len = rsastr_len(&hostkey);
  574. char *keystr = malloc(len);
  575. if (!keystr)
  576. fatalbox("Out of memory");
  577. rsastr_fmt(keystr, &hostkey);
  578. verify_ssh_host_key(savedhost, keystr);
  579. free(keystr);
  580. }
  581. for (i=0; i<32; i++) {
  582. rsabuf[i] = session_key[i];
  583. if (i < 16)
  584. rsabuf[i] ^= session_id[i];
  585. }
  586. if (hostkey.bytes > servkey.bytes) {
  587. rsaencrypt(rsabuf, 32, &servkey);
  588. rsaencrypt(rsabuf, servkey.bytes, &hostkey);
  589. } else {
  590. rsaencrypt(rsabuf, 32, &hostkey);
  591. rsaencrypt(rsabuf, hostkey.bytes, &servkey);
  592. }
  593. logevent("Encrypted session key");
  594. cipher_type = cfg.cipher == CIPHER_BLOWFISH ? SSH_CIPHER_BLOWFISH :
  595. cfg.cipher == CIPHER_DES ? SSH_CIPHER_DES :
  596. SSH_CIPHER_3DES;
  597. if ((supported_ciphers_mask & (1 << cipher_type)) == 0) {
  598. c_write("Selected cipher not supported, falling back to 3DES\r\n", 53);
  599. cipher_type = SSH_CIPHER_3DES;
  600. }
  601. switch (cipher_type) {
  602. case SSH_CIPHER_3DES: logevent("Using 3DES encryption"); break;
  603. case SSH_CIPHER_DES: logevent("Using single-DES encryption"); break;
  604. case SSH_CIPHER_BLOWFISH: logevent("Using Blowfish encryption"); break;
  605. }
  606. send_packet(SSH_CMSG_SESSION_KEY,
  607. PKT_CHAR, cipher_type,
  608. PKT_DATA, cookie, 8,
  609. PKT_CHAR, (len*8) >> 8, PKT_CHAR, (len*8) & 0xFF,
  610. PKT_DATA, rsabuf, len,
  611. PKT_INT, 0,
  612. PKT_END);
  613. logevent("Trying to enable encryption...");
  614. free(rsabuf);
  615. cipher = cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish :
  616. cipher_type == SSH_CIPHER_DES ? &ssh_des :
  617. &ssh_3des;
  618. cipher->sesskey(session_key);
  619. crWaitUntil(ispkt);
  620. if (pktin.type != SSH_SMSG_SUCCESS)
  621. fatalbox("Encryption not successfully enabled");
  622. logevent("Successfully started encryption");
  623. fflush(stdout);
  624. {
  625. static char username[100];
  626. static int pos = 0;
  627. static char c;
  628. if (!IS_SCP && !*cfg.username) {
  629. c_write("login as: ", 10);
  630. while (pos >= 0) {
  631. crWaitUntil(!ispkt);
  632. while (inlen--) switch (c = *in++) {
  633. case 10: case 13:
  634. username[pos] = 0;
  635. pos = -1;
  636. break;
  637. case 8: case 127:
  638. if (pos > 0) {
  639. c_write("\b \b", 3);
  640. pos--;
  641. }
  642. break;
  643. case 21: case 27:
  644. while (pos > 0) {
  645. c_write("\b \b", 3);
  646. pos--;
  647. }
  648. break;
  649. case 3: case 4:
  650. random_save_seed();
  651. exit(0);
  652. break;
  653. default:
  654. if (((c >= ' ' && c <= '~') ||
  655. ((unsigned char)c >= 160)) && pos < 40) {
  656. username[pos++] = c;
  657. c_write(&c, 1);
  658. }
  659. break;
  660. }
  661. }
  662. c_write("\r\n", 2);
  663. username[strcspn(username, "\n\r")] = '\0';
  664. } else {
  665. char stuff[200];
  666. strncpy(username, cfg.username, 99);
  667. username[99] = '\0';
  668. if (!IS_SCP) {
  669. sprintf(stuff, "Sent username \"%s\".\r\n", username);
  670. c_write(stuff, strlen(stuff));
  671. }
  672. }
  673. send_packet(SSH_CMSG_USER, PKT_STR, username, PKT_END);
  674. {
  675. char userlog[20+sizeof(username)];
  676. sprintf(userlog, "Sent username \"%s\"", username);
  677. logevent(userlog);
  678. }
  679. }
  680. crWaitUntil(ispkt);
  681. while (pktin.type == SSH_SMSG_FAILURE) {
  682. static char password[100];
  683. static int pos;
  684. static char c;
  685. static int pwpkt_type;
  686. /*
  687. * Show password prompt, having first obtained it via a TIS
  688. * exchange if we're doing TIS authentication.
  689. */
  690. pwpkt_type = SSH_CMSG_AUTH_PASSWORD;
  691. if (IS_SCP) {
  692. char prompt[200];
  693. sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost);
  694. ssh_get_password(prompt, password, sizeof(password));
  695. } else {
  696. if (pktin.type == SSH_SMSG_FAILURE &&
  697. cfg.try_tis_auth &&
  698. (supported_auths_mask & (1<<SSH_AUTH_TIS))) {
  699. pwpkt_type = SSH_CMSG_AUTH_TIS_RESPONSE;
  700. logevent("Requested TIS authentication");
  701. send_packet(SSH_CMSG_AUTH_TIS, PKT_END);
  702. crWaitUntil(ispkt);
  703. if (pktin.type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
  704. logevent("TIS authentication declined");
  705. c_write("TIS authentication refused.\r\n", 29);
  706. } else {
  707. int challengelen = ((pktin.body[0] << 24) |
  708. (pktin.body[1] << 16) |
  709. (pktin.body[2] << 8) |
  710. (pktin.body[3]));
  711. logevent("Received TIS challenge");
  712. c_write(pktin.body+4, challengelen);
  713. }
  714. }
  715. if (pwpkt_type == SSH_CMSG_AUTH_PASSWORD)
  716. c_write("password: ", 10);
  717. pos = 0;
  718. while (pos >= 0) {
  719. crWaitUntil(!ispkt);
  720. while (inlen--) switch (c = *in++) {
  721. case 10: case 13:
  722. password[pos] = 0;
  723. pos = -1;
  724. break;
  725. case 8: case 127:
  726. if (pos > 0)
  727. pos--;
  728. break;
  729. case 21: case 27:
  730. pos = 0;
  731. break;
  732. case 3: case 4:
  733. random_save_seed();
  734. exit(0);
  735. break;
  736. default:
  737. if (((c >= ' ' && c <= '~') ||
  738. ((unsigned char)c >= 160)) && pos < 40)
  739. password[pos++] = c;
  740. break;
  741. }
  742. }
  743. c_write("\r\n", 2);
  744. }
  745. send_packet(pwpkt_type, PKT_STR, password, PKT_END);
  746. logevent("Sent password");
  747. memset(password, 0, strlen(password));
  748. crWaitUntil(ispkt);
  749. if (pktin.type == SSH_SMSG_FAILURE) {
  750. c_write("Access denied\r\n", 15);
  751. logevent("Authentication refused");
  752. } else if (pktin.type == SSH_MSG_DISCONNECT) {
  753. logevent("Received disconnect request");
  754. crReturn(0);
  755. } else if (pktin.type != SSH_SMSG_SUCCESS) {
  756. fatalbox("Strange packet received, type %d", pktin.type);
  757. }
  758. }
  759. logevent("Authentication successful");
  760. if (cfg.ssh_compression &&
  761. ssh_compression_init(COMPRESSION_LEVEL)) {
  762. send_packet(SSH_CMSG_REQUEST_COMPRESSION,
  763. PKT_INT, COMPRESSION_LEVEL, PKT_END);
  764. crWaitUntil(ispkt);
  765. if (pktin.type == SSH_SMSG_SUCCESS) {
  766. use_compression = 1;
  767. logevent("Enabled SSH packet compression");
  768. } else if (pktin.type == SSH_SMSG_FAILURE) {
  769. logevent("Server does not support packet compression");
  770. } else {
  771. fatalbox("Strange packet received, type %d", pktin.type);
  772. }
  773. }
  774. crFinish(1);
  775. }
  776. static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
  777. crBegin;
  778. random_init();
  779. while (!do_ssh_login(in, inlen, ispkt))
  780. crReturnV;
  781. if (!cfg.nopty) {
  782. send_packet(SSH_CMSG_REQUEST_PTY,
  783. PKT_STR, cfg.termtype,
  784. PKT_INT, rows, PKT_INT, cols,
  785. PKT_INT, 0, PKT_INT, 0,
  786. PKT_CHAR, 0,
  787. PKT_END);
  788. ssh_state = SSH_STATE_INTERMED;
  789. do { crReturnV; } while (!ispkt);
  790. if (pktin.type != SSH_SMSG_SUCCESS && pktin.type != SSH_SMSG_FAILURE) {
  791. fatalbox("Protocol confusion");
  792. } else if (pktin.type == SSH_SMSG_FAILURE) {
  793. c_write("Server refused to allocate pty\r\n", 32);
  794. }
  795. logevent("Allocated pty");
  796. }
  797. send_packet(SSH_CMSG_EXEC_SHELL, PKT_END);
  798. logevent("Started session");
  799. ssh_state = SSH_STATE_SESSION;
  800. if (size_needed)
  801. ssh_size();
  802. while (1) {
  803. crReturnV;
  804. if (ispkt) {
  805. if (pktin.type == SSH_SMSG_STDOUT_DATA ||
  806. pktin.type == SSH_SMSG_STDERR_DATA) {
  807. long len = GET_32BIT(pktin.body);
  808. c_write(pktin.body+4, len);
  809. } else if (pktin.type == SSH_MSG_DISCONNECT) {
  810. ssh_state = SSH_STATE_CLOSED;
  811. logevent("Received disconnect request");
  812. } else if (pktin.type == SSH_SMSG_SUCCESS) {
  813. /* may be from EXEC_SHELL on some servers */
  814. } else if (pktin.type == SSH_SMSG_FAILURE) {
  815. /* may be from EXEC_SHELL on some servers
  816. * if no pty is available or in other odd cases. Ignore */
  817. } else if (pktin.type == SSH_SMSG_EXIT_STATUS) {
  818. send_packet(SSH_CMSG_EXIT_CONFIRMATION, PKT_END);
  819. } else {
  820. fatalbox("Strange packet received: type %d", pktin.type);
  821. }
  822. } else {
  823. send_packet(SSH_CMSG_STDIN_DATA,
  824. PKT_INT, inlen, PKT_DATA, in, inlen, PKT_END);
  825. }
  826. }
  827. crFinishV;
  828. }
  829. /*
  830. * Called to set up the connection. Will arrange for WM_NETEVENT
  831. * messages to be passed to the specified window, whose window
  832. * procedure should then call telnet_msg().
  833. *
  834. * Returns an error message, or NULL on success.
  835. */
  836. static char *ssh_init (HWND hwnd, char *host, int port, char **realhost) {
  837. char *p;
  838. #ifdef MSCRYPTOAPI
  839. if(crypto_startup() == 0)
  840. return "Microsoft high encryption pack not installed!";
  841. #endif
  842. p = connect_to_host(host, port, realhost);
  843. if (p != NULL)
  844. return p;
  845. if (!do_ssh_init())
  846. return "Protocol initialisation error";
  847. if (WSAAsyncSelect (s, hwnd, WM_NETEVENT, FD_READ | FD_CLOSE) == SOCKET_ERROR)
  848. switch (WSAGetLastError()) {
  849. case WSAENETDOWN: return "Network is down";
  850. default: return "WSAAsyncSelect(): unknown error";
  851. }
  852. return NULL;
  853. }
  854. /*
  855. * Process a WM_NETEVENT message. Will return 0 if the connection
  856. * has closed, or <0 for a socket error.
  857. */
  858. static int ssh_msg (WPARAM wParam, LPARAM lParam) {
  859. int ret;
  860. char buf[256];
  861. /*
  862. * Because reading less than the whole of the available pending
  863. * data can generate an FD_READ event, we need to allow for the
  864. * possibility that FD_READ may arrive with FD_CLOSE already in
  865. * the queue; so it's possible that we can get here even with s
  866. * invalid. If so, we return 1 and don't worry about it.
  867. */
  868. if (s == INVALID_SOCKET)
  869. return 1;
  870. if (WSAGETSELECTERROR(lParam) != 0)
  871. return -WSAGETSELECTERROR(lParam);
  872. switch (WSAGETSELECTEVENT(lParam)) {
  873. case FD_READ:
  874. case FD_CLOSE:
  875. ret = recv(s, buf, sizeof(buf), 0);
  876. if (ret < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
  877. return 1;
  878. if (ret < 0) /* any _other_ error */
  879. return -10000-WSAGetLastError();
  880. if (ret == 0) {
  881. s = INVALID_SOCKET;
  882. return 0;
  883. }
  884. ssh_gotdata (buf, ret);
  885. return 1;
  886. }
  887. return 1; /* shouldn't happen, but WTF */
  888. }
  889. /*
  890. * Called to send data down the Telnet connection.
  891. */
  892. static void ssh_send (char *buf, int len) {
  893. if (s == INVALID_SOCKET)
  894. return;
  895. ssh_protocol(buf, len, 0);
  896. }
  897. /*
  898. * Called to set the size of the window from Telnet's POV.
  899. */
  900. static void ssh_size(void) {
  901. switch (ssh_state) {
  902. case SSH_STATE_BEFORE_SIZE:
  903. case SSH_STATE_CLOSED:
  904. break; /* do nothing */
  905. case SSH_STATE_INTERMED:
  906. size_needed = TRUE; /* buffer for later */
  907. break;
  908. case SSH_STATE_SESSION:
  909. if (!cfg.nopty) {
  910. send_packet(SSH_CMSG_WINDOW_SIZE,
  911. PKT_INT, rows, PKT_INT, cols,
  912. PKT_INT, 0, PKT_INT, 0, PKT_END);
  913. }
  914. }
  915. }
  916. /*
  917. * (Send Telnet special codes)
  918. */
  919. static void ssh_special (Telnet_Special code) {
  920. /* do nothing */
  921. }
  922. /*
  923. * Read and decrypt one incoming SSH packet.
  924. * (only used by pSCP)
  925. */
  926. static void get_packet(void)
  927. {
  928. unsigned char buf[4096], *p;
  929. long to_read;
  930. int len;
  931. assert(IS_SCP);
  932. p = NULL;
  933. len = 0;
  934. while ((to_read = s_rdpkt(&p, &len)) > 0) {
  935. if (to_read > sizeof(buf)) to_read = sizeof(buf);
  936. len = s_read(buf, to_read);
  937. if (len != to_read) {
  938. closesocket(s);
  939. s = INVALID_SOCKET;
  940. return;
  941. }
  942. p = buf;
  943. }
  944. assert(len == 0);
  945. }
  946. /*
  947. * Receive a block of data over the SSH link. Block until
  948. * all data is available. Return nr of bytes read (0 if lost connection).
  949. * (only used by pSCP)
  950. */
  951. int ssh_scp_recv(unsigned char *buf, int len)
  952. {
  953. static int pending_input_len = 0;
  954. static unsigned char *pending_input_ptr;
  955. int to_read = len;
  956. assert(IS_SCP);
  957. if (pending_input_len >= to_read) {
  958. memcpy(buf, pending_input_ptr, to_read);
  959. pending_input_ptr += to_read;
  960. pending_input_len -= to_read;
  961. return len;
  962. }
  963. if (pending_input_len > 0) {
  964. memcpy(buf, pending_input_ptr, pending_input_len);
  965. buf += pending_input_len;
  966. to_read -= pending_input_len;
  967. pending_input_len = 0;
  968. }
  969. if (s == INVALID_SOCKET)
  970. return 0;
  971. while (to_read > 0) {
  972. get_packet();
  973. if (s == INVALID_SOCKET)
  974. return 0;
  975. if (pktin.type == SSH_SMSG_STDOUT_DATA) {
  976. int plen = GET_32BIT(pktin.body);
  977. if (plen <= to_read) {
  978. memcpy(buf, pktin.body + 4, plen);
  979. buf += plen;
  980. to_read -= plen;
  981. } else {
  982. memcpy(buf, pktin.body + 4, to_read);
  983. pending_input_len = plen - to_read;
  984. pending_input_ptr = pktin.body + 4 + to_read;
  985. to_read = 0;
  986. }
  987. } else if (pktin.type == SSH_SMSG_STDERR_DATA) {
  988. int plen = GET_32BIT(pktin.body);
  989. fwrite(pktin.body + 4, plen, 1, stderr);
  990. } else if (pktin.type == SSH_MSG_DISCONNECT) {
  991. logevent("Received disconnect request");
  992. } else if (pktin.type == SSH_SMSG_SUCCESS ||
  993. pktin.type == SSH_SMSG_FAILURE) {
  994. /* ignore */
  995. } else if (pktin.type == SSH_SMSG_EXIT_STATUS) {
  996. char logbuf[100];
  997. sprintf(logbuf, "Remote exit status: %d", GET_32BIT(pktin.body));
  998. logevent(logbuf);
  999. send_packet(SSH_CMSG_EXIT_CONFIRMATION, PKT_END);
  1000. logevent("Closing connection");
  1001. closesocket(s);
  1002. s = INVALID_SOCKET;
  1003. } else {
  1004. fatalbox("Strange packet received: type %d", pktin.type);
  1005. }
  1006. }
  1007. return len;
  1008. }
  1009. /*
  1010. * Send a block of data over the SSH link.
  1011. * Block until all data is sent.
  1012. * (only used by pSCP)
  1013. */
  1014. void ssh_scp_send(unsigned char *buf, int len)
  1015. {
  1016. assert(IS_SCP);
  1017. if (s == INVALID_SOCKET)
  1018. return;
  1019. send_packet(SSH_CMSG_STDIN_DATA,
  1020. PKT_INT, len, PKT_DATA, buf, len, PKT_END);
  1021. }
  1022. /*
  1023. * Send an EOF notification to the server.
  1024. * (only used by pSCP)
  1025. */
  1026. void ssh_scp_send_eof(void)
  1027. {
  1028. assert(IS_SCP);
  1029. if (s == INVALID_SOCKET)
  1030. return;
  1031. send_packet(SSH_CMSG_EOF, PKT_END);
  1032. }
  1033. /*
  1034. * Set up the connection, login on the remote host and
  1035. * start execution of a command.
  1036. * Returns an error message, or NULL on success.
  1037. * (only used by pSCP)
  1038. */
  1039. char *ssh_scp_init(char *host, int port, char *cmd, char **realhost)
  1040. {
  1041. char buf[160], *p;
  1042. assert(IS_SCP);
  1043. #ifdef MSCRYPTOAPI
  1044. if (crypto_startup() == 0)
  1045. return "Microsoft high encryption pack not installed!";
  1046. #endif
  1047. p = connect_to_host(host, port, realhost);
  1048. if (p != NULL)
  1049. return p;
  1050. random_init();
  1051. if (!do_ssh_init())
  1052. return "Protocol initialisation error";
  1053. /* Exchange keys and login */
  1054. do {
  1055. get_packet();
  1056. if (s == INVALID_SOCKET)
  1057. return "Connection closed by remote host";
  1058. } while (!do_ssh_login(NULL, 0, 1));
  1059. /* Execute command */
  1060. sprintf(buf, "Sending command: %.100s", cmd);
  1061. logevent(buf);
  1062. send_packet(SSH_CMSG_EXEC_CMD, PKT_STR, cmd, PKT_END);
  1063. return NULL;
  1064. }
  1065. Backend ssh_backend = {
  1066. ssh_init,
  1067. ssh_msg,
  1068. ssh_send,
  1069. ssh_size,
  1070. ssh_special
  1071. };