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