Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4373 - (show annotations) (download) (as text)
Tue Mar 8 00:22:12 2011 UTC (13 years, 1 month ago) by maya
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 236470 byte(s)
圧縮レベル 0 のときには KEX proposal で none だけを渡すようにした
  クライアントの proposal が優先されるので問題ないはずだが、define が変わってしまったときの念のため
1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 Copyright (c) 2004-2005, Yutaka Hirata
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
8
9 Redistributions of source code must retain the above copyright notice, this list of
10 conditions and the following disclaimer.
11
12 Redistributions in binary form must reproduce the above copyright notice, this list
13 of conditions and the following disclaimer in the documentation and/or other materials
14 provided with the distribution.
15
16 The name of Robert O'Callahan may not be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "ttxssh.h"
31 #include "util.h"
32 #include "resource.h"
33 #include "libputty.h"
34 #include "key.h"
35
36 #include <openssl/bn.h>
37 #include <openssl/evp.h>
38 #include <openssl/dh.h>
39 #include <openssl/engine.h>
40 #include <openssl/rsa.h>
41 #include <openssl/dsa.h>
42 #include <openssl/md5.h>
43 #include <limits.h>
44 #include <malloc.h>
45 #include <string.h>
46 #include <stdlib.h>
47 #include <process.h>
48 #include <time.h>
49 #include "buffer.h"
50 #include "ssh.h"
51 #include "crypt.h"
52 #include "fwd.h"
53 #include "sftp.h"
54 #include "kex.h"
55
56 #include <sys/types.h>
57 #include <sys/stat.h>
58 #include <assert.h>
59
60 #include <direct.h>
61 #include <io.h>
62
63 // SSH2 macro
64 #ifdef _DEBUG
65 #define SSH2_DEBUG
66 #endif
67
68 //#define DONT_WANTCONFIRM 1 // (2005.3.28 yutaka)
69 #undef DONT_WANTCONFIRM // (2008.11.25 maya)
70
71 //
72 // SSH2 data structure
73 //
74
75 // channel data structure
76 #define CHANNEL_MAX 100
77
78 enum scp_state {
79 SCP_INIT, SCP_TIMESTAMP, SCP_FILEINFO, SCP_DATA, SCP_CLOSING,
80 };
81
82 typedef struct bufchain {
83 buffer_t *msg;
84 struct bufchain *next;
85 } bufchain_t;
86
87 typedef struct scp {
88 enum scp_dir dir; // transfer direction
89 enum scp_state state; // SCP state
90 char localfile[MAX_PATH]; // local filename
91 char localfilefull[MAX_PATH]; // local filename fullpath
92 char remotefile[MAX_PATH]; // remote filename
93 FILE *localfp; // file pointer for local file
94 struct __stat64 filestat; // file status information
95 HWND progress_window;
96 HANDLE thread;
97 unsigned int thread_id;
98 PTInstVar pvar;
99 // for receiving file
100 long long filetotalsize;
101 long long filercvsize;
102 } scp_t;
103
104 typedef struct channel {
105 int used;
106 int self_id;
107 int remote_id;
108 unsigned int local_window;
109 unsigned int local_window_max;
110 unsigned int local_consumed;
111 unsigned int local_maxpacket;
112 unsigned int remote_window;
113 unsigned int remote_maxpacket;
114 enum channel_type type;
115 int local_num;
116 bufchain_t *bufchain;
117 scp_t scp;
118 buffer_t *agent_msg;
119 int agent_request_len;
120 } Channel_t;
121
122 static Channel_t channels[CHANNEL_MAX];
123
124 static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
125
126 static void try_send_credentials(PTInstVar pvar);
127 static void prep_compression(PTInstVar pvar);
128
129 // �����v���g�^�C�v����
130 void SSH2_send_kexinit(PTInstVar pvar);
131 static BOOL handle_SSH2_kexinit(PTInstVar pvar);
132 static void SSH2_dh_kex_init(PTInstVar pvar);
133 static void SSH2_dh_gex_kex_init(PTInstVar pvar);
134 static void SSH2_ecdh_kex_init(PTInstVar pvar);
135 static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
136 static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
137 static BOOL handle_SSH2_newkeys(PTInstVar pvar);
138 static BOOL handle_SSH2_service_accept(PTInstVar pvar);
139 static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
140 static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
141 static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
142 static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
143 static BOOL handle_SSH2_open_failure(PTInstVar pvar);
144 static BOOL handle_SSH2_request_success(PTInstVar pvar);
145 static BOOL handle_SSH2_request_failure(PTInstVar pvar);
146 static BOOL handle_SSH2_channel_success(PTInstVar pvar);
147 static BOOL handle_SSH2_channel_failure(PTInstVar pvar);
148 static BOOL handle_SSH2_channel_data(PTInstVar pvar);
149 static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
150 static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
151 static BOOL handle_SSH2_channel_close(PTInstVar pvar);
152 static BOOL handle_SSH2_channel_open(PTInstVar pvar);
153 static BOOL handle_SSH2_window_adjust(PTInstVar pvar);
154 static BOOL handle_SSH2_channel_request(PTInstVar pvar);
155 void SSH2_dispatch_init(int stage);
156 int SSH2_dispatch_enabled_check(unsigned char message);
157 void SSH2_dispatch_add_message(unsigned char message);
158 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);
159 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
160 static void start_ssh_heartbeat_thread(PTInstVar pvar);
161 static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen);
162 void ssh2_channel_send_close(PTInstVar pvar, Channel_t *c);
163 static BOOL SSH_agent_response(PTInstVar pvar, Channel_t *c, int local_channel_num, unsigned char *data, unsigned int buflen);
164
165 //
166 // channel function
167 //
168 static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack,
169 enum confirm_type type, int local_num)
170 {
171 int i, found;
172 Channel_t *c;
173
174 found = -1;
175 for (i = 0 ; i < CHANNEL_MAX ; i++) {
176 if (channels[i].used == 0) { // free channel
177 found = i;
178 break;
179 }
180 }
181 if (found == -1) { // not free channel
182 return (NULL);
183 }
184
185 // setup
186 c = &channels[found];
187 memset(c, 0, sizeof(Channel_t));
188 c->used = 1;
189 c->self_id = i;
190 c->remote_id = -1;
191 c->local_window = window;
192 c->local_window_max = window;
193 c->local_consumed = 0;
194 c->local_maxpacket = maxpack;
195 c->remote_window = 0;
196 c->remote_maxpacket = 0;
197 c->type = type;
198 c->local_num = local_num; // alloc_channel()�����l��������������
199 c->bufchain = NULL;
200 if (type == TYPE_SCP) {
201 c->scp.state = SCP_INIT;
202 c->scp.progress_window = NULL;
203 c->scp.thread = (HANDLE)-1;
204 c->scp.localfp = NULL;
205 }
206 if (type == TYPE_AGENT) {
207 c->agent_msg = buffer_init();
208 c->agent_request_len = 0;
209 }
210
211 return (c);
212 }
213
214 // remote_window�������������������A�������������o�b�t�@�����X�g�i�������j���������������B
215 static void ssh2_channel_add_bufchain(Channel_t *c, unsigned char *buf, unsigned int buflen)
216 {
217 bufchain_t *p, *old;
218
219 // allocate new buffer
220 p = malloc(sizeof(bufchain_t));
221 if (p == NULL)
222 return;
223 p->msg = buffer_init();
224 if (p == NULL) {
225 free(p);
226 return;
227 }
228 buffer_put_raw(p->msg, buf, buflen);
229 p->next = NULL;
230
231 if (c->bufchain == NULL) {
232 c->bufchain = p;
233 } else {
234 old = c->bufchain;
235 while (old->next)
236 old = old->next;
237 old->next = p;
238 }
239 }
240
241
242 static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c)
243 {
244 bufchain_t *ch;
245 unsigned int size;
246
247 while (c->bufchain) {
248 // ����������������
249 ch = c->bufchain;
250 size = buffer_len(ch->msg);
251 if (size >= c->remote_window)
252 break;
253
254 if (c->local_num == -1) { // shell or SCP
255 SSH2_send_channel_data(pvar, c, buffer_ptr(ch->msg), size);
256 } else { // port-forwarding
257 SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size);
258 }
259
260 c->bufchain = ch->next;
261
262 buffer_free(ch->msg);
263 free(ch);
264 }
265 }
266
267
268
269 // channel close�����`���l���\���������X�g�����p����
270 // (2007.4.26 yutaka)
271 static void ssh2_channel_delete(Channel_t *c)
272 {
273 bufchain_t *ch, *ptr;
274
275 ch = c->bufchain;
276 while (ch) {
277 if (ch->msg)
278 buffer_free(ch->msg);
279 ptr = ch;
280 ch = ch->next;
281 free(ptr);
282 }
283
284 if (c->type == TYPE_SCP) {
285 c->scp.state = SCP_CLOSING;
286 if (c->scp.localfp != NULL)
287 fclose(c->scp.localfp);
288 if (c->scp.progress_window != NULL) {
289 DestroyWindow(c->scp.progress_window);
290 c->scp.progress_window = NULL;
291 }
292 if (c->scp.thread != (HANDLE)-1L) {
293 WaitForSingleObject(c->scp.thread, INFINITE);
294 CloseHandle(c->scp.thread);
295 c->scp.thread = (HANDLE)-1L;
296 }
297 }
298 if (c->type == TYPE_AGENT) {
299 buffer_free(c->agent_msg);
300 }
301
302 memset(c, 0, sizeof(Channel_t));
303 c->used = 0;
304 }
305
306
307 // connection close������������
308 void ssh2_channel_free(void)
309 {
310 int i;
311 Channel_t *c;
312
313 for (i = 0 ; i < CHANNEL_MAX ; i++) {
314 c = &channels[i];
315 ssh2_channel_delete(c);
316 }
317
318 }
319
320 static Channel_t *ssh2_channel_lookup(int id)
321 {
322 Channel_t *c;
323
324 if (id < 0 || id >= CHANNEL_MAX) {
325 return (NULL);
326 }
327 c = &channels[id];
328 if (c->used == 0) { // already freed
329 return (NULL);
330 }
331 return (c);
332 }
333
334 // SSH1��������������channel�\���������ASSH2������Channel_t�����������B
335 // TODO: �����I�����`���l���\������1�������������B
336 // (2005.6.12 yutaka)
337 static Channel_t *ssh2_local_channel_lookup(int local_num)
338 {
339 int i;
340 Channel_t *c;
341
342 for (i = 0 ; i < CHANNEL_MAX ; i++) {
343 c = &channels[i];
344 if (c->local_num == local_num)
345 return (c);
346 }
347 return (NULL);
348 }
349
350
351 //
352 // SSH heartbeat mutex
353 //
354 // TTSSH�� thread-safe �������������A�}���`�X���b�h�������p�P�b�g���M�����������B
355 // �V���O���X���b�h�����R���e�L�X�g�X�C�b�`�������������������������A
356 // ���b�N�������K�v�����������A���������B(2007.12.26 yutaka)
357 //
358 static CRITICAL_SECTION g_ssh_heartbeat_lock; /* �����M�p���b�N */
359
360 void ssh_heartbeat_lock_initialize(void)
361 {
362 //InitializeCriticalSection(&g_ssh_heartbeat_lock);
363 }
364
365 void ssh_heartbeat_lock_finalize(void)
366 {
367 //DeleteCriticalSection(&g_ssh_heartbeat_lock);
368 }
369
370 void ssh_heartbeat_lock(void)
371 {
372 //EnterCriticalSection(&g_ssh_heartbeat_lock);
373 }
374
375 void ssh_heartbeat_unlock(void)
376 {
377 //LeaveCriticalSection(&g_ssh_heartbeat_lock);
378 }
379
380
381 //
382 // SSH memory dump (for debug)
383 //
384 // (2005.3.7 yutaka)
385 //
386 #define MEMTAG_MAX 300
387 #define LOGDUMP "ssh2connect.log"
388 #define LOG_PACKET_DUMP "ssh2packet.log"
389 #define SENDTOME "Please send '"LOGDUMP"' file to Tera Term developer team."
390
391 typedef struct memtag {
392 char *name;
393 char *desc;
394 time_t time;
395 int len;
396 char *data;
397 } memtag_t;
398
399 static memtag_t memtags[MEMTAG_MAX];
400 static int memtag_count = 0;
401 static int memtag_use = 0;
402
403 /* �_���v���C�����t�H�[�}�b�g�\������ */
404 static void displine_memdump(FILE *fp, int addr, int *bytes, int byte_cnt)
405 {
406 int i, c;
407
408 /* �������A�h���X�\�� */
409 fprintf(fp, "%08X : ", addr);
410
411 /* �o�C�i���\���i4�o�C�g�������������}���j*/
412 for (i = 0 ; i < byte_cnt ; i++) {
413 if (i > 0 && i % 4 == 0)
414 fprintf(fp, " ");
415
416 fprintf(fp, "%02X", bytes[i]);
417 }
418
419 /* ASCII�\���������������������� */
420 fprintf(fp, " %*s%*s", (16-byte_cnt)*2+1, " ", (16-byte_cnt+3)/4, " ");
421
422 /* ASCII�\�� */
423 for (i = 0 ; i < byte_cnt ; i++) {
424 c = bytes[i];
425 if (isprint(c)) {
426 fprintf(fp, "%c", c);
427 } else {
428 fprintf(fp, ".");
429 }
430 }
431
432 fprintf(fp, "\n");
433 }
434
435
436 /* �_���v���[�`�� */
437 static void dump_memdump(FILE *fp, char *data, int len)
438 {
439 int c, addr;
440 int bytes[16], *ptr;
441 int byte_cnt;
442 int i;
443
444 addr = 0;
445 byte_cnt = 0;
446 ptr = bytes;
447 for (i = 0 ; i < len ; i++) {
448 c = data[i];
449 *ptr++ = c & 0xff;
450 byte_cnt++;
451
452 if (byte_cnt == 16) {
453 displine_memdump(fp, addr, bytes, byte_cnt);
454
455 addr += 16;
456 byte_cnt = 0;
457 ptr = bytes;
458 }
459 }
460
461 if (byte_cnt > 0) {
462 displine_memdump(fp, addr, bytes, byte_cnt);
463 }
464 }
465
466 void init_memdump(void)
467 {
468 int i;
469
470 if (memtag_use > 0)
471 return;
472
473 for (i = 0 ; i < MEMTAG_MAX ; i++) {
474 memtags[i].name = NULL;
475 memtags[i].desc = NULL;
476 memtags[i].data = NULL;
477 memtags[i].len = 0;
478 }
479 memtag_use++;
480 }
481
482 void finish_memdump(void)
483 {
484 int i;
485
486 // initialize�������������������������������B(2005.4.3 yutaka)
487 if (memtag_use <= 0)
488 return;
489 memtag_use--;
490
491 for (i = 0 ; i < MEMTAG_MAX ; i++) {
492 free(memtags[i].name);
493 free(memtags[i].desc);
494 free(memtags[i].data);
495 memtags[i].len = 0;
496 }
497 memtag_count = 0;
498 }
499
500 void save_memdump(char *filename)
501 {
502 FILE *fp;
503 int i;
504 time_t t;
505 struct tm *tm;
506
507 fp = fopen(filename, "w");
508 if (fp == NULL)
509 return;
510
511 t = time(NULL);
512 tm = localtime(&t);
513
514 fprintf(fp, "<<< Tera Term SSH2 log dump >>>\n");
515 fprintf(fp, "saved time: %04d/%02d/%02d %02d:%02d:%02d\n",
516 tm->tm_year + 1900,
517 tm->tm_mon + 1,
518 tm->tm_mday,
519 tm->tm_hour,
520 tm->tm_min,
521 tm->tm_sec);
522 fprintf(fp, "\n");
523
524 for (i = 0 ; i < memtag_count ; i++) {
525 fprintf(fp, "============================================\n");
526 fprintf(fp, "name: %s\n", memtags[i].name);
527 fprintf(fp, "--------------------------------------------\n");
528 fprintf(fp, "description: %s\n", memtags[i].desc);
529 fprintf(fp, "--------------------------------------------\n");
530 fprintf(fp, "time: %s", ctime(&memtags[i].time));
531 fprintf(fp, "============================================\n");
532 dump_memdump(fp, memtags[i].data, memtags[i].len);
533 fprintf(fp, "\n\n\n");
534 }
535
536 fprintf(fp, "[EOF]\n");
537
538 fclose(fp);
539 }
540
541 void push_memdump(char *name, char *desc, char *data, int len)
542 {
543 memtag_t *ptr;
544 char *dp;
545
546 dp = malloc(len);
547 if (dp == NULL)
548 return;
549 memcpy(dp, data, len);
550
551 if (memtag_count >= MEMTAG_MAX)
552 return;
553
554 ptr = &memtags[memtag_count];
555 memtag_count++;
556 ptr->name = _strdup(name);
557 ptr->desc = _strdup(desc);
558 ptr->time = time(NULL);
559 ptr->data = dp;
560 ptr->len = len;
561 }
562
563 void push_bignum_memdump(char *name, char *desc, BIGNUM *bignum)
564 {
565 int len;
566 char *buf;
567
568 len = BN_num_bytes(bignum);
569 buf = malloc(len); // allocate
570 if (buf == NULL)
571 return;
572 BN_bn2bin(bignum, buf);
573 push_memdump(name, desc, buf, len); // at push_bignum_memdump()
574 free(buf); // free
575 }
576
577
578 //
579 //
580 //
581
582
583 static int get_predecryption_amount(PTInstVar pvar)
584 {
585 static int small_block_decryption_sizes[] = { 5, 5, 6, 6, 8 };
586
587 if (SSHv1(pvar)) {
588 return 0;
589 } else {
590 int block_size = CRYPT_get_decryption_block_size(pvar);
591
592 if (block_size < 5) {
593 return small_block_decryption_sizes[block_size];
594 } else {
595 return block_size;
596 }
597 }
598 }
599
600 /* Get up to 'limit' bytes into the payload buffer.
601 'limit' is counted from the start of the payload data.
602 Returns the amount of data in the payload buffer, or
603 -1 if there is an error.
604 We can return more than limit in some cases. */
605 static int buffer_packet_data(PTInstVar pvar, int limit)
606 {
607 if (pvar->ssh_state.payloadlen >= 0) {
608 return pvar->ssh_state.payloadlen;
609 } else {
610 int cur_decompressed_bytes =
611 pvar->ssh_state.decompress_stream.next_out -
612 pvar->ssh_state.postdecompress_inbuf;
613
614 while (limit > cur_decompressed_bytes) {
615 int result;
616
617 pvar->ssh_state.payload =
618 pvar->ssh_state.postdecompress_inbuf + 1;
619 if (pvar->ssh_state.postdecompress_inbuflen == cur_decompressed_bytes) {
620 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
621 &pvar->ssh_state.postdecompress_inbuflen,
622 min(limit, cur_decompressed_bytes * 2));
623 }
624
625 pvar->ssh_state.decompress_stream.next_out =
626 pvar->ssh_state.postdecompress_inbuf +
627 cur_decompressed_bytes;
628 pvar->ssh_state.decompress_stream.avail_out =
629 min(limit, pvar->ssh_state.postdecompress_inbuflen)
630 - cur_decompressed_bytes;
631
632 result =
633 inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH);
634 cur_decompressed_bytes =
635 pvar->ssh_state.decompress_stream.next_out -
636 pvar->ssh_state.postdecompress_inbuf;
637
638 switch (result) {
639 case Z_OK:
640 break;
641 case Z_BUF_ERROR:
642 pvar->ssh_state.payloadlen = cur_decompressed_bytes;
643 return cur_decompressed_bytes;
644 default:
645 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
646 "Invalid compressed data in received packet");
647 notify_fatal_error(pvar, pvar->ts->UIMsg);
648 return -1;
649 }
650 }
651
652 return cur_decompressed_bytes;
653 }
654 }
655
656 /* For use by the protocol processing code.
657 Gets N bytes of uncompressed payload. Returns FALSE if data not available
658 and a fatal error has been signaled.
659 The data is available in the payload buffer. This buffer address
660 can change during a call to grab_payload, so take care!
661 The payload pointer is set to point to the first byte of the actual data
662 (after the packet type byte).
663 */
664 static BOOL grab_payload(PTInstVar pvar, int num_bytes)
665 {
666 /* Accept maximum of 4MB of payload data */
667 int in_buffer = buffer_packet_data(pvar, PACKET_MAX_SIZE);
668
669 if (in_buffer < 0) {
670 return FALSE;
671 } else {
672 pvar->ssh_state.payload_grabbed += num_bytes;
673 if (pvar->ssh_state.payload_grabbed > in_buffer) {
674 char buf[128];
675 UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_ERROR", pvar,
676 "Received truncated packet (%ld > %d) @ grab_payload()");
677 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
678 pvar->ssh_state.payload_grabbed, in_buffer);
679 notify_fatal_error(pvar, buf);
680 return FALSE;
681 } else {
682 return TRUE;
683 }
684 }
685 }
686
687 static BOOL grab_payload_limited(PTInstVar pvar, int num_bytes)
688 {
689 int in_buffer;
690
691 pvar->ssh_state.payload_grabbed += num_bytes;
692 in_buffer = buffer_packet_data(pvar, pvar->ssh_state.payload_grabbed);
693
694 if (in_buffer < 0) {
695 return FALSE;
696 } else {
697 if (pvar->ssh_state.payload_grabbed > in_buffer) {
698 char buf[128];
699 UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_LIM_ERROR", pvar,
700 "Received truncated packet (%ld > %d) @ grab_payload_limited()");
701 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
702 pvar->ssh_state.payload_grabbed, in_buffer);
703 notify_fatal_error(pvar, buf);
704 return FALSE;
705 } else {
706 return TRUE;
707 }
708 }
709 }
710
711 #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))
712 #define get_uint32(buf) get_uint32_MSBfirst((buf))
713 #define set_uint32(buf, v) set_uint32_MSBfirst((buf), (v))
714 #define get_mpint_len(pvar, offset) ((get_ushort16_MSBfirst((pvar)->ssh_state.payload + (offset)) + 7) >> 3)
715 #define get_ushort16(buf) get_ushort16_MSBfirst((buf))
716
717 #define do_crc(buf, len) (~(uint32)crc32(0xFFFFFFFF, (buf), (len)))
718
719 /* Decrypt the payload, checksum it, eat the padding, get the packet type
720 and return it.
721 'data' points to the start of the packet --- its length field.
722 'len' is the length of the
723 payload + padding (+ length of CRC for SSHv1). 'padding' is the length
724 of the padding alone. */
725 static int prep_packet(PTInstVar pvar, char FAR * data, int len,
726 int padding)
727 {
728 pvar->ssh_state.payload = data + 4;
729 pvar->ssh_state.payloadlen = len;
730
731 if (SSHv1(pvar)) {
732 if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
733 UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar,
734 "'CORE insertion attack' detected. Aborting connection.");
735 notify_fatal_error(pvar, pvar->ts->UIMsg);
736 }
737
738 CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
739 /* PKT guarantees that the data is always 4-byte aligned */
740 if (do_crc(pvar->ssh_state.payload, len - 4) !=
741 get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
742 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
743 "Detected corrupted data; connection terminating.");
744 notify_fatal_error(pvar, pvar->ts->UIMsg);
745 return SSH_MSG_NONE;
746 }
747
748 pvar->ssh_state.payload += padding;
749 pvar->ssh_state.payloadlen -= padding + 4;
750 } else {
751 int already_decrypted = get_predecryption_amount(pvar);
752
753 #if 0
754 CRYPT_decrypt(pvar, data + already_decrypted,
755 len - already_decrypted);
756 #else
757 CRYPT_decrypt(pvar, data + already_decrypted,
758 (4 + len) - already_decrypted);
759 #endif
760
761 if (!CRYPT_verify_receiver_MAC
762 (pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4,
763 data + len + 4)) {
764 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
765 "Detected corrupted data; connection terminating.");
766 notify_fatal_error(pvar, pvar->ts->UIMsg);
767 return SSH_MSG_NONE;
768 }
769
770 pvar->ssh_state.payload++;
771 pvar->ssh_state.payloadlen -= padding + 1;
772 }
773
774 pvar->ssh_state.payload_grabbed = 0;
775
776 if (SSHv1(pvar)) {
777 if (pvar->ssh_state.decompressing) {
778 if (pvar->ssh_state.decompress_stream.avail_in != 0) {
779 UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
780 "Internal error: a packet was not fully decompressed.\n"
781 "This is a bug, please report it.");
782 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
783 }
784
785 pvar->ssh_state.decompress_stream.next_in =
786 pvar->ssh_state.payload;
787 pvar->ssh_state.decompress_stream.avail_in =
788 pvar->ssh_state.payloadlen;
789 pvar->ssh_state.decompress_stream.next_out =
790 pvar->ssh_state.postdecompress_inbuf;
791 pvar->ssh_state.payloadlen = -1;
792 } else {
793 pvar->ssh_state.payload++;
794 }
795
796 if (!grab_payload_limited(pvar, 1)) {
797 return SSH_MSG_NONE;
798 }
799
800 } else {
801 // support of SSH2 packet compression (2005.7.9 yutaka)
802 // support of "Compression delayed" (2006.6.23 maya)
803 if ((pvar->stoc_compression == COMP_ZLIB ||
804 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&
805 pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
806 int ret;
807
808 if (pvar->decomp_buffer == NULL) {
809 pvar->decomp_buffer = buffer_init();
810 if (pvar->decomp_buffer == NULL)
811 return SSH_MSG_NONE;
812 }
813 // ���x�m�������o�b�t�@���g�������������������Y�������B
814 buffer_clear(pvar->decomp_buffer);
815
816 // packet size��padding�������������y�C���[�h�����������W�J�����B
817 ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
818 pvar->ssh_state.payload,
819 pvar->ssh_state.payloadlen,
820 pvar->decomp_buffer);
821
822 // �|�C���^���X�V�B
823 pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
824 pvar->ssh_state.payload++;
825 pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
826
827 } else {
828 pvar->ssh_state.payload++;
829 }
830
831 if (!grab_payload_limited(pvar, 1)) {
832 return SSH_MSG_NONE;
833 }
834
835 }
836
837 pvar->ssh_state.receiver_sequence_number++;
838
839 return pvar->ssh_state.payload[-1];
840 }
841
842 /* Create a packet to be sent. The SSH protocol packet type is in 'type';
843 'len' contains the length of the packet payload, in bytes (this
844 does not include the space for any of the packet headers or padding,
845 or for the packet type byte).
846 Returns a pointer to the payload data area, a region of length 'len',
847 to be filled by the caller. */
848 static unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len)
849 {
850 unsigned char FAR *buf;
851
852 pvar->ssh_state.outgoing_packet_len = len + 1;
853
854 if (pvar->ssh_state.compressing) {
855 buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
856 &pvar->ssh_state.precompress_outbuflen, 1 + len);
857 buf = pvar->ssh_state.precompress_outbuf;
858 } else {
859 /* For SSHv2,
860 Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
861 + len(payload) + 4(minpadding), rounded up to nearest block_size
862 We only need a reasonable upper bound for the buffer size */
863 buf_ensure_size(&pvar->ssh_state.outbuf,
864 &pvar->ssh_state.outbuflen,
865 len + 30 + CRYPT_get_sender_MAC_size(pvar) +
866 CRYPT_get_encryption_block_size(pvar));
867 buf = pvar->ssh_state.outbuf + 12;
868 }
869
870 buf[0] = (unsigned char) type;
871 return buf + 1;
872 }
873
874 #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0)
875
876 // ���M���g���C����������
877 //
878 // WinSock�� send() ���o�b�t�@�T�C�Y(len)�������������l��������������������
879 // ���������������A�����������G���[���������B
880 // �����������ATCP�R�l�N�V�������f�������o���h���B
881 // (2006.12.9 yutaka)
882 static int retry_send_packet(PTInstVar pvar, char FAR * data, int len)
883 {
884 int n;
885 int err;
886
887 while (len > 0) {
888 n = (pvar->Psend)(pvar->socket, data, len, 0);
889
890 if (n < 0) {
891 err = WSAGetLastError();
892 if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
893 // send()�����l��0�������A�����G���[������ 10000 �������������A
894 // ���������������������B
895 // PuTTY 0.58���������Q�l�B
896 // (2007.2.4 yutak)
897 return 0; // success
898 }
899 return 1; // error
900 }
901
902 len -= n;
903 data += n;
904 }
905
906 return 0; // success
907 }
908
909 static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
910 {
911 // �p�P�b�g���M�����o�b�t�@���g�������������A�u���b�L���O�����M�����������K�v�������B
912 // �m���u���b�L���O�����M����WSAEWOULDBLOCK�����������������A�����o�b�t�@�����M��������
913 // ���������������������������������B(2007.10.30 yutaka)
914 u_long do_block = 0;
915 int code = 0;
916 char *kind = NULL, buf[256];
917
918 #if 0
919 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
920 0, 0) == SOCKET_ERROR
921 || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR
922 || retry_send_packet(pvar, data, len)
923 || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
924 pvar->notification_msg,
925 pvar->notification_events) ==
926 SOCKET_ERROR) {
927 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
928 "A communications error occurred while sending an SSH packet.\n"
929 "The connection will close.");
930 notify_fatal_error(pvar, pvar->ts->UIMsg);
931 return FALSE;
932 } else {
933 return TRUE;
934 }
935 #else
936 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
937 0, 0) == SOCKET_ERROR) {
938 code = WSAGetLastError();
939 kind = "WSAAsyncSelect1";
940 goto error;
941 }
942 if (ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR) {
943 code = WSAGetLastError();
944 kind = "ioctlsocket";
945 goto error;
946 }
947 if (retry_send_packet(pvar, data, len) != 0) {
948 code = WSAGetLastError();
949 kind = "retry_send_packet";
950 goto error;
951 }
952 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
953 pvar->notification_msg,
954 pvar->notification_events) ==
955 SOCKET_ERROR) {
956 code = WSAGetLastError();
957 kind = "WSAAsyncSelect2";
958 goto error;
959 }
960 return TRUE;
961
962 error:
963 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
964 "A communications error occurred while sending an SSH packet.\n"
965 "The connection will close. (%s:%d)");
966 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
967 kind, code);
968 notify_fatal_error(pvar, buf);
969 return FALSE;
970 #endif
971 }
972
973 /* if skip_compress is true, then the data has already been compressed
974 into outbuf + 12 */
975 static void finish_send_packet_special(PTInstVar pvar, int skip_compress)
976 {
977 unsigned int len = pvar->ssh_state.outgoing_packet_len;
978 unsigned char FAR *data;
979 unsigned int data_length;
980 buffer_t *msg = NULL; // for SSH2 packet compression
981
982 if (pvar->ssh_state.compressing) {
983 if (!skip_compress) {
984 buf_ensure_size(&pvar->ssh_state.outbuf,
985 &pvar->ssh_state.outbuflen,
986 (int)(len + (len >> 6) + 50 +
987 CRYPT_get_sender_MAC_size(pvar)));
988 pvar->ssh_state.compress_stream.next_in =
989 pvar->ssh_state.precompress_outbuf;
990 pvar->ssh_state.compress_stream.avail_in = len;
991 pvar->ssh_state.compress_stream.next_out =
992 pvar->ssh_state.outbuf + 12;
993 pvar->ssh_state.compress_stream.avail_out =
994 pvar->ssh_state.outbuflen - 12;
995
996 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
997 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
998 "An error occurred while compressing packet data.\n"
999 "The connection will close.");
1000 notify_fatal_error(pvar, pvar->ts->UIMsg);
1001 return;
1002 }
1003 }
1004
1005 len =
1006 pvar->ssh_state.outbuflen - 12 -
1007 pvar->ssh_state.compress_stream.avail_out;
1008 }
1009
1010 if (SSHv1(pvar)) {
1011 int padding = 8 - ((len + 4) % 8);
1012
1013 data = pvar->ssh_state.outbuf + 8 - padding;
1014 data_length = padding + len + 8;
1015
1016 set_uint32(data, len + 4);
1017 if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
1018 CRYPT_set_random_data(pvar, data + 4, padding);
1019 } else {
1020 memset(data + 4, 0, padding);
1021 }
1022 set_uint32(data + data_length - 4,
1023 do_crc(data + 4, data_length - 8));
1024 CRYPT_encrypt(pvar, data + 4, data_length - 4);
1025 } else { //for SSH2(yutaka)
1026 int block_size = CRYPT_get_encryption_block_size(pvar);
1027 unsigned int encryption_size;
1028 unsigned int padding;
1029 BOOL ret;
1030
1031 /*
1032 �f�[�^�\��
1033 pvar->ssh_state.outbuf:
1034 offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
1035 <--ignore---> ^^^^^^^^ <---- payload --->
1036 packet length
1037
1038 ^^padding
1039
1040 <---------------------------->
1041 SSH2 sending data on TCP
1042
1043 NOTE:
1044 payload = type(1) + raw-data
1045 len = ssh_state.outgoing_packet_len = payload size
1046 */
1047 // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
1048 // support of "Compression delayed" (2006.6.23 maya)
1049 if ((pvar->ctos_compression == COMP_ZLIB ||
1050 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
1051 pvar->ssh2_keys[MODE_OUT].comp.enabled) {
1052 // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
1053 msg = buffer_init();
1054 if (msg == NULL) {
1055 // TODO: error check
1056 return;
1057 }
1058
1059 // ���k�������w�b�_�������y�C���[�h�����B
1060 buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
1061 if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
1062 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1063 "An error occurred while compressing packet data.\n"
1064 "The connection will close.");
1065 notify_fatal_error(pvar, pvar->ts->UIMsg);
1066 return;
1067 }
1068 data = buffer_ptr(msg);
1069 len = buffer_len(msg) - 5; // 'len' is overwritten.
1070
1071 } else {
1072 // �����k
1073 data = pvar->ssh_state.outbuf + 7;
1074
1075 }
1076
1077 // ���M�p�P�b�g�\�z(input parameter: data, len)
1078 if (block_size < 8) {
1079 block_size = 8;
1080 }
1081 #if 0
1082 encryption_size = ((len + 8) / block_size + 1) * block_size;
1083 data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1084
1085 set_uint32(data, encryption_size - 4);
1086 padding = encryption_size - len - 5;
1087 data[4] = (unsigned char) padding;
1088 #else
1089 // �������p�P�b�g�����������������A�T�[�o����"Bad packet length"���������������������������B
1090 // (2007.10.29 yutaka)
1091 encryption_size = 4 + 1 + len;
1092 padding = block_size - (encryption_size % block_size);
1093 if (padding < 4)
1094 padding += block_size;
1095 encryption_size += padding;
1096 set_uint32(data, encryption_size - 4);
1097 data[4] = (unsigned char) padding;
1098 data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1099 #endif
1100 //if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;
1101 CRYPT_set_random_data(pvar, data + 5 + len, padding);
1102 ret = CRYPT_build_sender_MAC(pvar,
1103 pvar->ssh_state.sender_sequence_number,
1104 data, encryption_size,
1105 data + encryption_size);
1106 if (ret == FALSE) { // HMAC��������������������������
1107 data_length = encryption_size;
1108 }
1109
1110 // �p�P�b�g�������������BHMAC���~�������������O�B
1111 CRYPT_encrypt(pvar, data, encryption_size);
1112 }
1113
1114 send_packet_blocking(pvar, data, data_length);
1115
1116 buffer_free(msg);
1117
1118 pvar->ssh_state.sender_sequence_number++;
1119
1120 // ���M�������L�^
1121 pvar->ssh_heartbeat_tick = time(NULL);
1122 }
1123
1124 static void destroy_packet_buf(PTInstVar pvar)
1125 {
1126 memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1127 if (pvar->ssh_state.compressing) {
1128 memset(pvar->ssh_state.precompress_outbuf, 0,
1129 pvar->ssh_state.precompress_outbuflen);
1130 }
1131 }
1132
1133 /* The handlers are added to the queue for each message. When one of the
1134 handlers fires, if it returns FALSE, then all handlers in the set are
1135 removed from their queues. */
1136 static void enque_handlers(PTInstVar pvar, int num_msgs,
1137 const int FAR * messages,
1138 const SSHPacketHandler FAR * handlers)
1139 {
1140 SSHPacketHandlerItem FAR *first_item;
1141 SSHPacketHandlerItem FAR *last_item = NULL;
1142 int i;
1143
1144 for (i = 0; i < num_msgs; i++) {
1145 SSHPacketHandlerItem FAR *item =
1146 (SSHPacketHandlerItem FAR *)
1147 malloc(sizeof(SSHPacketHandlerItem));
1148 SSHPacketHandlerItem FAR *cur_item =
1149 pvar->ssh_state.packet_handlers[messages[i]];
1150
1151 item->handler = handlers[i];
1152
1153 if (cur_item == NULL) {
1154 pvar->ssh_state.packet_handlers[messages[i]] = item;
1155 item->next_for_message = item;
1156 item->last_for_message = item;
1157 item->active_for_message = messages[i];
1158 } else {
1159 item->next_for_message = cur_item;
1160 item->last_for_message = cur_item->last_for_message;
1161 cur_item->last_for_message->next_for_message = item;
1162 cur_item->last_for_message = item;
1163 item->active_for_message = -1;
1164 }
1165
1166 if (last_item != NULL) {
1167 last_item->next_in_set = item;
1168 } else {
1169 first_item = item;
1170 }
1171 last_item = item;
1172 }
1173
1174 if (last_item != NULL) {
1175 last_item->next_in_set = first_item;
1176 }
1177 }
1178
1179 static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1180 {
1181 SSHPacketHandlerItem FAR *cur_item =
1182 pvar->ssh_state.packet_handlers[message];
1183
1184 if (cur_item == NULL) {
1185 return NULL;
1186 } else {
1187 return cur_item->handler;
1188 }
1189 }
1190
1191 /* Called only by SSH_handle_packet */
1192 static void deque_handlers(PTInstVar pvar, int message)
1193 {
1194 SSHPacketHandlerItem FAR *cur_item =
1195 pvar->ssh_state.packet_handlers[message];
1196 SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1197
1198 if (cur_item == NULL)
1199 return;
1200
1201 do {
1202 SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1203
1204 if (cur_item->active_for_message >= 0) {
1205 SSHPacketHandlerItem FAR *replacement =
1206 cur_item->next_for_message;
1207
1208 if (replacement == cur_item) {
1209 replacement = NULL;
1210 } else {
1211 replacement->active_for_message =
1212 cur_item->active_for_message;
1213 }
1214 pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1215 replacement;
1216 }
1217 cur_item->next_for_message->last_for_message =
1218 cur_item->last_for_message;
1219 cur_item->last_for_message->next_for_message =
1220 cur_item->next_for_message;
1221
1222 free(cur_item);
1223 cur_item = next_in_set;
1224 } while (cur_item != first_item_in_set);
1225 }
1226
1227 static void enque_handler(PTInstVar pvar, int message,
1228 SSHPacketHandler handler)
1229 {
1230 enque_handlers(pvar, 1, &message, &handler);
1231 }
1232
1233 static void chop_newlines(char FAR * buf)
1234 {
1235 int len = strlen(buf);
1236
1237 while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1238 buf[len - 1] = 0;
1239 len--;
1240 }
1241 }
1242
1243 /********************/
1244 /* Message handlers */
1245 /********************/
1246
1247 static BOOL handle_forwarding_success(PTInstVar pvar)
1248 {
1249 return FALSE;
1250 }
1251
1252 static BOOL handle_forwarding_failure(PTInstVar pvar)
1253 {
1254 return FALSE;
1255 }
1256
1257 static void enque_forwarding_request_handlers(PTInstVar pvar)
1258 {
1259 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1260 static const SSHPacketHandler handlers[]
1261 = { handle_forwarding_success, handle_forwarding_failure };
1262
1263 enque_handlers(pvar, 2, msgs, handlers);
1264 }
1265
1266 static BOOL handle_auth_failure(PTInstVar pvar)
1267 {
1268 notify_verbose_message(pvar, "Authentication failed",
1269 LOG_LEVEL_VERBOSE);
1270
1271 // retry count������ (2005.7.15 yutaka)
1272 pvar->userauth_retry_count++;
1273
1274 AUTH_set_generic_mode(pvar);
1275 AUTH_advance_to_next_cred(pvar);
1276 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1277 try_send_credentials(pvar);
1278 return FALSE;
1279 }
1280
1281 static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1282 {
1283 if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1284 if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1285 // �S�������������I������
1286 safefree(pvar->pageant_key);
1287 }
1288 else {
1289 // ������������
1290 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1291 try_send_credentials(pvar);
1292 return TRUE;
1293 }
1294 }
1295 AUTH_destroy_cur_cred(pvar);
1296 return handle_auth_failure(pvar);
1297 }
1298
1299 static BOOL handle_TIS_challenge(PTInstVar pvar)
1300 {
1301 if (grab_payload(pvar, 4)) {
1302 int len = get_payload_uint32(pvar, 0);
1303
1304 if (grab_payload(pvar, len)) {
1305 notify_verbose_message(pvar, "Received TIS challenge",
1306 LOG_LEVEL_VERBOSE);
1307
1308 AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1309 AUTH_advance_to_next_cred(pvar);
1310 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1311 try_send_credentials(pvar);
1312 }
1313 }
1314 return FALSE;
1315 }
1316
1317 static BOOL handle_auth_required(PTInstVar pvar)
1318 {
1319 notify_verbose_message(pvar, "Server requires authentication",
1320 LOG_LEVEL_VERBOSE);
1321
1322 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1323 try_send_credentials(pvar);
1324 /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1325
1326 return FALSE;
1327 }
1328
1329 static BOOL handle_ignore(PTInstVar pvar)
1330 {
1331 if (SSHv1(pvar)) {
1332 notify_verbose_message(pvar, "SSH_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1333
1334 if (grab_payload(pvar, 4)
1335 && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1336 /* ignore it! but it must be decompressed */
1337 }
1338 }
1339 else {
1340 notify_verbose_message(pvar, "SSH2_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1341
1342 // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1343 // Cisco ���[�^���� (2006.11.28 maya)
1344 }
1345 return TRUE;
1346 }
1347
1348 static BOOL handle_debug(PTInstVar pvar)
1349 {
1350 BOOL always_display;
1351 char FAR *description;
1352 int description_len;
1353 char buf[2048];
1354
1355 if (SSHv1(pvar)) {
1356 notify_verbose_message(pvar, "SSH_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1357
1358 if (grab_payload(pvar, 4)
1359 && grab_payload(pvar, description_len =
1360 get_payload_uint32(pvar, 0))) {
1361 always_display = FALSE;
1362 description = pvar->ssh_state.payload + 4;
1363 description[description_len] = 0;
1364 } else {
1365 return TRUE;
1366 }
1367 } else {
1368 notify_verbose_message(pvar, "SSH2_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1369
1370 if (grab_payload(pvar, 5)
1371 && grab_payload(pvar,
1372 (description_len = get_payload_uint32(pvar, 1)) + 4)
1373 && grab_payload(pvar,
1374 get_payload_uint32(pvar, 5 + description_len))) {
1375 always_display = pvar->ssh_state.payload[0] != 0;
1376 description = pvar->ssh_state.payload + 5;
1377 description[description_len] = 0;
1378 } else {
1379 return TRUE;
1380 }
1381 }
1382
1383 chop_newlines(description);
1384 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1385 description);
1386 if (always_display) {
1387 notify_nonfatal_error(pvar, buf);
1388 } else {
1389 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1390 }
1391 return TRUE;
1392 }
1393
1394 static BOOL handle_disconnect(PTInstVar pvar)
1395 {
1396 int reason_code;
1397 char FAR *description;
1398 int description_len;
1399 char buf[2048];
1400 char FAR *explanation = "";
1401 char uimsg[MAX_UIMSG];
1402
1403 if (SSHv1(pvar)) {
1404 notify_verbose_message(pvar, "SSH_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1405
1406 if (grab_payload(pvar, 4)
1407 && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1408 reason_code = -1;
1409 description = pvar->ssh_state.payload + 4;
1410 description[description_len] = 0;
1411 } else {
1412 return TRUE;
1413 }
1414 } else {
1415 notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1416
1417 if (grab_payload(pvar, 8)
1418 && grab_payload(pvar,
1419 (description_len = get_payload_uint32(pvar, 4)) + 4)
1420 && grab_payload(pvar,
1421 get_payload_uint32(pvar, 8 + description_len))) {
1422 reason_code = get_payload_uint32(pvar, 0);
1423 description = pvar->ssh_state.payload + 8;
1424 description[description_len] = 0;
1425 } else {
1426 return TRUE;
1427 }
1428 }
1429
1430 chop_newlines(description);
1431 if (description[0] == 0) {
1432 description = NULL;
1433 }
1434
1435 if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1436 UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1437 "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1438 "This often happens when someone is already forwarding that port from the server.");
1439 strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1440 explanation = uimsg;
1441 }
1442
1443 if (description != NULL) {
1444 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1445 "Server disconnected with message '%s'%s");
1446 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1447 pvar->ts->UIMsg, description,
1448 explanation);
1449 } else {
1450 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1451 "Server disconnected (no reason given).%s");
1452 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1453 pvar->ts->UIMsg, explanation);
1454 }
1455 notify_fatal_error(pvar, buf);
1456
1457 return TRUE;
1458 }
1459
1460 static BOOL handle_unimplemented(PTInstVar pvar)
1461 {
1462 /* Should never receive this since we only send base 2.0 protocol messages */
1463 grab_payload(pvar, 4);
1464 return TRUE;
1465 }
1466
1467 static BOOL handle_crypt_success(PTInstVar pvar)
1468 {
1469 notify_verbose_message(pvar, "Secure mode successfully achieved",
1470 LOG_LEVEL_VERBOSE);
1471 return FALSE;
1472 }
1473
1474 static BOOL handle_noauth_success(PTInstVar pvar)
1475 {
1476 notify_verbose_message(pvar, "Server does not require authentication",
1477 LOG_LEVEL_VERBOSE);
1478 prep_compression(pvar);
1479 return FALSE;
1480 }
1481
1482 static BOOL handle_auth_success(PTInstVar pvar)
1483 {
1484 notify_verbose_message(pvar, "Authentication accepted",
1485 LOG_LEVEL_VERBOSE);
1486 prep_compression(pvar);
1487
1488 // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1489 start_ssh_heartbeat_thread(pvar);
1490
1491 return FALSE;
1492 }
1493
1494 static BOOL handle_server_public_key(PTInstVar pvar)
1495 {
1496 int server_key_public_exponent_len;
1497 int server_key_public_modulus_pos;
1498 int server_key_public_modulus_len;
1499 int host_key_bits_pos;
1500 int host_key_public_exponent_len;
1501 int host_key_public_modulus_pos;
1502 int host_key_public_modulus_len;
1503 int protocol_flags_pos;
1504 int supported_ciphers;
1505 char FAR *inmsg;
1506 Key hostkey;
1507 int supported_types;
1508
1509 notify_verbose_message(pvar, "SSH_SMSG_PUBLIC_KEY was received.", LOG_LEVEL_VERBOSE);
1510
1511 if (!grab_payload(pvar, 14))
1512 return FALSE;
1513 server_key_public_exponent_len = get_mpint_len(pvar, 12);
1514
1515 if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1516 return FALSE;
1517 server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1518 server_key_public_modulus_len =
1519 get_mpint_len(pvar, server_key_public_modulus_pos);
1520
1521 if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1522 return FALSE;
1523 host_key_bits_pos =
1524 server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1525 host_key_public_exponent_len =
1526 get_mpint_len(pvar, host_key_bits_pos + 4);
1527
1528 if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1529 return FALSE;
1530 host_key_public_modulus_pos =
1531 host_key_bits_pos + 6 + host_key_public_exponent_len;
1532 host_key_public_modulus_len =
1533 get_mpint_len(pvar, host_key_public_modulus_pos);
1534
1535 if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1536 return FALSE;
1537 protocol_flags_pos =
1538 host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1539
1540 inmsg = pvar->ssh_state.payload;
1541
1542 CRYPT_set_server_cookie(pvar, inmsg);
1543 if (!CRYPT_set_server_RSA_key(pvar,
1544 get_uint32(inmsg + 8),
1545 pvar->ssh_state.payload + 12,
1546 inmsg + server_key_public_modulus_pos))
1547 return FALSE;
1548 if (!CRYPT_set_host_RSA_key(pvar,
1549 get_uint32(inmsg + host_key_bits_pos),
1550 inmsg + host_key_bits_pos + 4,
1551 inmsg + host_key_public_modulus_pos))
1552 return FALSE;
1553 pvar->ssh_state.server_protocol_flags =
1554 get_uint32(inmsg + protocol_flags_pos);
1555
1556 supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1557 if (!CRYPT_set_supported_ciphers(pvar,
1558 supported_ciphers,
1559 supported_ciphers))
1560 return FALSE;
1561
1562 // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1563 // RSA ���L������ PAGEANT ���L��������
1564 supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1565 if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1566 supported_types |= (1 << SSH_AUTH_PAGEANT);
1567 }
1568 if (!AUTH_set_supported_auth_types(pvar,
1569 supported_types))
1570 return FALSE;
1571
1572 /* this must be the LAST THING in this function, since it can cause
1573 host_is_OK to be called. */
1574 hostkey.type = KEY_RSA1;
1575 hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1576 hostkey.exp = inmsg + host_key_bits_pos + 4;
1577 hostkey.mod = inmsg + host_key_public_modulus_pos;
1578 HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1579
1580 return FALSE;
1581 }
1582
1583 /*
1584 The ID must have already been found to start with "SSH-". It must
1585 be null-terminated.
1586 */
1587 static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1588 {
1589 char FAR *str;
1590
1591 for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1592 }
1593
1594 if (*str != '.') {
1595 return FALSE;
1596 }
1597
1598 pvar->protocol_major = atoi(ID + 4);
1599 pvar->protocol_minor = atoi(str + 1);
1600
1601 // for SSH2(yutaka)
1602 // 1.99����SSH2�����������s��
1603 if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
1604 // ���[�U�� SSH2 ���I������������������
1605 if (pvar->settings.ssh_protocol_version == 2) {
1606 pvar->protocol_major = 2;
1607 pvar->protocol_minor = 0;
1608 }
1609
1610 }
1611
1612 // SSH �o�[�W������ teraterm �����Z�b�g����
1613 // SCP �R�}���h������ (2008.2.3 maya)
1614 pvar->cv->isSSH = pvar->protocol_major;
1615
1616 for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1617 }
1618
1619 return *str == '-';
1620 }
1621
1622 /*
1623 On entry, the pvar->protocol_xxx fields hold the server's advertised
1624 protocol number. We replace the fields with the protocol number we will
1625 actually use, or return FALSE if there is no usable protocol version.
1626 */
1627 static BOOL negotiate_protocol(PTInstVar pvar)
1628 {
1629 switch (pvar->protocol_major) {
1630 case 1:
1631 if (pvar->protocol_minor > 5) {
1632 pvar->protocol_minor = 5;
1633 }
1634
1635 return TRUE;
1636
1637 // for SSH2(yutaka)
1638 case 2:
1639 return TRUE; // SSH2 support
1640
1641 default:
1642 return FALSE;
1643 }
1644 }
1645
1646 static void init_protocol(PTInstVar pvar)
1647 {
1648 CRYPT_initialize_random_numbers(pvar);
1649
1650 // known_hosts�t�@�C�������z�X�g���J������������������
1651 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1652
1653 /* while we wait for a response from the server... */
1654
1655 if (SSHv1(pvar)) {
1656 enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1657 enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1658 enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1659 enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1660
1661 } else { // for SSH2(yutaka)
1662 enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1663 enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1664 enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1665 enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1666 enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1667 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1668 enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1669 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1670 enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1671 enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1672 enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1673 enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1674 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1675 enque_handler(pvar, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, handle_SSH2_userauth_passwd_changereq);
1676
1677 enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1678
1679 // ���[�U�F�������f�B�X�p�b�`���[�`��
1680 enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1681 enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1682 enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1683 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1684 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1685 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1686 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1687 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1688 enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1689 enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1690 enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1691 // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1692 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1693 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1694
1695 }
1696 }
1697
1698 BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1699 {
1700 static const char prefix[] = "Received server prologue string: ";
1701
1702 // initialize SSH2 memory dump (2005.3.7 yutaka)
1703 init_memdump();
1704 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1705
1706 if (ID_len <= 0) {
1707 return FALSE;
1708 } else {
1709 int buf_len = ID_len + NUM_ELEM(prefix);
1710 char FAR *buf = (char FAR *) malloc(buf_len);
1711
1712 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1713 strncat_s(buf, buf_len, ID, _TRUNCATE);
1714 chop_newlines(buf);
1715
1716 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1717
1718 free(buf);
1719
1720
1721 // ���������R�s�[������ (2005.3.9 yutaka)
1722 #if 0
1723 // for calculate SSH2 hash
1724 // �T�[�o�o�[�W�����������i���s���������������j
1725 if (ID_len >= sizeof(pvar->server_version_string))
1726 return FALSE;
1727 strncpy(pvar->server_version_string, ID, ID_len);
1728 #endif
1729
1730
1731 if (ID[ID_len - 1] != '\n') {
1732 pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1733 return FALSE;
1734 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1735 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1736 return FALSE;
1737 } else if (strncmp(ID, "SSH-", 4) != 0) {
1738 return FALSE;
1739 } else {
1740 ID[ID_len - 1] = 0;
1741
1742 if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1743 ID[ID_len - 2] = 0;
1744 }
1745
1746 pvar->ssh_state.server_ID = _strdup(ID);
1747
1748 if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1749 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1750 "This program does not understand the server's version of the protocol.");
1751 notify_fatal_error(pvar, pvar->ts->UIMsg);
1752 } else {
1753 char TTSSH_ID[1024];
1754 int TTSSH_ID_len;
1755 int a, b, c, d;
1756
1757 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1758 get_file_version("ttxssh.dll", &a, &b, &c, &d);
1759
1760 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1761 "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1762 pvar->protocol_major, pvar->protocol_minor, a, b);
1763 TTSSH_ID_len = strlen(TTSSH_ID);
1764
1765 // for SSH2(yutaka)
1766 // �N���C�A���g�o�[�W�����������i���s���������������j
1767 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1768 TTSSH_ID, _TRUNCATE);
1769
1770 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1771 _snprintf_s(pvar->server_version_string,
1772 sizeof(pvar->server_version_string), _TRUNCATE,
1773 "%s", pvar->ssh_state.server_ID);
1774
1775 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1776 0) != TTSSH_ID_len) {
1777 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1778 "An error occurred while sending the SSH ID string.\n"
1779 "The connection will close.");
1780 notify_fatal_error(pvar, pvar->ts->UIMsg);
1781 } else {
1782 // ���s�R�[�h������ (2004.8.4 yutaka)
1783 pvar->client_version_string[--TTSSH_ID_len] = 0;
1784
1785 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1786 push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1787
1788 // SSH�n���h�����o�^���s��
1789 init_protocol(pvar);
1790
1791 SSH2_dispatch_init(1);
1792 SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1793 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1794 }
1795 }
1796
1797 return TRUE;
1798 }
1799 }
1800 }
1801
1802 static BOOL handle_exit(PTInstVar pvar)
1803 {
1804 if (grab_payload(pvar, 4)) {
1805 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1806 finish_send_packet(pvar);
1807 notify_closed_connection(pvar);
1808 }
1809 return TRUE;
1810 }
1811
1812 static BOOL handle_data(PTInstVar pvar)
1813 {
1814 if (grab_payload_limited(pvar, 4)) {
1815 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1816 pvar->ssh_state.payload_datastart = 4;
1817 }
1818 return TRUE;
1819 }
1820
1821 static BOOL handle_channel_open(PTInstVar pvar)
1822 {
1823 int host_len;
1824 int originator_len;
1825
1826 if ((pvar->ssh_state.
1827 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1828 if (grab_payload(pvar, 8)
1829 && grab_payload(pvar,
1830 8 + (host_len = get_payload_uint32(pvar, 4)))
1831 && grab_payload(pvar, originator_len =
1832 get_payload_uint32(pvar, host_len + 12))) {
1833 int local_port = get_payload_uint32(pvar, 8 + host_len);
1834
1835 pvar->ssh_state.payload[8 + host_len] = 0;
1836 FWD_open(pvar, get_payload_uint32(pvar, 0),
1837 pvar->ssh_state.payload + 8, local_port,
1838 pvar->ssh_state.payload + 16 + host_len,
1839 originator_len,
1840 NULL);
1841 }
1842 } else {
1843 if (grab_payload(pvar, 8)
1844 && grab_payload(pvar,
1845 4 + (host_len = get_payload_uint32(pvar, 4)))) {
1846 int local_port = get_payload_uint32(pvar, 8 + host_len);
1847
1848 pvar->ssh_state.payload[8 + host_len] = 0;
1849 FWD_open(pvar, get_payload_uint32(pvar, 0),
1850 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1851 NULL);
1852 }
1853 }
1854
1855 return TRUE;
1856 }
1857
1858 static BOOL handle_X11_channel_open(PTInstVar pvar)
1859 {
1860 int originator_len;
1861
1862 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1863 if (grab_payload(pvar, 8)
1864 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1865 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1866 pvar->ssh_state.payload + 8, originator_len, NULL);
1867 }
1868 } else {
1869 if (grab_payload(pvar, 4)) {
1870 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1871 }
1872 }
1873
1874 return TRUE;
1875 }
1876
1877 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1878 {
1879 if (grab_payload(pvar, 8)) {
1880 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1881 get_payload_uint32(pvar, 4));
1882 }
1883 return FALSE;
1884 }
1885
1886 static BOOL handle_channel_open_failure(PTInstVar pvar)
1887 {
1888 if (grab_payload(pvar, 4)) {
1889 FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1890 }
1891 return FALSE;
1892 }
1893
1894 static BOOL handle_channel_data(PTInstVar pvar)
1895 {
1896 int len;
1897
1898 if (grab_payload(pvar, 8)
1899 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1900 FWDChannel *channel;
1901 int local_channel_num = get_payload_uint32(pvar, 0);
1902 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1903 return FALSE;
1904 }
1905 channel = pvar->fwd_state.channels + local_channel_num;
1906 if (channel->type == TYPE_AGENT) {
1907 SSH_agent_response(pvar, NULL, local_channel_num,
1908 pvar->ssh_state.payload + 8, len);
1909 }
1910 else {
1911 FWD_received_data(pvar, local_channel_num,
1912 pvar->ssh_state.payload + 8, len);
1913 }
1914 }
1915 return TRUE;
1916 }
1917
1918 static BOOL handle_channel_input_eof(PTInstVar pvar)
1919 {
1920 if (grab_payload(pvar, 4)) {
1921 int local_channel_num = get_payload_uint32(pvar, 0);
1922 FWDChannel *channel;
1923 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1924 return FALSE;
1925 }
1926 channel = pvar->fwd_state.channels + local_channel_num;
1927 if (channel->type == TYPE_AGENT) {
1928 channel->status |= FWD_CLOSED_REMOTE_IN;
1929 SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1930 }
1931 else {
1932 FWD_channel_input_eof(pvar, local_channel_num);
1933 }
1934 }
1935 return TRUE;
1936 }
1937
1938 static BOOL handle_channel_output_eof(PTInstVar pvar)
1939 {
1940 if (grab_payload(pvar, 4)) {
1941 int local_channel_num = get_payload_uint32(pvar, 0);
1942 FWDChannel *channel;
1943 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1944 return FALSE;
1945 }
1946 channel = pvar->fwd_state.channels + local_channel_num;
1947 if (channel->type == TYPE_AGENT) {
1948 channel->status |= FWD_CLOSED_REMOTE_OUT;
1949 SSH_channel_output_eof(pvar, channel->remote_num);
1950 FWD_free_channel(pvar, local_channel_num);
1951 }
1952 else {
1953 FWD_channel_output_eof(pvar, local_channel_num);
1954 }
1955 }
1956 return TRUE;
1957 }
1958
1959 static BOOL handle_agent_open(PTInstVar pvar)
1960 {
1961 if (grab_payload(pvar, 4)) {
1962 int remote_id = get_payload_uint32(pvar, 0);
1963 int local_id;
1964
1965 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
1966 local_id = FWD_agent_open(pvar, remote_id);
1967 if (local_id == -1) {
1968 SSH_fail_channel_open(pvar, remote_id);
1969 }
1970 else {
1971 SSH_confirm_channel_open(pvar, remote_id, local_id);
1972 }
1973 }
1974 else {
1975 SSH_fail_channel_open(pvar, remote_id);
1976 }
1977 }
1978 /*
1979 else {
1980 // ���m��������channel����������������������������
1981 }
1982 */
1983
1984 return TRUE;
1985 }
1986
1987
1988
1989 // �n���h�����O�������b�Z�[�W����������
1990
1991 #define HANDLE_MESSAGE_MAX 30
1992 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1993 static int handle_message_count = 0;
1994 static int handle_message_stage = 0;
1995
1996 void SSH2_dispatch_init(int stage)
1997 {
1998 handle_message_count = 0;
1999 handle_message_stage = stage;
2000 }
2001
2002 int SSH2_dispatch_enabled_check(unsigned char message)
2003 {
2004 int i;
2005
2006 for (i = 0 ; i < handle_message_count ; i++) {
2007 if (handle_messages[i] == message)
2008 return 1;
2009 }
2010 return 0;
2011 }
2012
2013 void SSH2_dispatch_add_message(unsigned char message)
2014 {
2015 int i;
2016
2017 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2018 // TODO: error check
2019 return;
2020 }
2021
2022 // �������o�^�������������b�Z�[�W������������
2023 for (i=0; i<handle_message_count; i++) {
2024 if (handle_messages[i] == message) {
2025 return;
2026 }
2027 }
2028
2029 handle_messages[handle_message_count++] = message;
2030 }
2031
2032 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2033 {
2034 unsigned char c;
2035
2036 for (c = begin ; c <= end ; c++) {
2037 SSH2_dispatch_add_message(c);
2038 }
2039 }
2040
2041
2042 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
2043 int padding)
2044 {
2045 unsigned char message = prep_packet(pvar, data, len, padding);
2046
2047
2048 #ifdef SSH2_DEBUG
2049 // for SSH2(yutaka)
2050 if (SSHv2(pvar)) {
2051 if (pvar->key_done) {
2052 message = message;
2053 }
2054
2055 if (pvar->userauth_success) {
2056 message = message;
2057 }
2058
2059 if (pvar->rekeying) {
2060 message = message;
2061 }
2062 }
2063 #endif
2064
2065 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2066 if (message != SSH_MSG_NONE) {
2067 // ���b�Z�[�W�^�C�v���������n���h�����N��
2068 SSHPacketHandler handler = get_handler(pvar, message);
2069
2070 // for SSH2(yutaka)
2071 if (SSHv2(pvar)) {
2072 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2073 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2074 char buf[1024];
2075
2076 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2077 "Unexpected SSH2 message(%d) on current stage(%d)");
2078 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2079 pvar->ts->UIMsg, message, handle_message_stage);
2080 notify_fatal_error(pvar, buf);
2081 // abort
2082 }
2083 }
2084
2085 if (handler == NULL) {
2086 if (SSHv1(pvar)) {
2087 char buf[1024];
2088
2089 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2090 "Unexpected packet type received: %d");
2091 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2092 pvar->ts->UIMsg, message, handle_message_stage);
2093 notify_fatal_error(pvar, buf);
2094 } else {
2095 unsigned char FAR *outmsg =
2096 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2097
2098 set_uint32(outmsg,
2099 pvar->ssh_state.receiver_sequence_number - 1);
2100 finish_send_packet(pvar);
2101
2102 notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2103 /* XXX need to decompress incoming packet, but how? */
2104 }
2105 } else {
2106 if (!handler(pvar)) {
2107 deque_handlers(pvar, message);
2108 }
2109 }
2110 }
2111 }
2112
2113 static BOOL handle_pty_success(PTInstVar pvar)
2114 {
2115 FWD_enter_interactive_mode(pvar);
2116 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2117 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2118 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2119 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2120 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2121 handle_channel_input_eof);
2122 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2123 handle_channel_output_eof);
2124 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2125 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2126 enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2127 return FALSE;
2128 }
2129
2130 static BOOL handle_pty_failure(PTInstVar pvar)
2131 {
2132 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2133 "The server cannot allocate a pseudo-terminal. "
2134 "You may encounter some problems with the terminal.");
2135 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2136 return handle_pty_success(pvar);
2137 }
2138
2139 static void prep_pty(PTInstVar pvar)
2140 {
2141 int len = strlen(pvar->ts->TermType);
2142 unsigned char FAR *outmsg =
2143 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2144 4 + len + 16 + sizeof(ssh_ttymodes));
2145 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2146 static const SSHPacketHandler handlers[]
2147 = { handle_pty_success, handle_pty_failure };
2148
2149 set_uint32(outmsg, len);
2150 memcpy(outmsg + 4, pvar->ts->TermType, len);
2151 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2152 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2153 set_uint32(outmsg + 4 + len + 8, 0);
2154 set_uint32(outmsg + 4 + len + 12, 0);
2155 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2156 finish_send_packet(pvar);
2157
2158 enque_handlers(pvar, 2, msgs, handlers);
2159
2160 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2161 finish_send_packet(pvar);
2162 }
2163
2164 static BOOL handle_agent_request_success(PTInstVar pvar)
2165 {
2166 pvar->agentfwd_enable = TRUE;
2167 prep_pty(pvar);
2168 return FALSE;
2169 }
2170
2171 static BOOL handle_agent_request_failure(PTInstVar pvar)
2172 {
2173 prep_pty(pvar);
2174 return FALSE;
2175 }
2176
2177 static void prep_agent_request(PTInstVar pvar)
2178 {
2179 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2180 static const SSHPacketHandler handlers[]
2181 = { handle_agent_request_success, handle_agent_request_failure };
2182
2183 enque_handlers(pvar, 2, msgs, handlers);
2184
2185 begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2186 finish_send_packet(pvar);
2187 }
2188
2189 static void prep_forwarding(PTInstVar pvar)
2190 {
2191 FWD_prep_forwarding(pvar);
2192
2193 if (pvar->session_settings.ForwardAgent) {
2194 prep_agent_request(pvar);
2195 }
2196 else {
2197 prep_pty(pvar);
2198 }
2199 }
2200
2201
2202 //
2203 //
2204 // (2005.7.10 yutaka)
2205 static void enable_send_compression(PTInstVar pvar)
2206 {
2207 static int initialize = 0;
2208
2209 if (initialize) {
2210 deflateEnd(&pvar->ssh_state.compress_stream);
2211 }
2212 initialize = 1;
2213
2214 pvar->ssh_state.compress_stream.zalloc = NULL;
2215 pvar->ssh_state.compress_stream.zfree = NULL;
2216 pvar->ssh_state.compress_stream.opaque = NULL;
2217 if (deflateInit
2218 (&pvar->ssh_state.compress_stream,
2219 pvar->ssh_state.compression_level) != Z_OK) {
2220 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2221 "An error occurred while setting up compression.\n"
2222 "The connection will close.");
2223 notify_fatal_error(pvar, pvar->ts->UIMsg);
2224 return;
2225 } else {
2226 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2227 if (SSHv2(pvar)) {
2228 pvar->ssh_state.compressing = FALSE;
2229 } else {
2230 pvar->ssh_state.compressing = TRUE;
2231 }
2232 }
2233 }
2234
2235 static void enable_recv_compression(PTInstVar pvar)
2236 {
2237 static int initialize = 0;
2238
2239 if (initialize) {
2240 deflateEnd(&pvar->ssh_state.decompress_stream);
2241 }
2242 initialize = 1;
2243
2244 pvar->ssh_state.decompress_stream.zalloc = NULL;
2245 pvar->ssh_state.decompress_stream.zfree = NULL;
2246 pvar->ssh_state.decompress_stream.opaque = NULL;
2247 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2248 deflateEnd(&pvar->ssh_state.compress_stream);
2249 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2250 "An error occurred while setting up compression.\n"
2251 "The connection will close.");
2252 notify_fatal_error(pvar, pvar->ts->UIMsg);
2253 return;
2254 } else {
2255 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2256 if (SSHv2(pvar)) {
2257 pvar->ssh_state.decompressing = FALSE;
2258 } else {
2259 pvar->ssh_state.decompressing = TRUE;
2260 }
2261
2262 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2263 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2264 }
2265 }
2266
2267 static void enable_compression(PTInstVar pvar)
2268 {
2269 enable_send_compression(pvar);
2270 enable_recv_compression(pvar);
2271
2272 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2273 if (SSHv2(pvar)) {
2274 pvar->ssh_state.compressing = FALSE;
2275 pvar->ssh_state.decompressing = FALSE;
2276 }
2277
2278 }
2279
2280 static BOOL handle_enable_compression(PTInstVar pvar)
2281 {
2282 enable_compression(pvar);
2283 prep_forwarding(pvar);
2284 return FALSE;
2285 }
2286
2287 static BOOL handle_disable_compression(PTInstVar pvar)
2288 {
2289 prep_forwarding(pvar);
2290 return FALSE;
2291 }
2292
2293 static void prep_compression(PTInstVar pvar)
2294 {
2295 if (pvar->session_settings.CompressionLevel > 0) {
2296 // added if statement (2005.7.10 yutaka)
2297 if (SSHv1(pvar)) {
2298 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2299 static const SSHPacketHandler handlers[]
2300 = { handle_enable_compression, handle_disable_compression };
2301
2302 unsigned char FAR *outmsg =
2303 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2304
2305 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2306 finish_send_packet(pvar);
2307
2308 enque_handlers(pvar, 2, msgs, handlers);
2309 }
2310
2311 pvar->ssh_state.compression_level =
2312 pvar->session_settings.CompressionLevel;
2313
2314 } else {
2315 // added if statement (2005.7.10 yutaka)
2316 if (SSHv1(pvar)) {
2317 prep_forwarding(pvar);
2318 }
2319 }
2320 }
2321
2322 static void enque_simple_auth_handlers(PTInstVar pvar)
2323 {
2324 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2325 static const SSHPacketHandler handlers[]
2326 = { handle_auth_success, handle_auth_failure };
2327
2328 enque_handlers(pvar, 2, msgs, handlers);
2329 }
2330
2331 static BOOL handle_rsa_challenge(PTInstVar pvar)
2332 {
2333 int challenge_bytes;
2334
2335 if (!grab_payload(pvar, 2)) {
2336 return FALSE;
2337 }
2338
2339 challenge_bytes = get_mpint_len(pvar, 0);
2340
2341 if (grab_payload(pvar, challenge_bytes)) {
2342 unsigned char FAR *outmsg =
2343 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2344
2345 if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2346 if (CRYPT_generate_RSA_challenge_response
2347 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2348
2349 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2350 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2351 #if 0
2352 //AUTH_destroy_cur_cred(pvar);
2353 #endif
2354
2355 finish_send_packet(pvar);
2356
2357 enque_simple_auth_handlers(pvar);
2358 } else {
2359 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2360 "An error occurred while decrypting the RSA challenge.\n"
2361 "Perhaps the key file is corrupted.");
2362 notify_fatal_error(pvar, pvar->ts->UIMsg);
2363 }
2364 }
2365 else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2366 int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2367 int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2368 int server_key_bytes = (server_key_bits + 7) / 8;
2369 int host_key_bytes = (host_key_bits + 7) / 8;
2370 int session_buf_len = server_key_bytes + host_key_bytes + 8;
2371 char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2372 unsigned char session_id[16];
2373
2374 unsigned char *hash;
2375 int pubkeylen, hashlen;
2376
2377 /* Pageant ���n�b�V�����v�Z���������� */
2378 // ���J��������
2379 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2380 pvar->pageant_keylistlen);
2381 // �Z�b�V����ID������
2382 BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2383 BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2384 session_buf + host_key_bytes);
2385 memcpy(session_buf + server_key_bytes + host_key_bytes,
2386 pvar->crypt_state.server_cookie, 8);
2387 MD5(session_buf, session_buf_len, session_id);
2388 // �n�b�V������������
2389 hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2390 pubkeylen,
2391 pvar->ssh_state.payload,
2392 challenge_bytes + 2,
2393 session_id,
2394 &hashlen);
2395
2396 // �n�b�V�������M
2397 memcpy(outmsg, hash, 16);
2398 free(hash);
2399
2400 finish_send_packet(pvar);
2401
2402 enque_simple_auth_handlers(pvar);
2403 }
2404 }
2405
2406 return FALSE;
2407 }
2408
2409 #define OBFUSCATING_ROUND_TO 32
2410
2411 static int obfuscating_round_up(PTInstVar pvar, int size)
2412 {
2413 return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2414 }
2415
2416 static void try_send_credentials(PTInstVar pvar)
2417 {
2418 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2419 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2420 static const int RSA_msgs[] =
2421 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2422 static const SSHPacketHandler RSA_handlers[]
2423 = { handle_rsa_challenge, handle_rsa_auth_refused };
2424 static const int TIS_msgs[] =
2425 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2426 static const SSHPacketHandler TIS_handlers[]
2427 = { handle_TIS_challenge, handle_auth_failure };
2428
2429 // SSH2���������������������X�L�b�v
2430 if (SSHv2(pvar))
2431 goto skip_ssh2;
2432
2433 switch (cred->method) {
2434 case SSH_AUTH_NONE:
2435 return;
2436 case SSH_AUTH_PASSWORD:{
2437 int len = strlen(cred->password);
2438 // Round up password length to discourage traffic analysis
2439 int obfuscated_len = obfuscating_round_up(pvar, len);
2440 unsigned char FAR *outmsg =
2441 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2442 4 + obfuscated_len);
2443
2444 notify_verbose_message(pvar,
2445 "Trying PASSWORD authentication...",
2446 LOG_LEVEL_VERBOSE);
2447
2448 set_uint32(outmsg, obfuscated_len);
2449 memcpy(outmsg + 4, cred->password, len);
2450 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2451
2452 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2453 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2454 #if 0
2455 //AUTH_destroy_cur_cred(pvar);
2456 #endif
2457
2458 enque_simple_auth_handlers(pvar);
2459 break;
2460 }
2461 case SSH_AUTH_RHOSTS:{
2462 int len = strlen(cred->rhosts_client_user);
2463 unsigned char FAR *outmsg =
2464 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2465
2466 notify_verbose_message(pvar,
2467 "Trying RHOSTS authentication...",
2468 LOG_LEVEL_VERBOSE);
2469
2470 set_uint32(outmsg, len);
2471 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2472 AUTH_destroy_cur_cred(pvar);
2473 enque_simple_auth_handlers(pvar);
2474 break;
2475 }
2476 case SSH_AUTH_RSA:{
2477 int len = BN_num_bytes(cred->key_pair->rsa->n);
2478 unsigned char FAR *outmsg =
2479 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2480
2481 notify_verbose_message(pvar,
2482 "Trying RSA authentication...",
2483 LOG_LEVEL_VERBOSE);
2484
2485 set_ushort16_MSBfirst(outmsg, len * 8);
2486 BN_bn2bin(cred->key_pair->rsa->n, outmsg + 2);
2487 /* don't destroy the current credentials yet */
2488 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2489 break;
2490 }
2491 case SSH_AUTH_RHOSTS_RSA:{
2492 int mod_len = BN_num_bytes(cred->key_pair->rsa->n);
2493 int name_len = strlen(cred->rhosts_client_user);
2494 int exp_len = BN_num_bytes(cred->key_pair->rsa->e);
2495 int index;
2496 unsigned char FAR *outmsg =
2497 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2498 12 + mod_len + name_len + exp_len);
2499
2500 notify_verbose_message(pvar,
2501 "Trying RHOSTS+RSA authentication...",
2502 LOG_LEVEL_VERBOSE);
2503
2504 set_uint32(outmsg, name_len);
2505 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2506 index = 4 + name_len;
2507
2508 set_uint32(outmsg + index, 8 * mod_len);
2509 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2510 BN_bn2bin(cred->key_pair->rsa->e, outmsg + index + 6);
2511 index += 6 + exp_len;
2512
2513 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2514 BN_bn2bin(cred->key_pair->rsa->n, outmsg + index + 2);
2515 /* don't destroy the current credentials yet */
2516 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2517 break;
2518 }
2519 case SSH_AUTH_PAGEANT:{
2520 unsigned char FAR *outmsg;
2521 unsigned char *pubkey;
2522 int len, bn_bytes;
2523
2524 if (pvar->pageant_keycurrent != 0) {
2525 // ���O�������X�L�b�v
2526 pvar->pageant_curkey += 4;
2527 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2528 bn_bytes = (len + 7) / 8;
2529 pvar->pageant_curkey += 2 + bn_bytes;
2530 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2531 bn_bytes = (len + 7) / 8;
2532 pvar->pageant_curkey += 2 + bn_bytes;
2533 // ���O�������R�����g���X�L�b�v
2534 len = get_uint32_MSBfirst(pvar->pageant_curkey);
2535 pvar->pageant_curkey += 4 + len;
2536 // �����������u������
2537 }
2538 pubkey = pvar->pageant_curkey + 4;
2539 len = get_ushort16_MSBfirst(pubkey);
2540 bn_bytes = (len + 7) / 8;
2541 pubkey += 2 + bn_bytes;
2542 len = get_ushort16_MSBfirst(pubkey);
2543 bn_bytes = (len + 7) / 8;
2544 pubkey += 2;
2545 outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2546
2547 notify_verbose_message(pvar,
2548 "Trying RSA authentication...",
2549 LOG_LEVEL_VERBOSE);
2550
2551 set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2552 memcpy(outmsg + 2, pubkey, bn_bytes);
2553 /* don't destroy the current credentials yet */
2554
2555 pvar->pageant_keycurrent++;
2556
2557 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2558 break;
2559 }
2560 case SSH_AUTH_TIS:{
2561 if (cred->password == NULL) {
2562 unsigned char FAR *outmsg =
2563 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2564
2565 notify_verbose_message(pvar,
2566 "Trying TIS authentication...",
2567 LOG_LEVEL_VERBOSE);
2568 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2569 } else {
2570 int len = strlen(cred->password);
2571 int obfuscated_len = obfuscating_round_up(pvar, len);
2572 unsigned char FAR *outmsg =
2573 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2574 4 + obfuscated_len);
2575
2576 notify_verbose_message(pvar, "Sending TIS response",
2577 LOG_LEVEL_VERBOSE);
2578
2579 set_uint32(outmsg, obfuscated_len);
2580 memcpy(outmsg + 4, cred->password, len);
2581 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2582 enque_simple_auth_handlers(pvar);
2583 }
2584
2585 AUTH_destroy_cur_cred(pvar);
2586 break;
2587 }
2588 default:
2589 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2590 "Internal error: unsupported authentication method");
2591 notify_fatal_error(pvar, pvar->ts->UIMsg);
2592 return;
2593 }
2594
2595 finish_send_packet(pvar);
2596
2597 skip_ssh2:;
2598 destroy_packet_buf(pvar);
2599
2600 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2601 }
2602 }
2603
2604 static void try_send_user_name(PTInstVar pvar)
2605 {
2606 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2607 char FAR *username = AUTH_get_user_name(pvar);
2608
2609 if (username != NULL) {
2610 int len = strlen(username);
2611 int obfuscated_len = obfuscating_round_up(pvar, len);
2612 unsigned char FAR *outmsg =
2613 begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
2614 char buf[1024] = "Sending user name: ";
2615 static const int msgs[] =
2616 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2617 static const SSHPacketHandler handlers[]
2618 = { handle_noauth_success, handle_auth_required };
2619
2620 set_uint32(outmsg, obfuscated_len);
2621 memcpy(outmsg + 4, username, len);
2622 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2623 finish_send_packet(pvar);
2624
2625 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2626
2627 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2628 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2629
2630 enque_handlers(pvar, 2, msgs, handlers);
2631 }
2632 }
2633 }
2634
2635 static void send_session_key(PTInstVar pvar)
2636 {
2637 int encrypted_session_key_len;
2638 unsigned char FAR *outmsg;
2639
2640 if (SSHv1(pvar)) {
2641 encrypted_session_key_len =
2642 CRYPT_get_encrypted_session_key_len(pvar);
2643 }
2644
2645 if (!CRYPT_choose_ciphers(pvar))
2646 return;
2647
2648 if (SSHv1(pvar)) {
2649 outmsg =
2650 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2651 15 + encrypted_session_key_len);
2652 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2653 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2654 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2655 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2656 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2657 return;
2658 set_uint32(outmsg + 11 + encrypted_session_key_len,
2659 SSH_PROTOFLAG_SCREEN_NUMBER |
2660 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2661 finish_send_packet(pvar);
2662 }
2663
2664 if (!CRYPT_start_encryption(pvar, 1, 1))
2665 return;
2666 notify_established_secure_connection(pvar);
2667
2668 if (SSHv1(pvar)) {
2669 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2670 }
2671
2672 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2673
2674 if (SSHv1(pvar)) {
2675 try_send_user_name(pvar);
2676 }
2677 }
2678
2679 /*************************
2680 END of message handlers
2681 ************************/
2682
2683 void SSH_init(PTInstVar pvar)
2684 {
2685 int i;
2686
2687 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2688 buf_create(&pvar->ssh_state.precompress_outbuf,
2689 &pvar->ssh_state.precompress_outbuflen);
2690 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2691 &pvar->ssh_state.postdecompress_inbuflen);
2692 pvar->ssh_state.payload = NULL;
2693 pvar->ssh_state.compressing = FALSE;
2694 pvar->ssh_state.decompressing = FALSE;
2695 pvar->ssh_state.status_flags =
2696 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2697 pvar->ssh_state.payload_datalen = 0;
2698 pvar->ssh_state.hostname = NULL;
2699 pvar->ssh_state.server_ID = NULL;
2700 pvar->ssh_state.receiver_sequence_number = 0;
2701 pvar->ssh_state.sender_sequence_number = 0;
2702 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2703 pvar->ssh_state.packet_handlers[i] = NULL;
2704 }
2705
2706 // for SSH2(yutaka)
2707 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2708 pvar->userauth_success = 0;
2709 pvar->session_nego_status = 0;
2710 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2711 pvar->rekeying = 0;
2712 pvar->key_done = 0;
2713 pvar->ssh2_autologin = 0; // autologin disabled(default)
2714 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2715 pvar->userauth_retry_count = 0;
2716 pvar->decomp_buffer = NULL;
2717 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2718 pvar->tryed_ssh2_authlist = FALSE;
2719 pvar->agentfwd_enable = FALSE;
2720
2721 }
2722
2723 void SSH_open(PTInstVar pvar)
2724 {
2725 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2726 pvar->ssh_state.tcpport = pvar->ts->TCPPort;
2727 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2728 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2729 }
2730
2731 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2732 {
2733 if (SSHv1(pvar)) {
2734 int len = reason == NULL ? 0 : strlen(reason);
2735 unsigned char FAR *outmsg =
2736 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2737
2738 set_uint32(outmsg, len);
2739 if (reason != NULL) {
2740 memcpy(outmsg + 4, reason, len);
2741 }
2742 finish_send_packet(pvar);
2743
2744 } else { // for SSH2(yutaka)
2745 buffer_t *msg;
2746 unsigned char *outmsg;
2747 int len;
2748 Channel_t *c;
2749
2750 c = ssh2_channel_lookup(pvar->shell_id);
2751 if (c == NULL)
2752 return;
2753
2754 // SSH2 server��channel close���`����
2755 msg = buffer_init();
2756 if (msg == NULL) {
2757 // TODO: error check
2758 return;
2759 }
2760 buffer_put_int(msg, c->remote_id);
2761
2762 len = buffer_len(msg);
2763 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2764 memcpy(outmsg, buffer_ptr(msg), len);
2765 finish_send_packet(pvar);
2766 buffer_free(msg);
2767
2768 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_CLOSE was sent at SSH_notify_disconnecting().", LOG_LEVEL_VERBOSE);
2769 }
2770
2771 }
2772
2773 void SSH_notify_host_OK(PTInstVar pvar)
2774 {
2775 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2776 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2777 send_session_key(pvar);
2778 }
2779 }
2780
2781 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2782 {
2783 pvar->ssh_state.win_cols = cols;
2784 pvar->ssh_state.win_rows = rows;
2785
2786 if (SSHv1(pvar)) {
2787 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2788 unsigned char FAR *outmsg =
2789 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2790
2791 set_uint32(outmsg, rows);
2792 set_uint32(outmsg + 4, cols);
2793 set_uint32(outmsg + 8, 0);
2794 set_uint32(outmsg + 12, 0);
2795 finish_send_packet(pvar);
2796 }
2797
2798 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2799 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2800 buffer_t *msg;
2801 char *s;
2802 unsigned char *outmsg;
2803 int len;
2804 Channel_t *c;
2805
2806 c = ssh2_channel_lookup(pvar->shell_id);
2807 if (c == NULL)
2808 return;
2809
2810 msg = buffer_init();
2811 if (msg == NULL) {
2812 // TODO: error check
2813 return;
2814 }
2815 buffer_put_int(msg, c->remote_id);
2816 s = "window-change";
2817 buffer_put_string(msg, s, strlen(s));
2818 buffer_put_char(msg, 0); // wantconfirm
2819 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2820 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2821 buffer_put_int(msg, 480); // XXX:
2822 buffer_put_int(msg, 640); // XXX:
2823 len = buffer_len(msg);
2824 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2825 memcpy(outmsg, buffer_ptr(msg), len);
2826 finish_send_packet(pvar);
2827 buffer_free(msg);
2828
2829 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2830
2831 } else {
2832 // SSH�����������������������B
2833
2834 }
2835
2836 }
2837
2838 // �u���[�N�M���������B
2839 // OpenSSH ��"~B"�����������B�������ASSH2�����B
2840 // (2010.9.27 yutaka)
2841 int SSH_notify_break_signal(PTInstVar pvar)
2842 {
2843 int ret = 0;
2844
2845 if (SSHv1(pvar)) {
2846 // �����������B
2847
2848 } else if (SSHv2(pvar)) {
2849 buffer_t *msg;
2850 char *s;
2851 unsigned char *outmsg;
2852 int len;
2853 Channel_t *c;
2854
2855 c = ssh2_channel_lookup(pvar->shell_id);
2856 if (c == NULL)
2857 goto error;
2858
2859 msg = buffer_init();
2860 if (msg == NULL) {
2861 goto error;
2862 }
2863 buffer_put_int(msg, c->remote_id);
2864 s = "break";
2865 buffer_put_string(msg, s, strlen(s));
2866 buffer_put_char(msg, 0); // wantconfirm
2867 buffer_put_int(msg, 1000);
2868 len = buffer_len(msg);
2869 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2870 memcpy(outmsg, buffer_ptr(msg), len);
2871 finish_send_packet(pvar);
2872 buffer_free(msg);
2873
2874 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_break_signal().", LOG_LEVEL_VERBOSE);
2875
2876 ret = 1;
2877
2878 } else {
2879 // SSH�����������������������B
2880
2881 }
2882
2883 error:
2884 return (ret);
2885 }
2886
2887 int SSH_get_min_packet_size(PTInstVar pvar)
2888 {
2889 if (SSHv1(pvar)) {
2890 return 12;
2891 } else {
2892 int block_size = CRYPT_get_decryption_block_size(pvar);
2893
2894 return max(16, block_size);
2895 }
2896 }
2897
2898 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2899 at least 5 bytes must be decrypted */
2900 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2901 {
2902 if (SSHv2(pvar)) {
2903 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2904 }
2905 }
2906
2907 int SSH_get_clear_MAC_size(PTInstVar pvar)
2908 {
2909 if (SSHv1(pvar)) {
2910 return 0;
2911 } else {
2912 return CRYPT_get_receiver_MAC_size(pvar);
2913 }
2914 }
2915
2916 void SSH_notify_user_name(PTInstVar pvar)
2917 {
2918 try_send_user_name(pvar);
2919 }
2920
2921 void SSH_notify_cred(PTInstVar pvar)
2922 {
2923 try_send_credentials(pvar);
2924 }
2925
2926 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, unsigned int buflen)
2927 {
2928 // RAW�p�P�b�g�_���v������ (2008.8.15 yutaka)
2929 if (LOG_LEVEL_SSHDUMP <= pvar->session_settings.LogLevel) {
2930 init_memdump();
2931 push_memdump("SSH sending packet", "SSH_send", (char *)buf, buflen);
2932 }
2933
2934 if (SSHv1(pvar)) {
2935 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2936 return;
2937 }
2938
2939 while (buflen > 0) {
2940 int len =
2941 buflen >
2942 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2943 unsigned char FAR *outmsg =
2944 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2945
2946 set_uint32(outmsg, len);
2947
2948 if (pvar->ssh_state.compressing) {
2949 buf_ensure_size(&pvar->ssh_state.outbuf,
2950 &pvar->ssh_state.outbuflen,
2951 len + (len >> 6) + 50);
2952 pvar->ssh_state.compress_stream.next_in =
2953 pvar->ssh_state.precompress_outbuf;
2954 pvar->ssh_state.compress_stream.avail_in = 5;
2955 pvar->ssh_state.compress_stream.next_out =
2956 pvar->ssh_state.outbuf + 12;
2957 pvar->ssh_state.compress_stream.avail_out =
2958 pvar->ssh_state.outbuflen - 12;
2959
2960 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2961 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2962 "Error compressing packet data");
2963 notify_fatal_error(pvar, pvar->ts->UIMsg);
2964 return;
2965 }
2966
2967 pvar->ssh_state.compress_stream.next_in =
2968 (unsigned char FAR *) buf;
2969 pvar->ssh_state.compress_stream.avail_in = len;
2970
2971 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
2972 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2973 "Error compressing packet data");
2974 notify_fatal_error(pvar, pvar->ts->UIMsg);
2975 return;
2976 }
2977 } else {
2978 memcpy(outmsg + 4, buf, len);
2979 }
2980
2981 finish_send_packet_special(pvar, 1);
2982
2983 buflen -= len;
2984 buf += len;
2985 }
2986
2987 } else { // for SSH2(yutaka)
2988 Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
2989 SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen);
2990 }
2991
2992 }
2993
2994 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
2995 {
2996 int num_bytes = pvar->ssh_state.payload_datalen;
2997
2998 if (num_bytes > len) {
2999 num_bytes = len;
3000 }
3001
3002 if (!pvar->ssh_state.decompressing) {
3003 memcpy(dest,
3004 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
3005 num_bytes);
3006 pvar->ssh_state.payload_datastart += num_bytes;
3007 } else if (num_bytes > 0) {
3008 pvar->ssh_state.decompress_stream.next_out = dest;
3009 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
3010
3011 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
3012 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
3013 "Invalid compressed data in received packet");
3014 notify_fatal_error(pvar, pvar->ts->UIMsg);
3015 return 0;
3016 }
3017 }
3018
3019 pvar->ssh_state.payload_datalen -= num_bytes;
3020
3021 return num_bytes;
3022 }
3023
3024 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
3025 {
3026 char buf[1024];
3027 char buf2[1024];
3028
3029 // added support of SSH2 packet compression (2005.7.10 yutaka)
3030 // support of "Compression delayed" (2006.6.23 maya)
3031 if (pvar->ssh_state.compressing ||
3032 pvar->ctos_compression == COMP_ZLIB ||
3033 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
3034 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
3035 unsigned long total_out =
3036 pvar->ssh_state.compress_stream.total_out;
3037
3038 if (total_out > 0) {
3039 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3040 "level %d; ratio %.1f (%ld:%ld)");
3041 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
3042 pvar->ssh_state.compression_level,
3043 ((double) total_in) / total_out, total_in,
3044 total_out);
3045 } else {
3046 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3047 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
3048 pvar->ssh_state.compression_level);
3049 }
3050 } else {
3051 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3052 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
3053 }
3054
3055 // support of "Compression delayed" (2006.6.23 maya)
3056 if (pvar->ssh_state.decompressing ||
3057 pvar->stoc_compression == COMP_ZLIB ||
3058 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3059 unsigned long total_in =
3060 pvar->ssh_state.decompress_stream.total_in;
3061 unsigned long total_out =
3062 pvar->ssh_state.decompress_stream.total_out;
3063
3064 if (total_in > 0) {
3065 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3066 "level %d; ratio %.1f (%ld:%ld)");
3067 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3068 pvar->ssh_state.compression_level,
3069 ((double) total_out) / total_in, total_out,
3070 total_in);
3071 } else {
3072 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3073 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3074 pvar->ssh_state.compression_level);
3075 }
3076 } else {
3077 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3078 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
3079 }
3080
3081 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
3082 "Upstream %s; Downstream %s");
3083 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
3084 }
3085
3086 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
3087 {
3088 strncpy_s(dest, len,
3089 pvar->ssh_state.server_ID == NULL ? "Unknown"
3090 : pvar->ssh_state.server_ID,
3091 _TRUNCATE);
3092 }
3093
3094 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
3095 int len)
3096 {
3097 if (pvar->protocol_major == 0) {
3098 strncpy_s(dest, len, "Unknown", _TRUNCATE);
3099 } else {
3100 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
3101 pvar->protocol_minor);
3102 }
3103 }
3104
3105 void SSH_end(PTInstVar pvar)
3106 {
3107 int i;
3108 int mode;
3109
3110 for (i = 0; i < 256; i++) {
3111 SSHPacketHandlerItem FAR *first_item =
3112 pvar->ssh_state.packet_handlers[i];
3113
3114 if (first_item != NULL) {
3115 SSHPacketHandlerItem FAR *item = first_item;
3116
3117 do {
3118 SSHPacketHandlerItem FAR *cur_item = item;
3119
3120 item = item->next_for_message;
3121 free(cur_item);
3122 } while (item != first_item);
3123 }
3124 pvar->ssh_state.packet_handlers[i] = NULL;
3125 }
3126
3127 free(pvar->ssh_state.hostname);
3128 pvar->ssh_state.hostname = NULL;
3129 free(pvar->ssh_state.server_ID);
3130 pvar->ssh_state.server_ID = NULL;
3131 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
3132 buf_destroy(&pvar->ssh_state.precompress_outbuf,
3133 &pvar->ssh_state.precompress_outbuflen);
3134 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
3135 &pvar->ssh_state.postdecompress_inbuflen);
3136 pvar->agentfwd_enable = FALSE;
3137
3138 // support of "Compression delayed" (2006.6.23 maya)
3139 if (pvar->ssh_state.compressing ||
3140 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
3141 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
3142 deflateEnd(&pvar->ssh_state.compress_stream);
3143 pvar->ssh_state.compressing = FALSE;
3144 }
3145 // support of "Compression delayed" (2006.6.23 maya)
3146 if (pvar->ssh_state.decompressing ||
3147 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
3148 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3149 inflateEnd(&pvar->ssh_state.decompress_stream);
3150 pvar->ssh_state.decompressing = FALSE;
3151 }
3152
3153 #if 1
3154 // SSH2���f�[�^���������� (2004.12.27 yutaka)
3155 if (SSHv2(pvar)) {
3156 if (pvar->kexdh) {
3157 DH_free(pvar->kexdh);
3158 pvar->kexdh = NULL;
3159 }
3160 if (pvar->ecdh_client_key) {
3161 EC_KEY_free(pvar->ecdh_client_key);
3162 pvar->ecdh_client_key = NULL;
3163 }
3164 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
3165 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
3166
3167 if (pvar->my_kex != NULL) {
3168 buffer_free(pvar->my_kex);
3169 pvar->my_kex = NULL;
3170 }
3171 if (pvar->peer_kex != NULL) {
3172 buffer_free(pvar->peer_kex);
3173 pvar->peer_kex = NULL;
3174 }
3175
3176 pvar->we_need = 0;
3177 pvar->key_done = 0;
3178 pvar->rekeying = 0;
3179
3180 if (pvar->session_id != NULL) {
3181 free(pvar->session_id);
3182 pvar->session_id = NULL;
3183 }
3184 pvar->session_id_len = 0;
3185
3186 pvar->userauth_success = 0;
3187 //pvar->remote_id = 0;
3188 pvar->shell_id = 0;
3189 pvar->session_nego_status = 0;
3190
3191 pvar->ssh_heartbeat_tick = 0;
3192
3193 if (pvar->decomp_buffer != NULL) {
3194 buffer_free(pvar->decomp_buffer);
3195 pvar->decomp_buffer = NULL;
3196 }
3197
3198 if (pvar->ssh2_authlist != NULL) { // (2007.4.27 yutaka)
3199 free(pvar->ssh2_authlist);
3200 pvar->ssh2_authlist = NULL;
3201 }
3202
3203 pvar->tryed_ssh2_authlist = FALSE;
3204
3205 // add (2008.3.2 yutaka)
3206 for (mode = 0 ; mode < MODE_MAX ; mode++) {
3207 if (pvar->ssh2_keys[mode].