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 4423 - (show annotations) (download) (as text)
Fri Apr 8 07:34:37 2011 UTC (13 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 240211 byte(s)
hmac-ripemd160@openssh.com をサポート。hmac-ripemd160 は IANA に登録されていないのでサポートしない。

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