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 2972 - (hide annotations) (download) (as text)
Thu Apr 26 10:18:27 2007 UTC (16 years, 11 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 197785 byte(s)
port fowardingにおいて、channel close時にSSH2チャネル構造体を解放していなかったバグを修正した。

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