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