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 4495 - (show annotations) (download) (as text)
Sun Jun 12 16:19:27 2011 UTC (12 years, 10 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 244150 byte(s)
パケット圧縮を有効にした状態で、SCPファイル送信を行うと、不正なポインタアクセスにより、
Tera Term(TTSSH)がApplication faultで落ちる問題を修正した。

buffer_t バッファが内部で realloc() により、バッファ拡張された場合、バッファポインタが
変わることがあるため、再度バッファポインタの取り直しが必要であった。
他にも類似の問題が潜んでいるかもしれないが、水平展開は未。

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