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 3193 - (hide annotations) (download) (as text)
Fri Dec 19 08:39:04 2008 UTC (15 years, 3 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 241982 byte(s)
SSH2_MSG_CHANNEL_FAILURE を受信したときの処理を調整した。

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