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 3059 - (hide annotations) (download) (as text)
Wed Oct 31 02:49:57 2007 UTC (16 years, 5 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 194176 byte(s)
マージに失敗していたので修正した

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