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 2809 - (hide annotations) (download) (as text)
Sun Apr 3 14:39:48 2005 UTC (19 years ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 147296 byte(s)
SSH2 channel lookup機構の追加(ポートフォワーディングのため)。
TTSSH 2.10で追加したlog dump機構において、DH鍵再作成時にbuffer freeで
アプリケーションが落ちてしまうバグを修正。

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