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 3152 - (hide annotations) (download) (as text)
Sat Oct 4 12:37:29 2008 UTC (15 years, 6 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 225632 byte(s)
CheckAuthListFirst が有効な場合には、"none"認証の返事が返ってくるまで
OKボタンを押しても何も起こらないようにした。

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