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 3180 - (show annotations) (download) (as text)
Wed Dec 3 05:37:21 2008 UTC (15 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 244091 byte(s)
no message

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