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 7005 - (hide annotations) (download) (as text)
Mon Dec 18 11:06:06 2017 UTC (6 years, 3 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 268380 byte(s)
パスワード無しで bcrypt_KDF 形式で秘密鍵を保存した時に落ちるのを修正。

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