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 3168 - (hide annotations) (download) (as text)
Fri Nov 21 18:54:22 2008 UTC (15 years, 4 months ago) by doda
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 231456 byte(s)
SSH2 の共通鍵暗号として Arcfour をサポート (yasuhide) [Ttssh2-devel 1250]

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 maya 3167 notify_verbose_message(pvar, "SSH_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1320    
1321 maya 2938 if (grab_payload(pvar, 4)
1322 maya 3003 && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1323 maya 2938 /* ignore it! but it must be decompressed */
1324     }
1325 yutakakn 2728 }
1326 maya 2938 else {
1327 maya 3167 notify_verbose_message(pvar, "SSH2_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1328    
1329 maya 2938 // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1330     // Cisco ���[�^���� (2006.11.28 maya)
1331     }
1332 yutakakn 2728 return TRUE;
1333     }
1334    
1335     static BOOL handle_debug(PTInstVar pvar)
1336     {
1337     BOOL always_display;
1338     char FAR *description;
1339     int description_len;
1340     char buf[2048];
1341    
1342     if (SSHv1(pvar)) {
1343 maya 3167 notify_verbose_message(pvar, "SSH_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1344    
1345 yutakakn 2728 if (grab_payload(pvar, 4)
1346 maya 3003 && grab_payload(pvar, description_len =
1347     get_payload_uint32(pvar, 0))) {
1348 yutakakn 2728 always_display = FALSE;
1349     description = pvar->ssh_state.payload + 4;
1350     description[description_len] = 0;
1351     } else {
1352     return TRUE;
1353     }
1354     } else {
1355 maya 3167 notify_verbose_message(pvar, "SSH2_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1356    
1357 yutakakn 2728 if (grab_payload(pvar, 5)
1358 maya 3003 && grab_payload(pvar,
1359     (description_len = get_payload_uint32(pvar, 1)) + 4)
1360     && grab_payload(pvar,
1361     get_payload_uint32(pvar, 5 + description_len))) {
1362 yutakakn 2728 always_display = pvar->ssh_state.payload[0] != 0;
1363     description = pvar->ssh_state.payload + 5;
1364     description[description_len] = 0;
1365     } else {
1366     return TRUE;
1367     }
1368     }
1369    
1370     chop_newlines(description);
1371 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1372 maya 3003 description);
1373 yutakakn 2728 if (always_display) {
1374     notify_nonfatal_error(pvar, buf);
1375     } else {
1376     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1377     }
1378     return TRUE;
1379     }
1380    
1381     static BOOL handle_disconnect(PTInstVar pvar)
1382     {
1383     int reason_code;
1384     char FAR *description;
1385     int description_len;
1386     char buf[2048];
1387     char FAR *explanation = "";
1388 maya 2942 char uimsg[MAX_UIMSG];
1389 yutakakn 2728
1390     if (SSHv1(pvar)) {
1391 maya 3167 notify_verbose_message(pvar, "SSH_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1392    
1393 yutakakn 2728 if (grab_payload(pvar, 4)
1394 maya 3003 && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1395 yutakakn 2728 reason_code = -1;
1396     description = pvar->ssh_state.payload + 4;
1397     description[description_len] = 0;
1398     } else {
1399     return TRUE;
1400     }
1401     } else {
1402 maya 3167 notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1403    
1404 yutakakn 2728 if (grab_payload(pvar, 8)
1405 maya 3003 && grab_payload(pvar,
1406     (description_len = get_payload_uint32(pvar, 4)) + 4)
1407     && grab_payload(pvar,
1408     get_payload_uint32(pvar, 8 + description_len))) {
1409 yutakakn 2728 reason_code = get_payload_uint32(pvar, 0);
1410     description = pvar->ssh_state.payload + 8;
1411     description[description_len] = 0;
1412     } else {
1413     return TRUE;
1414     }
1415     }
1416    
1417     chop_newlines(description);
1418     if (description[0] == 0) {
1419     description = NULL;
1420     }
1421    
1422     if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1423 maya 2994 UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1424 maya 3003 "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1425     "This often happens when someone is already forwarding that port from the server.");
1426 maya 2992 strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1427 maya 2942 explanation = uimsg;
1428 yutakakn 2728 }
1429    
1430     if (description != NULL) {
1431 maya 2994 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1432 maya 3053 "Server disconnected with message '%s'%s");
1433 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1434 maya 3003 pvar->ts->UIMsg, description,
1435     explanation);
1436 yutakakn 2728 } else {
1437 maya 2994 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1438 maya 3003 "Server disconnected (no reason given).%s");
1439 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1440 maya 3003 pvar->ts->UIMsg, explanation);
1441 yutakakn 2728 }
1442     notify_fatal_error(pvar, buf);
1443    
1444     return TRUE;
1445     }
1446    
1447     static BOOL handle_unimplemented(PTInstVar pvar)
1448     {
1449     /* Should never receive this since we only send base 2.0 protocol messages */
1450     grab_payload(pvar, 4);
1451     return TRUE;
1452     }
1453    
1454     static BOOL handle_crypt_success(PTInstVar pvar)
1455     {
1456     notify_verbose_message(pvar, "Secure mode successfully achieved",
1457 maya 3003 LOG_LEVEL_VERBOSE);
1458 yutakakn 2728 return FALSE;
1459     }
1460    
1461     static BOOL handle_noauth_success(PTInstVar pvar)
1462     {
1463     notify_verbose_message(pvar, "Server does not require authentication",
1464 maya 3003 LOG_LEVEL_VERBOSE);
1465 yutakakn 2728 prep_compression(pvar);
1466     return FALSE;
1467     }
1468    
1469     static BOOL handle_auth_success(PTInstVar pvar)
1470     {
1471     notify_verbose_message(pvar, "Authentication accepted",
1472 maya 3003 LOG_LEVEL_VERBOSE);
1473 yutakakn 2728 prep_compression(pvar);
1474 yutakakn 2748
1475     // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1476     start_ssh_heartbeat_thread(pvar);
1477    
1478 yutakakn 2728 return FALSE;
1479     }
1480    
1481     static BOOL handle_server_public_key(PTInstVar pvar)
1482     {
1483     int server_key_public_exponent_len;
1484     int server_key_public_modulus_pos;
1485     int server_key_public_modulus_len;
1486     int host_key_bits_pos;
1487     int host_key_public_exponent_len;
1488     int host_key_public_modulus_pos;
1489     int host_key_public_modulus_len;
1490     int protocol_flags_pos;
1491     int supported_ciphers;
1492     char FAR *inmsg;
1493 yutakakn 2856 Key hostkey;
1494 maya 3108 int supported_types;
1495 yutakakn 2728
1496 maya 3167 notify_verbose_message(pvar, "SSH_SMSG_PUBLIC_KEY was received.", LOG_LEVEL_VERBOSE);
1497    
1498 yutakakn 2728 if (!grab_payload(pvar, 14))
1499     return FALSE;
1500     server_key_public_exponent_len = get_mpint_len(pvar, 12);
1501    
1502     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1503     return FALSE;
1504     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1505     server_key_public_modulus_len =
1506     get_mpint_len(pvar, server_key_public_modulus_pos);
1507    
1508     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1509     return FALSE;
1510     host_key_bits_pos =
1511     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1512     host_key_public_exponent_len =
1513     get_mpint_len(pvar, host_key_bits_pos + 4);
1514    
1515     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1516     return FALSE;
1517     host_key_public_modulus_pos =
1518     host_key_bits_pos + 6 + host_key_public_exponent_len;
1519     host_key_public_modulus_len =
1520     get_mpint_len(pvar, host_key_public_modulus_pos);
1521    
1522     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1523     return FALSE;
1524     protocol_flags_pos =
1525     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1526    
1527     inmsg = pvar->ssh_state.payload;
1528    
1529     CRYPT_set_server_cookie(pvar, inmsg);
1530 maya 3003 if (!CRYPT_set_server_RSA_key(pvar,
1531     get_uint32(inmsg + 8),
1532     pvar->ssh_state.payload + 12,
1533     inmsg + server_key_public_modulus_pos))
1534 yutakakn 2728 return FALSE;
1535 maya 3003 if (!CRYPT_set_host_RSA_key(pvar,
1536     get_uint32(inmsg + host_key_bits_pos),
1537     inmsg + host_key_bits_pos + 4,
1538     inmsg + host_key_public_modulus_pos))
1539 yutakakn 2728 return FALSE;
1540     pvar->ssh_state.server_protocol_flags =
1541     get_uint32(inmsg + protocol_flags_pos);
1542    
1543     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1544 maya 3003 if (!CRYPT_set_supported_ciphers(pvar,
1545     supported_ciphers,
1546     supported_ciphers))
1547 yutakakn 2728 return FALSE;
1548 maya 3108
1549     // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1550     // RSA ���L������ PAGEANT ���L��������
1551     supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1552     if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1553     supported_types |= (1 << SSH_AUTH_PAGEANT);
1554     }
1555 maya 3003 if (!AUTH_set_supported_auth_types(pvar,
1556 maya 3108 supported_types))
1557 yutakakn 2728 return FALSE;
1558    
1559     /* this must be the LAST THING in this function, since it can cause
1560     host_is_OK to be called. */
1561 yutakakn 2856 hostkey.type = KEY_RSA1;
1562     hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1563     hostkey.exp = inmsg + host_key_bits_pos + 4;
1564     hostkey.mod = inmsg + host_key_public_modulus_pos;
1565 maya 3126 HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1566 yutakakn 2728
1567     return FALSE;
1568     }
1569    
1570     /*
1571     The ID must have already been found to start with "SSH-". It must
1572     be null-terminated.
1573     */
1574     static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1575     {
1576     char FAR *str;
1577    
1578     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1579     }
1580    
1581     if (*str != '.') {
1582     return FALSE;
1583     }
1584    
1585     pvar->protocol_major = atoi(ID + 4);
1586     pvar->protocol_minor = atoi(str + 1);
1587    
1588     // for SSH2(yutaka)
1589     // 1.99����SSH2�����������s��
1590     if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
1591     // ���[�U�� SSH2 ���I������������������
1592     if (pvar->settings.ssh_protocol_version == 2) {
1593     pvar->protocol_major = 2;
1594     pvar->protocol_minor = 0;
1595     }
1596    
1597     }
1598    
1599 maya 3103 // SSH �o�[�W������ teraterm �����Z�b�g����
1600     // SCP �R�}���h������ (2008.2.3 maya)
1601 maya 3104 pvar->cv->isSSH = pvar->protocol_major;
1602 maya 3103
1603 yutakakn 2728 for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1604     }
1605    
1606     return *str == '-';
1607     }
1608    
1609     /*
1610     On entry, the pvar->protocol_xxx fields hold the server's advertised
1611     protocol number. We replace the fields with the protocol number we will
1612     actually use, or return FALSE if there is no usable protocol version.
1613     */
1614     static BOOL negotiate_protocol(PTInstVar pvar)
1615     {
1616     switch (pvar->protocol_major) {
1617     case 1:
1618     if (pvar->protocol_minor > 5) {
1619     pvar->protocol_minor = 5;
1620     }
1621    
1622     return TRUE;
1623    
1624     // for SSH2(yutaka)
1625     case 2:
1626     return TRUE; // SSH2 support
1627    
1628     default:
1629     return FALSE;
1630     }
1631     }
1632    
1633     static void init_protocol(PTInstVar pvar)
1634     {
1635     CRYPT_initialize_random_numbers(pvar);
1636 yutakakn 2856
1637     // known_hosts�t�@�C�������z�X�g���J������������������
1638 maya 3126 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1639 yutakakn 2856
1640 yutakakn 2728 /* while we wait for a response from the server... */
1641    
1642     if (SSHv1(pvar)) {
1643     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1644     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1645     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1646     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1647    
1648     } else { // for SSH2(yutaka)
1649     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1650     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1651     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1652     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1653     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1654 maya 3054 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1655     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1656 yutakakn 2728 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1657 maya 3151 enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1658 yutakakn 2728 enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1659     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1660     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1661 yutakakn 2782 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1662 yutakakn 2728
1663     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1664    
1665     // ���[�U�F�������f�B�X�p�b�`���[�`��
1666     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1667     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1668     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1669 maya 2926 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1670 yutakakn 2825 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1671 yutakakn 2728 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1672 yutakakn 2827 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1673 yutakakn 2728 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1674     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1675     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1676     // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1677 yutakakn 2825 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1678 yutakakn 2728 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1679    
1680     }
1681     }
1682    
1683     BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1684     {
1685     static const char prefix[] = "Received server prologue string: ";
1686    
1687 yutakakn 2796 // initialize SSH2 memory dump (2005.3.7 yutaka)
1688     init_memdump();
1689 maya 2929 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1690 yutakakn 2796
1691 yutakakn 2728 if (ID_len <= 0) {
1692     return FALSE;
1693     } else {
1694 maya 2992 int buf_len = ID_len + NUM_ELEM(prefix);
1695     char FAR *buf = (char FAR *) malloc(buf_len);
1696 yutakakn 2728
1697 maya 2992 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1698     strncat_s(buf, buf_len, ID, _TRUNCATE);
1699 yutakakn 2728 chop_newlines(buf);
1700    
1701     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1702    
1703     free(buf);
1704    
1705    
1706 yutakakn 2797 // ���������R�s�[������ (2005.3.9 yutaka)
1707     #if 0
1708 yutakakn 2728 // for calculate SSH2 hash
1709     // �T�[�o�o�[�W�����������i���s���������������j
1710 maya 3054 if (ID_len >= sizeof(pvar->server_version_string))
1711 yutakakn 2728 return FALSE;
1712     strncpy(pvar->server_version_string, ID, ID_len);
1713 yutakakn 2797 #endif
1714 yutakakn 2728
1715    
1716     if (ID[ID_len - 1] != '\n') {
1717     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1718     return FALSE;
1719 maya 3003 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1720 yutakakn 2728 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1721     return FALSE;
1722     } else if (strncmp(ID, "SSH-", 4) != 0) {
1723     return FALSE;
1724     } else {
1725     ID[ID_len - 1] = 0;
1726    
1727     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1728     ID[ID_len - 2] = 0;
1729     }
1730    
1731     pvar->ssh_state.server_ID = _strdup(ID);
1732    
1733     if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1734 maya 2994 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1735 maya 3003 "This program does not understand the server's version of the protocol.");
1736 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
1737 yutakakn 2728 } else {
1738     char TTSSH_ID[1024];
1739     int TTSSH_ID_len;
1740 yutakakn 2793 int a, b, c, d;
1741 yutakakn 2728
1742 yutakakn 2793 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1743     get_file_version("ttxssh.dll", &a, &b, &c, &d);
1744    
1745 maya 2992 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1746 maya 3003 "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1747     pvar->protocol_major, pvar->protocol_minor, a, b);
1748 yutakakn 2728 TTSSH_ID_len = strlen(TTSSH_ID);
1749    
1750     // for SSH2(yutaka)
1751     // �N���C�A���g�o�[�W�����������i���s���������������j
1752 maya 2992 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1753 maya 3003 TTSSH_ID, _TRUNCATE);
1754 yutakakn 2728
1755 yutakakn 2797 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1756 maya 2992 _snprintf_s(pvar->server_version_string,
1757 maya 3003 sizeof(pvar->server_version_string), _TRUNCATE,
1758     "%s", pvar->ssh_state.server_ID);
1759 yutakakn 2797
1760 yutakakn 2728 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1761 maya 3003 0) != TTSSH_ID_len) {
1762 maya 2994 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1763 maya 3003 "An error occurred while sending the SSH ID string.\n"
1764     "The connection will close.");
1765 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
1766 yutakakn 2728 } else {
1767     // ���s�R�[�h������ (2004.8.4 yutaka)
1768     pvar->client_version_string[--TTSSH_ID_len] = 0;
1769    
1770 yutakakn 2796 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1771     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1772    
1773 yutakakn 2728 // SSH�n���h�����o�^���s��
1774     init_protocol(pvar);
1775    
1776     SSH2_dispatch_init(1);
1777     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1778 yutakakn 2796 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1779 yutakakn 2728 }
1780     }
1781    
1782     return TRUE;
1783     }
1784     }
1785     }
1786    
1787     static BOOL handle_exit(PTInstVar pvar)
1788     {
1789     if (grab_payload(pvar, 4)) {
1790     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1791     finish_send_packet(pvar);
1792     notify_closed_connection(pvar);
1793     }
1794     return TRUE;
1795     }
1796    
1797     static BOOL handle_data(PTInstVar pvar)
1798     {
1799     if (grab_payload_limited(pvar, 4)) {
1800     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1801     pvar->ssh_state.payload_datastart = 4;
1802     }
1803     return TRUE;
1804     }
1805    
1806     static BOOL handle_channel_open(PTInstVar pvar)
1807     {
1808     int host_len;
1809     int originator_len;
1810    
1811     if ((pvar->ssh_state.
1812     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1813     if (grab_payload(pvar, 8)
1814 maya 3003 && grab_payload(pvar,
1815     8 + (host_len = get_payload_uint32(pvar, 4)))
1816     && grab_payload(pvar, originator_len =
1817     get_payload_uint32(pvar, host_len + 12))) {
1818 yutakakn 2728 int local_port = get_payload_uint32(pvar, 8 + host_len);
1819    
1820     pvar->ssh_state.payload[8 + host_len] = 0;
1821     FWD_open(pvar, get_payload_uint32(pvar, 0),
1822 maya 3003 pvar->ssh_state.payload + 8, local_port,
1823     pvar->ssh_state.payload + 16 + host_len,
1824 maya 3054 originator_len,
1825 maya 3003 NULL);
1826 yutakakn 2728 }
1827     } else {
1828     if (grab_payload(pvar, 8)
1829 maya 3003 && grab_payload(pvar,
1830     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1831 yutakakn 2728 int local_port = get_payload_uint32(pvar, 8 + host_len);
1832    
1833     pvar->ssh_state.payload[8 + host_len] = 0;
1834     FWD_open(pvar, get_payload_uint32(pvar, 0),
1835 maya 3003 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1836     NULL);
1837 yutakakn 2728 }
1838     }
1839    
1840     return TRUE;
1841     }
1842    
1843     static BOOL handle_X11_channel_open(PTInstVar pvar)
1844     {
1845     int originator_len;
1846    
1847 maya 3003 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1848 yutakakn 2728 if (grab_payload(pvar, 8)
1849 maya 3003 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1850 yutakakn 2728 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1851 maya 3003 pvar->ssh_state.payload + 8, originator_len, NULL);
1852 yutakakn 2728 }
1853     } else {
1854     if (grab_payload(pvar, 4)) {
1855 yutakakn 2829 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1856 yutakakn 2728 }
1857     }
1858    
1859     return TRUE;
1860     }
1861    
1862     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1863     {
1864     if (grab_payload(pvar, 8)) {
1865     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1866 maya 3003 get_payload_uint32(pvar, 4));
1867 yutakakn 2728 }
1868     return FALSE;
1869     }
1870    
1871     static BOOL handle_channel_open_failure(PTInstVar pvar)
1872     {
1873     if (grab_payload(pvar, 4)) {
1874     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1875     }
1876     return FALSE;
1877     }
1878    
1879     static BOOL handle_channel_data(PTInstVar pvar)
1880     {
1881     int len;
1882    
1883     if (grab_payload(pvar, 8)
1884 maya 3003 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1885 yutakakn 2728 FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1886 maya 3003 pvar->ssh_state.payload + 8, len);
1887 yutakakn 2728 }
1888     return TRUE;
1889     }
1890    
1891     static BOOL handle_channel_input_eof(PTInstVar pvar)
1892     {
1893     if (grab_payload(pvar, 4)) {
1894     FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1895     }
1896     return TRUE;
1897     }
1898    
1899     static BOOL handle_channel_output_eof(PTInstVar pvar)
1900     {
1901     if (grab_payload(pvar, 4)) {
1902     FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1903     }
1904     return TRUE;
1905     }
1906    
1907    
1908    
1909     // �n���h�����O�������b�Z�[�W����������
1910    
1911     #define HANDLE_MESSAGE_MAX 30
1912     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1913     static int handle_message_count = 0;
1914     static int handle_message_stage = 0;
1915    
1916     void SSH2_dispatch_init(int stage)
1917     {
1918     handle_message_count = 0;
1919     handle_message_stage = stage;
1920     }
1921    
1922     int SSH2_dispatch_enabled_check(unsigned char message)
1923     {
1924     int i;
1925    
1926     for (i = 0 ; i < handle_message_count ; i++) {
1927     if (handle_messages[i] == message)
1928     return 1;
1929     }
1930     return 0;
1931     }
1932    
1933     void SSH2_dispatch_add_message(unsigned char message)
1934     {
1935 maya 3152 int i;
1936 yutakakn 2728
1937     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1938     // TODO: error check
1939     return;
1940     }
1941    
1942 maya 3152 // �������o�^�������������b�Z�[�W������������
1943     for (i=0; i<handle_message_count; i++) {
1944     if (handle_messages[i] == message) {
1945     return;
1946     }
1947     }
1948    
1949 yutakakn 2728 handle_messages[handle_message_count++] = message;
1950     }
1951    
1952     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1953     {
1954     unsigned char c;
1955    
1956     for (c = begin ; c <= end ; c++) {
1957     SSH2_dispatch_add_message(c);
1958     }
1959     }
1960    
1961    
1962     void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1963     int padding)
1964     {
1965     unsigned char message = prep_packet(pvar, data, len, padding);
1966    
1967    
1968     #ifdef SSH2_DEBUG
1969     // for SSH2(yutaka)
1970     if (SSHv2(pvar)) {
1971     if (pvar->key_done) {
1972     message = message;
1973     }
1974    
1975     if (pvar->userauth_success) {
1976     message = message;
1977     }
1978    
1979     if (pvar->rekeying) {
1980     message = message;
1981     }
1982     }
1983     #endif
1984    
1985     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1986     if (message != SSH_MSG_NONE) {
1987     // ���b�Z�[�W�^�C�v���������n���h�����N��
1988     SSHPacketHandler handler = get_handler(pvar, message);
1989    
1990     // for SSH2(yutaka)
1991     if (SSHv2(pvar)) {
1992     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1993     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1994     char buf[1024];
1995    
1996 maya 2994 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
1997     "Unexpected SSH2 message(%d) on current stage(%d)");
1998 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1999 maya 2942 pvar->ts->UIMsg, message, handle_message_stage);
2000 yutakakn 2728 notify_fatal_error(pvar, buf);
2001     // abort
2002     }
2003     }
2004    
2005     if (handler == NULL) {
2006     if (SSHv1(pvar)) {
2007     char buf[1024];
2008    
2009 maya 2994 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2010 maya 3003 "Unexpected packet type received: %d");
2011 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2012 maya 2942 pvar->ts->UIMsg, message, handle_message_stage);
2013 yutakakn 2728 notify_fatal_error(pvar, buf);
2014     } else {
2015     unsigned char FAR *outmsg =
2016     begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2017    
2018     set_uint32(outmsg,
2019 maya 3003 pvar->ssh_state.receiver_sequence_number - 1);
2020 yutakakn 2728 finish_send_packet(pvar);
2021 maya 3167
2022     notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2023 yutakakn 2728 /* XXX need to decompress incoming packet, but how? */
2024     }
2025     } else {
2026     if (!handler(pvar)) {
2027     deque_handlers(pvar, message);
2028     }
2029     }
2030     }
2031     }
2032    
2033     static BOOL handle_pty_success(PTInstVar pvar)
2034     {
2035     FWD_enter_interactive_mode(pvar);
2036     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2037     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2038     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2039     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2040     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2041 maya 3003 handle_channel_input_eof);
2042 yutakakn 2728 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2043 maya 3003 handle_channel_output_eof);
2044 yutakakn 2728 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2045     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2046     return FALSE;
2047     }
2048    
2049     static BOOL handle_pty_failure(PTInstVar pvar)
2050     {
2051 maya 2994 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2052 maya 3003 "The server cannot allocate a pseudo-terminal. "
2053     "You may encounter some problems with the terminal.");
2054 maya 2942 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2055 yutakakn 2728 return handle_pty_success(pvar);
2056     }
2057    
2058     static void prep_pty(PTInstVar pvar)
2059     {
2060     int len = strlen(pvar->ts->TermType);
2061     unsigned char FAR *outmsg =
2062     begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2063 maya 3003 4 + len + 16 + sizeof(ssh_ttymodes));
2064 yutakakn 2728 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2065     static const SSHPacketHandler handlers[]
2066     = { handle_pty_success, handle_pty_failure };
2067    
2068     set_uint32(outmsg, len);
2069     memcpy(outmsg + 4, pvar->ts->TermType, len);
2070     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2071     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2072     set_uint32(outmsg + 4 + len + 8, 0);
2073     set_uint32(outmsg + 4 + len + 12, 0);
2074     memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2075     finish_send_packet(pvar);
2076    
2077     enque_handlers(pvar, 2, msgs, handlers);
2078    
2079     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2080     finish_send_packet(pvar);
2081     }
2082    
2083     static void prep_forwarding(PTInstVar pvar)
2084     {
2085     FWD_prep_forwarding(pvar);
2086     prep_pty(pvar);
2087     }
2088    
2089 yutakakn 2834
2090     //
2091     //
2092     // (2005.7.10 yutaka)
2093     static void enable_send_compression(PTInstVar pvar)
2094 yutakakn 2728 {
2095 yutakakn 2834 static int initialize = 0;
2096    
2097     if (initialize) {
2098     deflateEnd(&pvar->ssh_state.compress_stream);
2099     }
2100     initialize = 1;
2101    
2102 yutakakn 2728 pvar->ssh_state.compress_stream.zalloc = NULL;
2103     pvar->ssh_state.compress_stream.zfree = NULL;
2104     pvar->ssh_state.compress_stream.opaque = NULL;
2105     if (deflateInit
2106 maya 3003 (&pvar->ssh_state.compress_stream,
2107     pvar->ssh_state.compression_level) != Z_OK) {
2108 maya 2994 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2109 maya 3003 "An error occurred while setting up compression.\n"
2110     "The connection will close.");
2111 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
2112 yutakakn 2728 return;
2113     } else {
2114 yutakakn 2834 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2115     if (SSHv2(pvar)) {
2116     pvar->ssh_state.compressing = FALSE;
2117     } else {
2118     pvar->ssh_state.compressing = TRUE;
2119     }
2120 yutakakn 2728 }
2121 yutakakn 2834 }
2122 yutakakn 2728
2123 yutakakn 2834 static void enable_recv_compression(PTInstVar pvar)
2124     {
2125     static int initialize = 0;
2126    
2127     if (initialize) {
2128     deflateEnd(&pvar->ssh_state.decompress_stream);
2129     }
2130     initialize = 1;
2131    
2132 yutakakn 2728 pvar->ssh_state.decompress_stream.zalloc = NULL;
2133     pvar->ssh_state.decompress_stream.zfree = NULL;
2134     pvar->ssh_state.decompress_stream.opaque = NULL;
2135     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2136     deflateEnd(&pvar->ssh_state.compress_stream);
2137 maya 2994 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2138 maya 3003 "An error occurred while setting up compression.\n"
2139     "The connection will close.");
2140 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
2141 yutakakn 2728 return;
2142     } else {
2143 yutakakn 2834 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2144     if (SSHv2(pvar)) {
2145     pvar->ssh_state.decompressing = FALSE;
2146     } else {
2147     pvar->ssh_state.decompressing = TRUE;
2148     }
2149    
2150 yutakakn 2728 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2151 maya 3003 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2152 yutakakn 2728 }
2153 yutakakn 2834 }
2154 yutakakn 2833
2155 yutakakn 2834 static void enable_compression(PTInstVar pvar)
2156     {
2157     enable_send_compression(pvar);
2158     enable_recv_compression(pvar);
2159    
2160 yutakakn 2833 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2161     if (SSHv2(pvar)) {
2162     pvar->ssh_state.compressing = FALSE;
2163     pvar->ssh_state.decompressing = FALSE;
2164     }
2165    
2166 yutakakn 2728 }
2167    
2168     static BOOL handle_enable_compression(PTInstVar pvar)
2169     {
2170     enable_compression(pvar);
2171     prep_forwarding(pvar);
2172     return FALSE;
2173     }
2174    
2175     static BOOL handle_disable_compression(PTInstVar pvar)
2176     {
2177     prep_forwarding(pvar);
2178     return FALSE;
2179     }
2180    
2181     static void prep_compression(PTInstVar pvar)
2182     {
2183     if (pvar->session_settings.CompressionLevel > 0) {
2184 yutakakn 2833 // added if statement (2005.7.10 yutaka)
2185     if (SSHv1(pvar)) {
2186     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2187     static const SSHPacketHandler handlers[]
2188     = { handle_enable_compression, handle_disable_compression };
2189 yutakakn 2728
2190 yutakakn 2833 unsigned char FAR *outmsg =
2191     begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2192 yutakakn 2728
2193 yutakakn 2833 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2194     finish_send_packet(pvar);
2195 yutakakn 2728
2196 yutakakn 2833 enque_handlers(pvar, 2, msgs, handlers);
2197     }
2198    
2199 yutakakn 2728 pvar->ssh_state.compression_level =
2200     pvar->session_settings.CompressionLevel;
2201    
2202     } else {
2203 yutakakn 2833 // added if statement (2005.7.10 yutaka)
2204     if (SSHv1(pvar)) {
2205     prep_forwarding(pvar);
2206     }
2207 yutakakn 2728 }
2208     }
2209    
2210     static void enque_simple_auth_handlers(PTInstVar pvar)
2211     {
2212     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2213     static const SSHPacketHandler handlers[]
2214     = { handle_auth_success, handle_auth_failure };
2215    
2216     enque_handlers(pvar, 2, msgs, handlers);
2217     }
2218    
2219     static BOOL handle_rsa_challenge(PTInstVar pvar)
2220     {
2221     int challenge_bytes;
2222    
2223     if (!grab_payload(pvar, 2)) {
2224     return FALSE;
2225     }
2226    
2227     challenge_bytes = get_mpint_len(pvar, 0);
2228    
2229     if (grab_payload(pvar, challenge_bytes)) {
2230     unsigned char FAR *outmsg =
2231     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2232    
2233 maya 3108 if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2234     if (CRYPT_generate_RSA_challenge_response
2235     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2236 yutakakn 2811
2237 maya 3108 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2238     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2239 yutakakn 2811 #if 0
2240 maya 3108 //AUTH_destroy_cur_cred(pvar);
2241 yutakakn 2811 #endif
2242    
2243 maya 3108 finish_send_packet(pvar);
2244 yutakakn 2728
2245 maya 3108 enque_simple_auth_handlers(pvar);
2246     } else {
2247     UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2248     "An error occurred while decrypting the RSA challenge.\n"
2249     "Perhaps the key file is corrupted.");
2250     notify_fatal_error(pvar, pvar->ts->UIMsg);
2251     }
2252 yutakakn 2728 }
2253 maya 3108 else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2254 maya 3109 int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2255     int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2256     int server_key_bytes = (server_key_bits + 7) / 8;
2257     int host_key_bytes = (host_key_bits + 7) / 8;
2258     int session_buf_len = server_key_bytes + host_key_bytes + 8;
2259     char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2260     unsigned char session_id[16];
2261    
2262 maya 3108 unsigned char *hash;
2263     int pubkeylen, hashlen;
2264    
2265     /* Pageant ���n�b�V�����v�Z���������� */
2266 maya 3109 // ���J��������
2267 maya 3108 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2268     pvar->pageant_keylistlen);
2269 maya 3109 // �Z�b�V����ID������
2270     BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2271     BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2272     session_buf + host_key_bytes);
2273     memcpy(session_buf + server_key_bytes + host_key_bytes,
2274     pvar->crypt_state.server_cookie, 8);
2275     MD5(session_buf, session_buf_len, session_id);
2276     // �n�b�V������������
2277 maya 3108 hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2278     pubkeylen,
2279     pvar->ssh_state.payload,
2280     challenge_bytes + 2,
2281 maya 3109 session_id,
2282 maya 3108 &hashlen);
2283 maya 3109
2284     // �n�b�V�������M
2285     memcpy(outmsg, hash, 16);
2286     free(hash);
2287    
2288     finish_send_packet(pvar);
2289    
2290     enque_simple_auth_handlers(pvar);
2291 maya 3108 }
2292 yutakakn 2728 }
2293    
2294     return FALSE;
2295     }
2296    
2297     #define OBFUSCATING_ROUND_TO 32
2298    
2299     static int obfuscating_round_up(PTInstVar pvar, int size)
2300     {
2301     return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2302     }
2303    
2304     static void try_send_credentials(PTInstVar pvar)
2305     {
2306     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2307     AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2308     static const int RSA_msgs[] =
2309     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2310     static const SSHPacketHandler RSA_handlers[]
2311     = { handle_rsa_challenge, handle_rsa_auth_refused };
2312     static const int TIS_msgs[] =
2313     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2314     static const SSHPacketHandler TIS_handlers[]
2315     = { handle_TIS_challenge, handle_auth_failure };
2316    
2317 yutakakn 2800 // SSH2���������������������X�L�b�v
2318 maya 3054 if (SSHv2(pvar))
2319 yutakakn 2800 goto skip_ssh2;
2320    
2321 yutakakn 2728 switch (cred->method) {
2322     case SSH_AUTH_NONE:
2323     return;
2324     case SSH_AUTH_PASSWORD:{
2325     int len = strlen(cred->password);
2326     // Round up password length to discourage traffic analysis
2327     int obfuscated_len = obfuscating_round_up(pvar, len);
2328     unsigned char FAR *outmsg =
2329     begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2330 maya 3003 4 + obfuscated_len);
2331 yutakakn 2728
2332     notify_verbose_message(pvar,
2333 maya 3003 "Trying PASSWORD authentication...",
2334     LOG_LEVEL_VERBOSE);
2335 yutakakn 2728
2336     set_uint32(outmsg, obfuscated_len);
2337     memcpy(outmsg + 4, cred->password, len);
2338     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2339 yutakakn 2811
2340     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2341     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2342     #if 0
2343     //AUTH_destroy_cur_cred(pvar);
2344     #endif
2345    
2346 yutakakn 2728 enque_simple_auth_handlers(pvar);
2347     break;
2348     }
2349     case SSH_AUTH_RHOSTS:{
2350     int len = strlen(cred->rhosts_client_user);
2351     unsigned char FAR *outmsg =
2352     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2353    
2354     notify_verbose_message(pvar,
2355 maya 3003 "Trying RHOSTS authentication...",
2356     LOG_LEVEL_VERBOSE);
2357 yutakakn 2728
2358     set_uint32(outmsg, len);
2359     memcpy(outmsg + 4, cred->rhosts_client_user, len);
2360     AUTH_destroy_cur_cred(pvar);
2361     enque_simple_auth_handlers(pvar);
2362     break;
2363     }
2364     case SSH_AUTH_RSA:{
2365     int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2366     unsigned char FAR *outmsg =
2367     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2368    
2369     notify_verbose_message(pvar,
2370 maya 3003 "Trying RSA authentication...",
2371     LOG_LEVEL_VERBOSE);
2372 yutakakn 2728
2373     set_ushort16_MSBfirst(outmsg, len * 8);
2374     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2375     /* don't destroy the current credentials yet */
2376     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2377     break;
2378     }
2379     case SSH_AUTH_RHOSTS_RSA:{
2380     int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2381     int name_len = strlen(cred->rhosts_client_user);
2382     int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2383     int index;
2384     unsigned char FAR *outmsg =
2385     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2386 maya 3003 12 + mod_len + name_len + exp_len);
2387 yutakakn 2728
2388     notify_verbose_message(pvar,
2389 maya 3003 "Trying RHOSTS+RSA authentication...",
2390     LOG_LEVEL_VERBOSE);
2391 yutakakn 2728
2392     set_uint32(outmsg, name_len);
2393     memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2394     index = 4 + name_len;
2395    
2396     set_uint32(outmsg + index, 8 * mod_len);
2397     set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2398     BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2399     index += 6 + exp_len;
2400    
2401     set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2402     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2403     /* don't destroy the current credentials yet */
2404     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2405     break;
2406     }
2407 maya 3108 case SSH_AUTH_PAGEANT:{
2408     unsigned char FAR *outmsg;
2409     unsigned char *pubkey;
2410     int len, bn_bytes;
2411    
2412 maya 3109 if (pvar->pageant_keycurrent != 0) {
2413     // ���O�������X�L�b�v
2414     pvar->pageant_curkey += 4;
2415     len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2416     bn_bytes = (len + 7) / 8;
2417     pvar->pageant_curkey += 2 + bn_bytes;
2418     len =