Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3055 - (hide annotations) (download) (as text)
Sun Oct 28 15:10:09 2007 UTC (16 years, 5 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 192876 byte(s)
でかいパケットを送ろうとすると、サーバ側で"Bad packet length"になってしまう問題への対処。
remote_window未転送分の再送処理はTBD。

1 yutakakn 2728 /*
2     Copyright (c) 1998-2001, Robert O'Callahan
3 yutakakn 2794 Copyright (c) 2004-2005, Yutaka Hirata
4 yutakakn 2728 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    
33     #include <openssl/bn.h>
34     #include <openssl/evp.h>
35     #include <openssl/dh.h>
36     #include <openssl/engine.h>
37 yutakakn 2762 #include <openssl/rsa.h>
38     #include <openssl/dsa.h>
39 yutakakn 2728 #include <limits.h>
40     #include <malloc.h>
41     #include <string.h>
42     #include <stdlib.h>
43 yutakakn 2748 #include <process.h>
44 yutakakn 2796 #include <time.h>
45 yutakakn 2728 #include "buffer.h"
46     #include "ssh.h"
47     #include "crypt.h"
48 maya 2987 #include "fwd.h"
49 yutakakn 2728
50 yutakakn 2806 // SSH2 macro
51 yutakakn 2728 #ifdef _DEBUG
52     #define SSH2_DEBUG
53     #endif
54    
55 yutakakn 2806 #define DONT_WANTCONFIRM 1 // (2005.3.28 yutaka)
56 yutakakn 2762 #define INTBLOB_LEN 20
57     #define SIGBLOB_LEN (2*INTBLOB_LEN)
58    
59 yutakakn 2728 static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
60    
61     static void try_send_credentials(PTInstVar pvar);
62     static void prep_compression(PTInstVar pvar);
63    
64     // �����v���g�^�C�v����
65     void SSH2_send_kexinit(PTInstVar pvar);
66     static BOOL handle_SSH2_kexinit(PTInstVar pvar);
67     static void SSH2_dh_kex_init(PTInstVar pvar);
68     static void SSH2_dh_gex_kex_init(PTInstVar pvar);
69     static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
70     static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
71     static BOOL handle_SSH2_newkeys(PTInstVar pvar);
72     static BOOL handle_SSH2_authrequest(PTInstVar pvar);
73     static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
74     static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
75     static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
76     static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
77 yutakakn 2827 static BOOL handle_SSH2_open_failure(PTInstVar pvar);
78 yutakakn 2728 static BOOL handle_SSH2_request_success(PTInstVar pvar);
79 yutakakn 2825 static BOOL handle_SSH2_request_failure(PTInstVar pvar);
80 yutakakn 2728 static BOOL handle_SSH2_channel_success(PTInstVar pvar);
81     static BOOL handle_SSH2_channel_data(PTInstVar pvar);
82     static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
83     static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
84     static BOOL handle_SSH2_channel_close(PTInstVar pvar);
85 yutakakn 2825 static BOOL handle_SSH2_channel_open(PTInstVar pvar);
86 yutakakn 2728 static BOOL handle_SSH2_window_adjust(PTInstVar pvar);
87     static BOOL handle_SSH2_channel_request(PTInstVar pvar);
88     void SSH2_dispatch_init(int stage);
89     int SSH2_dispatch_enabled_check(unsigned char message);
90     void SSH2_dispatch_add_message(unsigned char message);
91     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);
92     int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
93 yutakakn 2748 static void start_ssh_heartbeat_thread(PTInstVar pvar);
94 yutakakn 2728
95    
96 yutakakn 2748 //
97 yutakakn 2809 // SSH2 data structure
98     //
99    
100     /* default window/packet sizes for tcp/x11-fwd-channel */
101     #define CHAN_SES_PACKET_DEFAULT (32*1024)
102     #define CHAN_SES_WINDOW_DEFAULT (2*CHAN_SES_PACKET_DEFAULT) // READAMOUNT @ pkt.c����������������
103 yutakakn 2826 #define CHAN_TCP_PACKET_DEFAULT (32*1024)
104     #define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT)
105     #define CHAN_X11_PACKET_DEFAULT (16*1024)
106     #define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
107 yutakakn 2809
108     // channel data structure
109     #define CHANNEL_MAX 100
110    
111 yutakakn 2823 enum channel_type {
112 maya 3054 TYPE_SHELL, TYPE_PORTFWD,
113 yutakakn 2823 };
114    
115 yutakapon 3055 typedef struct bufchain {
116     buffer_t *msg;
117     struct bufchain *next;
118     } bufchain_t;
119    
120 yutakakn 2809 typedef struct channel {
121     int used;
122     int self_id;
123     int remote_id;
124     unsigned int local_window;
125     unsigned int local_window_max;
126     unsigned int local_consumed;
127     unsigned int local_maxpacket;
128     unsigned int remote_window;
129     unsigned int remote_maxpacket;
130 yutakakn 2823 enum channel_type type;
131     int local_num;
132 yutakapon 3055 bufchain_t *bufchain;
133     int chain_count;
134 yutakakn 2809 } Channel_t;
135    
136     static Channel_t channels[CHANNEL_MAX];
137    
138     //
139     // channel function
140     //
141 maya 3003 static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack,
142     enum confirm_type type, int local_num)
143 yutakakn 2809 {
144     int i, found;
145     Channel_t *c;
146    
147     found = -1;
148     for (i = 0 ; i < CHANNEL_MAX ; i++) {
149     if (channels[i].used == 0) { // free channel
150     found = i;
151     break;
152     }
153     }
154     if (found == -1) { // not free channel
155     return (NULL);
156     }
157    
158     // setup
159     c = &channels[found];
160 yutakapon 3055 memset(c, 0, sizeof(Channel_t));
161 yutakakn 2809 c->used = 1;
162     c->self_id = i;
163     c->remote_id = -1;
164     c->local_window = window;
165     c->local_window_max = window;
166     c->local_consumed = 0;
167     c->local_maxpacket = maxpack;
168     c->remote_window = 0;
169     c->remote_maxpacket = 0;
170 yutakakn 2823 c->type = type;
171 yutakakn 2826 c->local_num = local_num; // alloc_channel()�����l��������������
172 yutakapon 3055 c->bufchain = NULL;
173 yutakakn 2809
174     return (c);
175     }
176    
177    
178 yutakapon 3055 static void ssh2_channel_add_bufchain(Channel_t *c, unsigned char *buf, unsigned int buflen)
179     {
180     bufchain_t *ch;
181    
182     ch = malloc(sizeof(bufchain_t));
183     if (ch == NULL)
184     return;
185     ch->msg = buffer_init();
186     if (ch == NULL) {
187     free(ch);
188     return;
189     }
190     buffer_put_string(ch->msg, buf, buflen);
191    
192     ch->next = c->bufchain;
193     c->bufchain = ch;
194     c->chain_count++;
195     }
196    
197    
198     static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c)
199     {
200     bufchain_t *ch, *ptr, *prev_ptr;
201     unsigned int size;
202    
203     while (c->bufchain) {
204     // ����������������
205     prev_ptr = NULL;
206     ptr = c->bufchain;
207     while (ptr->next) {
208     prev_ptr = ptr;
209     ptr = ptr->next;
210     }
211     ch = ptr;
212     size = buffer_len(ch->msg);
213     if (size >= c->remote_window)
214     break;
215    
216     SSH_channel_send(pvar, c->local_num, 0, buffer_ptr(ch->msg), size);
217     c->chain_count--;
218    
219     buffer_free(ch->msg);
220     free(ch);
221     if (prev_ptr)
222     prev_ptr->next = NULL;
223     else
224     c->bufchain = NULL;
225     }
226     }
227    
228    
229    
230 yutakapon 2972 // channel close�����`���l���\���������X�g�����p����
231     // (2007.4.26 yutaka)
232     static void ssh2_channel_delete(Channel_t *c)
233     {
234 yutakapon 3055 bufchain_t *ch, *ptr;
235    
236     ch = c->bufchain;
237     while (ch) {
238     if (ch->msg)
239     buffer_free(ch->msg);
240     ptr = ch;
241     ch = ch->next;
242     free(ptr);
243     }
244    
245 yutakapon 2972 memset(c, 0, sizeof(Channel_t));
246     c->used = 0;
247     }
248    
249    
250 yutakakn 2809 // connection close������������
251     void ssh2_channel_free(void)
252     {
253     int i;
254     Channel_t *c;
255    
256     for (i = 0 ; i < CHANNEL_MAX ; i++) {
257     c = &channels[i];
258 yutakapon 3055 ssh2_channel_delete(c);
259 yutakakn 2809 }
260    
261     }
262    
263     static Channel_t *ssh2_channel_lookup(int id)
264     {
265     Channel_t *c;
266    
267     if (id < 0 || id >= CHANNEL_MAX) {
268     return (NULL);
269     }
270     c = &channels[id];
271     if (c->used == 0) { // already freed
272     return (NULL);
273     }
274     return (c);
275     }
276    
277 yutakakn 2823 // SSH1��������������channel�\���������ASSH2������Channel_t�����������B
278     // TODO: �����I�����`���l���\������1�������������B
279     // (2005.6.12 yutaka)
280     static Channel_t *ssh2_local_channel_lookup(int local_num)
281     {
282     int i;
283     Channel_t *c;
284 yutakakn 2809
285 yutakakn 2823 for (i = 0 ; i < CHANNEL_MAX ; i++) {
286     c = &channels[i];
287     if (c->local_num == local_num)
288     return (c);
289     }
290     return (NULL);
291     }
292 yutakakn 2809
293 yutakakn 2823
294 yutakakn 2809 //
295 yutakakn 2748 // SSH heartbeat mutex
296     //
297     static CRITICAL_SECTION g_ssh_heartbeat_lock; /* ���b�N�p���� */
298    
299     void ssh_heartbeat_lock_initialize(void)
300     {
301     InitializeCriticalSection(&g_ssh_heartbeat_lock);
302     }
303    
304 yutakakn 2766 void ssh_heartbeat_lock_finalize(void)
305     {
306     DeleteCriticalSection(&g_ssh_heartbeat_lock);
307     }
308    
309 yutakakn 2748 void ssh_heartbeat_lock(void)
310     {
311     EnterCriticalSection(&g_ssh_heartbeat_lock);
312     }
313    
314     void ssh_heartbeat_unlock(void)
315     {
316     LeaveCriticalSection(&g_ssh_heartbeat_lock);
317     }
318    
319    
320 yutakakn 2796 //
321     // SSH memory dump (for debug)
322     //
323     // (2005.3.7 yutaka)
324     //
325     #define MEMTAG_MAX 100
326     #define LOGDUMP "ssh2dump.log"
327     #define SENDTOME "Please send '"LOGDUMP"' file to TeraTerm developer team."
328    
329     typedef struct memtag {
330     char *name;
331     char *desc;
332     int len;
333     char *data;
334     } memtag_t;
335    
336     static memtag_t memtags[MEMTAG_MAX];
337     static int memtag_count = 0;
338 maya 3054 static int memtag_use = 0;
339 yutakakn 2796
340     /* �_���v���C�����t�H�[�}�b�g�\������ */
341     static void displine_memdump(FILE *fp, int addr, int *bytes, int byte_cnt)
342     {
343     int i, c;
344    
345     /* �������A�h���X�\�� */
346     fprintf(fp, "%08X : ", addr);
347    
348     /* �o�C�i���\���i4�o�C�g�������������}���j*/
349     for (i = 0 ; i < byte_cnt ; i++) {
350     if (i > 0 && i % 4 == 0)
351     fprintf(fp, " ");
352    
353     fprintf(fp, "%02X", bytes[i]);
354     }
355    
356     /* ASCII�\���������������������� */
357     fprintf(fp, " %*s%*s", (16-byte_cnt)*2+1, " ", (16-byte_cnt+3)/4, " ");
358    
359     /* ASCII�\�� */
360     for (i = 0 ; i < byte_cnt ; i++) {
361     c = bytes[i];
362     if (c >= 0x20 && c <= 0x7f) {
363     fprintf(fp, "%c", c);
364     } else {
365     fprintf(fp, ".");
366     }
367     }
368    
369     fprintf(fp, "\n");
370     }
371    
372    
373     /* �_���v���[�`�� */
374     static void dump_memdump(FILE *fp, char *data, int len)
375     {
376     int c, addr;
377     int bytes[16], *ptr;
378     int byte_cnt;
379     int i;
380    
381     addr = 0;
382     byte_cnt = 0;
383     ptr = bytes;
384     for (i = 0 ; i < len ; i++) {
385     c = data[i];
386     *ptr++ = c & 0xff;
387     byte_cnt++;
388    
389     if (byte_cnt == 16) {
390     displine_memdump(fp, addr, bytes, byte_cnt);
391    
392     addr += 16;
393     byte_cnt = 0;
394     ptr = bytes;
395     }
396     }
397    
398     if (byte_cnt > 0) {
399     displine_memdump(fp, addr, bytes, byte_cnt);
400     }
401     }
402    
403     void init_memdump(void)
404     {
405     int i;
406    
407     for (i = 0 ; i < MEMTAG_MAX ; i++) {
408     memtags[i].name = NULL;
409     memtags[i].desc = NULL;
410     memtags[i].data = NULL;
411     memtags[i].len = 0;
412     }
413 yutakakn 2809 memtag_use++;
414 yutakakn 2796 }
415    
416     void finish_memdump(void)
417     {
418     int i;
419    
420 yutakakn 2809 // initialize�������������������������������B(2005.4.3 yutaka)
421     if (memtag_use <= 0)
422     return;
423     memtag_use--;
424    
425 yutakakn 2796 for (i = 0 ; i < MEMTAG_MAX ; i++) {
426     free(memtags[i].name);
427     free(memtags[i].desc);
428     free(memtags[i].data);
429     memtags[i].len = 0;
430     }
431     }
432    
433     void save_memdump(char *filename)
434     {
435     FILE *fp;
436     int i;
437     time_t t;
438     struct tm *tm;
439    
440     fp = fopen(filename, "w");
441     if (fp == NULL)
442     return;
443    
444     t = time(NULL);
445     tm = localtime(&t);
446    
447     fprintf(fp, "<<< TeraTerm SSH2 log dump >>>\n");
448     fprintf(fp, "saved time: %04d/%02d/%02d %02d:%02d:%02d\n",
449 maya 3003 tm->tm_year + 1900,
450     tm->tm_mon + 1,
451     tm->tm_mday,
452     tm->tm_hour,
453     tm->tm_min,
454     tm->tm_sec);
455 yutakakn 2796 fprintf(fp, "\n");
456    
457     for (i = 0 ; i < memtag_count ; i++) {
458     fprintf(fp, "============================================\n");
459     fprintf(fp, "name: %s\n", memtags[i].name);
460     fprintf(fp, "--------------------------------------------\n");
461     fprintf(fp, "description: %s\n", memtags[i].desc);
462     fprintf(fp, "============================================\n");
463     dump_memdump(fp, memtags[i].data, memtags[i].len);
464     fprintf(fp, "\n\n\n");
465     }
466    
467     fprintf(fp, "[EOF]\n");
468    
469     fclose(fp);
470     }
471    
472     void push_memdump(char *name, char *desc, char *data, int len)
473     {
474     memtag_t *ptr;
475     char *dp;
476    
477     dp = malloc(len);
478     if (dp == NULL)
479     return;
480     memcpy(dp, data, len);
481    
482     if (memtag_count >= MEMTAG_MAX)
483     return;
484    
485     ptr = &memtags[memtag_count];
486     memtag_count++;
487 yutakakn 2850 ptr->name = _strdup(name);
488     ptr->desc = _strdup(desc);
489 yutakakn 2796 ptr->data = dp;
490     ptr->len = len;
491     }
492    
493     void push_bignum_memdump(char *name, char *desc, BIGNUM *bignum)
494     {
495     int len;
496     char *buf;
497    
498     len = BN_num_bytes(bignum);
499     buf = malloc(len); // allocate
500     if (buf == NULL)
501     return;
502     BN_bn2bin(bignum, buf);
503     push_memdump(name, desc, buf, len); // at push_bignum_memdump()
504     free(buf); // free
505     }
506    
507    
508     //
509     //
510     //
511    
512    
513 yutakakn 2728 static int get_predecryption_amount(PTInstVar pvar)
514     {
515     static int small_block_decryption_sizes[] = { 5, 5, 6, 6, 8 };
516    
517     if (SSHv1(pvar)) {
518     return 0;
519     } else {
520     int block_size = CRYPT_get_decryption_block_size(pvar);
521    
522     if (block_size < 5) {
523     return small_block_decryption_sizes[block_size];
524     } else {
525     return block_size;
526     }
527     }
528     }
529    
530     /* Get up to 'limit' bytes into the payload buffer.
531     'limit' is counted from the start of the payload data.
532     Returns the amount of data in the payload buffer, or
533     -1 if there is an error.
534     We can return more than limit in some cases. */
535     static int buffer_packet_data(PTInstVar pvar, int limit)
536     {
537     if (pvar->ssh_state.payloadlen >= 0) {
538     return pvar->ssh_state.payloadlen;
539     } else {
540     int cur_decompressed_bytes =
541     pvar->ssh_state.decompress_stream.next_out -
542     pvar->ssh_state.postdecompress_inbuf;
543    
544     while (limit > cur_decompressed_bytes) {
545     int result;
546    
547     pvar->ssh_state.payload =
548     pvar->ssh_state.postdecompress_inbuf + 1;
549 maya 3003 if (pvar->ssh_state.postdecompress_inbuflen == cur_decompressed_bytes) {
550 yutakakn 2728 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
551 maya 3003 &pvar->ssh_state.postdecompress_inbuflen,
552     min(limit, cur_decompressed_bytes * 2));
553 yutakakn 2728 }
554    
555 maya 3003 pvar->ssh_state.decompress_stream.next_out =
556 yutakakn 2728 pvar->ssh_state.postdecompress_inbuf +
557     cur_decompressed_bytes;
558     pvar->ssh_state.decompress_stream.avail_out =
559     min(limit, pvar->ssh_state.postdecompress_inbuflen)
560     - cur_decompressed_bytes;
561    
562     result =
563     inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH);
564     cur_decompressed_bytes =
565     pvar->ssh_state.decompress_stream.next_out -
566     pvar->ssh_state.postdecompress_inbuf;
567    
568     switch (result) {
569     case Z_OK:
570     break;
571     case Z_BUF_ERROR:
572     pvar->ssh_state.payloadlen = cur_decompressed_bytes;
573     return cur_decompressed_bytes;
574     default:
575 maya 2994 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
576 maya 3003 "Invalid compressed data in received packet");
577 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
578 yutakakn 2728 return -1;
579     }
580     }
581    
582     return cur_decompressed_bytes;
583     }
584     }
585    
586     /* For use by the protocol processing code.
587     Gets N bytes of uncompressed payload. Returns FALSE if data not available
588     and a fatal error has been signaled.
589     The data is available in the payload buffer. This buffer address
590     can change during a call to grab_payload, so take care!
591     The payload pointer is set to point to the first byte of the actual data
592     (after the packet type byte).
593     */
594     static BOOL grab_payload(PTInstVar pvar, int num_bytes)
595     {
596     /* Accept maximum of 4MB of payload data */
597     int in_buffer = buffer_packet_data(pvar, 4 * 1024 * 1024);
598    
599     if (in_buffer < 0) {
600     return FALSE;
601     } else {
602     pvar->ssh_state.payload_grabbed += num_bytes;
603     if (pvar->ssh_state.payload_grabbed > in_buffer) {
604 yutakakn 2835 char buf[128];
605 maya 2994 UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_ERROR", pvar,
606 maya 3003 "Received truncated packet (%ld > %d) @ grab_payload()");
607 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
608 maya 3003 pvar->ssh_state.payload_grabbed, in_buffer);
609 yutakakn 2835 notify_fatal_error(pvar, buf);
610 yutakakn 2728 return FALSE;
611     } else {
612     return TRUE;
613     }
614     }
615     }
616    
617     static BOOL grab_payload_limited(PTInstVar pvar, int num_bytes)
618     {
619     int in_buffer;
620    
621     pvar->ssh_state.payload_grabbed += num_bytes;
622     in_buffer = buffer_packet_data(pvar, pvar->ssh_state.payload_grabbed);
623    
624     if (in_buffer < 0) {
625     return FALSE;
626     } else {
627     if (pvar->ssh_state.payload_grabbed > in_buffer) {
628 yutakakn 2835 char buf[128];
629 maya 2994 UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_LIM_ERROR", pvar,
630 maya 3003 "Received truncated packet (%ld > %d) @ grab_payload_limited()");
631 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
632 maya 3003 pvar->ssh_state.payload_grabbed, in_buffer);
633 yutakakn 2835 notify_fatal_error(pvar, buf);
634 yutakakn 2728 return FALSE;
635     } else {
636     return TRUE;
637     }
638     }
639     }
640    
641     #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))
642     #define get_uint32(buf) get_uint32_MSBfirst((buf))
643     #define set_uint32(buf, v) set_uint32_MSBfirst((buf), (v))
644     #define get_mpint_len(pvar, offset) ((get_ushort16_MSBfirst((pvar)->ssh_state.payload + (offset)) + 7) >> 3)
645     #define get_ushort16(buf) get_ushort16_MSBfirst((buf))
646    
647     #define do_crc(buf, len) (~(uint32)crc32(0xFFFFFFFF, (buf), (len)))
648    
649     /* Decrypt the payload, checksum it, eat the padding, get the packet type
650     and return it.
651     'data' points to the start of the packet --- its length field.
652     'len' is the length of the
653     payload + padding (+ length of CRC for SSHv1). 'padding' is the length
654     of the padding alone. */
655     static int prep_packet(PTInstVar pvar, char FAR * data, int len,
656     int padding)
657     {
658     pvar->ssh_state.payload = data + 4;
659     pvar->ssh_state.payloadlen = len;
660    
661     if (SSHv1(pvar)) {
662     if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
663 maya 2994 UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar,
664 maya 3003 "'CORE insertion attack' detected. Aborting connection.");
665 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
666 yutakakn 2728 }
667    
668     CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
669     /* PKT guarantees that the data is always 4-byte aligned */
670     if (do_crc(pvar->ssh_state.payload, len - 4) !=
671     get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
672 maya 2994 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
673 maya 3003 "Detected corrupted data; connection terminating.");
674 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
675 yutakakn 2728 return SSH_MSG_NONE;
676     }
677    
678     pvar->ssh_state.payload += padding;
679     pvar->ssh_state.payloadlen -= padding + 4;
680     } else {
681     int already_decrypted = get_predecryption_amount(pvar);
682    
683     #if 0
684     CRYPT_decrypt(pvar, data + already_decrypted,
685 maya 3003 len - already_decrypted);
686 yutakakn 2728 #else
687     CRYPT_decrypt(pvar, data + already_decrypted,
688 maya 3003 (4 + len) - already_decrypted);
689 yutakakn 2728 #endif
690    
691     if (!CRYPT_verify_receiver_MAC
692     (pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4,
693     data + len + 4)) {
694 maya 2994 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
695 maya 3003 "Detected corrupted data; connection terminating.");
696 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
697 yutakakn 2728 return SSH_MSG_NONE;
698     }
699    
700     pvar->ssh_state.payload++;
701     pvar->ssh_state.payloadlen -= padding + 1;
702     }
703    
704     pvar->ssh_state.payload_grabbed = 0;
705    
706 yutakakn 2833 if (SSHv1(pvar)) {
707     if (pvar->ssh_state.decompressing) {
708     if (pvar->ssh_state.decompress_stream.avail_in != 0) {
709 maya 2994 UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
710 maya 3003 "Internal error: a packet was not fully decompressed.\n"
711     "This is a bug, please report it.");
712 maya 2942 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
713 yutakakn 2833 }
714    
715     pvar->ssh_state.decompress_stream.next_in =
716     pvar->ssh_state.payload;
717     pvar->ssh_state.decompress_stream.avail_in =
718     pvar->ssh_state.payloadlen;
719     pvar->ssh_state.decompress_stream.next_out =
720     pvar->ssh_state.postdecompress_inbuf;
721     pvar->ssh_state.payloadlen = -1;
722     } else {
723     pvar->ssh_state.payload++;
724 yutakakn 2728 }
725    
726 yutakakn 2833 if (!grab_payload_limited(pvar, 1)) {
727     return SSH_MSG_NONE;
728     }
729    
730 yutakakn 2728 } else {
731 yutakakn 2833 // support of SSH2 packet compression (2005.7.9 yutaka)
732 yutakakn 2873 // support of "Compression delayed" (2006.6.23 maya)
733     if ((pvar->stoc_compression == COMP_ZLIB ||
734 maya 3003 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&
735     pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
736 yutakakn 2833 int ret;
737 yutakakn 2728
738 yutakakn 2833 if (pvar->decomp_buffer == NULL) {
739     pvar->decomp_buffer = buffer_init();
740 maya 3054 if (pvar->decomp_buffer == NULL)
741 yutakakn 2833 return SSH_MSG_NONE;
742     }
743     // ���x�m�������o�b�t�@���g�������������������Y�������B
744     buffer_clear(pvar->decomp_buffer);
745    
746     // packet size��padding�������������y�C���[�h�����������W�J�����B
747 maya 3003 ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
748     pvar->ssh_state.payload,
749     pvar->ssh_state.payloadlen,
750     pvar->decomp_buffer);
751 yutakakn 2833
752     // �|�C���^���X�V�B
753     pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
754     pvar->ssh_state.payload++;
755     pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
756    
757     } else {
758     pvar->ssh_state.payload++;
759     }
760    
761     if (!grab_payload_limited(pvar, 1)) {
762     return SSH_MSG_NONE;
763     }
764    
765 yutakakn 2728 }
766    
767     pvar->ssh_state.receiver_sequence_number++;
768    
769     return pvar->ssh_state.payload[-1];
770     }
771    
772     /* Create a packet to be sent. The SSH protocol packet type is in 'type';
773     'len' contains the length of the packet payload, in bytes (this
774     does not include the space for any of the packet headers or padding,
775     or for the packet type byte).
776     Returns a pointer to the payload data area, a region of length 'len',
777     to be filled by the caller. */
778 maya 3003 static unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len)
779 yutakakn 2728 {
780     unsigned char FAR *buf;
781    
782     pvar->ssh_state.outgoing_packet_len = len + 1;
783    
784     if (pvar->ssh_state.compressing) {
785     buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
786 maya 3003 &pvar->ssh_state.precompress_outbuflen, 1 + len);
787 yutakakn 2728 buf = pvar->ssh_state.precompress_outbuf;
788     } else {
789     /* For SSHv2,
790     Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
791     + len(payload) + 4(minpadding), rounded up to nearest block_size
792     We only need a reasonable upper bound for the buffer size */
793     buf_ensure_size(&pvar->ssh_state.outbuf,
794 maya 3003 &pvar->ssh_state.outbuflen,
795     len + 30 + CRYPT_get_sender_MAC_size(pvar) +
796     CRYPT_get_encryption_block_size(pvar));
797 yutakakn 2728 buf = pvar->ssh_state.outbuf + 12;
798     }
799    
800     buf[0] = (unsigned char) type;
801     return buf + 1;
802     }
803    
804     #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0)
805    
806 maya 3054 // ���M���g���C����������
807 yutakapon 2945 //
808     // WinSock�� send() ���o�b�t�@�T�C�Y(len)�������������l��������������������
809     // ���������������A�����������G���[���������B
810     // �����������ATCP�R�l�N�V�������f�������o���h���B
811     // (2006.12.9 yutaka)
812     static int retry_send_packet(PTInstVar pvar, char FAR * data, int len)
813     {
814     int n;
815 yutakapon 2957 int err;
816 yutakapon 2945
817     while (len > 0) {
818     n = (pvar->Psend)(pvar->socket, data, len, 0);
819 yutakapon 2957
820     if (n < 0) {
821     err = WSAGetLastError();
822     if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
823     // send()�����l��0�������A�����G���[������ 10000 �������������A
824     // ���������������������B
825     // PuTTY 0.58���������Q�l�B
826     // (2007.2.4 yutak)
827     return 0; // success
828     }
829 yutakapon 2945 return 1; // error
830 yutakapon 2957 }
831    
832 yutakapon 2945 len -= n;
833     data += n;
834     }
835 yutakapon 2957
836 yutakapon 2945 return 0; // success
837     }
838    
839 yutakakn 2728 static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
840     {
841 maya 3012 #if 0
842 yutakakn 2728 u_long do_block = 0;
843    
844     if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
845 maya 3003 0, 0) == SOCKET_ERROR
846     || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR
847     || retry_send_packet(pvar, data, len)
848     || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
849     pvar->notification_msg,
850     pvar->notification_events) ==
851 yutakakn 2728 SOCKET_ERROR) {
852 maya 3012 #else
853     // �\�P�b�g���m���u���b�L���O���������p�P�b�g���M���s���B(2007.9.26 yutaka)
854     if (retry_send_packet(pvar, data, len)) {
855     #endif
856 maya 2994 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
857 maya 3003 "A communications error occurred while sending an SSH packet.\n"
858     "The connection will close.");
859 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
860 yutakakn 2728 return FALSE;
861     } else {
862     return TRUE;
863     }
864     }
865    
866     /* if skip_compress is true, then the data has already been compressed
867     into outbuf + 12 */
868     static void finish_send_packet_special(PTInstVar pvar, int skip_compress)
869     {
870     int len = pvar->ssh_state.outgoing_packet_len;
871     char FAR *data;
872     int data_length;
873 yutakakn 2833 buffer_t *msg = NULL; // for SSH2 packet compression
874 yutakakn 2728
875     if (pvar->ssh_state.compressing) {
876     if (!skip_compress) {
877     buf_ensure_size(&pvar->ssh_state.outbuf,
878 maya 3003 &pvar->ssh_state.outbuflen,
879     len + (len >> 6) + 50 +
880     CRYPT_get_sender_MAC_size(pvar));
881 yutakakn 2728 pvar->ssh_state.compress_stream.next_in =
882     pvar->ssh_state.precompress_outbuf;
883     pvar->ssh_state.compress_stream.avail_in = len;
884     pvar->ssh_state.compress_stream.next_out =
885     pvar->ssh_state.outbuf + 12;
886     pvar->ssh_state.compress_stream.avail_out =
887     pvar->ssh_state.outbuflen - 12;
888    
889 maya 3003 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
890 maya 2994 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
891 maya 3003 "An error occurred while compressing packet data.\n"
892     "The connection will close.");
893 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
894 yutakakn 2728 return;
895     }
896     }
897    
898     len =
899     pvar->ssh_state.outbuflen - 12 -
900     pvar->ssh_state.compress_stream.avail_out;
901     }
902    
903     if (SSHv1(pvar)) {
904     int padding = 8 - ((len + 4) % 8);
905    
906     data = pvar->ssh_state.outbuf + 8 - padding;
907     data_length = padding + len + 8;
908    
909     set_uint32(data, len + 4);
910     if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
911     CRYPT_set_random_data(pvar, data + 4, padding);
912     } else {
913     memset(data + 4, 0, padding);
914     }
915     set_uint32(data + data_length - 4,
916 maya 3003 do_crc(data + 4, data_length - 8));
917 yutakakn 2728 CRYPT_encrypt(pvar, data + 4, data_length - 4);
918     } else { //for SSH2(yutaka)
919     int block_size = CRYPT_get_encryption_block_size(pvar);
920 maya 3053 unsigned int encryption_size;
921     unsigned int padding;
922 yutakakn 2728 BOOL ret;
923    
924 yutakakn 2833 /*
925     �f�[�^�\��
926     pvar->ssh_state.outbuf:
927     offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
928 maya 3054 <--ignore---> ^^^^^^^^ <---- payload --->
929 yutakakn 2833 packet length
930    
931     ^^padding
932    
933     <---------------------------->
934     SSH2 sending data on TCP
935 maya 3054
936 yutakakn 2833 NOTE:
937     payload = type(1) + raw-data
938     len = ssh_state.outgoing_packet_len = payload size
939     */
940     // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
941 yutakakn 2873 // support of "Compression delayed" (2006.6.23 maya)
942     if ((pvar->ctos_compression == COMP_ZLIB ||
943 maya 3003 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
944     pvar->ssh2_keys[MODE_OUT].comp.enabled) {
945 yutakakn 2833 // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
946 maya 3054 msg = buffer_init();
947 yutakakn 2833 if (msg == NULL) {
948     // TODO: error check
949     return;
950     }
951    
952     // ���k�������w�b�_�������y�C���[�h�����B
953     buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
954     if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
955 maya 2994 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
956 maya 3003 "An error occurred while compressing packet data.\n"
957     "The connection will close.");
958 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
959 yutakakn 2833 return;
960     }
961     data = buffer_ptr(msg);
962     len = buffer_len(msg) - 5; // 'len' is overwritten.
963    
964     } else {
965     // �����k
966     data = pvar->ssh_state.outbuf + 7;
967    
968     }
969    
970     // ���M�p�P�b�g�\�z(input parameter: data, len)
971 yutakakn 2728 if (block_size < 8) {
972     block_size = 8;
973     }
974 yutakapon 3055 #if 0
975 yutakakn 2728 encryption_size = ((len + 8) / block_size + 1) * block_size;
976     data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
977    
978     set_uint32(data, encryption_size - 4);
979     padding = encryption_size - len - 5;
980     data[4] = (unsigned char) padding;
981 yutakapon 3055 #else
982     // �������p�P�b�g�����������������A�T�[�o����"Bad packet length"���������������������������B
983     // (2007.10.29 yutaka)
984     encryption_size = 4 + 1 + len;
985     padding = block_size - (encryption_size % block_size);
986     if (padding < 4)
987     padding += block_size;
988     encryption_size += padding;
989     set_uint32(data, encryption_size - 4);
990     data[4] = (unsigned char) padding;
991     data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
992     #endif
993 yutakakn 2728 CRYPT_set_random_data(pvar, data + 5 + len, padding);
994     ret = CRYPT_build_sender_MAC(pvar,
995 maya 3003 pvar->ssh_state.sender_sequence_number,
996     data, encryption_size,
997     data + encryption_size);
998 yutakakn 2728 if (ret == FALSE) { // HMAC��������������������������
999     data_length = encryption_size;
1000     }
1001    
1002     // �p�P�b�g�������������BHMAC���~�������������O�B
1003     CRYPT_encrypt(pvar, data, encryption_size);
1004     }
1005    
1006     send_packet_blocking(pvar, data, data_length);
1007    
1008 yutakakn 2833 buffer_free(msg);
1009    
1010 yutakakn 2728 pvar->ssh_state.sender_sequence_number++;
1011 yutakakn 2748
1012 maya 3054 // ���M�������L�^
1013 yutakakn 2748 pvar->ssh_heartbeat_tick = time(NULL);
1014 yutakakn 2728 }
1015    
1016     static void destroy_packet_buf(PTInstVar pvar)
1017     {
1018     memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1019     if (pvar->ssh_state.compressing) {
1020     memset(pvar->ssh_state.precompress_outbuf, 0,
1021 maya 3003 pvar->ssh_state.precompress_outbuflen);
1022 yutakakn 2728 }
1023     }
1024    
1025     /* The handlers are added to the queue for each message. When one of the
1026     handlers fires, if it returns FALSE, then all handlers in the set are
1027     removed from their queues. */
1028     static void enque_handlers(PTInstVar pvar, int num_msgs,
1029 maya 3003 const int FAR * messages,
1030     const SSHPacketHandler FAR * handlers)
1031 yutakakn 2728 {
1032     SSHPacketHandlerItem FAR *first_item;
1033     SSHPacketHandlerItem FAR *last_item = NULL;
1034     int i;
1035    
1036     for (i = 0; i < num_msgs; i++) {
1037     SSHPacketHandlerItem FAR *item =
1038     (SSHPacketHandlerItem FAR *)
1039     malloc(sizeof(SSHPacketHandlerItem));
1040     SSHPacketHandlerItem FAR *cur_item =
1041     pvar->ssh_state.packet_handlers[messages[i]];
1042    
1043     item->handler = handlers[i];
1044    
1045     if (cur_item == NULL) {
1046     pvar->ssh_state.packet_handlers[messages[i]] = item;
1047     item->next_for_message = item;
1048     item->last_for_message = item;
1049     item->active_for_message = messages[i];
1050     } else {
1051     item->next_for_message = cur_item;
1052     item->last_for_message = cur_item->last_for_message;
1053     cur_item->last_for_message->next_for_message = item;
1054     cur_item->last_for_message = item;
1055     item->active_for_message = -1;
1056     }
1057    
1058     if (last_item != NULL) {
1059     last_item->next_in_set = item;
1060     } else {
1061     first_item = item;
1062     }
1063     last_item = item;
1064     }
1065    
1066     if (last_item != NULL) {
1067     last_item->next_in_set = first_item;
1068     }
1069     }
1070    
1071     static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1072     {
1073     SSHPacketHandlerItem FAR *cur_item =
1074     pvar->ssh_state.packet_handlers[message];
1075    
1076     if (cur_item == NULL) {
1077     return NULL;
1078     } else {
1079     return cur_item->handler;
1080     }
1081     }
1082    
1083     /* Called only by SSH_handle_packet */
1084     static void deque_handlers(PTInstVar pvar, int message)
1085     {
1086     SSHPacketHandlerItem FAR *cur_item =
1087     pvar->ssh_state.packet_handlers[message];
1088     SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1089    
1090     do {
1091     SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1092    
1093     if (cur_item->active_for_message >= 0) {
1094     SSHPacketHandlerItem FAR *replacement =
1095     cur_item->next_for_message;
1096    
1097     if (replacement == cur_item) {
1098     replacement = NULL;
1099     } else {
1100     replacement->active_for_message =
1101     cur_item->active_for_message;
1102     }
1103     pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1104     replacement;
1105     }
1106     cur_item->next_for_message->last_for_message =
1107     cur_item->last_for_message;
1108     cur_item->last_for_message->next_for_message =
1109     cur_item->next_for_message;
1110    
1111     free(cur_item);
1112     cur_item = next_in_set;
1113     } while (cur_item != first_item_in_set);
1114     }
1115    
1116     static void enque_handler(PTInstVar pvar, int message,
1117 maya 3003 SSHPacketHandler handler)
1118 yutakakn 2728 {
1119     enque_handlers(pvar, 1, &message, &handler);
1120     }
1121    
1122     static void chop_newlines(char FAR * buf)
1123     {
1124     int len = strlen(buf);
1125    
1126     while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1127     buf[len - 1] = 0;
1128     len--;
1129     }
1130     }
1131    
1132     /********************/
1133     /* Message handlers */
1134     /********************/
1135    
1136     static BOOL handle_forwarding_success(PTInstVar pvar)
1137     {
1138     return FALSE;
1139     }
1140    
1141     static BOOL handle_forwarding_failure(PTInstVar pvar)
1142     {
1143     return FALSE;
1144     }
1145    
1146     static void enque_forwarding_request_handlers(PTInstVar pvar)
1147     {
1148     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1149     static const SSHPacketHandler handlers[]
1150     = { handle_forwarding_success, handle_forwarding_failure };
1151    
1152     enque_handlers(pvar, 2, msgs, handlers);
1153     }
1154    
1155     static BOOL handle_auth_failure(PTInstVar pvar)
1156     {
1157     notify_verbose_message(pvar, "Authentication failed",
1158 maya 3003 LOG_LEVEL_VERBOSE);
1159 yutakakn 2728
1160 yutakakn 2835 // retry count������ (2005.7.15 yutaka)
1161     pvar->userauth_retry_count++;
1162    
1163 yutakakn 2728 AUTH_set_generic_mode(pvar);
1164     AUTH_advance_to_next_cred(pvar);
1165     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1166     try_send_credentials(pvar);
1167     return FALSE;
1168     }
1169    
1170     static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1171     {
1172     AUTH_destroy_cur_cred(pvar);
1173     return handle_auth_failure(pvar);
1174     }
1175    
1176     static BOOL handle_TIS_challenge(PTInstVar pvar)
1177     {
1178     if (grab_payload(pvar, 4)) {
1179     int len = get_payload_uint32(pvar, 0);
1180    
1181     if (grab_payload(pvar, len)) {
1182     notify_verbose_message(pvar, "Received TIS challenge",
1183 maya 3003 LOG_LEVEL_VERBOSE);
1184 yutakakn 2728
1185     AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1186     AUTH_advance_to_next_cred(pvar);
1187     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1188     try_send_credentials(pvar);
1189     }
1190     }
1191     return FALSE;
1192     }
1193    
1194     static BOOL handle_auth_required(PTInstVar pvar)
1195     {
1196     notify_verbose_message(pvar, "Server requires authentication",
1197 maya 3003 LOG_LEVEL_VERBOSE);
1198 yutakakn 2728
1199     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1200     try_send_credentials(pvar);
1201     /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1202    
1203     return FALSE;
1204     }
1205    
1206     static BOOL handle_ignore(PTInstVar pvar)
1207     {
1208 maya 2938 if (SSHv1(pvar)) {
1209     if (grab_payload(pvar, 4)
1210 maya 3003 && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1211 maya 2938 /* ignore it! but it must be decompressed */
1212     }
1213 yutakakn 2728 }
1214 maya 2938 /*
1215     else {
1216     // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1217     // Cisco ���[�^���� (2006.11.28 maya)
1218     }
1219     */
1220 yutakakn 2728 return TRUE;
1221     }
1222    
1223     static BOOL handle_debug(PTInstVar pvar)
1224     {
1225     BOOL always_display;
1226     char FAR *description;
1227     int description_len;
1228     char buf[2048];
1229    
1230     if (SSHv1(pvar)) {
1231     if (grab_payload(pvar, 4)
1232 maya 3003 && grab_payload(pvar, description_len =
1233     get_payload_uint32(pvar, 0))) {
1234 yutakakn 2728 always_display = FALSE;
1235     description = pvar->ssh_state.payload + 4;
1236     description[description_len] = 0;
1237     } else {
1238     return TRUE;
1239     }
1240     } else {
1241     if (grab_payload(pvar, 5)
1242 maya 3003 && grab_payload(pvar,
1243     (description_len = get_payload_uint32(pvar, 1)) + 4)
1244     && grab_payload(pvar,
1245     get_payload_uint32(pvar, 5 + description_len))) {
1246 yutakakn 2728 always_display = pvar->ssh_state.payload[0] != 0;
1247     description = pvar->ssh_state.payload + 5;
1248     description[description_len] = 0;
1249     } else {
1250     return TRUE;
1251     }
1252     }
1253    
1254     chop_newlines(description);
1255 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1256 maya 3003 description);
1257 yutakakn 2728 if (always_display) {
1258     notify_nonfatal_error(pvar, buf);
1259     } else {
1260     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1261     }
1262     return TRUE;
1263     }
1264    
1265     static BOOL handle_disconnect(PTInstVar pvar)
1266     {
1267     int reason_code;
1268     char FAR *description;
1269     int description_len;
1270     char buf[2048];
1271     char FAR *explanation = "";
1272 maya 2942 char uimsg[MAX_UIMSG];
1273 yutakakn 2728
1274     if (SSHv1(pvar)) {
1275     if (grab_payload(pvar, 4)
1276 maya 3003 && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1277 yutakakn 2728 reason_code = -1;
1278     description = pvar->ssh_state.payload + 4;
1279     description[description_len] = 0;
1280     } else {
1281     return TRUE;
1282     }
1283     } else {
1284     if (grab_payload(pvar, 8)
1285 maya 3003 && grab_payload(pvar,
1286     (description_len = get_payload_uint32(pvar, 4)) + 4)
1287     && grab_payload(pvar,
1288     get_payload_uint32(pvar, 8 + description_len))) {
1289 yutakakn 2728 reason_code = get_payload_uint32(pvar, 0);
1290     description = pvar->ssh_state.payload + 8;
1291     description[description_len] = 0;
1292     } else {
1293     return TRUE;
1294     }
1295     }
1296    
1297     chop_newlines(description);
1298     if (description[0] == 0) {
1299     description = NULL;
1300     }
1301    
1302     if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1303 maya 2994 UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1304 maya 3003 "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1305     "This often happens when someone is already forwarding that port from the server.");
1306 maya 2992 strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1307 maya 2942 explanation = uimsg;
1308 yutakakn 2728 }
1309    
1310     if (description != NULL) {
1311 maya 2994 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1312 maya 3053 "Server disconnected with message '%s'%s");
1313 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1314 maya 3003 pvar->ts->UIMsg, description,
1315     explanation);
1316 yutakakn 2728 } else {
1317 maya 2994 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1318 maya 3003 "Server disconnected (no reason given).%s");
1319 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1320 maya 3003 pvar->ts->UIMsg, explanation);
1321 yutakakn 2728 }
1322     notify_fatal_error(pvar, buf);
1323    
1324     return TRUE;
1325     }
1326    
1327     static BOOL handle_unimplemented(PTInstVar pvar)
1328     {
1329     /* Should never receive this since we only send base 2.0 protocol messages */
1330     grab_payload(pvar, 4);
1331     return TRUE;
1332     }
1333    
1334     static BOOL handle_crypt_success(PTInstVar pvar)
1335     {
1336     notify_verbose_message(pvar, "Secure mode successfully achieved",
1337 maya 3003 LOG_LEVEL_VERBOSE);
1338 yutakakn 2728 return FALSE;
1339     }
1340    
1341     static BOOL handle_noauth_success(PTInstVar pvar)
1342     {
1343     notify_verbose_message(pvar, "Server does not require authentication",
1344 maya 3003 LOG_LEVEL_VERBOSE);
1345 yutakakn 2728 prep_compression(pvar);
1346     return FALSE;
1347     }
1348    
1349     static BOOL handle_auth_success(PTInstVar pvar)
1350     {
1351     notify_verbose_message(pvar, "Authentication accepted",
1352 maya 3003 LOG_LEVEL_VERBOSE);
1353 yutakakn 2728 prep_compression(pvar);
1354 yutakakn 2748
1355     // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1356     start_ssh_heartbeat_thread(pvar);
1357    
1358 yutakakn 2728 return FALSE;
1359     }
1360    
1361     static BOOL handle_server_public_key(PTInstVar pvar)
1362     {
1363     int server_key_public_exponent_len;
1364     int server_key_public_modulus_pos;
1365     int server_key_public_modulus_len;
1366     int host_key_bits_pos;
1367     int host_key_public_exponent_len;
1368     int host_key_public_modulus_pos;
1369     int host_key_public_modulus_len;
1370     int protocol_flags_pos;
1371     int supported_ciphers;
1372     char FAR *inmsg;
1373 yutakakn 2856 Key hostkey;
1374 yutakakn 2728
1375     if (!grab_payload(pvar, 14))
1376     return FALSE;
1377     server_key_public_exponent_len = get_mpint_len(pvar, 12);
1378    
1379     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1380     return FALSE;
1381     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1382     server_key_public_modulus_len =
1383     get_mpint_len(pvar, server_key_public_modulus_pos);
1384    
1385     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1386     return FALSE;
1387     host_key_bits_pos =
1388     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1389     host_key_public_exponent_len =
1390     get_mpint_len(pvar, host_key_bits_pos + 4);
1391    
1392     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1393     return FALSE;
1394     host_key_public_modulus_pos =
1395     host_key_bits_pos + 6 + host_key_public_exponent_len;
1396     host_key_public_modulus_len =
1397     get_mpint_len(pvar, host_key_public_modulus_pos);
1398    
1399     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1400     return FALSE;
1401     protocol_flags_pos =
1402     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1403    
1404     inmsg = pvar->ssh_state.payload;
1405    
1406     CRYPT_set_server_cookie(pvar, inmsg);
1407 maya 3003 if (!CRYPT_set_server_RSA_key(pvar,
1408     get_uint32(inmsg + 8),
1409     pvar->ssh_state.payload + 12,
1410     inmsg + server_key_public_modulus_pos))
1411 yutakakn 2728 return FALSE;
1412 maya 3003 if (!CRYPT_set_host_RSA_key(pvar,
1413     get_uint32(inmsg + host_key_bits_pos),
1414     inmsg + host_key_bits_pos + 4,
1415     inmsg + host_key_public_modulus_pos))
1416 yutakakn 2728 return FALSE;
1417     pvar->ssh_state.server_protocol_flags =
1418     get_uint32(inmsg + protocol_flags_pos);
1419    
1420     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1421 maya 3003 if (!CRYPT_set_supported_ciphers(pvar,
1422     supported_ciphers,
1423     supported_ciphers))
1424 yutakakn 2728 return FALSE;
1425 maya 3003 if (!AUTH_set_supported_auth_types(pvar,
1426     get_uint32(inmsg + protocol_flags_pos + 8)))
1427 yutakakn 2728 return FALSE;
1428    
1429     /* this must be the LAST THING in this function, since it can cause
1430     host_is_OK to be called. */
1431 yutakakn 2856 hostkey.type = KEY_RSA1;
1432     hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1433     hostkey.exp = inmsg + host_key_bits_pos + 4;
1434     hostkey.mod = inmsg + host_key_public_modulus_pos;
1435     HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, &hostkey);
1436 yutakakn 2728
1437     return FALSE;
1438     }
1439    
1440     /*
1441     The ID must have already been found to start with "SSH-". It must
1442     be null-terminated.
1443     */
1444     static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1445     {
1446     char FAR *str;
1447    
1448     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1449     }
1450    
1451     if (*str != '.') {
1452     return FALSE;
1453     }
1454    
1455     pvar->protocol_major = atoi(ID + 4);
1456     pvar->protocol_minor = atoi(str + 1);
1457    
1458     // for SSH2(yutaka)
1459     // 1.99����SSH2�����������s��
1460     if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
1461     // ���[�U�� SSH2 ���I������������������
1462     if (pvar->settings.ssh_protocol_version == 2) {
1463     pvar->protocol_major = 2;
1464     pvar->protocol_minor = 0;
1465     }
1466    
1467     }
1468    
1469     for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1470     }
1471    
1472     return *str == '-';
1473     }
1474    
1475     /*
1476     On entry, the pvar->protocol_xxx fields hold the server's advertised
1477     protocol number. We replace the fields with the protocol number we will
1478     actually use, or return FALSE if there is no usable protocol version.
1479     */
1480     static BOOL negotiate_protocol(PTInstVar pvar)
1481     {
1482     switch (pvar->protocol_major) {
1483     case 1:
1484     if (pvar->protocol_minor > 5) {
1485     pvar->protocol_minor = 5;
1486     }
1487    
1488     return TRUE;
1489    
1490     // for SSH2(yutaka)
1491     case 2:
1492     return TRUE; // SSH2 support
1493    
1494     default:
1495     return FALSE;
1496     }
1497     }
1498    
1499     static void init_protocol(PTInstVar pvar)
1500     {
1501     CRYPT_initialize_random_numbers(pvar);
1502 yutakakn 2856
1503     // known_hosts�t�@�C�������z�X�g���J������������������
1504 yutakakn 2728 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname);
1505 yutakakn 2856
1506 yutakakn 2728 /* while we wait for a response from the server... */
1507    
1508     if (SSHv1(pvar)) {
1509     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1510     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1511     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1512     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1513    
1514     } else { // for SSH2(yutaka)
1515     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1516     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1517     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1518     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1519     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1520 maya 3054 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1521     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1522 yutakakn 2728 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1523     enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_authrequest);
1524     enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1525     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1526     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1527 yutakakn 2782 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1528 yutakakn 2728
1529     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1530    
1531     // ���[�U�F�������f�B�X�p�b�`���[�`��
1532     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1533     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1534     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1535 maya 2926 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1536 yutakakn 2825 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1537 yutakakn 2728 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1538 yutakakn 2827 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1539 yutakakn 2728 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1540     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1541     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1542     // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1543 yutakakn 2825 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1544 yutakakn 2728 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1545    
1546     }
1547     }
1548    
1549     BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1550     {
1551     static const char prefix[] = "Received server prologue string: ";
1552    
1553 yutakakn 2796 // initialize SSH2 memory dump (2005.3.7 yutaka)
1554     init_memdump();
1555 maya 2929 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1556 yutakakn 2796
1557 yutakakn 2728 if (ID_len <= 0) {
1558     return FALSE;
1559     } else {
1560 maya 2992 int buf_len = ID_len + NUM_ELEM(prefix);
1561     char FAR *buf = (char FAR *) malloc(buf_len);
1562 yutakakn 2728
1563 maya 2992 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1564     strncat_s(buf, buf_len, ID, _TRUNCATE);
1565 yutakakn 2728 chop_newlines(buf);
1566    
1567     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1568    
1569     free(buf);
1570    
1571    
1572 yutakakn 2797 // ���������R�s�[������ (2005.3.9 yutaka)
1573     #if 0
1574 yutakakn 2728 // for calculate SSH2 hash
1575     // �T�[�o�o�[�W�����������i���s���������������j
1576 maya 3054 if (ID_len >= sizeof(pvar->server_version_string))
1577 yutakakn 2728 return FALSE;
1578     strncpy(pvar->server_version_string, ID, ID_len);
1579 yutakakn 2797 #endif
1580 yutakakn 2728
1581    
1582     if (ID[ID_len - 1] != '\n') {
1583     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1584     return FALSE;
1585 maya 3003 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1586 yutakakn 2728 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1587     return FALSE;
1588     } else if (strncmp(ID, "SSH-", 4) != 0) {
1589     return FALSE;
1590     } else {
1591     ID[ID_len - 1] = 0;
1592    
1593     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1594     ID[ID_len - 2] = 0;
1595     }
1596    
1597     pvar->ssh_state.server_ID = _strdup(ID);
1598    
1599     if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1600 maya 2994 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1601 maya 3003 "This program does not understand the server's version of the protocol.");
1602 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
1603 yutakakn 2728 } else {
1604     char TTSSH_ID[1024];
1605     int TTSSH_ID_len;
1606 yutakakn 2793 int a, b, c, d;
1607 yutakakn 2728
1608 yutakakn 2793 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1609     get_file_version("ttxssh.dll", &a, &b, &c, &d);
1610    
1611 maya 2992 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1612 maya 3003 "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1613     pvar->protocol_major, pvar->protocol_minor, a, b);
1614 yutakakn 2728 TTSSH_ID_len = strlen(TTSSH_ID);
1615    
1616     // for SSH2(yutaka)
1617     // �N���C�A���g�o�[�W�����������i���s���������������j
1618 maya 2992 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1619 maya 3003 TTSSH_ID, _TRUNCATE);
1620 yutakakn 2728
1621 yutakakn 2797 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1622 maya 2992 _snprintf_s(pvar->server_version_string,
1623 maya 3003 sizeof(pvar->server_version_string), _TRUNCATE,
1624     "%s", pvar->ssh_state.server_ID);
1625 yutakakn 2797
1626 yutakakn 2728 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1627 maya 3003 0) != TTSSH_ID_len) {
1628 maya 2994 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1629 maya 3003 "An error occurred while sending the SSH ID string.\n"
1630     "The connection will close.");
1631 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
1632 yutakakn 2728 } else {
1633     // ���s�R�[�h������ (2004.8.4 yutaka)
1634     pvar->client_version_string[--TTSSH_ID_len] = 0;
1635    
1636 yutakakn 2796 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1637     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1638    
1639 yutakakn 2728 // SSH�n���h�����o�^���s��
1640     init_protocol(pvar);
1641    
1642     SSH2_dispatch_init(1);
1643     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1644 yutakakn 2796 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1645 yutakakn 2728 }
1646     }
1647    
1648     return TRUE;
1649     }
1650     }
1651     }
1652    
1653     static BOOL handle_exit(PTInstVar pvar)
1654     {
1655     if (grab_payload(pvar, 4)) {
1656     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1657     finish_send_packet(pvar);
1658     notify_closed_connection(pvar);
1659     }
1660     return TRUE;
1661     }
1662    
1663     static BOOL handle_data(PTInstVar pvar)
1664     {
1665     if (grab_payload_limited(pvar, 4)) {
1666     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1667     pvar->ssh_state.payload_datastart = 4;
1668     }
1669     return TRUE;
1670     }
1671    
1672     static BOOL handle_channel_open(PTInstVar pvar)
1673     {
1674     int host_len;
1675     int originator_len;
1676    
1677     if ((pvar->ssh_state.
1678     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1679     if (grab_payload(pvar, 8)
1680 maya 3003 && grab_payload(pvar,
1681     8 + (host_len = get_payload_uint32(pvar, 4)))
1682     && grab_payload(pvar, originator_len =
1683     get_payload_uint32(pvar, host_len + 12))) {
1684 yutakakn 2728 int local_port = get_payload_uint32(pvar, 8 + host_len);
1685    
1686     pvar->ssh_state.payload[8 + host_len] = 0;
1687     FWD_open(pvar, get_payload_uint32(pvar, 0),
1688 maya 3003 pvar->ssh_state.payload + 8, local_port,
1689     pvar->ssh_state.payload + 16 + host_len,
1690 maya 3054 originator_len,
1691 maya 3003 NULL);
1692 yutakakn 2728 }
1693     } else {
1694     if (grab_payload(pvar, 8)
1695 maya 3003 && grab_payload(pvar,
1696     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1697 yutakakn 2728 int local_port = get_payload_uint32(pvar, 8 + host_len);
1698    
1699     pvar->ssh_state.payload[8 + host_len] = 0;
1700     FWD_open(pvar, get_payload_uint32(pvar, 0),
1701 maya 3003 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1702     NULL);
1703 yutakakn 2728 }
1704     }
1705    
1706     return TRUE;
1707     }
1708    
1709     static BOOL handle_X11_channel_open(PTInstVar pvar)
1710     {
1711     int originator_len;
1712    
1713 maya 3003 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1714 yutakakn 2728 if (grab_payload(pvar, 8)
1715 maya 3003 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1716 yutakakn 2728 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1717 maya 3003 pvar->ssh_state.payload + 8, originator_len, NULL);
1718 yutakakn 2728 }
1719     } else {
1720     if (grab_payload(pvar, 4)) {
1721 yutakakn 2829 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1722 yutakakn 2728 }
1723     }
1724    
1725     return TRUE;
1726     }
1727    
1728     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1729     {
1730     if (grab_payload(pvar, 8)) {
1731     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1732 maya 3003 get_payload_uint32(pvar, 4));
1733 yutakakn 2728 }
1734     return FALSE;
1735     }
1736    
1737     static BOOL handle_channel_open_failure(PTInstVar pvar)
1738     {
1739     if (grab_payload(pvar, 4)) {
1740     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1741     }
1742     return FALSE;
1743     }
1744    
1745     static BOOL handle_channel_data(PTInstVar pvar)
1746     {
1747     int len;
1748    
1749     if (grab_payload(pvar, 8)
1750 maya 3003 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1751 yutakakn 2728 FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1752 maya 3003 pvar->ssh_state.payload + 8, len);
1753 yutakakn 2728 }
1754     return TRUE;
1755     }
1756    
1757     static BOOL handle_channel_input_eof(PTInstVar pvar)
1758     {
1759     if (grab_payload(pvar, 4)) {
1760     FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1761     }
1762     return TRUE;
1763     }
1764    
1765     static BOOL handle_channel_output_eof(PTInstVar pvar)
1766     {
1767     if (grab_payload(pvar, 4)) {
1768     FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1769     }
1770     return TRUE;
1771     }
1772    
1773    
1774    
1775     // �n���h�����O�������b�Z�[�W����������
1776    
1777     #define HANDLE_MESSAGE_MAX 30
1778     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1779     static int handle_message_count = 0;
1780     static int handle_message_stage = 0;
1781    
1782     void SSH2_dispatch_init(int stage)
1783     {
1784     handle_message_count = 0;
1785     handle_message_stage = stage;
1786     }
1787    
1788     int SSH2_dispatch_enabled_check(unsigned char message)
1789     {
1790     int i;
1791    
1792     for (i = 0 ; i < handle_message_count ; i++) {
1793     if (handle_messages[i] == message)
1794     return 1;
1795     }
1796     return 0;
1797     }
1798    
1799     void SSH2_dispatch_add_message(unsigned char message)
1800     {
1801    
1802     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1803     // TODO: error check
1804     return;
1805     }
1806    
1807     handle_messages[handle_message_count++] = message;
1808     }
1809    
1810     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1811     {
1812     unsigned char c;
1813    
1814     for (c = begin ; c <= end ; c++) {
1815     SSH2_dispatch_add_message(c);
1816     }
1817     }
1818    
1819    
1820     void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1821     int padding)
1822     {
1823     unsigned char message = prep_packet(pvar, data, len, padding);
1824    
1825    
1826     #ifdef SSH2_DEBUG
1827     // for SSH2(yutaka)
1828     if (SSHv2(pvar)) {
1829     if (pvar->key_done) {
1830     message = message;
1831     }
1832    
1833     if (pvar->userauth_success) {
1834     message = message;
1835     }
1836    
1837     if (pvar->rekeying) {
1838     message = message;
1839     }
1840     }
1841     #endif
1842    
1843     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1844     if (message != SSH_MSG_NONE) {
1845     // ���b�Z�[�W�^�C�v���������n���h�����N��
1846     SSHPacketHandler handler = get_handler(pvar, message);
1847    
1848     // for SSH2(yutaka)
1849     if (SSHv2(pvar)) {
1850     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1851     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1852     char buf[1024];
1853    
1854 maya 2994 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
1855     "Unexpected SSH2 message(%d) on current stage(%d)");
1856 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1857 maya 2942 pvar->ts->UIMsg, message, handle_message_stage);
1858 yutakakn 2728 notify_fatal_error(pvar, buf);
1859     // abort
1860     }
1861     }
1862    
1863     if (handler == NULL) {
1864     if (SSHv1(pvar)) {
1865     char buf[1024];
1866    
1867 maya 2994 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
1868 maya 3003 "Unexpected packet type received: %d");
1869 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1870 maya 2942 pvar->ts->UIMsg, message, handle_message_stage);
1871 yutakakn 2728 notify_fatal_error(pvar, buf);
1872     } else {
1873     unsigned char FAR *outmsg =
1874     begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
1875    
1876     set_uint32(outmsg,
1877 maya 3003 pvar->ssh_state.receiver_sequence_number - 1);
1878 yutakakn 2728 finish_send_packet(pvar);
1879     /* XXX need to decompress incoming packet, but how? */
1880     }
1881     } else {
1882     if (!handler(pvar)) {
1883     deque_handlers(pvar, message);
1884     }
1885     }
1886     }
1887     }
1888    
1889     static BOOL handle_pty_success(PTInstVar pvar)
1890     {
1891     FWD_enter_interactive_mode(pvar);
1892     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
1893     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
1894     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
1895     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
1896     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
1897 maya 3003 handle_channel_input_eof);
1898 yutakakn 2728 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
1899 maya 3003 handle_channel_output_eof);
1900 yutakakn 2728 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
1901     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
1902     return FALSE;
1903     }
1904    
1905     static BOOL handle_pty_failure(PTInstVar pvar)
1906     {
1907 maya 2994 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
1908 maya 3003 "The server cannot allocate a pseudo-terminal. "
1909     "You may encounter some problems with the terminal.");
1910 maya 2942 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1911 yutakakn 2728 return handle_pty_success(pvar);
1912     }
1913    
1914     static void prep_pty(PTInstVar pvar)
1915     {
1916     int len = strlen(pvar->ts->TermType);
1917     unsigned char FAR *outmsg =
1918     begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
1919 maya 3003 4 + len + 16 + sizeof(ssh_ttymodes));
1920 yutakakn 2728 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1921     static const SSHPacketHandler handlers[]
1922     = { handle_pty_success, handle_pty_failure };
1923    
1924     set_uint32(outmsg, len);
1925     memcpy(outmsg + 4, pvar->ts->TermType, len);
1926     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
1927     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
1928     set_uint32(outmsg + 4 + len + 8, 0);
1929     set_uint32(outmsg + 4 + len + 12, 0);
1930     memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
1931     finish_send_packet(pvar);
1932    
1933     enque_handlers(pvar, 2, msgs, handlers);
1934    
1935     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
1936     finish_send_packet(pvar);
1937     }
1938    
1939     static void prep_forwarding(PTInstVar pvar)
1940     {
1941     FWD_prep_forwarding(pvar);
1942     prep_pty(pvar);
1943     }
1944    
1945 yutakakn 2834
1946     //
1947     //
1948     // (2005.7.10 yutaka)
1949     static void enable_send_compression(PTInstVar pvar)
1950 yutakakn 2728 {
1951 yutakakn 2834 static int initialize = 0;
1952    
1953     if (initialize) {
1954     deflateEnd(&pvar->ssh_state.compress_stream);
1955     }
1956     initialize = 1;
1957    
1958 yutakakn 2728 pvar->ssh_state.compress_stream.zalloc = NULL;
1959     pvar->ssh_state.compress_stream.zfree = NULL;
1960     pvar->ssh_state.compress_stream.opaque = NULL;
1961     if (deflateInit
1962 maya 3003 (&pvar->ssh_state.compress_stream,
1963     pvar->ssh_state.compression_level) != Z_OK) {
1964 maya 2994 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
1965 maya 3003 "An error occurred while setting up compression.\n"
1966     "The connection will close.");
1967 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
1968 yutakakn 2728 return;
1969     } else {
1970 yutakakn 2834 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
1971     if (SSHv2(pvar)) {
1972     pvar->ssh_state.compressing = FALSE;
1973     } else {
1974     pvar->ssh_state.compressing = TRUE;
1975     }
1976 yutakakn 2728 }
1977 yutakakn 2834 }
1978 yutakakn 2728
1979 yutakakn 2834 static void enable_recv_compression(PTInstVar pvar)
1980     {
1981     static int initialize = 0;
1982    
1983     if (initialize) {
1984     deflateEnd(&pvar->ssh_state.decompress_stream);
1985     }
1986     initialize = 1;
1987    
1988 yutakakn 2728 pvar->ssh_state.decompress_stream.zalloc = NULL;
1989     pvar->ssh_state.decompress_stream.zfree = NULL;
1990     pvar->ssh_state.decompress_stream.opaque = NULL;
1991     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
1992     deflateEnd(&pvar->ssh_state.compress_stream);
1993 maya 2994 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
1994 maya 3003 "An error occurred while setting up compression.\n"
1995     "The connection will close.");
1996 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
1997 yutakakn 2728 return;
1998     } else {
1999 yutakakn 2834 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2000     if (SSHv2(pvar)) {
2001     pvar->ssh_state.decompressing = FALSE;
2002     } else {
2003     pvar->ssh_state.decompressing = TRUE;
2004     }
2005    
2006 yutakakn 2728 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2007 maya 3003 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2008 yutakakn 2728 }
2009 yutakakn 2834 }
2010 yutakakn 2833
2011 yutakakn 2834 static void enable_compression(PTInstVar pvar)
2012     {
2013     enable_send_compression(pvar);
2014     enable_recv_compression(pvar);
2015    
2016 yutakakn 2833 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2017     if (SSHv2(pvar)) {
2018     pvar->ssh_state.compressing = FALSE;
2019     pvar->ssh_state.decompressing = FALSE;
2020     }
2021    
2022 yutakakn 2728 }
2023    
2024     static BOOL handle_enable_compression(PTInstVar pvar)
2025     {
2026     enable_compression(pvar);
2027     prep_forwarding(pvar);
2028     return FALSE;
2029     }
2030    
2031     static BOOL handle_disable_compression(PTInstVar pvar)
2032     {
2033     prep_forwarding(pvar);
2034     return FALSE;
2035     }
2036    
2037     static void prep_compression(PTInstVar pvar)
2038     {
2039     if (pvar->session_settings.CompressionLevel > 0) {
2040 yutakakn 2833 // added if statement (2005.7.10 yutaka)
2041     if (SSHv1(pvar)) {
2042     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2043     static const SSHPacketHandler handlers[]
2044     = { handle_enable_compression, handle_disable_compression };
2045 yutakakn 2728
2046 yutakakn 2833 unsigned char FAR *outmsg =
2047     begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2048 yutakakn 2728
2049 yutakakn 2833 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2050     finish_send_packet(pvar);
2051 yutakakn 2728
2052 yutakakn 2833 enque_handlers(pvar, 2, msgs, handlers);
2053     }
2054    
2055 yutakakn 2728 pvar->ssh_state.compression_level =
2056     pvar->session_settings.CompressionLevel;
2057    
2058     } else {
2059 yutakakn 2833 // added if statement (2005.7.10 yutaka)
2060     if (SSHv1(pvar)) {
2061     prep_forwarding(pvar);
2062     }
2063 yutakakn 2728 }
2064     }
2065    
2066     static void enque_simple_auth_handlers(PTInstVar pvar)
2067     {
2068     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2069     static const SSHPacketHandler handlers[]
2070     = { handle_auth_success, handle_auth_failure };
2071    
2072     enque_handlers(pvar, 2, msgs, handlers);
2073     }
2074    
2075     static BOOL handle_rsa_challenge(PTInstVar pvar)
2076     {
2077     int challenge_bytes;
2078    
2079     if (!grab_payload(pvar, 2)) {
2080     return FALSE;
2081     }
2082    
2083     challenge_bytes = get_mpint_len(pvar, 0);
2084    
2085     if (grab_payload(pvar, challenge_bytes)) {
2086     unsigned char FAR *outmsg =
2087     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2088    
2089     if (CRYPT_generate_RSA_challenge_response
2090     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2091 yutakakn 2811
2092     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2093     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2094     #if 0
2095     //AUTH_destroy_cur_cred(pvar);
2096     #endif
2097    
2098 yutakakn 2728 finish_send_packet(pvar);
2099    
2100     enque_simple_auth_handlers(pvar);
2101     } else {
2102 maya 2994 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2103 maya 3003 "An error occurred while decrypting the RSA challenge.\n"
2104     "Perhaps the key file is corrupted.");
2105 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
2106 yutakakn 2728 }
2107     }
2108    
2109     return FALSE;
2110     }
2111    
2112     #define OBFUSCATING_ROUND_TO 32
2113    
2114     static int obfuscating_round_up(PTInstVar pvar, int size)
2115     {
2116     return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2117     }
2118    
2119     static void try_send_credentials(PTInstVar pvar)
2120     {
2121     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2122     AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2123     static const int RSA_msgs[] =
2124     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2125     static const SSHPacketHandler RSA_handlers[]
2126     = { handle_rsa_challenge, handle_rsa_auth_refused };
2127     static const int TIS_msgs[] =
2128     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2129     static const SSHPacketHandler TIS_handlers[]
2130     = { handle_TIS_challenge, handle_auth_failure };
2131    
2132 yutakakn 2800 // SSH2���������������������X�L�b�v
2133 maya 3054 if (SSHv2(pvar))
2134 yutakakn 2800 goto skip_ssh2;
2135    
2136 yutakakn 2728 switch (cred->method) {
2137     case SSH_AUTH_NONE:
2138     return;
2139     case SSH_AUTH_PASSWORD:{
2140     int len = strlen(cred->password);
2141     // Round up password length to discourage traffic analysis
2142     int obfuscated_len = obfuscating_round_up(pvar, len);
2143     unsigned char FAR *outmsg =
2144     begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2145 maya 3003 4 + obfuscated_len);
2146 yutakakn 2728
2147     notify_verbose_message(pvar,
2148 maya 3003 "Trying PASSWORD authentication...",
2149     LOG_LEVEL_VERBOSE);
2150 yutakakn 2728
2151     set_uint32(outmsg, obfuscated_len);
2152     memcpy(outmsg + 4, cred->password, len);
2153     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2154 yutakakn 2811
2155     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2156     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2157     #if 0
2158     //AUTH_destroy_cur_cred(pvar);
2159     #endif
2160    
2161 yutakakn 2728 enque_simple_auth_handlers(pvar);
2162     break;
2163     }
2164     case SSH_AUTH_RHOSTS:{
2165     int len = strlen(cred->rhosts_client_user);
2166     unsigned char FAR *outmsg =
2167     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2168    
2169     notify_verbose_message(pvar,
2170 maya 3003 "Trying RHOSTS authentication...",
2171     LOG_LEVEL_VERBOSE);
2172 yutakakn 2728
2173     set_uint32(outmsg, len);
2174     memcpy(outmsg + 4, cred->rhosts_client_user, len);
2175     AUTH_destroy_cur_cred(pvar);
2176     enque_simple_auth_handlers(pvar);
2177     break;
2178     }
2179     case SSH_AUTH_RSA:{
2180     int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2181     unsigned char FAR *outmsg =
2182     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2183    
2184     notify_verbose_message(pvar,
2185 maya 3003 "Trying RSA authentication...",
2186     LOG_LEVEL_VERBOSE);
2187 yutakakn 2728
2188     set_ushort16_MSBfirst(outmsg, len * 8);
2189     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2190     /* don't destroy the current credentials yet */
2191     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2192     break;
2193     }
2194     case SSH_AUTH_RHOSTS_RSA:{
2195     int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2196     int name_len = strlen(cred->rhosts_client_user);
2197     int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2198     int index;
2199     unsigned char FAR *outmsg =
2200     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2201 maya 3003 12 + mod_len + name_len + exp_len);
2202 yutakakn 2728
2203     notify_verbose_message(pvar,
2204 maya 3003 "Trying RHOSTS+RSA authentication...",
2205     LOG_LEVEL_VERBOSE);
2206 yutakakn 2728
2207     set_uint32(outmsg, name_len);
2208     memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2209     index = 4 + name_len;
2210    
2211     set_uint32(outmsg + index, 8 * mod_len);
2212     set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2213     BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2214     index += 6 + exp_len;
2215    
2216     set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2217     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2218     /* don't destroy the current credentials yet */
2219     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2220     break;
2221     }
2222     case SSH_AUTH_TIS:{
2223     if (cred->password == NULL) {
2224     unsigned char FAR *outmsg =
2225     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2226    
2227     notify_verbose_message(pvar,
2228 maya 3003 "Trying TIS authentication...",
2229     LOG_LEVEL_VERBOSE);
2230 yutakakn 2728 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2231     } else {
2232     int len = strlen(cred->password);
2233     int obfuscated_len = obfuscating_round_up(pvar, len);
2234     unsigned char FAR *outmsg =
2235     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2236 maya 3003 4 + obfuscated_len);
2237 yutakakn 2728
2238     notify_verbose_message(pvar, "Sending TIS response",
2239 maya 3003 LOG_LEVEL_VERBOSE);
2240 yutakakn 2728
2241     set_uint32(outmsg, obfuscated_len);
2242     memcpy(outmsg + 4, cred->password, len);
2243     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2244     enque_simple_auth_handlers(pvar);
2245     }
2246 yutakakn 2800
2247 yutakakn 2728 AUTH_destroy_cur_cred(pvar);
2248     break;
2249     }
2250     default:
2251 maya 2994 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2252 maya 3003 "Internal error: unsupported authentication method");
2253 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
2254 yutakakn 2728 return;
2255     }
2256    
2257     finish_send_packet(pvar);
2258 yutakakn 2800
2259     skip_ssh2:;
2260 yutakakn 2728 destroy_packet_buf(pvar);
2261    
2262     pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2263     }
2264     }
2265    
2266     static void try_send_user_name(PTInstVar pvar)
2267     {
2268     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2269     char FAR *username = AUTH_get_user_name(pvar);
2270    
2271     if (username != NULL) {
2272     int len = strlen(username);
2273     int obfuscated_len = obfuscating_round_up(pvar, len);
2274     unsigned char FAR *outmsg =
2275     begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
2276     char buf[1024] = "Sending user name: ";
2277     static const int msgs[] =
2278     { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2279     static const SSHPacketHandler handlers[]
2280     = { handle_noauth_success, handle_auth_required };
2281    
2282     set_uint32(outmsg, obfuscated_len);
2283     memcpy(outmsg + 4, username, len);
2284     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2285     finish_send_packet(pvar);
2286    
2287     pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2288    
2289 maya 2992 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2290 yutakakn 2728 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2291    
2292     enque_handlers(pvar, 2, msgs, handlers);
2293     }
2294     }
2295     }
2296    
2297     static void send_session_key(PTInstVar pvar)
2298     {
2299     int encrypted_session_key_len;
2300     unsigned char FAR *outmsg;
2301    
2302     if (SSHv1(pvar)) {
2303     encrypted_session_key_len =
2304     CRYPT_get_encrypted_session_key_len(pvar);
2305     }
2306    
2307     if (!CRYPT_choose_ciphers(pvar))
2308     return;
2309    
2310     if (SSHv1(pvar)) {
2311     outmsg =
2312     begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2313 maya 3003 15 + encrypted_session_key_len);
2314 yutakakn 2728 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2315     memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2316     outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2317     outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2318     if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2319     return;
2320     set_uint32(outmsg + 11 + encrypted_session_key_len,
2321 maya 3003 SSH_PROTOFLAG_SCREEN_NUMBER |
2322     SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2323 yutakakn 2728 finish_send_packet(pvar);
2324     }
2325    
2326     if (!CRYPT_start_encryption(pvar, 1, 1))
2327     return;
2328     notify_established_secure_connection(pvar);
2329    
2330     if (SSHv1(pvar)) {
2331     enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2332     }
2333    
2334     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2335    
2336     if (SSHv1(pvar)) {
2337     try_send_user_name(pvar);
2338     }
2339     }
2340    
2341     /*************************
2342     END of message handlers
2343     ************************/
2344    
2345     void SSH_init(PTInstVar pvar)
2346     {
2347     int i;
2348    
2349     buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2350     buf_create(&pvar->ssh_state.precompress_outbuf,
2351 maya 3003 &pvar->ssh_state.precompress_outbuflen);
2352 yutakakn 2728 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2353 maya 3003 &pvar->ssh_state.postdecompress_inbuflen);
2354 yutakakn 2728 pvar->ssh_state.payload = NULL;
2355     pvar->ssh_state.compressing = FALSE;
2356     pvar->ssh_state.decompressing = FALSE;
2357     pvar->ssh_state.status_flags =
2358     STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2359     pvar->ssh_state.payload_datalen = 0;
2360     pvar->ssh_state.hostname = NULL;
2361     pvar->ssh_state.server_ID = NULL;
2362     pvar->ssh_state.receiver_sequence_number = 0;
2363     pvar->ssh_state.sender_sequence_number = 0;
2364     for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2365     pvar->ssh_state.packet_handlers[i] = NULL;
2366     }
2367    
2368     // for SSH2(yutaka)
2369     memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2370     pvar->userauth_success = 0;
2371     pvar->session_nego_status = 0;
2372 yutakakn 2738 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2373 yutakakn 2728 pvar->rekeying = 0;
2374     pvar->key_done = 0;
2375 yutakakn 2739 pvar->ssh2_autologin = 0; // autologin disabled(default)
2376 maya 2908 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2377 yutakakn 2798 pvar->userauth_retry_count = 0;
2378 yutakakn 2833 pvar->decomp_buffer = NULL;
2379 yutakapon 2975 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2380 maya 3015 pvar->tryed_ssh2_authlist = FALSE;
2381 yutakakn 2728
2382     }
2383    
2384     void SSH_open(PTInstVar pvar)
2385     {
2386     pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2387     pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2388     pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2389     }
2390    
2391     void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2392     {
2393     if (SSHv1(pvar)) {
2394     int len = reason == NULL ? 0 : strlen(reason);
2395     unsigned char FAR *outmsg =
2396     begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2397    
2398     set_uint32(outmsg, len);
2399     if (reason != NULL) {
2400     memcpy(outmsg + 4, reason, len);
2401     }
2402     finish_send_packet(pvar);
2403    
2404     } else { // for SSH2(yutaka)
2405     buffer_t *msg;
2406     unsigned char *outmsg;
2407     int len;
2408 yutakakn 2809 Channel_t *c;
2409 yutakakn 2728
2410 yutakakn 2809 c = ssh2_channel_lookup(pvar->shell_id);
2411     if (c == NULL)
2412     return;
2413    
2414 yutakakn 2728 // SSH2 server��channel close���`����
2415     msg = buffer_init();
2416     if (msg == NULL) {
2417     // TODO: error check
2418     return;
2419     }
2420 maya 3054 buffer_put_int(msg, c->remote_id);
2421 yutakakn 2728
2422     len = buffer_len(msg);
2423     outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2424     memcpy(outmsg, buffer_ptr(msg), len);
2425     finish_send_packet(pvar);
2426     buffer_free(msg);
2427    
2428     }
2429    
2430     }
2431    
2432     void SSH_notify_host_OK(PTInstVar pvar)
2433     {
2434     if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2435     pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2436     send_session_key(pvar);
2437     }
2438     }
2439    
2440     void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2441     {
2442     pvar->ssh_state.win_cols = cols;
2443     pvar->ssh_state.win_rows = rows;
2444    
2445 yutakakn 2771 if (SSHv1(pvar)) {
2446     if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2447     unsigned char FAR *outmsg =
2448     begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2449 yutakakn 2728
2450 yutakakn 2771 set_uint32(outmsg, rows);
2451     set_uint32(outmsg + 4, cols);
2452     set_uint32(