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 2852 - (hide annotations) (download) (as text)
Thu Feb 23 14:13:57 2006 UTC (18 years, 1 month ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 169248 byte(s)
authorized_keysファイルの"command="をサポートした

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