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 2825 - (hide annotations) (download) (as text)
Sun Jun 26 14:26:24 2005 UTC (18 years, 9 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 156685 byte(s)
update: SSH2 port-forwarding (remote to local)

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