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 2995 - (hide annotations) (download) (as text)
Wed Aug 15 04:03:26 2007 UTC (16 years, 8 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 187698 byte(s)
$Log$ を削除した。

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