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 2827 - (hide annotations) (download) (as text)
Sat Jul 2 08:43:32 2005 UTC (18 years, 9 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 159616 byte(s)
SSH2_MSG_CHANNEL_OPEN_FAILURE ハンドラを追加した。

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