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 3056 - (hide annotations) (download) (as text)
Sun Oct 28 15:36:45 2007 UTC (16 years, 5 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 192847 byte(s)
ポート転送において、remote_window未転送分の再送処理を追加。ただし、未完。

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