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 2993 - (hide annotations) (download) (as text)
Wed Aug 8 16:25:10 2007 UTC (16 years, 8 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 206399 byte(s)
no message

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