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 2938 - (hide annotations) (download) (as text)
Tue Nov 28 13:20:52 2006 UTC (17 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 185841 byte(s)
Cisco ルータの送信する SSH2_MSG_IGNORE のデータが不正なようなので、何も処理しないようにした。

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