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 3165 - (hide annotations) (download) (as text)
Wed Nov 19 15:44:06 2008 UTC (15 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 227800 byte(s)
1.150の修正は意味がなかったので戻す

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