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 4152 - (show annotations) (download) (as text)
Wed Nov 10 16:15:13 2010 UTC (13 years, 5 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 256715 byte(s)
・keyboard-interactive 認証において、パスワード変更が行えるようにした。
・SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ の実装。ただし、未評価のため、フタをしてある。

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