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 7014 - (hide annotations) (download) (as text)
Tue Jan 9 09:06:11 2018 UTC (6 years, 3 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 259911 byte(s)
SSH Dump Log への出力で、末尾にゴミ(NUL バイト)が付加するのを修正

pvar->ssh_state.payload はメッセージタイプを除いたペイロードの先頭を指すが、
pvar->ssh_state.payloadlen はメッセージタイプ分の 1 バイトを含めた長さ。
ペイロード部分の長さは payloadlen から 1 を引かなければいけない。

payload の長さと payloadlen が対応していないのは分かりづらくミスの元なので
対処を考える必要あり。
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     }
1864     }
1865    
1866     return TRUE;
1867     }
1868     }
1869     }
1870    
1871     static BOOL handle_exit(PTInstVar pvar)
1872     {
1873     if (grab_payload(pvar, 4)) {
1874     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1875     finish_send_packet(pvar);
1876 maya 5678 notify_closed_connection(pvar, "disconnected by server request");
1877 maya 3227 }
1878     return TRUE;
1879     }
1880    
1881     static BOOL handle_data(PTInstVar pvar)
1882     {
1883     if (grab_payload_limited(pvar, 4)) {
1884     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1885     pvar->ssh_state.payload_datastart = 4;
1886     }
1887     return TRUE;
1888     }
1889    
1890     static BOOL handle_channel_open(PTInstVar pvar)
1891     {
1892     int host_len;
1893     int originator_len;
1894    
1895     if ((pvar->ssh_state.
1896     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1897     if (grab_payload(pvar, 8)
1898     && grab_payload(pvar,
1899     8 + (host_len = get_payload_uint32(pvar, 4)))
1900     && grab_payload(pvar, originator_len =
1901     get_payload_uint32(pvar, host_len + 12))) {
1902     int local_port = get_payload_uint32(pvar, 8 + host_len);
1903    
1904     pvar->ssh_state.payload[8 + host_len] = 0;
1905     FWD_open(pvar, get_payload_uint32(pvar, 0),
1906     pvar->ssh_state.payload + 8, local_port,
1907     pvar->ssh_state.payload + 16 + host_len,
1908     originator_len,
1909     NULL);
1910     }
1911     } else {
1912     if (grab_payload(pvar, 8)
1913     && grab_payload(pvar,
1914     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1915     int local_port = get_payload_uint32(pvar, 8 + host_len);
1916    
1917     pvar->ssh_state.payload[8 + host_len] = 0;
1918     FWD_open(pvar, get_payload_uint32(pvar, 0),
1919     pvar->ssh_state.payload + 8, local_port, NULL, 0,
1920     NULL);
1921     }
1922     }
1923    
1924     return TRUE;
1925     }
1926    
1927     static BOOL handle_X11_channel_open(PTInstVar pvar)
1928     {
1929     int originator_len;
1930    
1931     if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1932     if (grab_payload(pvar, 8)
1933     && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1934     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1935     pvar->ssh_state.payload + 8, originator_len, NULL);
1936     }
1937     } else {
1938     if (grab_payload(pvar, 4)) {
1939     FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1940     }
1941     }
1942    
1943     return TRUE;
1944     }
1945    
1946     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1947     {
1948     if (grab_payload(pvar, 8)) {
1949     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1950     get_payload_uint32(pvar, 4));
1951     }
1952     return FALSE;
1953     }
1954    
1955     static BOOL handle_channel_open_failure(PTInstVar pvar)
1956     {
1957     if (grab_payload(pvar, 4)) {
1958 doda 6844 FWD_failed_open(pvar, get_payload_uint32(pvar, 0), -1);
1959 maya 3227 }
1960     return FALSE;
1961     }
1962    
1963     static BOOL handle_channel_data(PTInstVar pvar)
1964     {
1965     int len;
1966    
1967     if (grab_payload(pvar, 8)
1968     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1969     FWDChannel *channel;
1970     int local_channel_num = get_payload_uint32(pvar, 0);
1971     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1972     return FALSE;
1973     }
1974     channel = pvar->fwd_state.channels + local_channel_num;
1975     if (channel->type == TYPE_AGENT) {
1976     SSH_agent_response(pvar, NULL, local_channel_num,
1977     pvar->ssh_state.payload + 8, len);
1978     }
1979     else {
1980     FWD_received_data(pvar, local_channel_num,
1981     pvar->ssh_state.payload + 8, len);
1982     }
1983     }
1984     return TRUE;
1985     }
1986    
1987     static BOOL handle_channel_input_eof(PTInstVar pvar)
1988     {
1989     if (grab_payload(pvar, 4)) {
1990     int local_channel_num = get_payload_uint32(pvar, 0);
1991     FWDChannel *channel;
1992     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1993     return FALSE;
1994     }
1995     channel = pvar->fwd_state.channels + local_channel_num;
1996     if (channel->type == TYPE_AGENT) {
1997     channel->status |= FWD_CLOSED_REMOTE_IN;
1998     SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1999     }
2000     else {
2001     FWD_channel_input_eof(pvar, local_channel_num);
2002     }
2003     }
2004     return TRUE;
2005     }
2006    
2007     static BOOL handle_channel_output_eof(PTInstVar pvar)
2008     {
2009     if (grab_payload(pvar, 4)) {
2010     int local_channel_num = get_payload_uint32(pvar, 0);
2011     FWDChannel *channel;
2012     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
2013     return FALSE;
2014     }
2015     channel = pvar->fwd_state.channels + local_channel_num;
2016     if (channel->type == TYPE_AGENT) {
2017     channel->status |= FWD_CLOSED_REMOTE_OUT;
2018     SSH_channel_output_eof(pvar, channel->remote_num);
2019     FWD_free_channel(pvar, local_channel_num);
2020     }
2021     else {
2022     FWD_channel_output_eof(pvar, local_channel_num);
2023     }
2024     }
2025     return TRUE;
2026     }
2027    
2028     static BOOL handle_agent_open(PTInstVar pvar)
2029     {
2030     if (grab_payload(pvar, 4)) {
2031     int remote_id = get_payload_uint32(pvar, 0);
2032     int local_id;
2033    
2034 doda 4233 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
2035 maya 3227 local_id = FWD_agent_open(pvar, remote_id);
2036     if (local_id == -1) {
2037     SSH_fail_channel_open(pvar, remote_id);
2038     }
2039     else {
2040     SSH_confirm_channel_open(pvar, remote_id, local_id);
2041     }
2042     }
2043     else {
2044     SSH_fail_channel_open(pvar, remote_id);
2045     }
2046     }
2047     /*
2048     else {
2049     // ���m��������channel����������������������������
2050     }
2051     */
2052    
2053     return TRUE;
2054     }
2055    
2056    
2057    
2058     // �n���h�����O�������b�Z�[�W����������
2059    
2060     #define HANDLE_MESSAGE_MAX 30
2061     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
2062     static int handle_message_count = 0;
2063     static int handle_message_stage = 0;
2064    
2065     void SSH2_dispatch_init(int stage)
2066     {
2067     handle_message_count = 0;
2068     handle_message_stage = stage;
2069 doda 7011
2070     SSH2_dispatch_add_message(SSH2_MSG_IGNORE);
2071     SSH2_dispatch_add_message(SSH2_MSG_DEBUG);
2072     SSH2_dispatch_add_message(SSH2_MSG_DISCONNECT);
2073     SSH2_dispatch_add_message(SSH2_MSG_UNIMPLEMENTED);
2074 maya 3227 }
2075    
2076     int SSH2_dispatch_enabled_check(unsigned char message)
2077     {
2078     int i;
2079    
2080     for (i = 0 ; i < handle_message_count ; i++) {
2081     if (handle_messages[i] == message)
2082     return 1;
2083     }
2084     return 0;
2085     }
2086    
2087     void SSH2_dispatch_add_message(unsigned char message)
2088     {
2089     int i;
2090    
2091     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2092     // TODO: error check
2093 doda 6824 logprintf(LOG_LEVEL_ERROR, __FUNCTION__ ": too many handlers. handlers:%d, max:%d",
2094     handle_message_count, HANDLE_MESSAGE_MAX);
2095 maya 3227 return;
2096     }
2097    
2098     // �������o�^�������������b�Z�[�W������������
2099     for (i=0; i<handle_message_count; i++) {
2100     if (handle_messages[i] == message) {
2101     return;
2102     }
2103     }
2104    
2105     handle_messages[handle_message_count++] = message;
2106     }
2107    
2108     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2109     {
2110     unsigned char c;
2111    
2112     for (c = begin ; c <= end ; c++) {
2113     SSH2_dispatch_add_message(c);
2114     }
2115     }
2116    
2117 doda 6982 void SSH1_handle_packet(PTInstVar pvar, char *data, unsigned int len, unsigned int padding)
2118 maya 3227 {
2119 doda 6968 unsigned char message = prep_packet_ssh1(pvar, data, len, padding);
2120 maya 3227
2121     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2122     if (message != SSH_MSG_NONE) {
2123     // ���b�Z�[�W�^�C�v���������n���h�����N��
2124     SSHPacketHandler handler = get_handler(pvar, message);
2125    
2126 doda 6968 if (handler == NULL) {
2127     char buf[1024];
2128 maya 3227
2129 doda 6968 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar, "Unexpected packet type received: %d");
2130     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);
2131     notify_fatal_error(pvar, buf, TRUE);
2132     } else {
2133     if (!handler(pvar)) {
2134     deque_handlers(pvar, message);
2135 maya 3227 }
2136     }
2137 doda 6968 }
2138     }
2139 maya 3227
2140 doda 6985 void SSH2_handle_packet(PTInstVar pvar, char *data, unsigned int len, unsigned int aadlen, unsigned int authlen)
2141 doda 6968 {
2142 doda 6985 unsigned char message = prep_packet_ssh2(pvar, data, len, aadlen, authlen);
2143 doda 6968
2144     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2145     if (message != SSH_MSG_NONE) {
2146     // ���b�Z�[�W�^�C�v���������n���h�����N��
2147     SSHPacketHandler handler = get_handler(pvar, message);
2148    
2149     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2150     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2151     char buf[1024];
2152    
2153     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar, "Unexpected SSH2 message(%d) on current stage(%d)");
2154     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);
2155     notify_fatal_error(pvar, buf, TRUE);
2156     return;
2157     }
2158    
2159 maya 3227 if (handler == NULL) {
2160 doda 6968 unsigned char *outmsg = begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2161 maya 3227
2162 doda 6968 set_uint32(outmsg, pvar->ssh_state.receiver_sequence_number - 1);
2163     finish_send_packet(pvar);
2164 maya 3227
2165 doda 6968 logputs(LOG_LEVEL_VERBOSE, __FUNCTION__ ": SSH2_MSG_UNIMPLEMENTED was sent.");
2166     /* XXX need to decompress incoming packet, but how? */
2167 maya 3227 } else {
2168     if (!handler(pvar)) {
2169     deque_handlers(pvar, message);
2170     }
2171     }
2172     }
2173     }
2174    
2175     static BOOL handle_pty_success(PTInstVar pvar)
2176     {
2177     FWD_enter_interactive_mode(pvar);
2178     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2179     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2180     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2181     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2182 doda 6967 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF, handle_channel_input_eof);
2183     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, handle_channel_output_eof);
2184 maya 3227 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2185     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2186     enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2187     return FALSE;
2188     }
2189    
2190     static BOOL handle_pty_failure(PTInstVar pvar)
2191     {
2192     UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2193     "The server cannot allocate a pseudo-terminal. "
2194     "You may encounter some problems with the terminal.");
2195     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2196     return handle_pty_success(pvar);
2197     }
2198    
2199     static void prep_pty(PTInstVar pvar)
2200     {
2201     int len = strlen(pvar->ts->TermType);
2202 doda 6967 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY, 4 + len + 16 + sizeof(ssh_ttymodes));
2203 maya 3227 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2204     static const SSHPacketHandler handlers[]
2205     = { handle_pty_success, handle_pty_failure };
2206 doda 6799 int x, y;
2207 maya 3227
2208 doda 6799 get_window_pixel_size(pvar, &x, &y);
2209    
2210 maya 3227 set_uint32(outmsg, len);
2211     memcpy(outmsg + 4, pvar->ts->TermType, len);
2212     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2213     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2214 doda 6799 set_uint32(outmsg + 4 + len + 8, x);
2215     set_uint32(outmsg + 4 + len + 12, y);
2216 maya 3227 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2217     finish_send_packet(pvar);
2218    
2219     enque_handlers(pvar, 2, msgs, handlers);
2220    
2221     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2222     finish_send_packet(pvar);
2223     }
2224    
2225     static BOOL handle_agent_request_success(PTInstVar pvar)
2226     {
2227     pvar->agentfwd_enable = TRUE;
2228     prep_pty(pvar);
2229     return FALSE;
2230     }
2231    
2232     static BOOL handle_agent_request_failure(PTInstVar pvar)
2233     {
2234     prep_pty(pvar);
2235     return FALSE;
2236     }
2237    
2238     static void prep_agent_request(PTInstVar pvar)
2239     {
2240     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2241 doda 6967 static const SSHPacketHandler handlers[] = { handle_agent_request_success, handle_agent_request_failure };
2242 maya 3227
2243     enque_handlers(pvar, 2, msgs, handlers);
2244    
2245     begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2246     finish_send_packet(pvar);
2247     }
2248    
2249     static void prep_forwarding(PTInstVar pvar)
2250     {
2251     FWD_prep_forwarding(pvar);
2252    
2253     if (pvar->session_settings.ForwardAgent) {
2254     prep_agent_request(pvar);
2255     }
2256     else {
2257     prep_pty(pvar);
2258     }
2259     }
2260    
2261     //
2262     //
2263     // (2005.7.10 yutaka)
2264     static void enable_send_compression(PTInstVar pvar)
2265     {
2266     static int initialize = 0;
2267    
2268     if (initialize) {
2269     deflateEnd(&pvar->ssh_state.compress_stream);
2270     }
2271     initialize = 1;
2272    
2273     pvar->ssh_state.compress_stream.zalloc = NULL;
2274     pvar->ssh_state.compress_stream.zfree = NULL;
2275     pvar->ssh_state.compress_stream.opaque = NULL;
2276 doda 6967 if (deflateInit(&pvar->ssh_state.compress_stream, pvar->ssh_state.compression_level) != Z_OK) {
2277 maya 3227 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2278     "An error occurred while setting up compression.\n"
2279     "The connection will close.");
2280 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2281 maya 3227 return;
2282     } else {
2283     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2284     if (SSHv2(pvar)) {
2285     pvar->ssh_state.compressing = FALSE;
2286     } else {
2287     pvar->ssh_state.compressing = TRUE;
2288     }
2289     }
2290     }
2291    
2292     static void enable_recv_compression(PTInstVar pvar)
2293     {
2294     static int initialize = 0;
2295    
2296     if (initialize) {
2297     deflateEnd(&pvar->ssh_state.decompress_stream);
2298     }
2299     initialize = 1;
2300    
2301     pvar->ssh_state.decompress_stream.zalloc = NULL;
2302     pvar->ssh_state.decompress_stream.zfree = NULL;
2303     pvar->ssh_state.decompress_stream.opaque = NULL;
2304     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2305     deflateEnd(&pvar->ssh_state.compress_stream);
2306     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2307     "An error occurred while setting up compression.\n"
2308     "The connection will close.");
2309 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2310 maya 3227 return;
2311     } else {
2312     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2313     if (SSHv2(pvar)) {
2314     pvar->ssh_state.decompressing = FALSE;
2315     } else {
2316     pvar->ssh_state.decompressing = TRUE;
2317     }
2318    
2319 doda 6967 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf, &pvar->ssh_state.postdecompress_inbuflen, 1000);
2320 maya 3227 }
2321     }
2322    
2323     static void enable_compression(PTInstVar pvar)
2324     {
2325     enable_send_compression(pvar);
2326     enable_recv_compression(pvar);
2327    
2328     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2329     if (SSHv2(pvar)) {
2330     pvar->ssh_state.compressing = FALSE;
2331     pvar->ssh_state.decompressing = FALSE;
2332     }
2333     }
2334    
2335     static BOOL handle_enable_compression(PTInstVar pvar)
2336     {
2337     enable_compression(pvar);
2338     prep_forwarding(pvar);
2339     return FALSE;
2340     }
2341    
2342     static BOOL handle_disable_compression(PTInstVar pvar)
2343     {
2344     prep_forwarding(pvar);
2345     return FALSE;
2346     }
2347    
2348     static void prep_compression(PTInstVar pvar)
2349     {
2350     if (pvar->session_settings.CompressionLevel > 0) {
2351     // added if statement (2005.7.10 yutaka)
2352     if (SSHv1(pvar)) {
2353     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2354 doda 6967 static const SSHPacketHandler handlers[] = { handle_enable_compression, handle_disable_compression };
2355 maya 3227
2356 doda 6967 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2357 maya 3227
2358     set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2359     finish_send_packet(pvar);
2360    
2361     enque_handlers(pvar, 2, msgs, handlers);
2362     }
2363    
2364 doda 6967 pvar->ssh_state.compression_level = pvar->session_settings.CompressionLevel;
2365 maya 3227
2366     } else {
2367     // added if statement (2005.7.10 yutaka)
2368     if (SSHv1(pvar)) {
2369     prep_forwarding(pvar);
2370     }
2371     }
2372     }
2373    
2374     static void enque_simple_auth_handlers(PTInstVar pvar)
2375     {
2376     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2377 doda 6967 static const SSHPacketHandler handlers[] = { handle_auth_success, handle_auth_failure };
2378 maya 3227
2379     enque_handlers(pvar, 2, msgs, handlers);
2380     }
2381    
2382     static BOOL handle_rsa_challenge(PTInstVar pvar)
2383     {
2384     int challenge_bytes;
2385    
2386     if (!grab_payload(pvar, 2)) {
2387     return FALSE;
2388     }
2389    
2390