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 3208 - (show annotations) (download) (as text)
Wed Feb 4 11:45:51 2009 UTC (15 years, 2 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 242214 byte(s)
サーバへの初回接続時の"Security Warning"ダイアログにおいて、サーバから切断されるまで放置したあと、
当該ダイアログのボタン押下による終了後、TTSSH で Application fault となる現象への対処(一部)を
追加した。
まだ、落ちます。

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