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