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 3011 - (hide annotations) (download) (as text)
Sat Sep 22 16:10:45 2007 UTC (16 years, 6 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 189390 byte(s)
password 認証で keyboard-interactive を使用するのをやめた。
明示的に challange/response を選択する必要がある。

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