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 4492 - (show annotations) (download) (as text)
Thu Jun 9 15:25:43 2011 UTC (12 years, 10 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 243744 byte(s)
パケット圧縮を有効にした状態で、BOFが発生していた問題を修正した。
FIXME: ただし、SCPによるファイル送信途中に、例外で落ちるので、まだ不完全。


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