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 2824 - (hide annotations) (download) (as text)
Tue Jun 21 13:28:26 2005 UTC (18 years, 9 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 152463 byte(s)
SSH2鍵交換中の(鍵交換以外の)SSH2メッセージ送信を破棄するようにした。

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