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 4656 - (show annotations) (download) (as text)
Mon Sep 26 12:03:03 2011 UTC (12 years, 6 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 247993 byte(s)
SSH2 の identification string は CR LF で終わることになっているので修正
  RFC 4253 4.2.
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 char prefix[64];
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;
1717 char FAR *buf;
1718
1719 strncpy_s(prefix, sizeof(prefix), "Received server identification string: ", _TRUNCATE);
1720 buf_len = strlen(prefix) + ID_len + 1;
1721 buf = (char FAR *) malloc(buf_len);
1722 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1723 strncat_s(buf, buf_len, ID, _TRUNCATE);
1724 chop_newlines(buf);
1725 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1726 free(buf);
1727
1728
1729 // ���������R�s�[������ (2005.3.9 yutaka)
1730 #if 0
1731 // for calculate SSH2 hash
1732 // �T�[�o�o�[�W�����������i���s���������������j
1733 if (ID_len >= sizeof(pvar->server_version_string))
1734 return FALSE;
1735 strncpy(pvar->server_version_string, ID, ID_len);
1736 #endif
1737
1738
1739 if (ID[ID_len - 1] != '\n') {
1740 pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1741 return FALSE;
1742 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1743 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1744 return FALSE;
1745 } else if (strncmp(ID, "SSH-", 4) != 0) {
1746 return FALSE;
1747 } else {
1748 ID[ID_len - 1] = 0;
1749
1750 if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1751 ID[ID_len - 2] = 0;
1752 }
1753
1754 pvar->ssh_state.server_ID = _strdup(ID);
1755
1756 if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1757 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1758 "This program does not understand the server's version of the protocol.");
1759 notify_fatal_error(pvar, pvar->ts->UIMsg);
1760 } else {
1761 char TTSSH_ID[1024];
1762 int TTSSH_ID_len;
1763 int a, b, c, d;
1764
1765 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1766 get_file_version("ttxssh.dll", &a, &b, &c, &d);
1767
1768 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1769 "SSH-%d.%d-TTSSH/%d.%d Win32\r\n",
1770 pvar->protocol_major, pvar->protocol_minor, a, b);
1771 TTSSH_ID_len = strlen(TTSSH_ID);
1772
1773 // for SSH2(yutaka)
1774 // �N���C�A���g�o�[�W�����������i���s���������������j
1775 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1776 TTSSH_ID, _TRUNCATE);
1777
1778 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1779 _snprintf_s(pvar->server_version_string,
1780 sizeof(pvar->server_version_string), _TRUNCATE,
1781 "%s", pvar->ssh_state.server_ID);
1782
1783 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1784 0) != TTSSH_ID_len) {
1785 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1786 "An error occurred while sending the SSH ID string.\n"
1787 "The connection will close.");
1788 notify_fatal_error(pvar, pvar->ts->UIMsg);
1789 } else {
1790 // ���s�R�[�h������ (2004.8.4 yutaka)
1791 pvar->client_version_string[--TTSSH_ID_len] = 0; // \n
1792 pvar->client_version_string[--TTSSH_ID_len] = 0; // \r
1793
1794 strncpy_s(prefix, sizeof(prefix), "Sent client identification string: ", _TRUNCATE);
1795 buf_len = strlen(prefix) + strlen(pvar->client_version_string) + 1;
1796 buf = (char FAR *) malloc(buf_len);
1797 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1798 strncat_s(buf, buf_len, pvar->client_version_string, _TRUNCATE);
1799 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1800 free(buf);
1801
1802 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1803 push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1804
1805 // SSH�n���h�����o�^���s��
1806 init_protocol(pvar);
1807
1808 SSH2_dispatch_init(1);
1809 SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1810 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1811 }
1812 }
1813
1814 return TRUE;
1815 }
1816 }
1817 }
1818
1819 static BOOL handle_exit(PTInstVar pvar)
1820 {
1821 if (grab_payload(pvar, 4)) {
1822 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1823 finish_send_packet(pvar);
1824 notify_closed_connection(pvar);
1825 }
1826 return TRUE;
1827 }
1828
1829 static BOOL handle_data(PTInstVar pvar)
1830 {
1831 if (grab_payload_limited(pvar, 4)) {
1832 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1833 pvar->ssh_state.payload_datastart = 4;
1834 }
1835 return TRUE;
1836 }
1837
1838 static BOOL handle_channel_open(PTInstVar pvar)
1839 {
1840 int host_len;
1841 int originator_len;
1842
1843 if ((pvar->ssh_state.
1844 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1845 if (grab_payload(pvar, 8)
1846 && grab_payload(pvar,
1847 8 + (host_len = get_payload_uint32(pvar, 4)))
1848 && grab_payload(pvar, originator_len =
1849 get_payload_uint32(pvar, host_len + 12))) {
1850 int local_port = get_payload_uint32(pvar, 8 + host_len);
1851
1852 pvar->ssh_state.payload[8 + host_len] = 0;
1853 FWD_open(pvar, get_payload_uint32(pvar, 0),
1854 pvar->ssh_state.payload + 8, local_port,
1855 pvar->ssh_state.payload + 16 + host_len,
1856 originator_len,
1857 NULL);
1858 }
1859 } else {
1860 if (grab_payload(pvar, 8)
1861 && grab_payload(pvar,
1862 4 + (host_len = get_payload_uint32(pvar, 4)))) {
1863 int local_port = get_payload_uint32(pvar, 8 + host_len);
1864
1865 pvar->ssh_state.payload[8 + host_len] = 0;
1866 FWD_open(pvar, get_payload_uint32(pvar, 0),
1867 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1868 NULL);
1869 }
1870 }
1871
1872 return TRUE;
1873 }
1874
1875 static BOOL handle_X11_channel_open(PTInstVar pvar)
1876 {
1877 int originator_len;
1878
1879 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1880 if (grab_payload(pvar, 8)
1881 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1882 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1883 pvar->ssh_state.payload + 8, originator_len, NULL);
1884 }
1885 } else {
1886 if (grab_payload(pvar, 4)) {
1887 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1888 }
1889 }
1890
1891 return TRUE;
1892 }
1893
1894 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1895 {
1896 if (grab_payload(pvar, 8)) {
1897 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1898 get_payload_uint32(pvar, 4));
1899 }
1900 return FALSE;
1901 }
1902
1903 static BOOL handle_channel_open_failure(PTInstVar pvar)
1904 {
1905 if (grab_payload(pvar, 4)) {
1906 FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1907 }
1908 return FALSE;
1909 }
1910
1911 static BOOL handle_channel_data(PTInstVar pvar)
1912 {
1913 int len;
1914
1915 if (grab_payload(pvar, 8)
1916 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1917 FWDChannel *channel;
1918 int local_channel_num = get_payload_uint32(pvar, 0);
1919 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1920 return FALSE;
1921 }
1922 channel = pvar->fwd_state.channels + local_channel_num;
1923 if (channel->type == TYPE_AGENT) {
1924 SSH_agent_response(pvar, NULL, local_channel_num,
1925 pvar->ssh_state.payload + 8, len);
1926 }
1927 else {
1928 FWD_received_data(pvar, local_channel_num,
1929 pvar->ssh_state.payload + 8, len);
1930 }
1931 }
1932 return TRUE;
1933 }
1934
1935 static BOOL handle_channel_input_eof(PTInstVar pvar)
1936 {
1937 if (grab_payload(pvar, 4)) {
1938 int local_channel_num = get_payload_uint32(pvar, 0);
1939 FWDChannel *channel;
1940 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1941 return FALSE;
1942 }
1943 channel = pvar->fwd_state.channels + local_channel_num;
1944 if (channel->type == TYPE_AGENT) {
1945 channel->status |= FWD_CLOSED_REMOTE_IN;
1946 SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1947 }
1948 else {
1949 FWD_channel_input_eof(pvar, local_channel_num);
1950 }
1951 }
1952 return TRUE;
1953 }
1954
1955 static BOOL handle_channel_output_eof(PTInstVar pvar)
1956 {
1957 if (grab_payload(pvar, 4)) {
1958 int local_channel_num = get_payload_uint32(pvar, 0);
1959 FWDChannel *channel;
1960 if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1961 return FALSE;
1962 }
1963 channel = pvar->fwd_state.channels + local_channel_num;
1964 if (channel->type == TYPE_AGENT) {
1965 channel->status |= FWD_CLOSED_REMOTE_OUT;
1966 SSH_channel_output_eof(pvar, channel->remote_num);
1967 FWD_free_channel(pvar, local_channel_num);
1968 }
1969 else {
1970 FWD_channel_output_eof(pvar, local_channel_num);
1971 }
1972 }
1973 return TRUE;
1974 }
1975
1976 static BOOL handle_agent_open(PTInstVar pvar)
1977 {
1978 if (grab_payload(pvar, 4)) {
1979 int remote_id = get_payload_uint32(pvar, 0);
1980 int local_id;
1981
1982 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
1983 local_id = FWD_agent_open(pvar, remote_id);
1984 if (local_id == -1) {
1985 SSH_fail_channel_open(pvar, remote_id);
1986 }
1987 else {
1988 SSH_confirm_channel_open(pvar, remote_id, local_id);
1989 }
1990 }
1991 else {
1992 SSH_fail_channel_open(pvar, remote_id);
1993 }
1994 }
1995 /*
1996 else {
1997 // ���m��������channel����������������������������
1998 }
1999 */
2000
2001 return TRUE;
2002 }
2003
2004
2005
2006 // �n���h�����O�������b�Z�[�W����������
2007
2008 #define HANDLE_MESSAGE_MAX 30
2009 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
2010 static int handle_message_count = 0;
2011 static int handle_message_stage = 0;
2012
2013 void SSH2_dispatch_init(int stage)
2014 {
2015 handle_message_count = 0;
2016 handle_message_stage = stage;
2017 }
2018
2019 int SSH2_dispatch_enabled_check(unsigned char message)
2020 {
2021 int i;
2022
2023 for (i = 0 ; i < handle_message_count ; i++) {
2024 if (handle_messages[i] == message)
2025 return 1;
2026 }
2027 return 0;
2028 }
2029
2030 void SSH2_dispatch_add_message(unsigned char message)
2031 {
2032 int i;
2033
2034 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2035 // TODO: error check
2036 return;
2037 }
2038
2039 // �������o�^�������������b�Z�[�W������������
2040 for (i=0; i<handle_message_count; i++) {
2041 if (handle_messages[i] == message) {
2042 return;
2043 }
2044 }
2045
2046 handle_messages[handle_message_count++] = message;
2047 }
2048
2049 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2050 {
2051 unsigned char c;
2052
2053 for (c = begin ; c <= end ; c++) {
2054 SSH2_dispatch_add_message(c);
2055 }
2056 }
2057
2058
2059 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
2060 int padding)
2061 {
2062 unsigned char message = prep_packet(pvar, data, len, padding);
2063
2064
2065 #ifdef SSH2_DEBUG
2066 // for SSH2(yutaka)
2067 if (SSHv2(pvar)) {
2068 if (pvar->key_done) {
2069 message = message;
2070 }
2071
2072 if (pvar->userauth_success) {
2073 message = message;
2074 }
2075
2076 if (pvar->rekeying) {
2077 message = message;
2078 }
2079 }
2080 #endif
2081
2082 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2083 if (message != SSH_MSG_NONE) {
2084 // ���b�Z�[�W�^�C�v���������n���h�����N��
2085 SSHPacketHandler handler = get_handler(pvar, message);
2086
2087 // for SSH2(yutaka)
2088 if (SSHv2(pvar)) {
2089 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2090 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2091 char buf[1024];
2092
2093 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2094 "Unexpected SSH2 message(%d) on current stage(%d)");
2095 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2096 pvar->ts->UIMsg, message, handle_message_stage);
2097 notify_fatal_error(pvar, buf);
2098 // abort
2099 }
2100 }
2101
2102 if (handler == NULL) {
2103 if (SSHv1(pvar)) {
2104 char buf[1024];
2105
2106 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2107 "Unexpected packet type received: %d");
2108 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2109 pvar->ts->UIMsg, message, handle_message_stage);
2110 notify_fatal_error(pvar, buf);
2111 } else {
2112 unsigned char FAR *outmsg =
2113 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2114
2115 set_uint32(outmsg,
2116 pvar->ssh_state.receiver_sequence_number - 1);
2117 finish_send_packet(pvar);
2118
2119 notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2120 /* XXX need to decompress incoming packet, but how? */
2121 }
2122 } else {
2123 if (!handler(pvar)) {
2124 deque_handlers(pvar, message);
2125 }
2126 }
2127 }
2128 }
2129
2130 static BOOL handle_pty_success(PTInstVar pvar)
2131 {
2132 FWD_enter_interactive_mode(pvar);
2133 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2134 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2135 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2136 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2137 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2138 handle_channel_input_eof);
2139 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2140 handle_channel_output_eof);
2141 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2142 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2143 enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2144 return FALSE;
2145 }
2146
2147 static BOOL handle_pty_failure(PTInstVar pvar)
2148 {
2149 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2150 "The server cannot allocate a pseudo-terminal. "
2151 "You may encounter some problems with the terminal.");
2152 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2153 return handle_pty_success(pvar);
2154 }
2155
2156 static void prep_pty(PTInstVar pvar)
2157 {
2158 int len = strlen(pvar->ts->TermType);
2159 unsigned char FAR *outmsg =
2160 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2161 4 + len + 16 + sizeof(ssh_ttymodes));
2162 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2163 static const SSHPacketHandler handlers[]
2164 = { handle_pty_success, handle_pty_failure };
2165
2166 set_uint32(outmsg, len);
2167 memcpy(outmsg + 4, pvar->ts->TermType, len);
2168 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2169 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2170 set_uint32(outmsg + 4 + len + 8, 0);
2171 set_uint32(outmsg + 4 + len + 12, 0);
2172 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2173 finish_send_packet(pvar);
2174
2175 enque_handlers(pvar, 2, msgs, handlers);
2176
2177 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2178 finish_send_packet(pvar);
2179 }
2180
2181 static BOOL handle_agent_request_success(PTInstVar pvar)
2182 {
2183 pvar->agentfwd_enable = TRUE;
2184 prep_pty(pvar);
2185 return FALSE;
2186 }
2187
2188 static BOOL handle_agent_request_failure(PTInstVar pvar)
2189 {
2190 prep_pty(pvar);
2191 return FALSE;
2192 }
2193
2194 static void prep_agent_request(PTInstVar pvar)
2195 {
2196 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2197 static const SSHPacketHandler handlers[]
2198 = { handle_agent_request_success, handle_agent_request_failure };
2199
2200 enque_handlers(pvar, 2, msgs, handlers);
2201
2202 begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2203 finish_send_packet(pvar);
2204 }
2205
2206 static void prep_forwarding(PTInstVar pvar)
2207 {
2208 FWD_prep_forwarding(pvar);
2209
2210 if (pvar->session_settings.ForwardAgent) {
2211 prep_agent_request(pvar);
2212 }
2213 else {
2214 prep_pty(pvar);
2215 }
2216 }
2217
2218
2219 //
2220 //
2221 // (2005.7.10 yutaka)
2222 static void enable_send_compression(PTInstVar pvar)
2223 {
2224 static int initialize = 0;
2225
2226 if (initialize) {
2227 deflateEnd(&pvar->ssh_state.compress_stream);
2228 }
2229 initialize = 1;
2230
2231 pvar->ssh_state.compress_stream.zalloc = NULL;
2232 pvar->ssh_state.compress_stream.zfree = NULL;
2233 pvar->ssh_state.compress_stream.opaque = NULL;
2234 if (deflateInit
2235 (&pvar->ssh_state.compress_stream,
2236 pvar->ssh_state.compression_level) != Z_OK) {
2237 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2238 "An error occurred while setting up compression.\n"
2239 "The connection will close.");
2240 notify_fatal_error(pvar, pvar->ts->UIMsg);
2241 return;
2242 } else {
2243 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2244 if (SSHv2(pvar)) {
2245 pvar->ssh_state.compressing = FALSE;
2246 } else {
2247 pvar->ssh_state.compressing = TRUE;
2248 }
2249 }
2250 }
2251
2252 static void enable_recv_compression(PTInstVar pvar)
2253 {
2254 static int initialize = 0;
2255
2256 if (initialize) {
2257 deflateEnd(&pvar->ssh_state.decompress_stream);
2258 }
2259 initialize = 1;
2260
2261 pvar->ssh_state.decompress_stream.zalloc = NULL;
2262 pvar->ssh_state.decompress_stream.zfree = NULL;
2263 pvar->ssh_state.decompress_stream.opaque = NULL;
2264 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2265 deflateEnd(&pvar->ssh_state.compress_stream);
2266 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2267 "An error occurred while setting up compression.\n"
2268 "The connection will close.");
2269 notify_fatal_error(pvar, pvar->ts->UIMsg);
2270 return;
2271 } else {
2272 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2273 if (SSHv2(pvar)) {
2274 pvar->ssh_state.decompressing = FALSE;
2275 } else {
2276 pvar->ssh_state.decompressing = TRUE;
2277 }
2278
2279 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2280 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2281 }
2282 }
2283
2284 static void enable_compression(PTInstVar pvar)
2285 {
2286 enable_send_compression(pvar);
2287 enable_recv_compression(pvar);
2288
2289 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2290 if (SSHv2(pvar)) {
2291 pvar->ssh_state.compressing = FALSE;
2292 pvar->ssh_state.decompressing = FALSE;
2293 }
2294
2295 }
2296
2297 static BOOL handle_enable_compression(PTInstVar pvar)
2298 {
2299 enable_compression(pvar);
2300 prep_forwarding(pvar);
2301 return FALSE;
2302 }
2303
2304 static BOOL handle_disable_compression(PTInstVar pvar)
2305 {
2306 prep_forwarding(pvar);
2307 return FALSE;
2308 }
2309
2310 static void prep_compression(PTInstVar pvar)
2311 {
2312 if (pvar->session_settings.CompressionLevel > 0) {
2313 // added if statement (2005.7.10 yutaka)
2314 if (SSHv1(pvar)) {
2315 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2316 static const SSHPacketHandler handlers[]
2317 = { handle_enable_compression, handle_disable_compression };
2318
2319 unsigned char FAR *outmsg =
2320 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2321
2322 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2323 finish_send_packet(pvar);
2324
2325 enque_handlers(pvar, 2, msgs, handlers);
2326 }
2327
2328 pvar->ssh_state.compression_level =
2329 pvar->session_settings.CompressionLevel;
2330
2331 } else {
2332 // added if statement (2005.7.10 yutaka)
2333 if (SSHv1(pvar)) {
2334 prep_forwarding(pvar);
2335 }
2336 }
2337 }
2338
2339 static void enque_simple_auth_handlers(PTInstVar pvar)
2340 {
2341 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2342 static const SSHPacketHandler handlers[]
2343 = { handle_auth_success, handle_auth_failure };
2344
2345 enque_handlers(pvar, 2, msgs, handlers);
2346 }
2347
2348 static BOOL handle_rsa_challenge(PTInstVar pvar)
2349 {
2350 int challenge_bytes;
2351
2352 if (!grab_payload(pvar, 2)) {
2353 return FALSE;
2354 }
2355
2356 challenge_bytes = get_mpint_len(pvar, 0);
2357
2358 if (grab_payload(pvar, challenge_bytes)) {
2359 unsigned char FAR *outmsg =
2360 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2361
2362 if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2363 if (CRYPT_generate_RSA_challenge_response
2364 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2365
2366 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2367 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2368 #if 0
2369 //AUTH_destroy_cur_cred(pvar);
2370 #endif
2371
2372 finish_send_packet(pvar);
2373
2374 enque_simple_auth_handlers(pvar);
2375 } else {
2376 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2377 "An error occurred while decrypting the RSA challenge.\n"
2378 "Perhaps the key file is corrupted.");
2379 notify_fatal_error(pvar, pvar->ts->UIMsg);
2380 }
2381 }
2382 else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2383 int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2384 int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2385 int server_key_bytes = (server_key_bits + 7) / 8;
2386 int host_key_bytes = (host_key_bits + 7) / 8;
2387 int session_buf_len = server_key_bytes + host_key_bytes + 8;
2388 char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2389 unsigned char session_id[16];
2390
2391 unsigned char *hash;
2392 int pubkeylen, hashlen;
2393
2394 /* Pageant ���n�b�V�����v�Z���������� */
2395 // ���J��������
2396 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2397 pvar->pageant_keylistlen);
2398 // �Z�b�V����ID������
2399 BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2400 BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2401 session_buf + host_key_bytes);
2402 memcpy(session_buf + server_key_bytes + host_key_bytes,
2403 pvar->crypt_state.server_cookie, 8);
2404 MD5(session_buf, session_buf_len, session_id);
2405 // �n�b�V������������
2406 hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2407 pubkeylen,
2408 pvar->ssh_state.payload,
2409 challenge_bytes + 2,
2410 session_id,
2411 &hashlen);
2412
2413 // �n�b�V�������M
2414 memcpy(outmsg, hash, 16);
2415 free(hash);
2416
2417 finish_send_packet(pvar);
2418
2419 enque_simple_auth_handlers(pvar);
2420 }
2421 }
2422
2423 return FALSE;
2424 }
2425
2426 static void try_send_credentials(PTInstVar pvar)
2427 {
2428 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2429 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2430 static const int RSA_msgs[] =
2431 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2432 static const SSHPacketHandler RSA_handlers[]
2433 = { handle_rsa_challenge, handle_rsa_auth_refused };
2434 static const int TIS_msgs[] =
2435 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2436 static const SSHPacketHandler TIS_handlers[]
2437 = { handle_TIS_challenge, handle_auth_failure };
2438
2439 // SSH2���������������������X�L�b�v
2440 if (SSHv2(pvar))
2441 goto skip_ssh2;
2442
2443 switch (cred->method) {
2444 case SSH_AUTH_NONE:
2445 return;
2446 case SSH_AUTH_PASSWORD:{
2447 int len = strlen(cred->password);
2448 unsigned char FAR *outmsg =
2449 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2450 4 + len);
2451
2452 notify_verbose_message(pvar,
2453 "Trying PASSWORD authentication...",
2454 LOG_LEVEL_VERBOSE);
2455
2456 set_uint32(outmsg, len);
2457 memcpy(outmsg + 4, cred->password, len);
2458
2459 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2460 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2461 #if 0
2462 //AUTH_destroy_cur_cred(pvar);
2463 #endif
2464
2465 enque_simple_auth_handlers(pvar);
2466 break;
2467 }
2468 case SSH_AUTH_RHOSTS:{
2469 int len = strlen(cred->rhosts_client_user);
2470 unsigned char FAR *outmsg =
2471 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2472
2473 notify_verbose_message(pvar,
2474 "Trying RHOSTS authentication...",
2475 LOG_LEVEL_VERBOSE);
2476
2477 set_uint32(outmsg, len);
2478 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2479 AUTH_destroy_cur_cred(pvar);
2480 enque_simple_auth_handlers(pvar);
2481 break;
2482 }
2483 case SSH_AUTH_RSA:{
2484 int len = BN_num_bytes(cred->key_pair->rsa->n);
2485 unsigned char FAR *outmsg =
2486 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2487
2488 notify_verbose_message(pvar,
2489 "Trying RSA authentication...",
2490 LOG_LEVEL_VERBOSE);
2491
2492 set_ushort16_MSBfirst(outmsg, len * 8);
2493 BN_bn2bin(cred->key_pair->rsa->n, outmsg + 2);
2494 /* don't destroy the current credentials yet */
2495 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2496 break;
2497 }
2498 case SSH_AUTH_RHOSTS_RSA:{
2499 int mod_len = BN_num_bytes(cred->key_pair->rsa->n);
2500 int name_len = strlen(cred->rhosts_client_user);
2501 int exp_len = BN_num_bytes(cred->key_pair->rsa->e);
2502 int index;
2503 unsigned char FAR *outmsg =
2504 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2505 12 + mod_len + name_len + exp_len);
2506
2507 notify_verbose_message(pvar,
2508 "Trying RHOSTS+RSA authentication...",
2509 LOG_LEVEL_VERBOSE);
2510
2511 set_uint32(outmsg, name_len);
2512 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2513 index = 4 + name_len;
2514
2515 set_uint32(outmsg + index, 8 * mod_len);
2516 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2517 BN_bn2bin(cred->key_pair->rsa->e, outmsg + index + 6);
2518 index += 6 + exp_len;
2519
2520 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2521 BN_bn2bin(cred->key_pair->rsa->n, outmsg + index + 2);
2522 /* don't destroy the current credentials yet */
2523 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2524 break;
2525 }
2526 case SSH_AUTH_PAGEANT:{
2527 unsigned char FAR *outmsg;
2528 unsigned char *pubkey;
2529 int len, bn_bytes;
2530
2531 if (pvar->pageant_keycurrent != 0) {
2532 // ���O�������X�L�b�v
2533 pvar->pageant_curkey += 4;
2534 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2535 bn_bytes = (len + 7) / 8;
2536 pvar->pageant_curkey += 2 + bn_bytes;
2537 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2538 bn_bytes = (len + 7) / 8;
2539 pvar->pageant_curkey += 2 + bn_bytes;
2540 // ���O�������R�����g���X�L�b�v
2541 len = get_uint32_MSBfirst(pvar->pageant_curkey);
2542 pvar->pageant_curkey += 4 + len;
2543 // �����������u������
2544 }
2545 pubkey = pvar->pageant_curkey + 4;
2546 len = get_ushort16_MSBfirst(pubkey);
2547 bn_bytes = (len + 7) / 8;
2548 pubkey += 2 + bn_bytes;
2549 len = get_ushort16_MSBfirst(pubkey);
2550 bn_bytes = (len + 7) / 8;
2551 pubkey += 2;
2552 outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2553
2554 notify_verbose_message(pvar,
2555 "Trying RSA authentication...",
2556 LOG_LEVEL_VERBOSE);
2557
2558 set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2559 memcpy(outmsg + 2, pubkey, bn_bytes);
2560 /* don't destroy the current credentials yet */
2561
2562 pvar->pageant_keycurrent++;
2563
2564 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2565 break;
2566 }
2567 case SSH_AUTH_TIS:{
2568 if (cred->password == NULL) {
2569 unsigned char FAR *outmsg =
2570 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2571
2572 notify_verbose_message(pvar,
2573 "Trying TIS authentication...",
2574 LOG_LEVEL_VERBOSE);
2575 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2576 } else {
2577 int len = strlen(cred->password);
2578 unsigned char FAR *outmsg =
2579 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2580 4 + len);
2581
2582 notify_verbose_message(pvar,
2583 "Sending TIS response",
2584 LOG_LEVEL_VERBOSE);
2585
2586 set_uint32(outmsg, len);
2587 memcpy(outmsg + 4, cred->password, len);
2588 enque_simple_auth_handlers(pvar);
2589 }
2590
2591 AUTH_destroy_cur_cred(pvar);
2592 break;
2593 }
2594 default:
2595 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2596 "Internal error: unsupported authentication method");
2597 notify_fatal_error(pvar, pvar->ts->UIMsg);
2598 return;
2599 }
2600
2601 finish_send_packet(pvar);
2602
2603 skip_ssh2:;
2604 destroy_packet_buf(pvar);
2605
2606 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2607 }
2608 }
2609
2610 static void try_send_user_name(PTInstVar pvar)
2611 {
2612 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2613 char FAR *username = AUTH_get_user_name(pvar);
2614
2615 if (username != NULL) {
2616 int len = strlen(username);
2617 unsigned char FAR *outmsg =
2618 begin_send_packet(pvar, SSH_CMSG_USER, 4 + len);
2619 char buf[1024] = "Sending user name: ";
2620 static const int msgs[] =
2621 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2622 static const SSHPacketHandler handlers[]
2623 = { handle_noauth_success, handle_auth_required };
2624
2625 set_uint32(outmsg, len);
2626 memcpy(outmsg + 4, username, len);
2627 finish_send_packet(pvar);
2628
2629 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2630
2631 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2632 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2633
2634 enque_handlers(pvar, 2, msgs, handlers);
2635 }
2636 }
2637 }
2638
2639 static void send_session_key(PTInstVar pvar)
2640 {
2641 int encrypted_session_key_len;
2642 unsigned char FAR *outmsg;
2643
2644 if (SSHv1(pvar)) {
2645 encrypted_session_key_len =
2646 CRYPT_get_encrypted_session_key_len(pvar);
2647 }
2648
2649 if (!CRYPT_choose_ciphers(pvar))
2650 return;
2651
2652 if (SSHv1(pvar)) {
2653 outmsg =
2654 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2655 15 + encrypted_session_key_len);
2656 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2657 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2658 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2659 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2660 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2661 return;
2662 set_uint32(outmsg + 11 + encrypted_session_key_len,
2663 SSH_PROTOFLAG_SCREEN_NUMBER |
2664 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2665 finish_send_packet(pvar);
2666 }
2667
2668 if (!CRYPT_start_encryption(pvar, 1, 1))
2669 return;
2670 notify_established_secure_connection(pvar);
2671
2672 if (SSHv1(pvar)) {
2673 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2674 }
2675
2676 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2677
2678 if (SSHv1(pvar)) {
2679 try_send_user_name(pvar);
2680 }
2681 }
2682
2683 /*************************
2684 END of message handlers
2685 ************************/
2686
2687 void SSH_init(PTInstVar pvar)
2688 {
2689 int i;
2690
2691 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2692 buf_create(&pvar->ssh_state.precompress_outbuf,
2693 &pvar->ssh_state.precompress_outbuflen);
2694 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2695 &pvar->ssh_state.postdecompress_inbuflen);
2696 pvar->ssh_state.payload = NULL;
2697 pvar->ssh_state.compressing = FALSE;
2698 pvar->ssh_state.decompressing = FALSE;
2699 pvar->ssh_state.status_flags =
2700 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2701 pvar->ssh_state.payload_datalen = 0;
2702 pvar->ssh_state.hostname = NULL;
2703 pvar->ssh_state.server_ID = NULL;
2704 pvar->ssh_state.receiver_sequence_number = 0;
2705 pvar->ssh_state.sender_sequence_number = 0;
2706 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2707 pvar->ssh_state.packet_handlers[i] = NULL;
2708 }
2709
2710 // for SSH2(yutaka)
2711 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2712 pvar->userauth_success = 0;
2713 pvar->session_nego_status = 0;
2714 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2715 pvar->rekeying = 0;
2716 pvar->key_done = 0;
2717 pvar->ssh2_autologin = 0; // autologin disabled(default)
2718 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2719 pvar->userauth_retry_count = 0;
2720 pvar->decomp_buffer = NULL;
2721 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2722 pvar->tryed_ssh2_authlist = FALSE;
2723 pvar->agentfwd_enable = FALSE;
2724
2725 }
2726
2727 void SSH_open(PTInstVar pvar)
2728 {
2729 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2730 pvar->ssh_state.tcpport = pvar->ts->TCPPort;
2731 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2732 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2733 }
2734
2735 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2736 {
2737 if (SSHv1(pvar)) {
2738 int len = reason == NULL ? 0 : strlen(reason);
2739 unsigned char FAR *outmsg =
2740 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2741
2742 set_uint32(outmsg, len);
2743 if (reason != NULL) {
2744 memcpy(outmsg + 4, reason, len);
2745 }
2746 finish_send_packet(pvar);
2747
2748 } else { // for SSH2(yutaka)
2749 buffer_t *msg;
2750 unsigned char *outmsg;
2751 int len;
2752 Channel_t *c;
2753
2754 c = ssh2_channel_lookup(pvar->shell_id);
2755 if (c == NULL)
2756 return;
2757
2758 // SSH2 server��channel close���`����
2759 msg = buffer_init();
2760 if (msg == NULL) {
2761 // TODO: error check
2762 return;
2763 }
2764 buffer_put_int(msg, c->remote_id);
2765
2766 len = buffer_len(msg);
2767 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2768 memcpy(outmsg, buffer_ptr(msg), len);
2769 finish_send_packet(pvar);
2770 buffer_free(msg);
2771
2772 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_CLOSE was sent at SSH_notify_disconnecting().", LOG_LEVEL_VERBOSE);
2773 }
2774
2775 }
2776
2777 void SSH_notify_host_OK(PTInstVar pvar)
2778 {
2779 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2780 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2781 send_session_key(pvar);
2782 }
2783 }
2784
2785 void get_window_pixel_size(PTInstVar pvar, int *x, int *y)
2786 {
2787 RECT r;
2788
2789 if (pvar->cv->HWin && GetWindowRect(pvar->cv->HWin, &r)) {
2790 *x = r.right - r.left;
2791 *y = r.bottom - r.top;
2792 }
2793 else {
2794 *x = 0;
2795 *y = 0;
2796 }
2797
2798 return;
2799 }
2800
2801 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2802 {
2803 int x, y;
2804
2805 pvar->ssh_state.win_cols = cols;
2806 pvar->ssh_state.win_rows = rows;
2807
2808 if (SSHv1(pvar)) {
2809 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2810 unsigned char FAR *outmsg =
2811 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2812
2813 set_uint32(outmsg, rows);
2814 set_uint32(outmsg + 4, cols);
2815 set_uint32(outmsg + 8, 0);
2816 set_uint32(outmsg + 12, 0);
2817 finish_send_packet(pvar);
2818 }
2819
2820 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2821 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2822 buffer_t *msg;
2823 char *s;
2824 unsigned char *outmsg;
2825 int len;
2826 Channel_t *c;
2827
2828 c = ssh2_channel_lookup(pvar->shell_id);
2829 if (c == NULL)
2830 return;
2831
2832 msg = buffer_init();
2833 if (msg == NULL) {
2834 // TODO: error check
2835 return;
2836 }
2837 buffer_put_int(msg, c->remote_id);
2838 s = "window-change";
2839 buffer_put_string(msg, s, strlen(s));
2840 buffer_put_char(msg, 0); // wantconfirm
2841 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2842 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2843 get_window_pixel_size(pvar, &x, &y);
2844 buffer_put_int(msg, x); // window width (pixel):
2845 buffer_put_int(msg, y); // window height (pixel):
2846 len = buffer_len(msg);
2847 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2848 memcpy(outmsg, buffer_ptr(msg), len);
2849 finish_send_packet(pvar);
2850 buffer_free(msg);
2851
2852 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2853
2854 } else {
2855 // SSH�����������������������B
2856
2857 }
2858
2859 }
2860
2861 // �u���[�N�M���������B
2862 // OpenSSH ��"~B"�����������B�������ASSH2�����B
2863 // (2010.9.27 yutaka)
2864 int SSH_notify_break_signal(PTInstVar pvar)
2865 {
2866 int ret = 0;
2867
2868 if (SSHv1(pvar)) {
2869 // �����������B
2870
2871 } else if (SSHv2(pvar)) {
2872 buffer_t *msg;
2873 char *s;
2874 unsigned char *outmsg;
2875 int len;
2876 Channel_t *c;
2877
2878 c = ssh2_channel_lookup(pvar->shell_id);
2879 if (c == NULL)
2880 goto error;
2881
2882 msg = buffer_init();
2883 if (msg == NULL) {
2884 goto error;
2885 }
2886 buffer_put_int(msg, c->remote_id);
2887 s = "break";
2888 buffer_put_string(msg, s, strlen(s));
2889 buffer_put_char(msg, 0); // wantconfirm
2890 buffer_put_int(msg, 1000);
2891 len = buffer_len(msg);
2892 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2893 memcpy(outmsg, buffer_ptr(msg), len);
2894 finish_send_packet(pvar);
2895 buffer_free(msg);
2896
2897 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_break_signal().", LOG_LEVEL_VERBOSE);
2898
2899 ret = 1;
2900
2901 } else {
2902 // SSH�����������������������B
2903
2904 }
2905
2906 error:
2907 return (ret);
2908 }
2909
2910 int SSH_get_min_packet_size(PTInstVar pvar)
2911 {
2912 if (SSHv1(pvar)) {
2913 return 12;
2914 } else {
2915 int block_size = CRYPT_get_decryption_block_size(pvar);
2916
2917 return max(16, block_size);
2918 }
2919 }
2920
2921 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2922 at least 5 bytes must be decrypted */
2923 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2924 {
2925 if (SSHv2(pvar)) {
2926 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2927 }
2928 }
2929
2930 int SSH_get_clear_MAC_size(PTInstVar pvar)
2931 {
2932 if (SSHv1(pvar)) {
2933 return 0;
2934 } else {
2935 return CRYPT_get_receiver_MAC_size(pvar);
2936 }
2937 }
2938
2939 void SSH_notify_user_name(PTInstVar pvar)
2940 {
2941 try_send_user_name(pvar);
2942 }
2943
2944 void SSH_notify_cred(PTInstVar pvar)
2945 {
2946 try_send_credentials(pvar);
2947 }
2948
2949 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, unsigned int buflen)
2950 {
2951 // RAW�p�P�b�g�_���v������ (2008.8.15 yutaka)
2952 if (LOG_LEVEL_SSHDUMP <= pvar->session_settings.LogLevel) {
2953 init_memdump();
2954 push_memdump("SSH sending packet", "SSH_send", (char *)buf, buflen);
2955 }
2956
2957 if (SSHv1(pvar)) {
2958 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2959 return;
2960 }
2961
2962 while (buflen > 0) {
2963 int len =
2964 buflen >
2965 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2966 unsigned char FAR *outmsg =
2967 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2968
2969 set_uint32(outmsg, len);
2970
2971 if (pvar->ssh_state.compressing) {
2972 buf_ensure_size(&pvar->ssh_state.outbuf,
2973 &pvar->ssh_state.outbuflen,
2974 len + (len >> 6) + 50);
2975 pvar->ssh_state.compress_stream.next_in =
2976 pvar->ssh_state.precompress_outbuf;
2977 pvar->ssh_state.compress_stream.avail_in = 5;
2978 pvar->ssh_state.compress_stream.next_out =
2979 pvar->ssh_state.outbuf + 12;
2980 pvar->ssh_state.compress_stream.avail_out =
2981 pvar->ssh_state.outbuflen - 12;
2982
2983 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2984 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2985 "Error compressing packet data");
2986 notify_fatal_error(pvar, pvar->ts->UIMsg);
2987 return;
2988 }
2989
2990 pvar->ssh_state.compress_stream.next_in =
2991 (unsigned char FAR *) buf;
2992 pvar->ssh_state.compress_stream.avail_in = len;
2993
2994 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
2995 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2996 "Error compressing packet data");
2997 notify_fatal_error(pvar, pvar->ts->UIMsg);
2998 return;
2999 }
3000 } else {
3001 memcpy(outmsg + 4, buf, len);
3002 }
3003
3004 finish_send_packet_special(pvar, 1);
3005
3006 buflen -= len;
3007 buf += len;
3008 }
3009
3010 } else { // for SSH2(yutaka)
3011 Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
3012 SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen);
3013 }
3014
3015 }
3016
3017 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
3018 {
3019 int num_bytes = pvar->ssh_state.payload_datalen;
3020
3021 if (num_bytes > len) {
3022 num_bytes = len;
3023 }
3024
3025 if (!pvar->ssh_state.decompressing) {
3026 memcpy(dest,
3027 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
3028 num_bytes);
3029 pvar->ssh_state.payload_datastart += num_bytes;
3030 } else if (num_bytes > 0) {
3031 pvar->ssh_state.decompress_stream.next_out = dest;
3032 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
3033
3034 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
3035 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
3036 "Invalid compressed data in received packet");
3037 notify_fatal_error(pvar, pvar->ts->UIMsg);
3038 return 0;
3039 }
3040 }
3041
3042 pvar->ssh_state.payload_datalen -= num_bytes;
3043
3044 return num_bytes;
3045 }
3046
3047 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
3048 {
3049 char buf[1024];
3050 char buf2[1024];
3051
3052 // added support of SSH2 packet compression (2005.7.10 yutaka)
3053 // support of "Compression delayed" (2006.6.23 maya)
3054 if (pvar->ssh_state.compressing ||
3055 pvar->ctos_compression == COMP_ZLIB ||
3056 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
3057 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
3058 unsigned long total_out =
3059 pvar->ssh_state.compress_stream.total_out;
3060
3061 if (total_out > 0) {
3062 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3063 "level %d; ratio %.1f (%ld:%ld)");
3064 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
3065 pvar->ssh_state.compression_level,
3066 ((double) total_in) / total_out, total_in,
3067 total_out);
3068 } else {
3069 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3070 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
3071 pvar->ssh_state.compression_level);
3072 }
3073 } else {
3074 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3075 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
3076 }
3077
3078 // support of "Compression delayed" (2006.6.23 maya)
3079 if (pvar->ssh_state.decompressing ||
3080 pvar->stoc_compression == COMP_ZLIB ||
3081 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3082 unsigned long total_in =
3083 pvar->ssh_state.decompress_stream.total_in;
3084 unsigned long total_out =
3085 pvar->ssh_state.decompress_stream.total_out;
3086
3087 if (total_in > 0) {
3088 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
3089 "level %d; ratio %.1f (%ld:%ld)");
3090 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3091 pvar->ssh_state.compression_level,
3092 ((double) total_out) / total_in, total_out,
3093 total_in);
3094 } else {
3095 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
3096 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
3097 pvar->ssh_state.compression_level);
3098 }
3099 } else {
3100 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
3101 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
3102 }
3103
3104 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
3105 "Upstream %s; Downstream %s");
3106 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
3107 }
3108
3109 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
3110 {
3111 strncpy_s(dest, len,
3112 pvar->ssh_state.server_ID == NULL ? "Unknown"
3113 : pvar->ssh_state.server_ID,
3114 _TRUNCATE);
3115 }
3116
3117 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
3118 int len)
3119 {
3120 if (pvar->protocol_major == 0) {
3121 strncpy_s(dest, len, "Unknown", _TRUNCATE);
3122 } else {
3123 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
3124 pvar->protocol_minor);
3125 }
3126 }
3127
3128 void SSH_end(PTInstVar pvar)
3129 {
3130 int i;
3131 int mode;
3132
3133 for (i = 0; i < 256; i++) {
3134 SSHPacketHandlerItem FAR *first_item =
3135 pvar->ssh_state.packet_handlers[i];
3136
3137 if (first_item != NULL) {
3138 SSHPacketHandlerItem FAR *item = first_item;
3139
3140 do {
3141 SSHPacketHandlerItem FAR *cur_item = item;
3142
3143 item = item->next_for_message;
3144 free(cur_item);
3145 } while (item != first_item);
3146 }
3147 pvar->ssh_state.packet_handlers[i] = NULL;
3148 }
3149
3150 free(pvar->ssh_state.hostname);
3151 pvar->ssh_state.hostname = NULL;
3152 free(pvar->ssh_state.server_ID);
3153 pvar->ssh_state.server_ID = NULL;
3154 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
3155 buf_destroy(&pvar->ssh_state.precompress_outbuf,
3156 &pvar->ssh_state.precompress_outbuflen);
3157 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
3158 &pvar->ssh_state.postdecompress_inbuflen);
3159 pvar->agentfwd_enable = FALSE;
3160
3161 // support of "Compression delayed" (2006.6.23 maya)
3162 if (pvar->ssh_state.compressing ||
3163 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
3164 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
3165 deflateEnd(&pvar->ssh_state.compress_stream);
3166 pvar->ssh_state.compressing = FALSE;
3167 }
3168 // support of "Compression delayed" (2006.6.23 maya)
3169 if (pvar->ssh_state.decompressing ||
3170 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
3171 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
3172 inflateEnd(&pvar->ssh_state.decompress_stream);
3173 pvar->ssh_state.decompressing = FALSE;
3174 }
3175
3176 #if 1
3177 // SSH2���f�[�^���������� (2004.12.27 yutaka)
3178 if (SSHv2(pvar)) {
3179 if (pvar->kexdh) {
3180 DH_free(pvar->kexdh);
3181 pvar->kexdh = NULL;
3182 }
3183 if (pvar->ecdh_client_key) {
3184 EC_KEY_free(pvar->ecdh_client_key);
3185 pvar->ecdh_client_key = NULL;
3186 }
3187 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
3188 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
3189
3190 if (pvar->my_kex != NULL) {
3191 buffer_free(pvar->my_kex);
3192 pvar->my_kex = NULL;
3193 }
3194 if (pvar->peer_kex != NULL) {
3195 buffer_free(pvar->peer_kex);
3196 pvar->peer_kex = NULL;
3197 }
3198
3199 pvar->we_need = 0;
3200 pvar->key_done = 0;
3201 pvar->rekeying = 0;
3202
3203 if (pvar->session_id != NULL) {
3204 free(pvar->session_id);
3205 pvar->session_id = NULL;
3206 }
3207 pvar->session_id_len = 0;
3208
3209 pvar->userauth_success = 0;
3210 //pvar->remote_id = 0;