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 6967 - (show annotations) (download) (as text)
Thu Nov 2 11:37:33 2017 UTC (6 years, 5 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 265208 byte(s)
コード整理。

・不用なコードを削除
・インデント修正
・改行位置変更
・空行削除
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(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 (SSHv1(pvar)) {
735 if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
736 UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar, "'CORE insertion attack' detected. Aborting connection.");
737 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
738 }
739
740 CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
741 /* PKT guarantees that the data is always 4-byte aligned */
742 if (do_crc(pvar->ssh_state.payload, len - 4) != get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
743 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating.");
744 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
745 return SSH_MSG_NONE;
746 }
747
748 pvar->ssh_state.payload += padding;
749 pvar->ssh_state.payloadlen -= padding + 4;
750 } else {
751 int already_decrypted = get_predecryption_amount(pvar);
752
753 CRYPT_decrypt(pvar, data + already_decrypted, (4 + len) - already_decrypted);
754
755 if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) {
756 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
757 "Detected corrupted data; connection terminating.");
758 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
759 return SSH_MSG_NONE;
760 }
761
762 pvar->ssh_state.payload++;
763 pvar->ssh_state.payloadlen -= padding + 1;
764 }
765
766 pvar->ssh_state.payload_grabbed = 0;
767
768 if (SSHv1(pvar)) {
769 if (pvar->ssh_state.decompressing) {
770 if (pvar->ssh_state.decompress_stream.avail_in != 0) {
771 UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
772 "Internal error: a packet was not fully decompressed.\n"
773 "This is a bug, please report it.");
774 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
775 }
776
777 pvar->ssh_state.decompress_stream.next_in = pvar->ssh_state.payload;
778 pvar->ssh_state.decompress_stream.avail_in = pvar->ssh_state.payloadlen;
779 pvar->ssh_state.decompress_stream.next_out = pvar->ssh_state.postdecompress_inbuf;
780 pvar->ssh_state.payloadlen = -1;
781 } else {
782 pvar->ssh_state.payload++;
783 }
784
785 if (!grab_payload_limited(pvar, 1)) {
786 return SSH_MSG_NONE;
787 }
788
789 } else {
790 // support of SSH2 packet compression (2005.7.9 yutaka)
791 // support of "Compression delayed" (2006.6.23 maya)
792 if ((pvar->stoc_compression == COMP_ZLIB ||
793 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&
794 pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
795 int ret;
796
797 if (pvar->decomp_buffer == NULL) {
798 pvar->decomp_buffer = buffer_init();
799 if (pvar->decomp_buffer == NULL)
800 return SSH_MSG_NONE;
801 }
802 // ���x�m�������o�b�t�@���g�������������������Y�������B
803 buffer_clear(pvar->decomp_buffer);
804
805 // packet size��padding�������������y�C���[�h�����������W�J�����B
806 ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
807 pvar->ssh_state.payload,
808 pvar->ssh_state.payloadlen,
809 pvar->decomp_buffer);
810
811 // �|�C���^���X�V�B
812 pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
813 pvar->ssh_state.payload++;
814 pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
815
816 } else {
817 pvar->ssh_state.payload++;
818 }
819
820 if (!grab_payload_limited(pvar, 1)) {
821 return SSH_MSG_NONE;
822 }
823
824 }
825
826 pvar->ssh_state.receiver_sequence_number++;
827
828 return pvar->ssh_state.payload[-1];
829 }
830
831 /* Create a packet to be sent. The SSH protocol packet type is in 'type';
832 'len' contains the length of the packet payload, in bytes (this
833 does not include the space for any of the packet headers or padding,
834 or for the packet type byte).
835 Returns a pointer to the payload data area, a region of length 'len',
836 to be filled by the caller. */
837 unsigned char *begin_send_packet(PTInstVar pvar, int type, int len)
838 {
839 unsigned char *buf;
840
841 pvar->ssh_state.outgoing_packet_len = len + 1;
842
843 if (pvar->ssh_state.compressing) {
844 buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
845 &pvar->ssh_state.precompress_outbuflen, 1 + len);
846 buf = pvar->ssh_state.precompress_outbuf;
847 } else {
848 /* For SSHv2,
849 Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
850 + len(payload) + 4(minpadding), rounded up to nearest block_size
851 We only need a reasonable upper bound for the buffer size */
852 buf_ensure_size(&pvar->ssh_state.outbuf,
853 &pvar->ssh_state.outbuflen,
854 len + 30 + CRYPT_get_sender_MAC_size(pvar) +
855 CRYPT_get_encryption_block_size(pvar));
856 buf = pvar->ssh_state.outbuf + 12;
857 }
858
859 buf[0] = (unsigned char) type;
860 return buf + 1;
861 }
862
863
864 // ���M���g���C����������
865 //
866 // WinSock�� send() ���o�b�t�@�T�C�Y(len)�������������l��������������������
867 // ���������������A�����������G���[���������B
868 // �����������ATCP�R�l�N�V�������f�������o���h���B
869 // (2006.12.9 yutaka)
870 static int retry_send_packet(PTInstVar pvar, char *data, int len)
871 {
872 int n;
873 int err;
874
875 while (len > 0) {
876 n = (pvar->Psend)(pvar->socket, data, len, 0);
877
878 if (n < 0) {
879 err = WSAGetLastError();
880 if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
881 // send()�����l��0�������A�����G���[������ 10000 �������������A
882 // ���������������������B
883 // PuTTY 0.58���������Q�l�B
884 // (2007.2.4 yutak)
885 return 0; // success
886 }
887 return 1; // error
888 }
889
890 len -= n;
891 data += n;
892 }
893
894 return 0; // success
895 }
896
897 static BOOL send_packet_blocking(PTInstVar pvar, char *data, int len)
898 {
899 // �p�P�b�g���M�����o�b�t�@���g�������������A�u���b�L���O�����M�����������K�v�������B
900 // �m���u���b�L���O�����M����WSAEWOULDBLOCK�����������������A�����o�b�t�@�����M��������
901 // ���������������������������������B(2007.10.30 yutaka)
902 u_long do_block = 0;
903 int code = 0;
904 char *kind = NULL, buf[256];
905
906 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, 0, 0) == SOCKET_ERROR) {
907 code = WSAGetLastError();
908 kind = "WSAAsyncSelect1";
909 goto error;
910 }
911 if (ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR) {
912 code = WSAGetLastError();
913 kind = "ioctlsocket";
914 goto error;
915 }
916 if (retry_send_packet(pvar, data, len) != 0) {
917 code = WSAGetLastError();
918 kind = "retry_send_packet";
919 goto error;
920 }
921 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
922 pvar->notification_msg,
923 pvar->notification_events) == SOCKET_ERROR) {
924 code = WSAGetLastError();
925 kind = "WSAAsyncSelect2";
926 goto error;
927 }
928 return TRUE;
929
930 error:
931 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
932 "A communications error occurred while sending an SSH packet.\n"
933 "The connection will close. (%s:%d)");
934 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
935 kind, code);
936 notify_fatal_error(pvar, buf, TRUE);
937 return FALSE;
938 }
939
940 /* if skip_compress is true, then the data has already been compressed
941 into outbuf + 12 */
942 void finish_send_packet_special(PTInstVar pvar, int skip_compress)
943 {
944 unsigned int len = pvar->ssh_state.outgoing_packet_len;
945 unsigned char *data;
946 unsigned int data_length;
947 buffer_t *msg = NULL; // for SSH2 packet compression
948
949 if (pvar->ssh_state.compressing) {
950 if (!skip_compress) {
951 buf_ensure_size(&pvar->ssh_state.outbuf,
952 &pvar->ssh_state.outbuflen,
953 (int)(len + (len >> 6) + 50 + CRYPT_get_sender_MAC_size(pvar)));
954 pvar->ssh_state.compress_stream.next_in = pvar->ssh_state.precompress_outbuf;
955 pvar->ssh_state.compress_stream.avail_in = len;
956 pvar->ssh_state.compress_stream.next_out = pvar->ssh_state.outbuf + 12;
957 pvar->ssh_state.compress_stream.avail_out = pvar->ssh_state.outbuflen - 12;
958
959 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
960 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
961 "An error occurred while compressing packet data.\n"
962 "The connection will close.");
963 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
964 return;
965 }
966 }
967
968 len = pvar->ssh_state.outbuflen - 12 - pvar->ssh_state.compress_stream.avail_out;
969 }
970
971 if (SSHv1(pvar)) {
972 int padding = 8 - ((len + 4) % 8);
973
974 data = pvar->ssh_state.outbuf + 8 - padding;
975 data_length = padding + len + 8;
976
977 set_uint32(data, len + 4);
978 if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
979 CRYPT_set_random_data(pvar, data + 4, padding);
980 } else {
981 memset(data + 4, 0, padding);
982 }
983 set_uint32(data + data_length - 4, do_crc(data + 4, data_length - 8));
984 CRYPT_encrypt(pvar, data + 4, data_length - 4);
985 } else { //for SSH2(yutaka)
986 int block_size = CRYPT_get_encryption_block_size(pvar);
987 unsigned int encryption_size;
988 unsigned int padding;
989 BOOL ret;
990
991 /*
992 �f�[�^�\��
993 pvar->ssh_state.outbuf:
994 offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
995 <--ignore---> ^^^^^^^^ <---- payload --->
996 packet length
997
998 ^^padding
999
1000 <---------------------------->
1001 SSH2 sending data on TCP
1002
1003 NOTE:
1004 payload = type(1) + raw-data
1005 len = ssh_state.outgoing_packet_len = payload size
1006 */
1007 // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
1008 // support of "Compression delayed" (2006.6.23 maya)
1009 if ((pvar->ctos_compression == COMP_ZLIB ||
1010 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
1011 pvar->ssh2_keys[MODE_OUT].comp.enabled) {
1012 // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
1013 msg = buffer_init();
1014 if (msg == NULL) {
1015 // TODO: error check
1016 logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_init returns NULL.");
1017 return;
1018 }
1019
1020 // ���k�������w�b�_�������y�C���[�h�����B
1021 buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
1022 if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
1023 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1024 "An error occurred while compressing packet data.\n"
1025 "The connection will close.");
1026 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1027 return;
1028 }
1029 data = buffer_ptr(msg);
1030 len = buffer_len(msg) - 5; // 'len' is overwritten.
1031
1032 } else {
1033 // �����k
1034 data = pvar->ssh_state.outbuf + 7;
1035 }
1036
1037 // ���M�p�P�b�g�\�z(input parameter: data, len)
1038 if (block_size < 8) {
1039 block_size = 8;
1040 }
1041
1042 encryption_size = 4 + 1 + len;
1043 padding = block_size - (encryption_size % block_size);
1044 if (padding < 4)
1045 padding += block_size;
1046 encryption_size += padding;
1047 set_uint32(data, encryption_size - 4);
1048 data[4] = (unsigned char) padding;
1049 data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1050 if (msg) {
1051 // �p�P�b�g���k�������A�o�b�t�@���g�������B(2011.6.10 yutaka)
1052 buffer_append_space(msg, padding + EVP_MAX_MD_SIZE);
1053 // realloc()���������A�|�C���^�����������\�������������A���x���������B
1054 data = buffer_ptr(msg);
1055 }
1056
1057 //if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;
1058 CRYPT_set_random_data(pvar, data + 5 + len, padding);
1059 ret = CRYPT_build_sender_MAC(pvar,
1060 pvar->ssh_state.sender_sequence_number,
1061 data, encryption_size,
1062 data + encryption_size);
1063 if (ret == FALSE) { // MAC��������������������������
1064 data_length = encryption_size;
1065 }
1066
1067 // �p�P�b�g�������������BMAC���~�������������O�B
1068 CRYPT_encrypt(pvar, data, encryption_size);
1069 }
1070
1071 send_packet_blocking(pvar, data, data_length);
1072
1073 buffer_free(msg);
1074
1075 pvar->ssh_state.sender_sequence_number++;
1076
1077 // ���M�������L�^
1078 pvar->ssh_heartbeat_tick = time(NULL);
1079 }
1080
1081 static void destroy_packet_buf(PTInstVar pvar)
1082 {
1083 memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1084 if (pvar->ssh_state.compressing) {
1085 memset(pvar->ssh_state.precompress_outbuf, 0,
1086 pvar->ssh_state.precompress_outbuflen);
1087 }
1088 }
1089
1090 /* The handlers are added to the queue for each message. When one of the
1091 handlers fires, if it returns FALSE, then all handlers in the set are
1092 removed from their queues. */
1093 static void enque_handlers(PTInstVar pvar, int num_msgs,
1094 const int *messages,
1095 const SSHPacketHandler *handlers)
1096 {
1097 SSHPacketHandlerItem *first_item;
1098 SSHPacketHandlerItem *last_item = NULL;
1099 int i;
1100
1101 for (i = 0; i < num_msgs; i++) {
1102 SSHPacketHandlerItem *item =
1103 (SSHPacketHandlerItem *)
1104 malloc(sizeof(SSHPacketHandlerItem));
1105 SSHPacketHandlerItem *cur_item =
1106 pvar->ssh_state.packet_handlers[messages[i]];
1107
1108 item->handler = handlers[i];
1109
1110 if (cur_item == NULL) {
1111 pvar->ssh_state.packet_handlers[messages[i]] = item;
1112 item->next_for_message = item;
1113 item->last_for_message = item;
1114 item->active_for_message = messages[i];
1115 } else {
1116 item->next_for_message = cur_item;
1117 item->last_for_message = cur_item->last_for_message;
1118 cur_item->last_for_message->next_for_message = item;
1119 cur_item->last_for_message = item;
1120 item->active_for_message = -1;
1121 }
1122
1123 if (last_item != NULL) {
1124 last_item->next_in_set = item;
1125 } else {
1126 first_item = item;
1127 }
1128 last_item = item;
1129 }
1130
1131 if (last_item != NULL) {
1132 last_item->next_in_set = first_item;
1133 }
1134 }
1135
1136 static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1137 {
1138 SSHPacketHandlerItem *cur_item =
1139 pvar->ssh_state.packet_handlers[message];
1140
1141 if (cur_item == NULL) {
1142 return NULL;
1143 } else {
1144 return cur_item->handler;
1145 }
1146 }
1147
1148 /* Called only by SSH_handle_packet */
1149 static void deque_handlers(PTInstVar pvar, int message)
1150 {
1151 SSHPacketHandlerItem *cur_item =
1152 pvar->ssh_state.packet_handlers[message];
1153 SSHPacketHandlerItem *first_item_in_set = cur_item;
1154
1155 if (cur_item == NULL)
1156 return;
1157
1158 do {
1159 SSHPacketHandlerItem *next_in_set = cur_item->next_in_set;
1160
1161 if (cur_item->active_for_message >= 0) {
1162 SSHPacketHandlerItem *replacement =
1163 cur_item->next_for_message;
1164
1165 if (replacement == cur_item) {
1166 replacement = NULL;
1167 } else {
1168 replacement->active_for_message =
1169 cur_item->active_for_message;
1170 }
1171 pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1172 replacement;
1173 }
1174 cur_item->next_for_message->last_for_message =
1175 cur_item->last_for_message;
1176 cur_item->last_for_message->next_for_message =
1177 cur_item->next_for_message;
1178
1179 free(cur_item);
1180 cur_item = next_in_set;
1181 } while (cur_item != first_item_in_set);
1182 }
1183
1184 static void enque_handler(PTInstVar pvar, int message,
1185 SSHPacketHandler handler)
1186 {
1187 enque_handlers(pvar, 1, &message, &handler);
1188 }
1189
1190 static void chop_newlines(char *buf)
1191 {
1192 int len = strlen(buf);
1193
1194 while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1195 buf[len - 1] = 0;
1196 len--;
1197 }
1198 }
1199
1200 /********************/
1201 /* Message handlers */
1202 /********************/
1203
1204 static BOOL handle_forwarding_success(PTInstVar pvar)
1205 {
1206 return FALSE;
1207 }
1208
1209 static BOOL handle_forwarding_failure(PTInstVar pvar)
1210 {
1211 return FALSE;
1212 }
1213
1214 static void enque_forwarding_request_handlers(PTInstVar pvar)
1215 {
1216 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1217 static const SSHPacketHandler handlers[]
1218 = { handle_forwarding_success, handle_forwarding_failure };
1219
1220 enque_handlers(pvar, 2, msgs, handlers);
1221 }
1222
1223 static BOOL handle_auth_failure(PTInstVar pvar)
1224 {
1225 logputs(LOG_LEVEL_VERBOSE, "Authentication failed");
1226
1227 // retry count������ (2005.7.15 yutaka)
1228 pvar->userauth_retry_count++;
1229
1230 AUTH_set_generic_mode(pvar);
1231 AUTH_advance_to_next_cred(pvar);
1232 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1233 try_send_credentials(pvar);
1234 return FALSE;
1235 }
1236
1237 static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1238 {
1239 if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1240 if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1241 // �S�������������I������
1242 safefree(pvar->pageant_key);
1243 }
1244 else {
1245 // ������������
1246 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1247 try_send_credentials(pvar);
1248 return TRUE;
1249 }
1250 }
1251 AUTH_destroy_cur_cred(pvar);
1252 return handle_auth_failure(pvar);
1253 }
1254
1255 static BOOL handle_TIS_challenge(PTInstVar pvar)
1256 {
1257 if (grab_payload(pvar, 4)) {
1258 int len = get_payload_uint32(pvar, 0);
1259
1260 if (grab_payload(pvar, len)) {
1261 logputs(LOG_LEVEL_VERBOSE, "Received TIS challenge");
1262
1263 AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1264 AUTH_advance_to_next_cred(pvar);
1265 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1266 try_send_credentials(pvar);
1267 }
1268 }
1269 return FALSE;
1270 }
1271
1272 static BOOL handle_auth_required(PTInstVar pvar)
1273 {
1274 logputs(LOG_LEVEL_VERBOSE, "Server requires authentication");
1275
1276 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1277 try_send_credentials(pvar);
1278 /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1279
1280 return FALSE;
1281 }
1282
1283 static BOOL handle_ignore(PTInstVar pvar)
1284 {
1285 if (SSHv1(pvar)) {
1286 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_IGNORE was received.");
1287
1288 if (grab_payload(pvar, 4)
1289 && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1290 /* ignore it! but it must be decompressed */
1291 }
1292 }
1293 else {
1294 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_IGNORE was received.");
1295
1296 // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1297 // Cisco ���[�^���� (2006.11.28 maya)
1298 }
1299 return TRUE;
1300 }
1301
1302 static BOOL handle_debug(PTInstVar pvar)
1303 {
1304 BOOL always_display;
1305 char *description;
1306 int description_len;
1307 char buf[2048];
1308
1309 if (SSHv1(pvar)) {
1310 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_DEBUG was received.");
1311
1312 if (grab_payload(pvar, 4)
1313 && grab_payload(pvar, description_len =
1314 get_payload_uint32(pvar, 0))) {
1315 always_display = FALSE;
1316 description = pvar->ssh_state.payload + 4;
1317 description[description_len] = 0;
1318 } else {
1319 return TRUE;
1320 }
1321 } else {
1322 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_DEBUG was received.");
1323
1324 if (grab_payload(pvar, 5)
1325 && grab_payload(pvar,
1326 (description_len = get_payload_uint32(pvar, 1)) + 4)
1327 && grab_payload(pvar,
1328 get_payload_uint32(pvar, 5 + description_len))) {
1329 always_display = pvar->ssh_state.payload[0] != 0;
1330 description = pvar->ssh_state.payload + 5;
1331 description[description_len] = 0;
1332 } else {
1333 return TRUE;
1334 }
1335 }
1336
1337 chop_newlines(description);
1338 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1339 description);
1340 if (always_display) {
1341 notify_nonfatal_error(pvar, buf);
1342 } else {
1343 logputs(LOG_LEVEL_VERBOSE, buf);
1344 }
1345 return TRUE;
1346 }
1347
1348 static BOOL handle_disconnect(PTInstVar pvar)
1349 {
1350 int reason_code;
1351 char *description;
1352 int description_len;
1353 char buf[2048];
1354 char *explanation = "";
1355 char uimsg[MAX_UIMSG];
1356
1357 if (SSHv1(pvar)) {
1358 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_DISCONNECT was received.");
1359
1360 if (grab_payload(pvar, 4)
1361 && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1362 reason_code = -1;
1363 description = pvar->ssh_state.payload + 4;
1364 description[description_len] = 0;
1365 } else {
1366 return TRUE;
1367 }
1368 } else {
1369 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_DISCONNECT was received.");
1370
1371 if (grab_payload(pvar, 8)
1372 && grab_payload(pvar,
1373 (description_len = get_payload_uint32(pvar, 4)) + 4)
1374 && grab_payload(pvar,
1375 get_payload_uint32(pvar, 8 + description_len))) {
1376 reason_code = get_payload_uint32(pvar, 0);
1377 description = pvar->ssh_state.payload + 8;
1378 description[description_len] = 0;
1379 } else {
1380 return TRUE;
1381 }
1382 }
1383
1384 chop_newlines(description);
1385 if (description[0] == 0) {
1386 description = NULL;
1387 }
1388
1389 if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1390 UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1391 "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1392 "This often happens when someone is already forwarding that port from the server.");
1393 strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1394 explanation = uimsg;
1395 }
1396
1397 if (description != NULL) {
1398 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1399 "Server disconnected with message '%s'%s");
1400 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1401 pvar->ts->UIMsg, description,
1402 explanation);
1403 } else {
1404 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1405 "Server disconnected (no reason given).%s");
1406 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1407 pvar->ts->UIMsg, explanation);
1408 }
1409
1410 if (SSHv2(pvar)) {
1411 // SSH2_MSG_DISCONNECT �������������������������M��������������
1412 notify_fatal_error(pvar, buf, FALSE);
1413 }
1414 else {
1415 // SSH1 ���������d�l�����������������A���O����������������
1416 notify_fatal_error(pvar, buf, TRUE);
1417 }
1418
1419 return TRUE;
1420 }
1421
1422 static BOOL handle_unimplemented(PTInstVar pvar)
1423 {
1424 /* Should never receive this since we only send base 2.0 protocol messages */
1425 grab_payload(pvar, 4);
1426 return TRUE;
1427 }
1428
1429 static BOOL handle_crypt_success(PTInstVar pvar)
1430 {
1431 logputs(LOG_LEVEL_VERBOSE, "Secure mode successfully achieved");
1432 return FALSE;
1433 }
1434
1435 static BOOL handle_noauth_success(PTInstVar pvar)
1436 {
1437 logputs(LOG_LEVEL_VERBOSE, "Server does not require authentication");
1438 prep_compression(pvar);
1439 return FALSE;
1440 }
1441
1442 static BOOL handle_auth_success(PTInstVar pvar)
1443 {
1444 logputs(LOG_LEVEL_VERBOSE, "Authentication accepted");
1445 prep_compression(pvar);
1446
1447 // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1448 start_ssh_heartbeat_thread(pvar);
1449
1450 return FALSE;
1451 }
1452
1453 static BOOL handle_server_public_key(PTInstVar pvar)
1454 {
1455 int server_key_public_exponent_len;
1456 int server_key_public_modulus_pos;
1457 int server_key_public_modulus_len;
1458 int host_key_bits_pos;
1459 int host_key_public_exponent_len;
1460 int host_key_public_modulus_pos;
1461 int host_key_public_modulus_len;
1462 int protocol_flags_pos;
1463 int supported_ciphers;
1464 char *inmsg;
1465 Key hostkey;
1466 int supported_types;
1467
1468 logputs(LOG_LEVEL_VERBOSE, "SSH_SMSG_PUBLIC_KEY was received.");
1469
1470 if (!grab_payload(pvar, 14))
1471 return FALSE;
1472 server_key_public_exponent_len = get_mpint_len(pvar, 12);
1473
1474 if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1475 return FALSE;
1476 server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1477 server_key_public_modulus_len =
1478 get_mpint_len(pvar, server_key_public_modulus_pos);
1479
1480 if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1481 return FALSE;
1482 host_key_bits_pos =
1483 server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1484 host_key_public_exponent_len =
1485 get_mpint_len(pvar, host_key_bits_pos + 4);
1486
1487 if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1488 return FALSE;
1489 host_key_public_modulus_pos =
1490 host_key_bits_pos + 6 + host_key_public_exponent_len;
1491 host_key_public_modulus_len =
1492 get_mpint_len(pvar, host_key_public_modulus_pos);
1493
1494 if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1495 return FALSE;
1496 protocol_flags_pos =
1497 host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1498
1499 inmsg = pvar->ssh_state.payload;
1500
1501 CRYPT_set_server_cookie(pvar, inmsg);
1502 if (!CRYPT_set_server_RSA_key(pvar,
1503 get_uint32(inmsg + 8),
1504 pvar->ssh_state.payload + 12,
1505 inmsg + server_key_public_modulus_pos))
1506 return FALSE;
1507 if (!CRYPT_set_host_RSA_key(pvar,
1508 get_uint32(inmsg + host_key_bits_pos),
1509 inmsg + host_key_bits_pos + 4,
1510 inmsg + host_key_public_modulus_pos))
1511 return FALSE;
1512 pvar->ssh_state.server_protocol_flags =
1513 get_uint32(inmsg + protocol_flags_pos);
1514
1515 supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1516 if (!CRYPT_set_supported_ciphers(pvar,
1517 supported_ciphers,
1518 supported_ciphers))
1519 return FALSE;
1520
1521 // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1522 // RSA ���L������ PAGEANT ���L��������
1523 supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1524 if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1525 supported_types |= (1 << SSH_AUTH_PAGEANT);
1526 }
1527 if (!AUTH_set_supported_auth_types(pvar,
1528 supported_types))
1529 return FALSE;
1530
1531 /* this must be the LAST THING in this function, since it can cause
1532 host_is_OK to be called. */
1533 hostkey.type = KEY_RSA1;
1534 hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1535 hostkey.exp = inmsg + host_key_bits_pos + 4;
1536 hostkey.mod = inmsg + host_key_public_modulus_pos;
1537 HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1538
1539 return FALSE;
1540 }
1541
1542 /*
1543 The ID must have already been found to start with "SSH-". It must
1544 be null-terminated.
1545 */
1546 static BOOL parse_protocol_ID(PTInstVar pvar, char *ID)
1547 {
1548 char *str;
1549
1550 for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1551 }
1552
1553 if (*str != '.') {
1554 return FALSE;
1555 }
1556
1557 pvar->protocol_major = atoi(ID + 4);
1558 pvar->protocol_minor = atoi(str + 1);
1559
1560 for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1561 }
1562
1563 return *str == '-';
1564 }
1565
1566 /*
1567 On entry, the pvar->protocol_xxx fields hold the server's advertised
1568 protocol number. We replace the fields with the protocol number we will
1569 actually use, or return FALSE if there is no usable protocol version.
1570 */
1571 static int negotiate_protocol(PTInstVar pvar)
1572 {
1573 switch (pvar->protocol_major) {
1574 case 1:
1575 if (pvar->protocol_minor == 99 &&
1576 pvar->settings.ssh_protocol_version == 2) {
1577 // �T�[�o�� 1.99 �����[�U�� SSH2 ���I������������������
1578 // 2.0 ����������
1579 pvar->protocol_major = 2;
1580 pvar->protocol_minor = 0;
1581 return 0;
1582 }
1583
1584 if (pvar->settings.ssh_protocol_version == 2) {
1585 // �o�[�W��������
1586 return -1;
1587 }
1588
1589 if (pvar->protocol_minor > 5) {
1590 pvar->protocol_minor = 5;
1591 }
1592
1593 return 0;
1594
1595 // for SSH2(yutaka)
1596 case 2:
1597 if (pvar->settings.ssh_protocol_version == 1) {
1598 // �o�[�W��������
1599 return -1;
1600 }
1601
1602 return 0; // SSH2 support
1603
1604 default:
1605 return 1;
1606 }
1607 }
1608
1609 static void init_protocol(PTInstVar pvar)
1610 {
1611 CRYPT_initialize_random_numbers(pvar);
1612
1613 // known_hosts�t�@�C�������z�X�g���J������������������
1614 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1615
1616 /* while we wait for a response from the server... */
1617
1618 if (SSHv1(pvar)) {
1619 enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1620 enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1621 enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1622 enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1623
1624 } else { // for SSH2(yutaka)
1625 enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1626 enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1627 enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1628 enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1629 enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1630 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1631 enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1632 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1633 enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1634 enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1635 enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1636 enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1637 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_msg60);
1638
1639 enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1640
1641 // ���[�U�F�������f�B�X�p�b�`���[�`��
1642 enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1643 enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1644 enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1645 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1646 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1647 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1648 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1649 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1650 enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1651 enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1652 enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1653 enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_SSH2_client_global_request);
1654 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1655 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1656
1657 client_init_global_confirm();
1658
1659 }
1660 }
1661
1662 void server_version_check(PTInstVar pvar)
1663 {
1664 char *server_swver;
1665
1666 pvar->server_compat_flag = 0;
1667
1668 if ((server_swver = strchr(pvar->server_version_string+4, '-')) == NULL) {
1669 logputs(LOG_LEVEL_WARNING, "Can't get server software version string.");
1670 return;
1671 }
1672 server_swver++;
1673
1674 if (strncmp(server_swver, "Cisco-1", 7) == 0) {
1675 pvar->server_compat_flag |= SSH_BUG_DHGEX_LARGE;
1676 logputs(LOG_LEVEL_INFO, "Server version string is matched to \"Cisco-1\", compatibility flag SSH_BUG_DHGEX_LARGE is enabled.");
1677 }
1678 }
1679
1680 BOOL SSH_handle_server_ID(PTInstVar pvar, char *ID, int ID_len)
1681 {
1682 static char prefix[64];
1683 int negotiate;
1684 char uimsg[MAX_UIMSG];
1685
1686 // initialize SSH2 memory dump (2005.3.7 yutaka)
1687 init_memdump();
1688 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1689
1690 if (ID_len <= 0) {
1691 return FALSE;
1692 } else {
1693 int buf_len;
1694 char *buf;
1695
1696 strncpy_s(prefix, sizeof(prefix), "Received server identification string: ", _TRUNCATE);
1697 buf_len = strlen(prefix) + ID_len + 1;
1698 buf = (char *) malloc(buf_len);
1699 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1700 strncat_s(buf, buf_len, ID, _TRUNCATE);
1701 chop_newlines(buf);
1702 logputs(LOG_LEVEL_VERBOSE, buf);
1703 free(buf);
1704
1705 if (ID[ID_len - 1] != '\n') {
1706 pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1707 return FALSE;
1708 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1709 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1710 return FALSE;
1711 } else if (strncmp(ID, "SSH-", 4) != 0) {
1712 return FALSE;
1713 } else {
1714 ID[ID_len - 1] = 0;
1715
1716 if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1717 ID[ID_len - 2] = 0;
1718 }
1719
1720 pvar->ssh_state.server_ID = _strdup(ID);
1721
1722 if (!parse_protocol_ID(pvar, ID)) {
1723 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1724 "This program does not understand the server's version of the protocol.");
1725 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1726 }
1727 else if ((negotiate = negotiate_protocol(pvar)) == 1) {
1728 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1729 "This program does not understand the server's version of the protocol.");
1730 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1731 }
1732 else if (negotiate == -1) {
1733 UTIL_get_lang_msg("MSG_SSH_VERSION_MISMATCH", pvar,
1734 "Protocol version mismatch. server:%d.%d client:%d");
1735 _snprintf_s(uimsg, sizeof(uimsg), _TRUNCATE, pvar->ts->UIMsg,
1736 pvar->protocol_major, pvar->protocol_minor, pvar->settings.ssh_protocol_version);
1737 notify_fatal_error(pvar, uimsg, TRUE);
1738 }
1739 else {
1740 char TTSSH_ID[1024];
1741 int TTSSH_ID_len;
1742
1743 // SSH �o�[�W������ teraterm �����Z�b�g����
1744 // SCP �R�}���h������ (2008.2.3 maya)
1745 pvar->cv->isSSH = pvar->protocol_major;
1746
1747 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1748 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1749 "SSH-%d.%d-TTSSH/%d.%d Win32\r\n",
1750 pvar->protocol_major, pvar->protocol_minor,
1751 TTSSH_VERSION_MAJOR, TTSSH_VERSION_MINOR);
1752 TTSSH_ID_len = strlen(TTSSH_ID);
1753
1754 // for SSH2(yutaka)
1755 // �N���C�A���g�o�[�W�����������i���s���������������j
1756 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1757 TTSSH_ID, _TRUNCATE);
1758
1759 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1760 _snprintf_s(pvar->server_version_string,
1761 sizeof(pvar->server_version_string), _TRUNCATE,
1762 "%s", pvar->ssh_state.server_ID);
1763
1764 // �T�[�o�o�[�W�������`�F�b�N
1765 server_version_check(pvar);
1766
1767 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len, 0) != TTSSH_ID_len) {
1768 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1769 "An error occurred while sending the SSH ID string.\n"
1770 "The connection will close.");
1771 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1772 } else {
1773 // ���s������
1774 chop_newlines(pvar->client_version_string);
1775 logprintf(LOG_LEVEL_VERBOSE, "Sent client identification string: %s", pvar->client_version_string);
1776
1777 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1778 push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1779
1780 // SSH�n���h�����o�^���s��
1781 init_protocol(pvar);
1782
1783 SSH2_dispatch_init(1);
1784 SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1785 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1786 SSH2_dispatch_add_message(SSH2_MSG_DEBUG);
1787 }
1788 }
1789
1790 return TRUE;
1791 }
1792 }
1793 }
1794
1795 static BOOL handle_exit(PTInstVar pvar)
1796 {
1797 if (grab_payload(pvar, 4)) {
1798 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1799 finish_send_packet(pvar);
1800 notify_closed_connection(pvar, "disconnected by server request");
1801 }
1802 return TRUE;
1803 }
1804
1805 static BOOL handle_data(PTInstVar pvar)
1806 {
1807 if (grab_payload_limited(pvar, 4)) {
1808 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1809 pvar->ssh_state.payload_datastart = 4;
1810 }
1811 return TRUE;
1812 }
1813
1814 static BOOL handle_channel_open(PTInstVar pvar)
1815 {
1816 int host_len;
1817 int originator_len;
1818
1819 if ((pvar->ssh_state.
1820 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1821 if (grab_payload(pvar, 8)
1822 && grab_payload(pvar,
1823 8 + (host_len = get_payload_uint32(pvar, 4)))
1824 && grab_payload(pvar, originator_len =
1825 get_payload_uint32(pvar, host_len + 12))) {
1826 int local_port = get_payload_uint32(pvar, 8 + host_len);
1827
1828 pvar->ssh_state.payload[8 + host_len] = 0;
1829 FWD_open(pvar, get_payload_uint32(pvar, 0),
1830 pvar->ssh_state.payload + 8, local_port,
1831 pvar->ssh_state.payload + 16 + host_len,
1832 originator_len,
1833 NULL);
1834 }
1835 } else {
1836 if (grab_payload(pvar, 8)
1837 && grab_payload(pvar,
1838 4 + (host_len = get_payload_uint32(pvar, 4)))) {
1839 int local_port = get_payload_uint32(pvar, 8 + host_len);
1840
1841 pvar->ssh_state.payload[8 + host_len] = 0;
1842 FWD_open(pvar, get_payload_uint32(pvar, 0),
1843 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1844 NULL);
1845 }
1846 }
1847
1848 return TRUE;
1849 }
1850
1851 static BOOL handle_X11_channel_open(PTInstVar pvar)
1852 {
1853 int originator_len;
1854
1855 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1856 if (grab_payload(pvar, 8)
1857 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1858 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1859 pvar->ssh_state.payload + 8, originator_len, NULL);
1860 }
1861 } else {
1862 if (grab_payload(pvar, 4)) {
1863 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1864 }
1865 }
1866
1867 return TRUE;
1868 }
1869
1870 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1871 {
1872 if (grab_payload(pvar, 8)) {
1873 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1874 get_payload_uint32(pvar, 4));
1875 }
1876 return FALSE;
1877 }
1878
1879 static BOOL handle_channel_open_failure(PTInstVar pvar)
1880 {
1881 if (grab_payload(pvar, 4)) {
1882 FWD_failed_open(pvar, get_payload_uint32(pvar, 0), -1);
1883 }
1884 return FALSE;
1885 }
1886
1887 static BOOL handle_channel_data(PTInstVar pvar)
1888 {
1889 int len;
1890
1891 if (grab_payload(pvar, 8)
1892 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1893 FWDChannel *channel;
1894 int local_channel_num = get_payload_uint32(pvar, 0);
1895 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1896 return FALSE;
1897 }
1898 channel = pvar->fwd_state.channels + local_channel_num;
1899 if (channel->type == TYPE_AGENT) {
1900 SSH_agent_response(pvar, NULL, local_channel_num,
1901 pvar->ssh_state.payload + 8, len);
1902 }
1903 else {
1904 FWD_received_data(pvar, local_channel_num,
1905 pvar->ssh_state.payload + 8, len);
1906 }
1907 }
1908 return TRUE;
1909 }
1910
1911 static BOOL handle_channel_input_eof(PTInstVar pvar)
1912 {
1913 if (grab_payload(pvar, 4)) {
1914 int local_channel_num = get_payload_uint32(pvar, 0);
1915 FWDChannel *channel;
1916 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1917 return FALSE;
1918 }
1919 channel = pvar->fwd_state.channels + local_channel_num;
1920 if (channel->type == TYPE_AGENT) {
1921 channel->status |= FWD_CLOSED_REMOTE_IN;
1922 SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1923 }
1924 else {
1925 FWD_channel_input_eof(pvar, local_channel_num);
1926 }
1927 }
1928 return TRUE;
1929 }
1930
1931 static BOOL handle_channel_output_eof(PTInstVar pvar)
1932 {
1933 if (grab_payload(pvar, 4)) {
1934 int local_channel_num = get_payload_uint32(pvar, 0);
1935 FWDChannel *channel;
1936 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1937 return FALSE;
1938 }
1939 channel = pvar->fwd_state.channels + local_channel_num;
1940 if (channel->type == TYPE_AGENT) {
1941 channel->status |= FWD_CLOSED_REMOTE_OUT;
1942 SSH_channel_output_eof(pvar, channel->remote_num);
1943 FWD_free_channel(pvar, local_channel_num);
1944 }
1945 else {
1946 FWD_channel_output_eof(pvar, local_channel_num);
1947 }
1948 }
1949 return TRUE;
1950 }
1951
1952 static BOOL handle_agent_open(PTInstVar pvar)
1953 {
1954 if (grab_payload(pvar, 4)) {
1955 int remote_id = get_payload_uint32(pvar, 0);
1956 int local_id;
1957
1958 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
1959 local_id = FWD_agent_open(pvar, remote_id);
1960 if (local_id == -1) {
1961 SSH_fail_channel_open(pvar, remote_id);
1962 }
1963 else {
1964 SSH_confirm_channel_open(pvar, remote_id, local_id);
1965 }
1966 }
1967 else {
1968 SSH_fail_channel_open(pvar, remote_id);
1969 }
1970 }
1971 /*
1972 else {
1973 // ���m��������channel����������������������������
1974 }
1975 */
1976
1977 return TRUE;
1978 }
1979
1980
1981
1982 // �n���h�����O�������b�Z�[�W����������
1983
1984 #define HANDLE_MESSAGE_MAX 30
1985 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1986 static int handle_message_count = 0;
1987 static int handle_message_stage = 0;
1988
1989 void SSH2_dispatch_init(int stage)
1990 {
1991 handle_message_count = 0;
1992 handle_message_stage = stage;
1993 }
1994
1995 int SSH2_dispatch_enabled_check(unsigned char message)
1996 {
1997 int i;
1998
1999 for (i = 0 ; i < handle_message_count ; i++) {
2000 if (handle_messages[i] == message)
2001 return 1;
2002 }
2003 return 0;
2004 }
2005
2006 void SSH2_dispatch_add_message(unsigned char message)
2007 {
2008 int i;
2009
2010 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2011 // TODO: error check
2012 logprintf(LOG_LEVEL_ERROR, __FUNCTION__ ": too many handlers. handlers:%d, max:%d",
2013 handle_message_count, HANDLE_MESSAGE_MAX);
2014 return;
2015 }
2016
2017 // �������o�^�������������b�Z�[�W������������
2018 for (i=0; i<handle_message_count; i++) {
2019 if (handle_messages[i] == message) {
2020 return;
2021 }
2022 }
2023
2024 handle_messages[handle_message_count++] = message;
2025 }
2026
2027 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2028 {
2029 unsigned char c;
2030
2031 for (c = begin ; c <= end ; c++) {
2032 SSH2_dispatch_add_message(c);
2033 }
2034 }
2035
2036
2037 void SSH_handle_packet(PTInstVar pvar, char *data, int len, int padding)
2038 {
2039 unsigned char message = prep_packet(pvar, data, len, padding);
2040
2041 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2042 if (message != SSH_MSG_NONE) {
2043 // ���b�Z�[�W�^�C�v���������n���h�����N��
2044 SSHPacketHandler handler = get_handler(pvar, message);
2045
2046 // for SSH2(yutaka)
2047 if (SSHv2(pvar)) {
2048 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2049 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2050 char buf[1024];
2051
2052 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar, "Unexpected SSH2 message(%d) on current stage(%d)");
2053 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);
2054 notify_fatal_error(pvar, buf, TRUE);
2055 return;
2056 }
2057 }
2058
2059 if (handler == NULL) {
2060 if (SSHv1(pvar)) {
2061 char buf[1024];
2062
2063 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar, "Unexpected packet type received: %d");
2064 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);
2065 notify_fatal_error(pvar, buf, TRUE);
2066 } else {
2067 unsigned char *outmsg = begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2068
2069 set_uint32(outmsg, pvar->ssh_state.receiver_sequence_number - 1);
2070 finish_send_packet(pvar);
2071
2072 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().");
2073 /* XXX need to decompress incoming packet, but how? */
2074 }
2075 } else {
2076 if (!handler(pvar)) {
2077 deque_handlers(pvar, message);
2078 }
2079 }
2080 }
2081 }
2082
2083 static BOOL handle_pty_success(PTInstVar pvar)
2084 {
2085 FWD_enter_interactive_mode(pvar);
2086 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2087 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2088 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2089 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2090 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF, handle_channel_input_eof);
2091 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, handle_channel_output_eof);
2092 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2093 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2094 enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2095 return FALSE;
2096 }
2097
2098 static BOOL handle_pty_failure(PTInstVar pvar)
2099 {
2100 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2101 "The server cannot allocate a pseudo-terminal. "
2102 "You may encounter some problems with the terminal.");
2103 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2104 return handle_pty_success(pvar);
2105 }
2106
2107 static void prep_pty(PTInstVar pvar)
2108 {
2109 int len = strlen(pvar->ts->TermType);
2110 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY, 4 + len + 16 + sizeof(ssh_ttymodes));
2111 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2112 static const SSHPacketHandler handlers[]
2113 = { handle_pty_success, handle_pty_failure };
2114 int x, y;
2115
2116 get_window_pixel_size(pvar, &x, &y);
2117
2118 set_uint32(outmsg, len);
2119 memcpy(outmsg + 4, pvar->ts->TermType, len);
2120 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2121 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2122 set_uint32(outmsg + 4 + len + 8, x);
2123 set_uint32(outmsg + 4 + len + 12, y);
2124 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2125 finish_send_packet(pvar);
2126
2127 enque_handlers(pvar, 2, msgs, handlers);
2128
2129 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2130 finish_send_packet(pvar);
2131 }
2132
2133 static BOOL handle_agent_request_success(PTInstVar pvar)
2134 {
2135 pvar->agentfwd_enable = TRUE;
2136 prep_pty(pvar);
2137 return FALSE;
2138 }
2139
2140 static BOOL handle_agent_request_failure(PTInstVar pvar)
2141 {
2142 prep_pty(pvar);
2143 return FALSE;
2144 }
2145
2146 static void prep_agent_request(PTInstVar pvar)
2147 {
2148 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2149 static const SSHPacketHandler handlers[] = { handle_agent_request_success, handle_agent_request_failure };
2150
2151 enque_handlers(pvar, 2, msgs, handlers);
2152
2153 begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2154 finish_send_packet(pvar);
2155 }
2156
2157 static void prep_forwarding(PTInstVar pvar)
2158 {
2159 FWD_prep_forwarding(pvar);
2160
2161 if (pvar->session_settings.ForwardAgent) {
2162 prep_agent_request(pvar);
2163 }
2164 else {
2165 prep_pty(pvar);
2166 }
2167 }
2168
2169 //
2170 //
2171 // (2005.7.10 yutaka)
2172 static void enable_send_compression(PTInstVar pvar)
2173 {
2174 static int initialize = 0;
2175
2176 if (initialize) {
2177 deflateEnd(&pvar->ssh_state.compress_stream);
2178 }
2179 initialize = 1;
2180
2181 pvar->ssh_state.compress_stream.zalloc = NULL;
2182 pvar->ssh_state.compress_stream.zfree = NULL;
2183 pvar->ssh_state.compress_stream.opaque = NULL;
2184 if (deflateInit(&pvar->ssh_state.compress_stream, pvar->ssh_state.compression_level) != Z_OK) {
2185 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2186 "An error occurred while setting up compression.\n"
2187 "The connection will close.");
2188 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2189 return;
2190 } else {
2191 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2192 if (SSHv2(pvar)) {
2193 pvar->ssh_state.compressing = FALSE;
2194 } else {
2195 pvar->ssh_state.compressing = TRUE;
2196 }
2197 }
2198 }
2199
2200 static void enable_recv_compression(PTInstVar pvar)
2201 {
2202 static int initialize = 0;
2203
2204 if (initialize) {
2205 deflateEnd(&pvar->ssh_state.decompress_stream);
2206 }
2207 initialize = 1;
2208
2209 pvar->ssh_state.decompress_stream.zalloc = NULL;
2210 pvar->ssh_state.decompress_stream.zfree = NULL;
2211 pvar->ssh_state.decompress_stream.opaque = NULL;
2212 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2213 deflateEnd(&pvar->ssh_state.compress_stream);
2214 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2215 "An error occurred while setting up compression.\n"
2216 "The connection will close.");
2217 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2218 return;
2219 } else {
2220 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2221 if (SSHv2(pvar)) {
2222 pvar->ssh_state.decompressing = FALSE;
2223 } else {
2224 pvar->ssh_state.decompressing = TRUE;
2225 }
2226
2227 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf, &pvar->ssh_state.postdecompress_inbuflen, 1000);
2228 }
2229 }
2230
2231 static void enable_compression(PTInstVar pvar)
2232 {
2233 enable_send_compression(pvar);
2234 enable_recv_compression(pvar);
2235
2236 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2237 if (SSHv2(pvar)) {
2238 pvar->ssh_state.compressing = FALSE;
2239 pvar->ssh_state.decompressing = FALSE;
2240 }
2241 }
2242
2243 static BOOL handle_enable_compression(PTInstVar pvar)
2244 {
2245 enable_compression(pvar);
2246 prep_forwarding(pvar);
2247 return FALSE;
2248 }
2249
2250 static BOOL handle_disable_compression(PTInstVar pvar)
2251 {
2252 prep_forwarding(pvar);
2253 return FALSE;
2254 }
2255
2256 static void prep_compression(PTInstVar pvar)
2257 {
2258 if (pvar->session_settings.CompressionLevel > 0) {
2259 // added if statement (2005.7.10 yutaka)
2260 if (SSHv1(pvar)) {
2261 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2262 static const SSHPacketHandler handlers[] = { handle_enable_compression, handle_disable_compression };
2263
2264 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2265
2266 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2267 finish_send_packet(pvar);
2268
2269 enque_handlers(pvar, 2, msgs, handlers);
2270 }
2271
2272 pvar->ssh_state.compression_level = pvar->session_settings.CompressionLevel;
2273
2274 } else {
2275 // added if statement (2005.7.10 yutaka)
2276 if (SSHv1(pvar)) {
2277 prep_forwarding(pvar);
2278 }
2279 }
2280 }
2281
2282 static void enque_simple_auth_handlers(PTInstVar pvar)
2283 {
2284 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2285 static const SSHPacketHandler handlers[] = { handle_auth_success, handle_auth_failure };
2286
2287 enque_handlers(pvar, 2, msgs, handlers);
2288 }
2289
2290 static BOOL handle_rsa_challenge(PTInstVar pvar)
2291 {
2292 int challenge_bytes;
2293
2294 if (!grab_payload(pvar, 2)) {
2295 return FALSE;
2296 }
2297
2298 challenge_bytes = get_mpint_len(pvar, 0);
2299
2300 if (grab_payload(pvar, challenge_bytes)) {
2301 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2302
2303 if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2304 if (CRYPT_generate_RSA_challenge_response
2305 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2306
2307 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2308 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2309 //AUTH_destroy_cur_cred(pvar);
2310
2311 finish_send_packet(pvar);
2312
2313 enque_simple_auth_handlers(pvar);
2314 } else {
2315 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2316 "An error occurred while decrypting the RSA challenge.\n"
2317 "Perhaps the key file is corrupted.");
2318 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2319 }
2320 }
2321 else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2322 int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2323 int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2324 int server_key_bytes = (server_key_bits + 7) / 8;
2325 int host_key_bytes = (host_key_bits + 7) / 8;
2326 int session_buf_len = server_key_bytes + host_key_bytes + 8;
2327 char *session_buf = (char *) malloc(session_buf_len);
2328 unsigned char session_id[16];
2329
2330 unsigned char *hash;
2331 int pubkeylen, hashlen;
2332
2333 /* Pageant ���n�b�V�����v�Z���������� */
2334 // ���J��������
2335 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey, pvar->pageant_keylistlen);
2336 // �Z�b�V����ID������
2337 BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2338 BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n, session_buf + host_key_bytes);
2339 memcpy(session_buf + server_key_bytes + host_key_bytes, pvar->crypt_state.server_cookie, 8);
2340 MD5(session_buf, session_buf_len, session_id);
2341 // �n�b�V������������
2342 hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2343 pubkeylen,
2344 pvar->ssh_state.payload,
2345 challenge_bytes + 2,
2346 session_id,
2347 &hashlen);
2348
2349 // �n�b�V�������M
2350 memcpy(outmsg, hash, 16);
2351 free(hash);
2352
2353 finish_send_packet(pvar);
2354
2355 enque_simple_auth_handlers(pvar);
2356 }
2357 }
2358
2359 return FALSE;
2360 }
2361
2362 static void try_send_credentials(PTInstVar pvar)
2363 {
2364 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2365 AUTHCred *cred = AUTH_get_cur_cred(pvar);
2366 static const int RSA_msgs[] =
2367 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2368 static const SSHPacketHandler RSA_handlers[]
2369 = { handle_rsa_challenge, handle_rsa_auth_refused };
2370 static const int TIS_msgs[] =
2371 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2372 static const SSHPacketHandler TIS_handlers[]
2373 = { handle_TIS_challenge, handle_auth_failure };
2374
2375 // SSH2���������������������X�L�b�v
2376 if (SSHv2(pvar))
2377 goto skip_ssh2;
2378
2379 switch (cred->method) {
2380 case SSH_AUTH_NONE:
2381 return;
2382 case SSH_AUTH_PASSWORD:{
2383 int len = strlen(cred->password);
2384 unsigned char *outmsg =
2385 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2386 4 + len);
2387
2388 logputs(LOG_LEVEL_VERBOSE, "Trying PASSWORD authentication...");
2389
2390 set_uint32(outmsg, len);
2391 memcpy(outmsg + 4, cred->password, len);
2392
2393 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2394 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2395 //AUTH_destroy_cur_cred(pvar);
2396
2397 enque_simple_auth_handlers(pvar);
2398 break;
2399 }
2400 case SSH_AUTH_RHOSTS:{
2401 int len = strlen(cred->rhosts_client_user);
2402 unsigned char *outmsg =
2403 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2404
2405 logputs(LOG_LEVEL_VERBOSE, "Trying RHOSTS authentication...");
2406
2407 set_uint32(outmsg, len);
2408 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2409 AUTH_destroy_cur_cred(pvar);
2410 enque_simple_auth_handlers(pvar);
2411 break;
2412 }
2413 case SSH_AUTH_RSA:{
2414 int len = BN_num_bytes(cred->key_pair->rsa->n);
2415 unsigned char *outmsg =
2416 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2417
2418 logputs(LOG_LEVEL_VERBOSE, "Trying RSA authentication...");
2419
2420 set_ushort16_MSBfirst(outmsg, len * 8);
2421 BN_bn2bin(cred->key_pair->rsa->n, outmsg + 2);
2422 /* don't destroy the current credentials yet */
2423 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2424 break;
2425 }
2426 case SSH_AUTH_RHOSTS_RSA:{
2427 int mod_len = BN_num_bytes(cred->key_pair->rsa->n);
2428 int name_len = strlen(cred->rhosts_client_user);
2429 int exp_len = BN_num_bytes(cred->key_pair->rsa->e);
2430 int index;
2431 unsigned char *outmsg =
2432 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2433 12 + mod_len + name_len + exp_len);
2434
2435 logputs(LOG_LEVEL_VERBOSE, "Trying RHOSTS+RSA authentication...");
2436
2437 set_uint32(outmsg, name_len);
2438 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2439 index = 4 + name_len;
2440
2441 set_uint32(outmsg + index, 8 * mod_len);
2442 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2443 BN_bn2bin(cred->key_pair->rsa->e, outmsg + index + 6);
2444 index += 6 + exp_len;
2445
2446 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2447 BN_bn2bin(cred->key_pair->rsa->n, outmsg + index + 2);
2448 /* don't destroy the current credentials yet */
2449 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2450 break;
2451 }
2452 case SSH_AUTH_PAGEANT:{
2453 unsigned char *outmsg;
2454 unsigned char *pubkey;
2455 int len, bn_bytes;
2456
2457 if (pvar->pageant_keycurrent != 0) {
2458 // ���O�������X�L�b�v
2459 pvar->pageant_curkey += 4;
2460 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2461 bn_bytes = (len + 7) / 8;
2462 pvar->pageant_curkey += 2 + bn_bytes;
2463 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2464 bn_bytes = (len + 7) / 8;
2465 pvar->pageant_curkey += 2 + bn_bytes;
2466 // ���O�������R�����g���X�L�b�v
2467 len = get_uint32_MSBfirst(pvar->pageant_curkey);
2468 pvar->pageant_curkey += 4 + len;
2469 // �����������u������
2470 }
2471 pubkey = pvar->pageant_curkey + 4;
2472 len = get_ushort16_MSBfirst(pubkey);
2473 bn_bytes = (len + 7) / 8;
2474 pubkey += 2 + bn_bytes;
2475 len = get_ushort16_MSBfirst(pubkey);
2476 bn_bytes = (len + 7) / 8;
2477 pubkey += 2;
2478 outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2479
2480 logputs(LOG_LEVEL_VERBOSE, "Trying RSA authentication...");
2481
2482 set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2483 memcpy(outmsg + 2, pubkey, bn_bytes);
2484 /* don't destroy the current credentials yet */
2485
2486 pvar->pageant_keycurrent++;
2487
2488 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2489 break;
2490 }
2491 case SSH_AUTH_TIS:{
2492 if (cred->password == NULL) {
2493 unsigned char *outmsg =
2494 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2495
2496 logputs(LOG_LEVEL_VERBOSE, "Trying TIS authentication...");
2497 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2498 } else {
2499 int len = strlen(cred->password);
2500 unsigned char *outmsg =
2501 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2502 4 + len);
2503
2504 logputs(LOG_LEVEL_VERBOSE, "Sending TIS response");
2505
2506 set_uint32(outmsg, len);
2507 memcpy(outmsg + 4, cred->password, len);
2508 enque_simple_auth_handlers(pvar);
2509 }
2510
2511 AUTH_destroy_cur_cred(pvar);
2512 break;
2513 }
2514 default:
2515 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2516 "Internal error: unsupported authentication method");
2517 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2518 return;
2519 }
2520
2521 finish_send_packet(pvar);
2522
2523 skip_ssh2:;
2524 destroy_packet_buf(pvar);
2525
2526 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2527 }
2528 }
2529
2530 static void try_send_user_name(PTInstVar pvar)
2531 {
2532 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2533 char *username = AUTH_get_user_name(pvar);
2534
2535 if (username != NULL) {
2536 int len = strlen(username);
2537 unsigned char *outmsg =
2538 begin_send_packet(pvar, SSH_CMSG_USER, 4 + len);
2539 static const int msgs[] =
2540 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2541 static const SSHPacketHandler handlers[]
2542 = { handle_noauth_success, handle_auth_required };
2543
2544 set_uint32(outmsg, len);
2545 memcpy(outmsg + 4, username, len);
2546 finish_send_packet(pvar);
2547
2548 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2549
2550 logprintf(LOG_LEVEL_VERBOSE, "Sending user name: %s", username);
2551
2552 enque_handlers(pvar, 2, msgs, handlers);
2553 }
2554 }
2555 }
2556
2557 static void send_session_key(PTInstVar pvar)
2558 {
2559 int encrypted_session_key_len;
2560 unsigned char *outmsg;
2561
2562 if (SSHv1(pvar)) {
2563 encrypted_session_key_len =
2564 CRYPT_get_encrypted_session_key_len(pvar);
2565 }
2566
2567 if (!CRYPT_choose_ciphers(pvar))
2568 return;
2569
2570 if (SSHv1(pvar)) {
2571 outmsg =
2572 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2573 15 + encrypted_session_key_len);
2574 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2575 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2576 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2577 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2578 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2579 return;
2580 set_uint32(outmsg + 11 + encrypted_session_key_len,
2581 SSH_PROTOFLAG_SCREEN_NUMBER |
2582 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2583 finish_send_packet(pvar);
2584 }
2585
2586 if (!CRYPT_start_encryption(pvar, 1, 1))
2587 return;
2588 notify_established_secure_connection(pvar);
2589
2590 if (SSHv1(pvar)) {
2591 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2592 }
2593
2594 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2595
2596 if (SSHv1(pvar)) {
2597 try_send_user_name(pvar);
2598 }
2599 }
2600
2601 /*************************
2602 END of message handlers
2603 ************************/
2604
2605 void SSH_init(PTInstVar pvar)
2606 {
2607 int i;
2608
2609 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2610 buf_create(&pvar->ssh_state.precompress_outbuf,
2611 &pvar->ssh_state.precompress_outbuflen);
2612 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2613 &pvar->ssh_state.postdecompress_inbuflen);
2614 pvar->ssh_state.payload = NULL;
2615 pvar->ssh_state.compressing = FALSE;
2616 pvar->ssh_state.decompressing = FALSE;
2617 pvar->ssh_state.status_flags =
2618 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2619 pvar->ssh_state.payload_datalen = 0;
2620 pvar->ssh_state.hostname = NULL;
2621 pvar->ssh_state.server_ID = NULL;
2622 pvar->ssh_state.receiver_sequence_number = 0;
2623 pvar->ssh_state.sender_sequence_number = 0;
2624 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2625 pvar->ssh_state.packet_handlers[i] = NULL;
2626 }
2627
2628 // for SSH2(yutaka)
2629 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2630 pvar->userauth_success = 0;
2631 pvar->session_nego_status = 0;
2632 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2633 pvar->rekeying = 0;
2634 pvar->key_done = 0;
2635 pvar->ssh2_autologin = 0; // autologin disabled(default)
2636 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2637 pvar->userauth_retry_count = 0;
2638 pvar->decomp_buffer = NULL;
2639 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2640 pvar->tryed_ssh2_authlist = FALSE;
2641 pvar->agentfwd_enable = FALSE;
2642
2643 }
2644
2645 void SSH_open(PTInstVar pvar)
2646 {
2647 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2648 pvar->ssh_state.tcpport = pvar->ts->TCPPort;
2649 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2650 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2651 }
2652
2653 void SSH_notify_disconnecting(PTInstVar pvar, char *reason)
2654 {
2655 if (SSHv1(pvar)) {
2656 int len = reason == NULL ? 0 : strlen(reason);
2657 unsigned char *outmsg =
2658 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2659
2660 set_uint32(outmsg, len);
2661 if (reason != NULL) {
2662 memcpy(outmsg + 4, reason, len);
2663 }
2664 finish_send_packet(pvar);
2665
2666 } else { // for SSH2(yutaka)
2667 buffer_t *msg;
2668 unsigned char *outmsg;
2669 char *s;
2670 int len;
2671
2672 // SSH2 server��disconnect���`����
2673 msg = buffer_init();
2674 if (msg == NULL) {
2675 // TODO: error check
2676 logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_init returns NULL.");
2677 return;
2678 }
2679 buffer_put_int(msg, SSH2_DISCONNECT_BY_APPLICATION);
2680 buffer_put_string(msg, reason, strlen(reason));
2681 s = "";
2682 buffer_put_string(msg, s, strlen(s));
2683
2684 len = buffer_len(msg);
2685 outmsg = begin_send_packet(pvar, SSH2_MSG_DISCONNECT, len);
2686 memcpy(outmsg, buffer_ptr(msg), len);
2687 finish_send_packet(pvar);
2688 buffer_free(msg);
2689
2690 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_DISCONNECT was sent at SSH_notify_disconnecting().");
2691 }
2692 }
2693
2694 void SSH_notify_host_OK(PTInstVar pvar)
2695 {
2696 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2697 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2698 send_session_key(pvar);
2699 }
2700 }
2701
2702 static void get_window_pixel_size(PTInstVar pvar, int *x, int *y)
2703 {
2704 RECT r;
2705
2706 if (pvar->cv->HWin && GetWindowRect(pvar->cv->HWin, &r)) {
2707 *x = r.right - r.left;
2708 *y = r.bottom - r.top;
2709 }
2710 else {
2711 *x = 0;
2712 *y = 0;
2713 }
2714
2715 return;
2716 }
2717
2718 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2719 {
2720 int x, y;
2721
2722 pvar->ssh_state.win_cols = cols;
2723 pvar->ssh_state.win_rows = rows;
2724
2725 get_window_pixel_size(pvar, &x, &y);
2726
2727 if (SSHv1(pvar)) {
2728 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2729 unsigned char *outmsg =
2730 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2731
2732 set_uint32(outmsg, rows); // window height (characters)
2733 set_uint32(outmsg + 4, cols); // window width (characters)
2734 set_uint32(outmsg + 8, x); // window width (pixels)
2735 set_uint32(outmsg + 12, y); // window height (pixels)
2736 finish_send_packet(pvar);
2737 logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ ": sending SSH_CMSG_WINDOW_SIZE. "
2738 "cols: %d, rows: %d, x: %d, y: %d", cols, rows, x, y);
2739 }
2740
2741 } else if (SSHv2(pvar)) {
2742 // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2743 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2744 buffer_t *msg;
2745 char *req_type = "window-change";
2746 unsigned char *outmsg;
2747 int len;
2748 Channel_t *c;
2749
2750 c = ssh2_channel_lookup(pvar->shell_id);
2751 if (c == NULL) {
2752 logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": shell channel not found.");
2753 return;
2754 }
2755
2756
2757 msg = buffer_init();
2758 if (msg == NULL) {
2759 // TODO: error check
2760 logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_init returns NULL.");
2761 return;
2762 }
2763 buffer_put_int(msg, c->remote_id);
2764 buffer_put_string(msg, req_type, strlen(req_type));
2765 buffer_put_char(msg, 0); // want_reply
2766 buffer_put_int(msg, cols); // columns
2767 buffer_put_int(msg, rows); // lines
2768 buffer_put_int(msg, x); // window width (pixel):
2769 buffer_put_int(msg, y); // window height (pixel):
2770 len = buffer_len(msg);
2771 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2772 memcpy(outmsg, buffer_ptr(msg), len);
2773 finish_send_packet(pvar);
2774 buffer_free(msg);
2775
2776 logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ ": sending SSH2_MSG_CHANNEL_REQUEST. "
2777 "local: %d, remote: %d, request-type: %s, cols: %d, rows: %d, x: %d, y: %d",
2778 c->self_id, c->remote_id, req_type, cols, rows, x, y);
2779
2780 } else {
2781 // SSH�����������������������B
2782 }
2783 }
2784
2785 // �u���[�N�M�������� -- RFC 4335
2786 // OpenSSH ��"~B"�����������B
2787 // (2010.9.27 yutaka)
2788 int SSH_notify_break_signal(PTInstVar pvar)
2789 {
2790 int ret = 0;
2791
2792 if (SSHv2(pvar)) { // SSH2 ��������
2793 buffer_t *msg;
2794 char *req_type = "break";
2795 unsigned char *outmsg;
2796 int len;
2797 Channel_t *c;
2798
2799 c = ssh2_channel_lookup(pvar->shell_id);
2800 if (c == NULL) {
2801 logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": shell channel not found.");
2802 goto error;
2803 }
2804
2805 msg = buffer_init();
2806 if (msg == NULL) {
2807 logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_init returns NULL.");
2808 goto error;
2809 }
2810 buffer_put_int(msg, c->remote_id);
2811 buffer_put_string(msg, req_type, strlen(req_type));
2812 buffer_put_char(msg, 0); // want_reply
2813 buffer_put_int(msg, 1000); // break-length (msec)
2814 len = buffer_len(msg);
2815 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2816 memcpy(outmsg, buffer_ptr(msg), len);
2817 finish_send_packet(pvar);
2818 buffer_free(msg);
2819
2820 logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ ": sending SSH2_MSG_CHANNEL_REQUEST. "
2821 "local: %d, remote: %d, request-type: %s, break-length: %d",
2822 c->self_id, c->remote_id, req_type, 1000);
2823
2824 ret = 1;
2825 }
2826
2827 error:
2828 return (ret);
2829 }
2830
2831 int SSH_get_min_packet_size(PTInstVar pvar)
2832 {
2833 if (SSHv1(pvar)) {
2834 return 12;
2835 } else {
2836 int block_size = CRYPT_get_decryption_block_size(pvar);
2837
2838 return max(16, block_size);
2839 }
2840 }
2841
2842 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2843 at least 5 bytes must be decrypted */
2844 void SSH_predecrpyt_packet(PTInstVar pvar, char *data)
2845 {
2846 if (SSHv2(pvar)) {
2847 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2848 }
2849 }
2850
2851 int SSH_get_clear_MAC_size(PTInstVar pvar)
2852 {
2853 if (SSHv1(pvar)) {
2854 return 0;
2855 } else {
2856 return CRYPT_get_receiver_MAC_size(pvar);
2857 }
2858 }
2859
2860 void SSH_notify_user_name(PTInstVar pvar)
2861 {
2862 try_send_user_name(pvar);
2863 }
2864
2865 void SSH_notify_cred(PTInstVar pvar)
2866 {
2867 try_send_credentials(pvar);
2868 }
2869
2870 void SSH_send(PTInstVar pvar, unsigned char const *buf, unsigned int buflen)
2871 {
2872 // RAW�p�P�b�g�_���v������ (2008.8.15 yutaka)
2873 if (LogLevel(pvar, LOG_LEVEL_SSHDUMP)) {
2874 init_memdump();
2875 push_memdump("SSH sending packet", "SSH_send", (char *)buf, buflen);
2876 }
2877
2878 if (SSHv1(pvar)) {
2879 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2880 return;
2881 }
2882
2883 while (buflen > 0) {
2884 int len =
2885 buflen >
2886 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2887 unsigned char *outmsg =
2888 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2889
2890 set_uint32(outmsg, len);
2891
2892 if (pvar->ssh_state.compressing) {
2893 buf_ensure_size(&pvar->ssh_state.outbuf,
2894 &pvar->ssh_state.outbuflen,
2895 len + (len >> 6) + 50);
2896 pvar->ssh_state.compress_stream.next_in =
2897 pvar->ssh_state.precompress_outbuf;
2898 pvar->ssh_state.compress_stream.avail_in = 5;
2899 pvar->ssh_state.compress_stream.next_out =
2900 pvar->ssh_state.outbuf + 12;
2901 pvar->ssh_state.compress_stream.avail_out =
2902 pvar->ssh_state.outbuflen - 12;
2903
2904 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2905 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2906 "Error compressing packet data");
2907 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2908 return;
2909 }
2910
2911 pvar->ssh_state.compress_stream.next_in =
2912 (unsigned char *) buf;
2913 pvar->ssh_state.compress_stream.avail_in = len;
2914
2915 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
2916 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2917 "Error compressing packet data");
2918 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2919 return;
2920 }
2921 } else {
2922 memcpy(outmsg + 4, buf, len);
2923 }
2924
2925 finish_send_packet_special(pvar, 1);
2926
2927 buflen -= len;
2928 buf += len;
2929 }
2930
2931 } else { // for SSH2(yutaka)
2932 Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
2933 if (c == NULL) {
2934 logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": shell channel not found.");
2935 }
2936 else {
2937 SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen, 0);
2938 }
2939 }
2940
2941 }
2942
2943 int SSH_extract_payload(PTInstVar pvar, unsigned char *dest, int len)
2944 {
2945 int num_bytes = pvar->ssh_state.payload_datalen;
2946
2947 if (num_bytes > len) {
2948 num_bytes = len;
2949 }
2950
2951 if (!pvar->ssh_state.decompressing) {
2952 memcpy(dest,
2953 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
2954 num_bytes);
2955 pvar->ssh_state.payload_datastart += num_bytes;
2956 } else if (num_bytes > 0) {
2957 pvar->ssh_state.decompress_stream.next_out = dest;
2958 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
2959
2960 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
2961 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
2962 "Invalid compressed data in received packet");
2963 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2964 return 0;
2965 }
2966 }
2967
2968 pvar->ssh_state.payload_datalen -= num_bytes;
2969
2970 return num_bytes;
2971 }
2972
2973 void SSH_get_compression_info(PTInstVar pvar, char *dest, int len)
2974 {
2975 char buf[1024];
2976 char buf2[1024];
2977
2978 // added support of SSH2 packet compression (2005.7.10 yutaka)
2979 // support of "Compression delayed" (2006.6.23 maya)
2980 if (pvar->ssh_state.compressing ||
2981 pvar->ctos_compression == COMP_ZLIB ||
2982 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2983 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2984 unsigned long total_out =
2985 pvar->ssh_state.compress_stream.total_out;
2986
2987 if (total_out > 0) {
2988 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2989 "level %d; ratio %.1f (%ld:%ld)");
2990 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2991 pvar->ssh_state.compression_level,
2992 ((double) total_in) / total_out, total_in,
2993 total_out);
2994 } else {
2995 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2996 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2997 pvar->ssh_state.compression_level);
2998 }
2999 } else {
3000 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3001 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
3002 }
3003
3004 // support of "Compression delayed" (2006.6.23 maya)
3005 if (pvar->ssh_state.decompressing ||
3006 pvar->stoc_compression == COMP_ZLIB ||
3007 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3008 unsigned long total_in =
3009 pvar->ssh_state.decompress_stream.total_in;
3010 unsigned long total_out =
3011 pvar->ssh_state.decompress_stream.total_out;
3012
3013 if (total_in > 0) {
3014 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3015 "level %d; ratio %.1f (%ld:%ld)");
3016 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3017 pvar->ssh_state.compression_level,
3018 ((double) total_out) / total_in, total_out,
3019 total_in);
3020 } else {
3021 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3022 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3023 pvar->ssh_state.compression_level);
3024 }
3025 } else {
3026 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3027 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
3028 }
3029
3030 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
3031 "Upstream %s; Downstream %s");
3032 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
3033 }
3034
3035 void SSH_get_server_ID_info(PTInstVar pvar, char *dest, int len)
3036 {
3037 strncpy_s(dest, len,
3038 pvar->ssh_state.server_ID == NULL ? "Unknown"
3039 : pvar->ssh_state.server_ID,
3040 _TRUNCATE);
3041 }
3042
3043 void SSH_get_protocol_version_info(PTInstVar pvar, char *dest,
3044 int len)
3045 {
3046 if (pvar->protocol_major == 0) {
3047 strncpy_s(dest, len, "Unknown", _TRUNCATE);
3048 } else {
3049 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
3050 pvar->protocol_minor);
3051 }
3052 }
3053
3054 void SSH_get_mac_info(PTInstVar pvar, char *dest, int len)
3055 {
3056 UTIL_get_lang_msg("DLG_ABOUT_MAC_INFO", pvar,
3057 "%s to server, %s from server");
3058 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg,
3059 get_ssh2_mac_name(pvar->ctos_hmac),
3060 get_ssh2_mac_name(pvar->stoc_hmac));
3061 }
3062
3063 void SSH_end(PTInstVar pvar)
3064 {
3065 int i;
3066 int mode;
3067
3068 for (i = 0; i < 256; i++) {
3069 SSHPacketHandlerItem *first_item =
3070 pvar->ssh_state.packet_handlers[i];
3071
3072 if (first_item != NULL) {
3073 SSHPacketHandlerItem *item = first_item;
3074
3075 do {
3076 SSHPacketHandlerItem *cur_item = item;
3077
3078 item = item->next_for_message;
3079 free(cur_item);
3080 } while (item != first_item);
3081 }
3082 pvar->ssh_state.packet_handlers[i] = NULL;
3083 }
3084
3085 free(pvar->ssh_state.hostname);
3086 pvar->ssh_state.hostname = NULL;
3087 free(pvar->ssh_state.server_ID);
3088 pvar->ssh_state.server_ID = NULL;
3089 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
3090 buf_destroy(&pvar->ssh_state.precompress_outbuf,
3091 &pvar->ssh_state.precompress_outbuflen);
3092 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
3093 &pvar->ssh_state.postdecompress_inbuflen);
3094 pvar->agentfwd_enable = FALSE;
3095
3096 // support of "Compression delayed" (2006.6.23 maya)
3097 if (pvar->ssh_state.compressing ||
3098 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
3099 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
3100 deflateEnd(&pvar->ssh_state.compress_stream);
3101 pvar->ssh_state.compressing = FALSE;
3102 }
3103 // support of "Compression delayed" (2006.6.23 maya)
3104 if (pvar->ssh_state.decompressing ||
3105 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
3106 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3107 inflateEnd(&pvar->ssh_state.decompress_stream);
3108 pvar->ssh_state.decompressing = FALSE;
3109 }
3110
3111 // SSH2���f�[�^���������� (2004.12.27 yutaka)
3112 if (SSHv2(pvar)) {
3113 if (pvar->kexdh) {
3114 DH_free(pvar->kexdh);
3115 pvar->kexdh = NULL;
3116 }
3117 if (pvar->ecdh_client_key) {
3118 EC_KEY_free(pvar->ecdh_client_key);
3119 pvar->ecdh_client_key = NULL;
3120 }
3121 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
3122 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
3123
3124 if (pvar->my_kex != NULL) {
3125 buffer_free(pvar->my_kex);
3126 pvar->my_kex = NULL;
3127 }
3128 if (pvar->peer_kex != NULL) {
3129 buffer_free(pvar->peer_kex);
3130 pvar->peer_kex = NULL;
3131 }
3132
3133 pvar->we_need = 0;
3134 pvar->key_done = 0;
3135 pvar->rekeying = 0;
3136
3137 if (pvar->session_id != NULL) {
3138 free(pvar->session_id);
3139 pvar->session_id = NULL;
3140 }
3141 pvar->session_id_len = 0;
3142
3143 pvar->userauth_success = 0;
3144 //pvar->remote_id = 0;
3145 pvar->shell_id = 0;
3146 pvar->session_nego_status = 0;
3147