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