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 5838 - (show annotations) (download) (as text)
Sun Apr 26 14:46:48 2015 UTC (8 years, 11 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 253918 byte(s)
チケット #35047 SSH サーバホスト公開鍵の自動更新

・SSH2_MSG_GLOBAL_REQUESTの"hostkeys-00@openssh.com"に対して、
 OpenSSH 6.8の実装に合わせて、常に success を返すように変更した。
・ホスト鍵の自動更新処理を実装中。
 現時点では、サーバから送られてきた鍵のfingerprintをログ採取するところまで。
・key_from_blob()の引数チェックを追加した。
・SSHハンドラの pvar->ssh_state.payloadlen のコメント誤りを修正した。
 pvar->ssh_state.payload には type が含まれていないので、payloadlenに type 分の
 サイズが含まれているのは、オリジナルバグではないかと思う。

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