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 3182 - (hide annotations) (download) (as text)
Wed Dec 3 06:34:01 2008 UTC (15 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 244347 byte(s)
no message

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