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 2945 - (hide annotations) (download) (as text)
Fri Dec 8 16:11:54 2006 UTC (17 years, 4 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 195288 byte(s)
パケット送信処理にTCPコネクション切断の誤検出をしないようにした。

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