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