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 3215 - (hide annotations) (download) (as text)
Wed Mar 4 11:40:44 2009 UTC (15 years, 1 month ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 242248 byte(s)
最大パケットサイズをマクロ定義した。

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