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 2957 - (hide annotations) (download) (as text)
Sun Feb 4 13:45:47 2007 UTC (17 years, 2 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 197227 byte(s)
パケット送信関数が失敗した場合、WSAGetLastError()がWSABASEERR(10000)未満であれば、成功したものと見なすようにした。

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