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