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 6810 - (show annotations) (download) (as text)
Mon Jun 19 12:51:04 2017 UTC (6 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 259565 byte(s)
同じ事柄に対するログが2行出ていたのを修正。

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