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 2943 - (hide annotations) (download) (as text)
Wed Dec 6 14:25:40 2006 UTC (17 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 194739 byte(s)
表示メッセージの読み込み対応

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     static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
762     {
763     u_long do_block = 0;
764    
765     if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
766     0, 0) == SOCKET_ERROR
767     || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR
768     || (pvar->Psend) (pvar->socket, data, len, 0) != len
769     || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
770     pvar->notification_msg,
771     pvar->notification_events) ==
772     SOCKET_ERROR) {
773 maya 2940 #ifdef I18N
774 maya 2942 strcpy(pvar->ts->UIMsg, "A communications error occurred while sending an SSH packet.\n"
775     "The connection will close.");
776     UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar);
777     notify_fatal_error(pvar, pvar->ts->UIMsg);
778 maya 2940 #else
779 yutakakn 2728 notify_fatal_error(pvar,
780     "A communications error occurred while sending an SSH packet.\n"
781     "The connection will close.");
782 maya 2940 #endif
783 yutakakn 2728 return FALSE;
784     } else {
785     return TRUE;
786     }
787     }
788    
789     /* if skip_compress is true, then the data has already been compressed
790     into outbuf + 12 */
791     static void finish_send_packet_special(PTInstVar pvar, int skip_compress)
792     {
793     int len = pvar->ssh_state.outgoing_packet_len;
794     char FAR *data;
795     int data_length;
796 yutakakn 2833 buffer_t *msg = NULL; // for SSH2 packet compression
797 yutakakn 2728
798     if (pvar->ssh_state.compressing) {
799     if (!skip_compress) {
800     buf_ensure_size(&pvar->ssh_state.outbuf,
801     &pvar->ssh_state.outbuflen,
802     len + (len >> 6) + 50 +
803     CRYPT_get_sender_MAC_size(pvar));
804     pvar->ssh_state.compress_stream.next_in =
805     pvar->ssh_state.precompress_outbuf;
806     pvar->ssh_state.compress_stream.avail_in = len;
807     pvar->ssh_state.compress_stream.next_out =
808     pvar->ssh_state.outbuf + 12;
809     pvar->ssh_state.compress_stream.avail_out =
810     pvar->ssh_state.outbuflen - 12;
811    
812     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
813     Z_OK) {
814 maya 2940 #ifdef I18N
815 maya 2942 strcpy(pvar->ts->UIMsg, "An error occurred while compressing packet data.\n"
816     "The connection will close.");
817     UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar);
818     notify_fatal_error(pvar, pvar->ts->UIMsg);
819 maya 2940 #else
820 yutakakn 2728 notify_fatal_error(pvar,
821     "An error occurred while compressing packet data.\n"
822     "The connection will close.");
823 maya 2940 #endif
824 yutakakn 2728 return;
825     }
826     }
827    
828     len =
829     pvar->ssh_state.outbuflen - 12 -
830     pvar->ssh_state.compress_stream.avail_out;
831     }
832    
833     if (SSHv1(pvar)) {
834     int padding = 8 - ((len + 4) % 8);
835    
836     data = pvar->ssh_state.outbuf + 8 - padding;
837     data_length = padding + len + 8;
838    
839     set_uint32(data, len + 4);
840     if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
841     CRYPT_set_random_data(pvar, data + 4, padding);
842     } else {
843     memset(data + 4, 0, padding);
844     }
845     set_uint32(data + data_length - 4,
846     do_crc(data + 4, data_length - 8));
847     CRYPT_encrypt(pvar, data + 4, data_length - 4);
848     } else { //for SSH2(yutaka)
849     int block_size = CRYPT_get_encryption_block_size(pvar);
850     int encryption_size;
851     int padding;
852     BOOL ret;
853    
854 yutakakn 2833 /*
855     �f�[�^�\��
856     pvar->ssh_state.outbuf:
857     offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
858     <--ignore---> ^^^^^^^^ <---- payload --->
859     packet length
860    
861     ^^padding
862    
863     <---------------------------->
864     SSH2 sending data on TCP
865    
866     NOTE:
867     payload = type(1) + raw-data
868     len = ssh_state.outgoing_packet_len = payload size
869     */
870     // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
871 yutakakn 2873 // support of "Compression delayed" (2006.6.23 maya)
872     if ((pvar->ctos_compression == COMP_ZLIB ||
873     pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
874     pvar->ssh2_keys[MODE_OUT].comp.enabled) {
875 yutakakn 2833 // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
876     msg = buffer_init();
877     if (msg == NULL) {
878     // TODO: error check
879     return;
880     }
881    
882     // ���k�������w�b�_�������y�C���[�h�����B
883     buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
884     if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
885 maya 2940 #ifdef I18N
886 maya 2942 strcpy(pvar->ts->UIMsg, "An error occurred while compressing packet data.\n"
887     "The connection will close.");
888     UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar);
889     notify_fatal_error(pvar, pvar->ts->UIMsg);
890 maya 2940 #else
891 yutakakn 2833 notify_fatal_error(pvar,
892     "An error occurred while compressing packet data.\n"
893     "The connection will close.");
894 maya 2940 #endif
895 yutakakn 2833 return;
896     }
897     data = buffer_ptr(msg);
898     len = buffer_len(msg) - 5; // 'len' is overwritten.
899    
900     } else {
901     // �����k
902     data = pvar->ssh_state.outbuf + 7;
903    
904     }
905    
906     // ���M�p�P�b�g�\�z(input parameter: data, len)
907 yutakakn 2728 if (block_size < 8) {
908     block_size = 8;
909     }
910     encryption_size = ((len + 8) / block_size + 1) * block_size;
911     data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
912    
913     set_uint32(data, encryption_size - 4);
914     padding = encryption_size - len - 5;
915     data[4] = (unsigned char) padding;
916     CRYPT_set_random_data(pvar, data + 5 + len, padding);
917     ret = CRYPT_build_sender_MAC(pvar,
918     pvar->ssh_state.sender_sequence_number,
919     data, encryption_size,
920     data + encryption_size);
921     if (ret == FALSE) { // HMAC��������������������������
922     data_length = encryption_size;
923     }
924    
925     // �p�P�b�g�������������BHMAC���~�������������O�B
926     CRYPT_encrypt(pvar, data, encryption_size);
927     }
928    
929     send_packet_blocking(pvar, data, data_length);
930    
931 yutakakn 2833 buffer_free(msg);
932    
933 yutakakn 2728 pvar->ssh_state.sender_sequence_number++;
934 yutakakn 2748
935     // ���M�������L�^
936     pvar->ssh_heartbeat_tick = time(NULL);
937 yutakakn 2728 }
938    
939     static void destroy_packet_buf(PTInstVar pvar)
940     {
941     memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
942     if (pvar->ssh_state.compressing) {
943     memset(pvar->ssh_state.precompress_outbuf, 0,
944     pvar->ssh_state.precompress_outbuflen);
945     }
946     }
947    
948     /* The handlers are added to the queue for each message. When one of the
949     handlers fires, if it returns FALSE, then all handlers in the set are
950     removed from their queues. */
951     static void enque_handlers(PTInstVar pvar, int num_msgs,
952     const int FAR * messages,
953     const SSHPacketHandler FAR * handlers)
954     {
955     SSHPacketHandlerItem FAR *first_item;
956     SSHPacketHandlerItem FAR *last_item = NULL;
957     int i;
958    
959     for (i = 0; i < num_msgs; i++) {
960     SSHPacketHandlerItem FAR *item =
961     (SSHPacketHandlerItem FAR *)
962     malloc(sizeof(SSHPacketHandlerItem));
963     SSHPacketHandlerItem FAR *cur_item =
964     pvar->ssh_state.packet_handlers[messages[i]];
965    
966     item->handler = handlers[i];
967    
968     if (cur_item == NULL) {
969     pvar->ssh_state.packet_handlers[messages[i]] = item;
970     item->next_for_message = item;
971     item->last_for_message = item;
972     item->active_for_message = messages[i];
973     } else {
974     item->next_for_message = cur_item;
975     item->last_for_message = cur_item->last_for_message;
976     cur_item->last_for_message->next_for_message = item;
977     cur_item->last_for_message = item;
978     item->active_for_message = -1;
979     }
980    
981     if (last_item != NULL) {
982     last_item->next_in_set = item;
983     } else {
984     first_item = item;
985     }
986     last_item = item;
987     }
988    
989     if (last_item != NULL) {
990     last_item->next_in_set = first_item;
991     }
992     }
993    
994     static SSHPacketHandler get_handler(PTInstVar pvar, int message)
995     {
996     SSHPacketHandlerItem FAR *cur_item =
997     pvar->ssh_state.packet_handlers[message];
998    
999     if (cur_item == NULL) {
1000     return NULL;
1001     } else {
1002     return cur_item->handler;
1003     }
1004     }
1005    
1006     /* Called only by SSH_handle_packet */
1007     static void deque_handlers(PTInstVar pvar, int message)
1008     {
1009     SSHPacketHandlerItem FAR *cur_item =
1010     pvar->ssh_state.packet_handlers[message];
1011     SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1012    
1013     do {
1014     SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1015    
1016     if (cur_item->active_for_message >= 0) {
1017     SSHPacketHandlerItem FAR *replacement =
1018     cur_item->next_for_message;
1019    
1020     if (replacement == cur_item) {
1021     replacement = NULL;
1022     } else {
1023     replacement->active_for_message =
1024     cur_item->active_for_message;
1025     }
1026     pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1027     replacement;
1028     }
1029     cur_item->next_for_message->last_for_message =
1030     cur_item->last_for_message;
1031     cur_item->last_for_message->next_for_message =
1032     cur_item->next_for_message;
1033    
1034     free(cur_item);
1035     cur_item = next_in_set;
1036     } while (cur_item != first_item_in_set);
1037     }
1038    
1039     static void enque_handler(PTInstVar pvar, int message,
1040     SSHPacketHandler handler)
1041     {
1042     enque_handlers(pvar, 1, &message, &handler);
1043     }
1044    
1045     static void chop_newlines(char FAR * buf)
1046     {
1047     int len = strlen(buf);
1048    
1049     while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1050     buf[len - 1] = 0;
1051     len--;
1052     }
1053     }
1054    
1055     /********************/
1056     /* Message handlers */
1057     /********************/
1058    
1059     static BOOL handle_forwarding_success(PTInstVar pvar)
1060     {
1061     return FALSE;
1062     }
1063    
1064     static BOOL handle_forwarding_failure(PTInstVar pvar)
1065     {
1066     return FALSE;
1067     }
1068    
1069     static void enque_forwarding_request_handlers(PTInstVar pvar)
1070     {
1071     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1072     static const SSHPacketHandler handlers[]
1073     = { handle_forwarding_success, handle_forwarding_failure };
1074    
1075     enque_handlers(pvar, 2, msgs, handlers);
1076     }
1077    
1078     static BOOL handle_auth_failure(PTInstVar pvar)
1079     {
1080     notify_verbose_message(pvar, "Authentication failed",
1081     LOG_LEVEL_VERBOSE);
1082    
1083 yutakakn 2835 // retry count������ (2005.7.15 yutaka)
1084     pvar->userauth_retry_count++;
1085    
1086 yutakakn 2728 AUTH_set_generic_mode(pvar);
1087     AUTH_advance_to_next_cred(pvar);
1088     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1089     try_send_credentials(pvar);
1090     return FALSE;
1091     }
1092    
1093     static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1094     {
1095     AUTH_destroy_cur_cred(pvar);
1096     return handle_auth_failure(pvar);
1097     }
1098    
1099     static BOOL handle_TIS_challenge(PTInstVar pvar)
1100     {
1101     if (grab_payload(pvar, 4)) {
1102     int len = get_payload_uint32(pvar, 0);
1103    
1104     if (grab_payload(pvar, len)) {
1105     notify_verbose_message(pvar, "Received TIS challenge",
1106     LOG_LEVEL_VERBOSE);
1107    
1108     AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1109     AUTH_advance_to_next_cred(pvar);
1110     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1111     try_send_credentials(pvar);
1112     }
1113     }
1114     return FALSE;
1115     }
1116    
1117     static BOOL handle_auth_required(PTInstVar pvar)
1118     {
1119     notify_verbose_message(pvar, "Server requires authentication",
1120     LOG_LEVEL_VERBOSE);
1121    
1122     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1123     try_send_credentials(pvar);
1124     /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1125    
1126     return FALSE;
1127     }
1128    
1129     static BOOL handle_ignore(PTInstVar pvar)
1130     {
1131 maya 2938 if (SSHv1(pvar)) {
1132     if (grab_payload(pvar, 4)
1133     && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1134     /* ignore it! but it must be decompressed */
1135     }
1136 yutakakn 2728 }
1137 maya 2938 /*
1138     else {
1139     // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1140     // Cisco ���[�^���� (2006.11.28 maya)
1141     }
1142     */
1143 yutakakn 2728 return TRUE;
1144     }
1145    
1146     static BOOL handle_debug(PTInstVar pvar)
1147     {
1148     BOOL always_display;
1149     char FAR *description;
1150     int description_len;
1151     char buf[2048];
1152    
1153     if (SSHv1(pvar)) {
1154     if (grab_payload(pvar, 4)
1155     && grab_payload(pvar, description_len =
1156     get_payload_uint32(pvar, 0))) {
1157     always_display = FALSE;
1158     description = pvar->ssh_state.payload + 4;
1159     description[description_len] = 0;
1160     } else {
1161     return TRUE;
1162     }
1163     } else {
1164     if (grab_payload(pvar, 5)
1165     && grab_payload(pvar,
1166     (description_len =
1167     get_payload_uint32(pvar, 1)) + 4)
1168     && grab_payload(pvar,
1169     get_payload_uint32(pvar,
1170     5 + description_len))) {
1171     always_display = pvar->ssh_state.payload[0] != 0;
1172     description = pvar->ssh_state.payload + 5;
1173     description[description_len] = 0;
1174     } else {
1175     return TRUE;
1176     }
1177     }
1178    
1179     chop_newlines(description);
1180     _snprintf(buf, sizeof(buf), "DEBUG message from server: %s",
1181     description);
1182     buf[sizeof(buf) - 1] = 0;
1183     if (always_display) {
1184     notify_nonfatal_error(pvar, buf);
1185     } else {
1186     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1187     }
1188     return TRUE;
1189     }
1190    
1191     static BOOL handle_disconnect(PTInstVar pvar)
1192     {
1193     int reason_code;
1194     char FAR *description;
1195     int description_len;
1196     char buf[2048];
1197     char FAR *explanation = "";
1198 maya 2942 #ifdef I18N
1199     char uimsg[MAX_UIMSG];
1200     #endif
1201 yutakakn 2728
1202     if (SSHv1(pvar)) {
1203     if (grab_payload(pvar, 4)
1204     && grab_payload(pvar, description_len =
1205     get_payload_uint32(pvar, 0))) {
1206     reason_code = -1;
1207     description = pvar->ssh_state.payload + 4;
1208     description[description_len] = 0;
1209     } else {
1210     return TRUE;
1211     }
1212     } else {
1213     if (grab_payload(pvar, 8)
1214     && grab_payload(pvar,
1215     (description_len =
1216     get_payload_uint32(pvar, 4)) + 4)
1217     && grab_payload(pvar,
1218     get_payload_uint32(pvar,
1219     8 + description_len))) {
1220     reason_code = get_payload_uint32(pvar, 0);
1221     description = pvar->ssh_state.payload + 8;
1222     description[description_len] = 0;
1223     } else {
1224     return TRUE;
1225     }
1226     }
1227    
1228     chop_newlines(description);
1229     if (description[0] == 0) {
1230     description = NULL;
1231     }
1232    
1233     if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1234 maya 2940 #ifdef I18N
1235 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"
1236     "This often happens when someone is already forwarding that port from the server.");
1237     UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar);
1238     strcpy(uimsg, pvar->ts->UIMsg);
1239     explanation = uimsg;
1240 maya 2940 #else
1241 yutakakn 2728 explanation =
1242     "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1243     "This often happens when someone is already forwarding that port from the server.";
1244 maya 2940 #endif
1245 yutakakn 2728 }
1246    
1247     if (description != NULL) {
1248 maya 2940 #ifdef I18N
1249 maya 2942 strcpy(pvar->ts->UIMsg, "Server disconnected with message '%s'.%s");
1250     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar);
1251     _snprintf(buf, sizeof(buf),
1252     pvar->ts->UIMsg, description,
1253     explanation);
1254 maya 2940 #else
1255 yutakakn 2728 _snprintf(buf, sizeof(buf),
1256     "Server disconnected with message '%s'.%s", description,
1257     explanation);
1258 maya 2940 #endif
1259 yutakakn 2728 } else {
1260 maya 2940 #ifdef I18N
1261 maya 2942 strcpy(pvar->ts->UIMsg, "Server disconnected (no reason given).%s");
1262     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar);
1263     _snprintf(buf, sizeof(buf),
1264     pvar->ts->UIMsg, explanation);
1265 maya 2940 #else
1266 yutakakn 2728 _snprintf(buf, sizeof(buf),
1267     "Server disconnected (no reason given).%s", explanation);
1268 maya 2940 #endif
1269 yutakakn 2728 }
1270     buf[sizeof(buf) - 1] = 0;
1271     notify_fatal_error(pvar, buf);
1272    
1273     return TRUE;
1274     }
1275    
1276     static BOOL handle_unimplemented(PTInstVar pvar)
1277     {
1278     /* Should never receive this since we only send base 2.0 protocol messages */
1279     grab_payload(pvar, 4);
1280     return TRUE;
1281     }
1282    
1283     static BOOL handle_crypt_success(PTInstVar pvar)
1284     {
1285     notify_verbose_message(pvar, "Secure mode successfully achieved",
1286     LOG_LEVEL_VERBOSE);
1287     return FALSE;
1288     }
1289    
1290     static BOOL handle_noauth_success(PTInstVar pvar)
1291     {
1292     notify_verbose_message(pvar, "Server does not require authentication",
1293     LOG_LEVEL_VERBOSE);
1294     prep_compression(pvar);
1295     return FALSE;
1296     }
1297    
1298     static BOOL handle_auth_success(PTInstVar pvar)
1299     {
1300     notify_verbose_message(pvar, "Authentication accepted",
1301     LOG_LEVEL_VERBOSE);
1302     prep_compression(pvar);
1303 yutakakn 2748
1304     // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1305     start_ssh_heartbeat_thread(pvar);
1306    
1307 yutakakn 2728 return FALSE;
1308     }
1309    
1310     static BOOL handle_server_public_key(PTInstVar pvar)
1311     {
1312     int server_key_public_exponent_len;
1313     int server_key_public_modulus_pos;
1314     int server_key_public_modulus_len;
1315     int host_key_bits_pos;
1316     int host_key_public_exponent_len;
1317     int host_key_public_modulus_pos;
1318     int host_key_public_modulus_len;
1319     int protocol_flags_pos;
1320     int supported_ciphers;
1321     char FAR *inmsg;
1322 yutakakn 2856 Key hostkey;
1323 yutakakn 2728
1324     if (!grab_payload(pvar, 14))
1325     return FALSE;
1326     server_key_public_exponent_len = get_mpint_len(pvar, 12);
1327    
1328     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1329     return FALSE;
1330     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1331     server_key_public_modulus_len =
1332     get_mpint_len(pvar, server_key_public_modulus_pos);
1333    
1334     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1335     return FALSE;
1336     host_key_bits_pos =
1337     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1338     host_key_public_exponent_len =
1339     get_mpint_len(pvar, host_key_bits_pos + 4);
1340    
1341     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1342     return FALSE;
1343     host_key_public_modulus_pos =
1344     host_key_bits_pos + 6 + host_key_public_exponent_len;
1345     host_key_public_modulus_len =
1346     get_mpint_len(pvar, host_key_public_modulus_pos);
1347    
1348     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1349     return FALSE;
1350     protocol_flags_pos =
1351     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1352    
1353     inmsg = pvar->ssh_state.payload;
1354    
1355     CRYPT_set_server_cookie(pvar, inmsg);
1356     if (!CRYPT_set_server_RSA_key
1357     (pvar, get_uint32(inmsg + 8), pvar->ssh_state.payload + 12,
1358     inmsg + server_key_public_modulus_pos))
1359     return FALSE;
1360     if (!CRYPT_set_host_RSA_key
1361     (pvar, get_uint32(inmsg + host_key_bits_pos),
1362     inmsg + host_key_bits_pos + 4,
1363     inmsg + host_key_public_modulus_pos))
1364     return FALSE;
1365     pvar->ssh_state.server_protocol_flags =
1366     get_uint32(inmsg + protocol_flags_pos);
1367    
1368     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1369     if (!CRYPT_set_supported_ciphers
1370     (pvar, supported_ciphers, supported_ciphers))
1371     return FALSE;
1372     if (!AUTH_set_supported_auth_types
1373     (pvar, get_uint32(inmsg + protocol_flags_pos + 8)))
1374     return FALSE;
1375    
1376     /* this must be the LAST THING in this function, since it can cause
1377     host_is_OK to be called. */
1378 yutakakn 2856 hostkey.type = KEY_RSA1;
1379     hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1380     hostkey.exp = inmsg + host_key_bits_pos + 4;
1381     hostkey.mod = inmsg + host_key_public_modulus_pos;
1382     HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, &hostkey);
1383 yutakakn 2728
1384     return FALSE;
1385     }
1386    
1387     /*
1388     The ID must have already been found to start with "SSH-". It must
1389     be null-terminated.
1390     */
1391     static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1392     {
1393     char FAR *str;
1394    
1395     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1396     }
1397    
1398     if (*str != '.') {
1399     return FALSE;
1400     }
1401    
1402     pvar->protocol_major = atoi(ID + 4);
1403     pvar->protocol_minor = atoi(str + 1);
1404    
1405     // for SSH2(yutaka)
1406     // 1.99����SSH2�����������s��
1407     if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
1408     // ���[�U�� SSH2 ���I������������������
1409     if (pvar->settings.ssh_protocol_version == 2) {
1410     pvar->protocol_major = 2;
1411     pvar->protocol_minor = 0;
1412     }
1413    
1414     }
1415    
1416     for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1417     }
1418    
1419     return *str == '-';
1420     }
1421    
1422     /*
1423     On entry, the pvar->protocol_xxx fields hold the server's advertised
1424     protocol number. We replace the fields with the protocol number we will
1425     actually use, or return FALSE if there is no usable protocol version.
1426     */
1427     static BOOL negotiate_protocol(PTInstVar pvar)
1428     {
1429     switch (pvar->protocol_major) {
1430     case 1:
1431     if (pvar->protocol_minor > 5) {
1432     pvar->protocol_minor = 5;
1433     }
1434    
1435     return TRUE;
1436    
1437     // for SSH2(yutaka)
1438     case 2:
1439     return TRUE; // SSH2 support
1440    
1441     default:
1442     return FALSE;
1443     }
1444     }
1445    
1446     static void init_protocol(PTInstVar pvar)
1447     {
1448     CRYPT_initialize_random_numbers(pvar);
1449 yutakakn 2856
1450     // known_hosts�t�@�C�������z�X�g���J������������������
1451 yutakakn 2728 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname);
1452 yutakakn 2856
1453 yutakakn 2728 /* while we wait for a response from the server... */
1454    
1455     if (SSHv1(pvar)) {
1456     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1457     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1458     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1459     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1460    
1461     } else { // for SSH2(yutaka)
1462     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1463     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1464     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1465     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1466     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1467     enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1468     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1469     enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1470     enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_authrequest);
1471     enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1472     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1473     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1474 yutakakn 2782 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1475 yutakakn 2728
1476     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1477    
1478     // ���[�U�F�������f�B�X�p�b�`���[�`��
1479     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1480     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1481     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1482 maya 2926 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1483 yutakakn 2825 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1484 yutakakn 2728 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1485 yutakakn 2827 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1486 yutakakn 2728 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1487     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1488     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1489     // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1490 yutakakn 2825 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1491 yutakakn 2728 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1492    
1493     }
1494     }
1495    
1496     BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1497     {
1498     static const char prefix[] = "Received server prologue string: ";
1499    
1500 yutakakn 2796 // initialize SSH2 memory dump (2005.3.7 yutaka)
1501     init_memdump();
1502 maya 2929 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1503 yutakakn 2796
1504 yutakakn 2728 if (ID_len <= 0) {
1505     return FALSE;
1506     } else {
1507     char FAR *buf = (char FAR *) malloc(ID_len + NUM_ELEM(prefix));
1508    
1509     strcpy(buf, prefix);
1510     strncpy(buf + NUM_ELEM(prefix) - 1, ID, ID_len);
1511     buf[NUM_ELEM(prefix) + ID_len - 1] = 0;
1512     chop_newlines(buf);
1513    
1514     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1515    
1516     free(buf);
1517    
1518    
1519 yutakakn 2797 // ���������R�s�[������ (2005.3.9 yutaka)
1520     #if 0
1521 yutakakn 2728 // for calculate SSH2 hash
1522     // �T�[�o�o�[�W�����������i���s���������������j
1523     if (ID_len >= sizeof(pvar->server_version_string))
1524     return FALSE;
1525     strncpy(pvar->server_version_string, ID, ID_len);
1526 yutakakn 2797 #endif
1527 yutakakn 2728
1528    
1529     if (ID[ID_len - 1] != '\n') {
1530     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1531     return FALSE;
1532     } else
1533     if ((pvar->ssh_state.
1534     status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1535     pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1536     return FALSE;
1537     } else if (strncmp(ID, "SSH-", 4) != 0) {
1538     return FALSE;
1539     } else {
1540     ID[ID_len - 1] = 0;
1541    
1542     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1543     ID[ID_len - 2] = 0;
1544     }
1545    
1546     pvar->ssh_state.server_ID = _strdup(ID);
1547    
1548     if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1549 maya 2940 #ifdef I18N
1550 maya 2942 strcpy(pvar->ts->UIMsg, "This program does not understand the server's version of the protocol.");
1551     UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar);
1552     notify_fatal_error(pvar, pvar->ts->UIMsg);
1553 maya 2940 #else
1554 yutakakn 2728 notify_fatal_error(pvar,
1555     "This program does not understand the server's version of the protocol.");
1556 maya 2941 #endif
1557 yutakakn 2728 } else {
1558     char TTSSH_ID[1024];
1559     int TTSSH_ID_len;
1560 yutakakn 2793 int a, b, c, d;
1561 yutakakn 2728
1562 yutakakn 2793 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1563     get_file_version("ttxssh.dll", &a, &b, &c, &d);
1564    
1565 yutakakn 2728 _snprintf(TTSSH_ID, sizeof(TTSSH_ID),
1566 yutakakn 2793 "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1567     pvar->protocol_major, pvar->protocol_minor, a, b);
1568 yutakakn 2728 TTSSH_ID_len = strlen(TTSSH_ID);
1569    
1570     // for SSH2(yutaka)
1571     // �N���C�A���g�o�[�W�����������i���s���������������j
1572     strncpy(pvar->client_version_string, TTSSH_ID, TTSSH_ID_len);
1573    
1574 yutakakn 2797 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1575     _snprintf(pvar->server_version_string, sizeof(pvar->server_version_string), "%s", pvar->ssh_state.server_ID);
1576    
1577 yutakakn 2728 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1578     0) != TTSSH_ID_len) {
1579 maya 2940 #ifdef I18N
1580 maya 2942 strcpy(pvar->ts->UIMsg, "An error occurred while sending the SSH ID string.\n"
1581     "The connection will close.");
1582     UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar);
1583     notify_fatal_error(pvar, pvar->ts->UIMsg);
1584 maya 2940 #else
1585 yutakakn 2728 notify_fatal_error(pvar,
1586     "An error occurred while sending the SSH ID string.\n"
1587     "The connection will close.");
1588 maya 2940 #endif
1589 yutakakn 2728 } else {
1590     // ���s�R�[�h������ (2004.8.4 yutaka)
1591     pvar->client_version_string[--TTSSH_ID_len] = 0;
1592    
1593 yutakakn 2796 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1594     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1595    
1596 yutakakn 2728 // SSH�n���h�����o�^���s��
1597     init_protocol(pvar);
1598    
1599     SSH2_dispatch_init(1);
1600     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1601 yutakakn 2796 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1602 yutakakn 2728 }
1603     }
1604    
1605     return TRUE;
1606     }
1607     }
1608     }
1609    
1610     static BOOL handle_exit(PTInstVar pvar)
1611     {
1612     if (grab_payload(pvar, 4)) {
1613     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1614     finish_send_packet(pvar);
1615     notify_closed_connection(pvar);
1616     }
1617     return TRUE;
1618     }
1619    
1620     static BOOL handle_data(PTInstVar pvar)
1621     {
1622     if (grab_payload_limited(pvar, 4)) {
1623     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1624     pvar->ssh_state.payload_datastart = 4;
1625     }
1626     return TRUE;
1627     }
1628    
1629     static BOOL handle_channel_open(PTInstVar pvar)
1630     {
1631     int host_len;
1632     int originator_len;
1633    
1634     if ((pvar->ssh_state.
1635     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1636     if (grab_payload(pvar, 8)
1637     && grab_payload(pvar,
1638     8 + (host_len = get_payload_uint32(pvar, 4)))
1639     && grab_payload(pvar, originator_len =
1640     get_payload_uint32(pvar, host_len + 12))) {
1641     int local_port = get_payload_uint32(pvar, 8 + host_len);
1642    
1643     pvar->ssh_state.payload[8 + host_len] = 0;
1644     FWD_open(pvar, get_payload_uint32(pvar, 0),
1645     pvar->ssh_state.payload + 8, local_port,
1646     pvar->ssh_state.payload + 16 + host_len,
1647 yutakakn 2826 originator_len,
1648     NULL);
1649 yutakakn 2728 }
1650     } else {
1651     if (grab_payload(pvar, 8)
1652     && grab_payload(pvar,
1653     4 + (host_len =
1654     get_payload_uint32(pvar, 4)))) {
1655     int local_port = get_payload_uint32(pvar, 8 + host_len);
1656    
1657     pvar->ssh_state.payload[8 + host_len] = 0;
1658     FWD_open(pvar, get_payload_uint32(pvar, 0),
1659 yutakakn 2826 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1660     NULL);
1661 yutakakn 2728 }
1662     }
1663    
1664     return TRUE;
1665     }
1666    
1667     static BOOL handle_X11_channel_open(PTInstVar pvar)
1668     {
1669     int originator_len;
1670    
1671     if ((pvar->ssh_state.
1672     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1673     if (grab_payload(pvar, 8)
1674     && grab_payload(pvar, originator_len =
1675     get_payload_uint32(pvar, 4))) {
1676     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1677 yutakakn 2829 pvar->ssh_state.payload + 8, originator_len, NULL);
1678 yutakakn 2728 }
1679     } else {
1680     if (grab_payload(pvar, 4)) {
1681 yutakakn 2829 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1682 yutakakn 2728 }
1683     }
1684    
1685     return TRUE;
1686     }
1687    
1688     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1689     {
1690     if (grab_payload(pvar, 8)) {
1691     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1692     get_payload_uint32(pvar, 4));
1693     }
1694     return FALSE;
1695     }
1696    
1697     static BOOL handle_channel_open_failure(PTInstVar pvar)
1698     {
1699     if (grab_payload(pvar, 4)) {
1700     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1701     }
1702     return FALSE;
1703     }
1704    
1705     static BOOL handle_channel_data(PTInstVar pvar)
1706     {
1707     int len;
1708    
1709     if (grab_payload(pvar, 8)
1710     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1711     FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1712     pvar->ssh_state.payload + 8, len);
1713     }
1714     return TRUE;
1715     }
1716    
1717     static BOOL handle_channel_input_eof(PTInstVar pvar)
1718     {
1719     if (grab_payload(pvar, 4)) {
1720     FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1721     }
1722     return TRUE;
1723     }
1724    
1725     static BOOL handle_channel_output_eof(PTInstVar pvar)
1726     {
1727     if (grab_payload(pvar, 4)) {
1728     FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1729     }
1730     return TRUE;
1731     }
1732    
1733    
1734    
1735     // �n���h�����O�������b�Z�[�W����������
1736    
1737     #define HANDLE_MESSAGE_MAX 30
1738     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1739     static int handle_message_count = 0;
1740     static int handle_message_stage = 0;
1741    
1742     void SSH2_dispatch_init(int stage)
1743     {
1744     handle_message_count = 0;
1745     handle_message_stage = stage;
1746     }
1747    
1748     int SSH2_dispatch_enabled_check(unsigned char message)
1749     {
1750     int i;
1751    
1752     for (i = 0 ; i < handle_message_count ; i++) {
1753     if (handle_messages[i] == message)
1754     return 1;
1755     }
1756     return 0;
1757     }
1758    
1759     void SSH2_dispatch_add_message(unsigned char message)
1760     {
1761    
1762     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1763     // TODO: error check
1764     return;
1765     }
1766    
1767     handle_messages[handle_message_count++] = message;
1768     }
1769    
1770     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1771     {
1772     unsigned char c;
1773    
1774     for (c = begin ; c <= end ; c++) {
1775     SSH2_dispatch_add_message(c);
1776     }
1777     }
1778    
1779    
1780     void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1781     int padding)
1782     {
1783     unsigned char message = prep_packet(pvar, data, len, padding);
1784    
1785    
1786     #ifdef SSH2_DEBUG
1787     // for SSH2(yutaka)
1788     if (SSHv2(pvar)) {
1789     if (pvar->key_done) {
1790     message = message;
1791     }
1792    
1793     if (pvar->userauth_success) {
1794     message = message;
1795     }
1796    
1797     if (pvar->rekeying) {
1798     message = message;
1799     }
1800     }
1801     #endif
1802    
1803     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1804     if (message != SSH_MSG_NONE) {
1805     // ���b�Z�[�W�^�C�v���������n���h�����N��
1806     SSHPacketHandler handler = get_handler(pvar, message);
1807    
1808     // for SSH2(yutaka)
1809     if (SSHv2(pvar)) {
1810     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1811     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1812     char buf[1024];
1813    
1814 maya 2940 #ifdef I18N
1815 maya 2942 strcpy(pvar->ts->UIMsg, "Unexpected SSH2 message(%d) on current stage(%d)");
1816     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar);
1817     _snprintf(buf, sizeof(buf),
1818     pvar->ts->UIMsg, message, handle_message_stage);
1819 maya 2940 #else
1820 yutakakn 2728 _snprintf(buf, sizeof(buf),
1821     "Unexpected SSH2 message(%d) on current stage(%d)", message, handle_message_stage);
1822 maya 2940 #endif
1823 yutakakn 2728 notify_fatal_error(pvar, buf);
1824     // abort
1825     }
1826     }
1827    
1828     if (handler == NULL) {
1829     if (SSHv1(pvar)) {
1830     char buf[1024];
1831    
1832 maya 2940 #ifdef I18N
1833 maya 2942 strcpy(pvar->ts->UIMsg, "Unexpected packet type received: %d");
1834     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar);
1835     _snprintf(buf, sizeof(buf),
1836     pvar->ts->UIMsg, message, handle_message_stage);
1837 maya 2940 #else
1838 yutakakn 2728 _snprintf(buf, sizeof(buf),
1839     "Unexpected packet type received: %d", message);
1840 maya 2940 #endif
1841 yutakakn 2728 buf[sizeof(buf) - 1] = 0;
1842     notify_fatal_error(pvar, buf);
1843     } else {
1844     unsigned char FAR *outmsg =
1845     begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
1846    
1847     set_uint32(outmsg,
1848     pvar->ssh_state.receiver_sequence_number - 1);
1849     finish_send_packet(pvar);
1850     /* XXX need to decompress incoming packet, but how? */
1851     }
1852     } else {
1853     if (!handler(pvar)) {
1854     deque_handlers(pvar, message);
1855     }
1856     }
1857     }
1858     }
1859    
1860     static BOOL handle_pty_success(PTInstVar pvar)
1861     {
1862     FWD_enter_interactive_mode(pvar);
1863     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
1864     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
1865     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
1866     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
1867     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
1868     handle_channel_input_eof);
1869     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
1870     handle_channel_output_eof);
1871     enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
1872     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
1873     return FALSE;
1874     }
1875    
1876     static BOOL handle_pty_failure(PTInstVar pvar)
1877     {
1878 maya 2940 #ifdef I18N
1879 maya 2942 strcpy(pvar->ts->UIMsg, "The server cannot allocate a pseudo-terminal. "
1880     "You may encounter some problems with the terminal.");
1881     UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar);
1882     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1883 maya 2940 #else
1884 yutakakn 2728 notify_nonfatal_error(pvar,
1885     "The server cannot allocate a pseudo-terminal. "
1886     "You may encounter some problems with the terminal.");
1887 maya 2940 #endif
1888 yutakakn 2728 return handle_pty_success(pvar);
1889     }
1890    
1891     static void prep_pty(PTInstVar pvar)
1892     {
1893     int len = strlen(pvar->ts->TermType);
1894     unsigned char FAR *outmsg =
1895     begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
1896     4 + len + 16 + sizeof(ssh_ttymodes));
1897     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1898     static const SSHPacketHandler handlers[]
1899     = { handle_pty_success, handle_pty_failure };
1900    
1901     set_uint32(outmsg, len);
1902     memcpy(outmsg + 4, pvar->ts->TermType, len);
1903     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
1904     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
1905     set_uint32(outmsg + 4 + len + 8, 0);
1906     set_uint32(outmsg + 4 + len + 12, 0);
1907     memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
1908     finish_send_packet(pvar);
1909    
1910     enque_handlers(pvar, 2, msgs, handlers);
1911    
1912     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
1913     finish_send_packet(pvar);
1914     }
1915    
1916     static void prep_forwarding(PTInstVar pvar)
1917     {
1918     FWD_prep_forwarding(pvar);
1919     prep_pty(pvar);
1920     }
1921    
1922 yutakakn 2834
1923     //
1924     //
1925     // (2005.7.10 yutaka)
1926     static void enable_send_compression(PTInstVar pvar)
1927 yutakakn 2728 {
1928 yutakakn 2834 static int initialize = 0;
1929    
1930     if (initialize) {
1931     deflateEnd(&pvar->ssh_state.compress_stream);
1932     }
1933     initialize = 1;
1934    
1935 yutakakn 2728 pvar->ssh_state.compress_stream.zalloc = NULL;
1936     pvar->ssh_state.compress_stream.zfree = NULL;
1937     pvar->ssh_state.compress_stream.opaque = NULL;
1938     if (deflateInit
1939     (&pvar->ssh_state.compress_stream,
1940     pvar->ssh_state.compression_level) != Z_OK) {
1941 maya 2940 #ifdef I18N
1942 maya 2942 strcpy(pvar->ts->UIMsg, "An error occurred while setting up compression.\n"
1943     "The connection will close.");
1944     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar);
1945     notify_fatal_error(pvar, pvar->ts->UIMsg);
1946 maya 2940 #else
1947 yutakakn 2728 notify_fatal_error(pvar,
1948     "An error occurred while setting up compression.\n"
1949     "The connection will close.");
1950 maya 2940 #endif
1951 yutakakn 2728 return;
1952     } else {
1953 yutakakn 2834 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
1954     if (SSHv2(pvar)) {
1955     pvar->ssh_state.compressing = FALSE;
1956     } else {
1957     pvar->ssh_state.compressing = TRUE;
1958     }
1959 yutakakn 2728 }
1960 yutakakn 2834 }
1961 yutakakn 2728
1962 yutakakn 2834 static void enable_recv_compression(PTInstVar pvar)
1963     {
1964     static int initialize = 0;
1965    
1966     if (initialize) {
1967     deflateEnd(&pvar->ssh_state.decompress_stream);
1968     }
1969     initialize = 1;
1970    
1971 yutakakn 2728 pvar->ssh_state.decompress_stream.zalloc = NULL;
1972     pvar->ssh_state.decompress_stream.zfree = NULL;
1973     pvar->ssh_state.decompress_stream.opaque = NULL;
1974     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
1975     deflateEnd(&pvar->ssh_state.compress_stream);
1976 maya 2940 #ifdef I18N
1977 maya 2942 strcpy(pvar->ts->UIMsg, "An error occurred while setting up compression.\n"
1978     "The connection will close.");
1979     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar);
1980     notify_fatal_error(pvar, pvar->ts->UIMsg);
1981 maya 2940 #else
1982 yutakakn 2728 notify_fatal_error(pvar,
1983     "An error occurred while setting up compression.\n"
1984     "The connection will close.");
1985 maya 2940 #endif
1986 yutakakn 2728 return;
1987     } else {
1988 yutakakn 2834 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
1989     if (SSHv2(pvar)) {
1990     pvar->ssh_state.decompressing = FALSE;
1991     } else {
1992     pvar->ssh_state.decompressing = TRUE;
1993     }
1994    
1995 yutakakn 2728 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
1996     &pvar->ssh_state.postdecompress_inbuflen, 1000);
1997     }
1998 yutakakn 2834 }
1999 yutakakn 2833
2000 yutakakn 2834 static void enable_compression(PTInstVar pvar)
2001     {
2002     enable_send_compression(pvar);
2003     enable_recv_compression(pvar);
2004    
2005 yutakakn 2833 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2006     if (SSHv2(pvar)) {
2007     pvar->ssh_state.compressing = FALSE;
2008     pvar->ssh_state.decompressing = FALSE;
2009     }
2010    
2011 yutakakn 2728 }
2012    
2013     static BOOL handle_enable_compression(PTInstVar pvar)
2014     {
2015     enable_compression(pvar);
2016     prep_forwarding(pvar);
2017     return FALSE;
2018     }
2019    
2020     static BOOL handle_disable_compression(PTInstVar pvar)
2021     {
2022     prep_forwarding(pvar);
2023     return FALSE;
2024     }
2025    
2026     static void prep_compression(PTInstVar pvar)
2027     {
2028     if (pvar->session_settings.CompressionLevel > 0) {
2029 yutakakn 2833 // added if statement (2005.7.10 yutaka)
2030     if (SSHv1(pvar)) {
2031     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2032     static const SSHPacketHandler handlers[]
2033     = { handle_enable_compression, handle_disable_compression };
2034 yutakakn 2728
2035 yutakakn 2833 unsigned char FAR *outmsg =
2036     begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2037 yutakakn 2728
2038 yutakakn 2833 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2039     finish_send_packet(pvar);
2040 yutakakn 2728
2041 yutakakn 2833 enque_handlers(pvar, 2, msgs, handlers);
2042     }
2043    
2044 yutakakn 2728 pvar->ssh_state.compression_level =
2045     pvar->session_settings.CompressionLevel;
2046    
2047     } else {
2048 yutakakn 2833 // added if statement (2005.7.10 yutaka)
2049     if (SSHv1(pvar)) {
2050     prep_forwarding(pvar);
2051     }
2052 yutakakn 2728 }
2053     }
2054    
2055     static void enque_simple_auth_handlers(PTInstVar pvar)
2056     {
2057     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2058     static const SSHPacketHandler handlers[]
2059     = { handle_auth_success, handle_auth_failure };
2060    
2061     enque_handlers(pvar, 2, msgs, handlers);
2062     }
2063    
2064     static BOOL handle_rsa_challenge(PTInstVar pvar)
2065     {
2066     int challenge_bytes;
2067    
2068     if (!grab_payload(pvar, 2)) {
2069     return FALSE;
2070     }
2071    
2072     challenge_bytes = get_mpint_len(pvar, 0);
2073    
2074     if (grab_payload(pvar, challenge_bytes)) {
2075     unsigned char FAR *outmsg =
2076     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2077    
2078     if (CRYPT_generate_RSA_challenge_response
2079     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2080 yutakakn 2811
2081     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2082     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2083     #if 0
2084     //AUTH_destroy_cur_cred(pvar);
2085     #endif
2086    
2087 yutakakn 2728 finish_send_packet(pvar);
2088    
2089     enque_simple_auth_handlers(pvar);
2090     } else {
2091 maya 2940 #ifdef I18N
2092 maya 2942 strcpy(pvar->ts->UIMsg, "An error occurred while decrypting the RSA challenge.\n"
2093     "Perhaps the key file is corrupted.");
2094     UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar);
2095     notify_fatal_error(pvar, pvar->ts->UIMsg);
2096 maya 2940 #else
2097 yutakakn 2728 notify_fatal_error(pvar,
2098     "An error occurred while decrypting the RSA challenge.\n"
2099     "Perhaps the key file is corrupted.");
2100 maya 2940 #endif
2101 yutakakn 2728 }
2102     }
2103    
2104     return FALSE;
2105     }
2106    
2107     #define OBFUSCATING_ROUND_TO 32
2108    
2109     static int obfuscating_round_up(PTInstVar pvar, int size)
2110     {
2111     return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2112     }
2113    
2114     static void try_send_credentials(PTInstVar pvar)
2115     {
2116     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2117     AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2118     static const int RSA_msgs[] =
2119     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2120     static const SSHPacketHandler RSA_handlers[]
2121     = { handle_rsa_challenge, handle_rsa_auth_refused };
2122     static const int TIS_msgs[] =
2123     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2124     static const SSHPacketHandler TIS_handlers[]
2125     = { handle_TIS_challenge, handle_auth_failure };
2126    
2127 yutakakn 2800 // SSH2���������������������X�L�b�v
2128     if (SSHv2(pvar))
2129     goto skip_ssh2;
2130    
2131 yutakakn 2728 switch (cred->method) {
2132     case SSH_AUTH_NONE:
2133     return;
2134     case SSH_AUTH_PASSWORD:{
2135     int len = strlen(cred->password);
2136     // Round up password length to discourage traffic analysis
2137     int obfuscated_len = obfuscating_round_up(pvar, len);
2138     unsigned char FAR *outmsg =
2139     begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2140     4 + obfuscated_len);
2141    
2142     notify_verbose_message(pvar,
2143     "Trying PASSWORD authentication...",
2144     LOG_LEVEL_VERBOSE);
2145    
2146     set_uint32(outmsg, obfuscated_len);
2147     memcpy(outmsg + 4, cred->password, len);
2148     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2149 yutakakn 2811
2150     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2151     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2152     #if 0
2153     //AUTH_destroy_cur_cred(pvar);
2154     #endif
2155    
2156 yutakakn 2728 enque_simple_auth_handlers(pvar);
2157     break;
2158     }
2159     case SSH_AUTH_RHOSTS:{
2160     int len = strlen(cred->rhosts_client_user);
2161     unsigned char FAR *outmsg =
2162     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2163    
2164     notify_verbose_message(pvar,
2165     "Trying RHOSTS authentication...",
2166     LOG_LEVEL_VERBOSE);
2167    
2168     set_uint32(outmsg, len);
2169     memcpy(outmsg + 4, cred->rhosts_client_user, len);
2170     AUTH_destroy_cur_cred(pvar);
2171     enque_simple_auth_handlers(pvar);
2172     break;
2173     }
2174     case SSH_AUTH_RSA:{
2175     int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2176     unsigned char FAR *outmsg =
2177     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2178    
2179     notify_verbose_message(pvar,
2180     "Trying RSA authentication...",
2181     LOG_LEVEL_VERBOSE);
2182    
2183     set_ushort16_MSBfirst(outmsg, len * 8);
2184     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2185     /* don't destroy the current credentials yet */
2186     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2187     break;
2188     }
2189     case SSH_AUTH_RHOSTS_RSA:{
2190     int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2191     int name_len = strlen(cred->rhosts_client_user);
2192     int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2193     int index;
2194     unsigned char FAR *outmsg =
2195     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2196     12 + mod_len + name_len + exp_len);
2197    
2198     notify_verbose_message(pvar,
2199     "Trying RHOSTS+RSA authentication...",
2200     LOG_LEVEL_VERBOSE);
2201    
2202     set_uint32(outmsg, name_len);
2203     memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2204     index = 4 + name_len;
2205    
2206     set_uint32(outmsg + index, 8 * mod_len);
2207     set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2208     BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2209     index += 6 + exp_len;
2210    
2211     set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2212     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2213     /* don't destroy the current credentials yet */
2214     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2215     break;
2216     }
2217     case SSH_AUTH_TIS:{
2218     if (cred->password == NULL) {
2219     unsigned char FAR *outmsg =
2220     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2221    
2222     notify_verbose_message(pvar,
2223 yutakakn 2800 "Trying TIS authentication...",
2224     LOG_LEVEL_VERBOSE);
2225 yutakakn 2728 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2226     } else {
2227     int len = strlen(cred->password);
2228     int obfuscated_len = obfuscating_round_up(pvar, len);
2229     unsigned char FAR *outmsg =
2230     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2231 yutakakn 2800 4 + obfuscated_len);
2232 yutakakn 2728
2233     notify_verbose_message(pvar, "Sending TIS response",
2234 yutakakn 2800 LOG_LEVEL_VERBOSE);
2235 yutakakn 2728
2236     set_uint32(outmsg, obfuscated_len);
2237     memcpy(outmsg + 4, cred->password, len);
2238     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2239     enque_simple_auth_handlers(pvar);
2240     }
2241 yutakakn 2800
2242 yutakakn 2728 AUTH_destroy_cur_cred(pvar);
2243     break;
2244     }
2245     default:
2246 maya 2940 #ifdef I18N
2247 maya 2942 strcpy(pvar->ts->UIMsg, "Internal error: unsupported authentication method");
2248     UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar);
2249     notify_fatal_error(pvar, pvar->ts->UIMsg);
2250 maya 2940 #else
2251 yutakakn 2728 notify_fatal_error(pvar,
2252     "Internal error: unsupported authentication method");
2253 maya 2940 #endif
2254 yutakakn 2728 return;
2255     }
2256    
2257     finish_send_packet(pvar);
2258 yutakakn 2800
2259     skip_ssh2:;
2260 yutakakn 2728 destroy_packet_buf(pvar);
2261    
2262     pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2263     }
2264     }
2265    
2266     static void try_send_user_name(PTInstVar pvar)
2267     {
2268     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2269     char FAR *username = AUTH_get_user_name(pvar);
2270    
2271     if (username != NULL) {
2272     int len = strlen(username);
2273     int obfuscated_len = obfuscating_round_up(pvar, len);
2274     unsigned char FAR *outmsg =
2275     begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
2276     char buf[1024] = "Sending user name: ";
2277     static const int msgs[] =
2278     { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2279     static const SSHPacketHandler handlers[]
2280     = { handle_noauth_success, handle_auth_required };
2281    
2282     set_uint32(outmsg, obfuscated_len);
2283     memcpy(outmsg + 4, username, len);
2284     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2285     finish_send_packet(pvar);
2286    
2287     pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2288    
2289     strncpy(buf + strlen(buf), username,
2290     sizeof(buf) - strlen(buf) - 2);
2291     buf[sizeof(buf) - 1] = 0;
2292     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2293    
2294     enque_handlers(pvar, 2, msgs, handlers);
2295     }
2296     }
2297     }
2298    
2299     static void send_session_key(PTInstVar pvar)
2300     {
2301     int encrypted_session_key_len;
2302     unsigned char FAR *outmsg;
2303    
2304     if (SSHv1(pvar)) {
2305     encrypted_session_key_len =
2306     CRYPT_get_encrypted_session_key_len(pvar);
2307     }
2308    
2309     if (!CRYPT_choose_ciphers(pvar))
2310     return;
2311    
2312     if (SSHv1(pvar)) {
2313     outmsg =
2314     begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2315     15 + encrypted_session_key_len);
2316     outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2317     memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2318     outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2319     outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2320     if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2321     return;
2322     set_uint32(outmsg + 11 + encrypted_session_key_len,
2323     SSH_PROTOFLAG_SCREEN_NUMBER |
2324     SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2325     finish_send_packet(pvar);
2326     }
2327    
2328     if (!CRYPT_start_encryption(pvar, 1, 1))
2329     return;
2330     notify_established_secure_connection(pvar);
2331    
2332     if (SSHv1(pvar)) {
2333     enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2334     }
2335    
2336     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2337    
2338     if (SSHv1(pvar)) {
2339     try_send_user_name(pvar);
2340     }
2341     }
2342    
2343     /*************************
2344     END of message handlers
2345     ************************/
2346    
2347     void SSH_init(PTInstVar pvar)
2348     {
2349     int i;
2350    
2351     buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2352     buf_create(&pvar->ssh_state.precompress_outbuf,
2353     &pvar->ssh_state.precompress_outbuflen);
2354     buf_create(&pvar->ssh_state.postdecompress_inbuf,
2355     &pvar->ssh_state.postdecompress_inbuflen);
2356     pvar->ssh_state.payload = NULL;
2357     pvar->ssh_state.compressing = FALSE;
2358     pvar->ssh_state.decompressing = FALSE;
2359     pvar->ssh_state.status_flags =
2360     STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2361     pvar->ssh_state.payload_datalen = 0;
2362     pvar->ssh_state.hostname = NULL;
2363     pvar->ssh_state.server_ID = NULL;
2364     pvar->ssh_state.receiver_sequence_number = 0;
2365     pvar->ssh_state.sender_sequence_number = 0;
2366     for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2367     pvar->ssh_state.packet_handlers[i] = NULL;
2368     }
2369    
2370     // for SSH2(yutaka)
2371     memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2372     pvar->userauth_success = 0;
2373     pvar->session_nego_status = 0;
2374 yutakakn 2738 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2375 yutakakn 2728 pvar->rekeying = 0;
2376     pvar->key_done = 0;
2377 yutakakn 2739 pvar->ssh2_autologin = 0; // autologin disabled(default)
2378 maya 2908 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2379 yutakakn 2798 pvar->userauth_retry_count = 0;
2380 yutakakn 2833 pvar->decomp_buffer = NULL;
2381 yutakakn 2728
2382     }
2383    
2384     void SSH_open(PTInstVar pvar)
2385     {
2386     pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2387     pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2388     pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2389     }
2390    
2391     void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2392     {
2393     if (SSHv1(pvar)) {
2394     int len = reason == NULL ? 0 : strlen(reason);
2395     unsigned char FAR *outmsg =
2396     begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2397    
2398     set_uint32(outmsg, len);
2399     if (reason != NULL) {
2400     memcpy(outmsg + 4, reason, len);
2401     }
2402     finish_send_packet(pvar);
2403    
2404     } else { // for SSH2(yutaka)
2405     buffer_t *msg;
2406     unsigned char *outmsg;
2407     int len;
2408 yutakakn 2809 Channel_t *c;
2409 yutakakn 2728
2410 yutakakn 2809 c = ssh2_channel_lookup(pvar->shell_id);
2411     if (c == NULL)
2412     return;
2413    
2414 yutakakn 2728 // SSH2 server��channel close���`����
2415     msg = buffer_init();
2416     if (msg == NULL) {
2417     // TODO: error check
2418     return;
2419     }
2420 yutakakn 2809 buffer_put_int(msg, c->remote_id);
2421 yutakakn 2728
2422     len = buffer_len(msg);
2423     outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2424     memcpy(outmsg, buffer_ptr(msg), len);
2425     finish_send_packet(pvar);
2426     buffer_free(msg);
2427    
2428     }
2429    
2430     }
2431    
2432     void SSH_notify_host_OK(PTInstVar pvar)
2433     {
2434     if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2435     pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2436     send_session_key(pvar);
2437     }
2438     }
2439    
2440     void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2441     {
2442     pvar->ssh_state.win_cols = cols;
2443     pvar->ssh_state.win_rows = rows;
2444    
2445 yutakakn 2771 if (SSHv1(pvar)) {
2446     if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2447     unsigned char FAR *outmsg =
2448     begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2449 yutakakn 2728
2450 yutakakn 2771 set_uint32(outmsg, rows);
2451     set_uint32(outmsg + 4, cols);
2452     set_uint32(outmsg + 8, 0);
2453     set_uint32(outmsg + 12, 0);
2454     finish_send_packet(pvar);
2455     }
2456    
2457 yutakakn 2777 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2458     // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2459 yutakakn 2771 buffer_t *msg;
2460     char *s;
2461     unsigned char *outmsg;
2462     int len;
2463 yutakakn 2809 Channel_t *c;
2464 yutakakn 2771
2465 yutakakn 2809 c = ssh2_channel_lookup(pvar->shell_id);
2466     if (c == NULL)
2467     return;
2468    
2469 yutakakn 2771 msg = buffer_init();
2470     if (msg == NULL) {
2471     // TODO: error check
2472     return;
2473     }
2474 yutakakn 2809 buffer_put_int(msg, c->remote_id);
2475 yutakakn 2771 s = "window-change";
2476     buffer_put_string(msg, s, strlen(s));