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 3137 - (hide annotations) (download) (as text)
Fri Jul 25 15:48:44 2008 UTC (15 years, 8 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 223537 byte(s)
*** empty log message ***

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