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