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 6984 - (hide annotations) (download) (as text)
Sat Nov 25 15:26:39 2017 UTC (6 years, 4 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 267164 byte(s)
ssh の暗号方式関連のコード整理

・暗号関連のパラメータ取得で、暗号方式が見つからなかった時(通常は無い)に
  未初期化の変数の値を返していたのを修正。
・条件分岐の簡略化
・不用な条件分岐/代入を削除
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     * etm - MAC ������ EtM �����������t���O
788     */
789    
790 doda 6983 static int prep_packet_ssh2(PTInstVar pvar, char *data, unsigned int len, int etm)
791 doda 6968 {
792 doda 6983 unsigned int padding;
793    
794 doda 6969 if (etm) {
795 doda 6972 // EtM ������������ MAC ���������s��
796 doda 6969 if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) {
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 maya 3227
802 doda 6972 // �p�P�b�g������(����4�o�C�g)�������������������������A�������X�L�b�v�������������B
803 doda 6969 CRYPT_decrypt(pvar, data + 4, len);
804 doda 6968 }
805 doda 6969 else {
806 doda 6972 // E&M �����������������O���������������B
807     // ���O�������������������������B
808 doda 6982 unsigned int already_decrypted = get_predecryption_amount(pvar);
809 maya 3227
810 doda 6972 // ���O�����������������X�L�b�v�����A�c�������������������B
811 doda 6969 CRYPT_decrypt(pvar, data + already_decrypted, (4 + len) - already_decrypted);
812    
813 doda 6972 // E&M ������������ MAC ���������s���B
814 doda 6969 if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) {
815     UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating.");
816     notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
817     return SSH_MSG_NONE;
818     }
819     }
820    
821 doda 6983 // �p�f�B���O��������
822     padding = (unsigned int) data[4];
823    
824 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������
825     pvar->ssh_state.payload = data + 4 + 1;
826 maya 3227
827 doda 6972 // �p�f�B���O������(1�o�C�g)���p�f�B���O���������������y�C���[�h��
828     pvar->ssh_state.payloadlen = len - 1 - padding;
829    
830 doda 6968 pvar->ssh_state.payload_grabbed = 0;
831 maya 3227
832 doda 6968 // data compression
833     if (pvar->ssh2_keys[MODE_IN].comp.enabled &&
834     (pvar->stoc_compression == COMP_ZLIB ||
835     pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success)) {
836    
837     if (pvar->decomp_buffer == NULL) {
838     pvar->decomp_buffer = buffer_init();
839     if (pvar->decomp_buffer == NULL)
840     return SSH_MSG_NONE;
841 maya 3227 }
842 doda 6968 // ���x�m�������o�b�t�@���g�������������������Y�������B
843     buffer_clear(pvar->decomp_buffer);
844 maya 3227
845 doda 6968 // packet size��padding�������������y�C���[�h�����������W�J�����B
846     buffer_decompress(&pvar->ssh_state.decompress_stream,
847     pvar->ssh_state.payload,
848     pvar->ssh_state.payloadlen,
849     pvar->decomp_buffer);
850    
851     // �|�C���^���X�V�B
852     pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
853     pvar->ssh_state.payload++;
854     pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
855     } else {
856     pvar->ssh_state.payload++;
857 maya 3227 }
858    
859 doda 6968 if (!grab_payload_limited(pvar, 1)) {
860     return SSH_MSG_NONE;
861     }
862    
863 maya 3227 pvar->ssh_state.receiver_sequence_number++;
864    
865     return pvar->ssh_state.payload[-1];
866     }
867    
868     /* Create a packet to be sent. The SSH protocol packet type is in 'type';
869     'len' contains the length of the packet payload, in bytes (this
870     does not include the space for any of the packet headers or padding,
871     or for the packet type byte).
872     Returns a pointer to the payload data area, a region of length 'len',
873     to be filled by the caller. */
874 doda 6801 unsigned char *begin_send_packet(PTInstVar pvar, int type, int len)
875 maya 3227 {
876 doda 6801 unsigned char *buf;
877 maya 3227
878     pvar->ssh_state.outgoing_packet_len = len + 1;
879    
880     if (pvar->ssh_state.compressing) {
881     buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
882     &pvar->ssh_state.precompress_outbuflen, 1 + len);
883     buf = pvar->ssh_state.precompress_outbuf;
884     } else {
885     /* For SSHv2,
886     Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
887     + len(payload) + 4(minpadding), rounded up to nearest block_size
888     We only need a reasonable upper bound for the buffer size */
889     buf_ensure_size(&pvar->ssh_state.outbuf,
890     &pvar->ssh_state.outbuflen,
891 doda 6982 (int)(len + 30 + CRYPT_get_sender_MAC_size(pvar) +
892     CRYPT_get_encryption_block_size(pvar)));
893 maya 3227 buf = pvar->ssh_state.outbuf + 12;
894     }
895    
896     buf[0] = (unsigned char) type;
897     return buf + 1;
898     }
899    
900    
901     // ���M���g���C����������
902     //
903     // WinSock�� send() ���o�b�t�@�T�C�Y(len)�������������l��������������������
904     // ���������������A�����������G���[���������B
905     // �����������ATCP�R�l�N�V�������f�������o���h���B
906     // (2006.12.9 yutaka)
907 doda 6801 static int retry_send_packet(PTInstVar pvar, char *data, int len)
908 maya 3227 {
909     int n;
910     int err;
911    
912     while (len > 0) {
913     n = (pvar->Psend)(pvar->socket, data, len, 0);
914    
915     if (n < 0) {
916     err = WSAGetLastError();
917     if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
918     // send()�����l��0�������A�����G���[������ 10000 �������������A
919     // ���������������������B
920     // PuTTY 0.58���������Q�l�B
921     // (2007.2.4 yutak)
922     return 0; // success
923     }
924     return 1; // error
925     }
926    
927     len -= n;
928     data += n;
929     }
930    
931     return 0; // success
932     }
933    
934 doda 6801 static BOOL send_packet_blocking(PTInstVar pvar, char *data, int len)
935 maya 3227 {
936     // �p�P�b�g���M�����o�b�t�@���g�������������A�u���b�L���O�����M�����������K�v�������B
937     // �m���u���b�L���O�����M����WSAEWOULDBLOCK�����������������A�����o�b�t�@�����M��������
938     // ���������������������������������B(2007.10.30 yutaka)
939     u_long do_block = 0;
940     int code = 0;
941     char *kind = NULL, buf[256];
942    
943 doda 6967 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, 0, 0) == SOCKET_ERROR) {
944     code = WSAGetLastError();
945     kind = "WSAAsyncSelect1";
946     goto error;
947 maya 3227 }
948     if (ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR) {
949 doda 6967 code = WSAGetLastError();
950     kind = "ioctlsocket";
951     goto error;
952 maya 3227 }
953     if (retry_send_packet(pvar, data, len) != 0) {
954 doda 6967 code = WSAGetLastError();
955     kind = "retry_send_packet";
956     goto error;
957 maya 3227 }
958     if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
959     pvar->notification_msg,
960 doda 6967 pvar->notification_events) == SOCKET_ERROR) {
961     code = WSAGetLastError();
962     kind = "WSAAsyncSelect2";
963     goto error;
964 maya 3227 }
965     return TRUE;
966    
967     error:
968     UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
969     "A communications error occurred while sending an SSH packet.\n"
970     "The connection will close. (%s:%d)");
971     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
972     kind, code);
973 maya 5678 notify_fatal_error(pvar, buf, TRUE);
974 maya 3227 return FALSE;
975     }
976    
977     /* if skip_compress is true, then the data has already been compressed
978     into outbuf + 12 */
979 yutakapon 4926 void finish_send_packet_special(PTInstVar pvar, int skip_compress)
980 maya 3227 {
981     unsigned int len = pvar->ssh_state.outgoing_packet_len;
982 doda 6801 unsigned char *data;
983 maya 3227 unsigned int data_length;
984     buffer_t *msg = NULL; // for SSH2 packet compression
985    
986     if (pvar->ssh_state.compressing) {
987     if (!skip_compress) {
988     buf_ensure_size(&pvar->ssh_state.outbuf,
989     &pvar->ssh_state.outbuflen,
990 doda 6967 (int)(len + (len >> 6) + 50 + CRYPT_get_sender_MAC_size(pvar)));
991     pvar->ssh_state.compress_stream.next_in = pvar->ssh_state.precompress_outbuf;
992 maya 3227 pvar->ssh_state.compress_stream.avail_in = len;
993 doda 6967 pvar->ssh_state.compress_stream.next_out = pvar->ssh_state.outbuf + 12;
994     pvar->ssh_state.compress_stream.avail_out = pvar->ssh_state.outbuflen - 12;
995 maya 3227
996     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
997     UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
998     "An error occurred while compressing packet data.\n"
999     "The connection will close.");
1000 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1001 maya 3227 return;
1002     }
1003     }
1004    
1005 doda 6967 len = pvar->ssh_state.outbuflen - 12 - pvar->ssh_state.compress_stream.avail_out;
1006 maya 3227 }
1007    
1008     if (SSHv1(pvar)) {
1009     int padding = 8 - ((len + 4) % 8);
1010    
1011     data = pvar->ssh_state.outbuf + 8 - padding;
1012     data_length = padding + len + 8;
1013    
1014     set_uint32(data, len + 4);
1015     if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
1016     CRYPT_set_random_data(pvar, data + 4, padding);
1017     } else {
1018     memset(data + 4, 0, padding);
1019     }
1020 doda 6967 set_uint32(data + data_length - 4, do_crc(data + 4, data_length - 8));
1021 maya 3227 CRYPT_encrypt(pvar, data + 4, data_length - 4);
1022     } else { //for SSH2(yutaka)
1023 doda 6982 unsigned int block_size = CRYPT_get_encryption_block_size(pvar);
1024 maya 3227 unsigned int encryption_size;
1025     unsigned int padding;
1026     BOOL ret;
1027 doda 6969 struct Mac *mac = &pvar->ssh2_keys[MODE_OUT].mac;
1028 doda 6982 unsigned int aadlen = 0, maclen = 0;
1029 maya 3227
1030     /*
1031     �f�[�^�\��
1032     pvar->ssh_state.outbuf:
1033     offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
1034     <--ignore---> ^^^^^^^^ <---- payload --->
1035 doda 6967 packet length
1036 maya 3227
1037 doda 6967 ^^padding
1038 maya 3227
1039 doda 6967 <---------------------------->
1040     SSH2 sending data on TCP
1041 maya 3227
1042     NOTE:
1043     payload = type(1) + raw-data
1044     len = ssh_state.outgoing_packet_len = payload size
1045     */
1046     // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
1047     // support of "Compression delayed" (2006.6.23 maya)
1048     if ((pvar->ctos_compression == COMP_ZLIB ||
1049     pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
1050     pvar->ssh2_keys[MODE_OUT].comp.enabled) {
1051     // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
1052     msg = buffer_init();
1053     if (msg == NULL) {
1054     // TODO: error check
1055 doda 6824 logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_init returns NULL.");
1056 maya 3227 return;
1057     }
1058    
1059     // ���k�������w�b�_�������y�C���[�h�����B
1060     buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
1061     if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
1062     UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1063     "An error occurred while compressing packet data.\n"
1064     "The connection will close.");
1065 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1066 maya 3227 return;
1067     }
1068     data = buffer_ptr(msg);
1069     len = buffer_len(msg) - 5; // 'len' is overwritten.
1070    
1071     } else {
1072     // �����k
1073     data = pvar->ssh_state.outbuf + 7;
1074     }
1075    
1076     // ���M�p�P�b�g�\�z(input parameter: data, len)
1077     if (block_size < 8) {
1078     block_size = 8;
1079     }
1080    
1081 doda 6969 if (mac && mac->etm) {
1082 doda 6972 // ���������������������AMAC ����������������������
1083 doda 6969 aadlen = 4;
1084     }
1085    
1086     encryption_size = 4 - aadlen + 1 + len;
1087 maya 3227 padding = block_size - (encryption_size % block_size);
1088     if (padding < 4)
1089     padding += block_size;
1090     encryption_size += padding;
1091 doda 6969 set_uint32(data, encryption_size - 4 + aadlen);
1092 maya 3227 data[4] = (unsigned char) padding;
1093 yutakapon 4492 if (msg) {
1094     // �p�P�b�g���k�������A�o�b�t�@���g�������B(2011.6.10 yutaka)
1095     buffer_append_space(msg, padding + EVP_MAX_MD_SIZE);
1096 yutakapon 4495 // realloc()���������A�|�C���^�����������\�������������A���x���������B
1097     data = buffer_ptr(msg);
1098 yutakapon 4492 }
1099 doda 6967
1100 maya 3227 CRYPT_set_random_data(pvar, data + 5 + len, padding);
1101 doda 6969
1102     if (aadlen == 0) {
1103 doda 6972 // E&M �������� MAC ���v�Z����
1104 doda 6969 ret = CRYPT_build_sender_MAC(pvar, pvar->ssh_state.sender_sequence_number,
1105     data, encryption_size, data + encryption_size);
1106     if (ret) {
1107 doda 6972 maclen = CRYPT_get_sender_MAC_size(pvar);
1108 doda 6969 }
1109 maya 3227 }
1110    
1111 doda 5262 // �p�P�b�g�������������BMAC���~�������������O�B
1112 doda 6969 CRYPT_encrypt(pvar, data + aadlen, encryption_size);
1113    
1114     if (aadlen) {
1115 doda 6972 // EtM �������������� MAC ���v�Z����
1116 doda 6969 ret = CRYPT_build_sender_MAC(pvar, pvar->ssh_state.sender_sequence_number,
1117 doda 6972 data, aadlen + encryption_size, data + aadlen + encryption_size);
1118 doda 6969 if (ret) {
1119     maclen = CRYPT_get_sender_MAC_size(pvar);
1120     }
1121     }
1122    
1123 doda 6972 data_length = encryption_size + aadlen + maclen;
1124    
1125     logprintf(150, __FUNCTION__
1126     ": built packet info: aadlen:%d, enclen:%d, padlen:%d, datalen:%d, maclen:%d, mode:%s",
1127     aadlen, encryption_size, padding, data_length, maclen, aadlen ? "EtM" : "E&M");
1128 maya 3227 }
1129    
1130     send_packet_blocking(pvar, data, data_length);
1131    
1132     buffer_free(msg);
1133    
1134     pvar->ssh_state.sender_sequence_number++;
1135    
1136     // ���M�������L�^
1137     pvar->ssh_heartbeat_tick = time(NULL);
1138     }
1139    
1140     static void destroy_packet_buf(PTInstVar pvar)
1141     {
1142     memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1143     if (pvar->ssh_state.compressing) {
1144     memset(pvar->ssh_state.precompress_outbuf, 0,
1145     pvar->ssh_state.precompress_outbuflen);
1146     }
1147     }
1148    
1149     /* The handlers are added to the queue for each message. When one of the
1150     handlers fires, if it returns FALSE, then all handlers in the set are
1151     removed from their queues. */
1152     static void enque_handlers(PTInstVar pvar, int num_msgs,
1153 doda 6801 const int *messages,
1154     const SSHPacketHandler *handlers)
1155 maya 3227 {
1156 doda 6801 SSHPacketHandlerItem *first_item;
1157     SSHPacketHandlerItem *last_item = NULL;
1158 maya 3227 int i;
1159    
1160     for (i = 0; i < num_msgs; i++) {
1161 doda 6801 SSHPacketHandlerItem *item =
1162     (SSHPacketHandlerItem *)
1163 maya 3227 malloc(sizeof(SSHPacketHandlerItem));
1164 doda 6801 SSHPacketHandlerItem *cur_item =
1165 maya 3227 pvar->ssh_state.packet_handlers[messages[i]];
1166    
1167     item->handler = handlers[i];
1168    
1169     if (cur_item == NULL) {
1170     pvar->ssh_state.packet_handlers[messages[i]] = item;
1171     item->next_for_message = item;
1172     item->last_for_message = item;
1173     item->active_for_message = messages[i];
1174     } else {
1175     item->next_for_message = cur_item;
1176     item->last_for_message = cur_item->last_for_message;
1177     cur_item->last_for_message->next_for_message = item;
1178     cur_item->last_for_message = item;
1179     item->active_for_message = -1;
1180     }
1181    
1182     if (last_item != NULL) {
1183     last_item->next_in_set = item;
1184     } else {
1185     first_item = item;
1186     }
1187     last_item = item;
1188     }
1189    
1190     if (last_item != NULL) {
1191     last_item->next_in_set = first_item;
1192     }
1193     }
1194    
1195     static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1196     {
1197 doda 6801 SSHPacketHandlerItem *cur_item =
1198 maya 3227 pvar->ssh_state.packet_handlers[message];
1199    
1200     if (cur_item == NULL) {
1201     return NULL;
1202     } else {
1203     return cur_item->handler;
1204     }
1205     }
1206    
1207     /* Called only by SSH_handle_packet */
1208     static void deque_handlers(PTInstVar pvar, int message)
1209     {
1210 doda 6801 SSHPacketHandlerItem *cur_item =
1211 maya 3227 pvar->ssh_state.packet_handlers[message];
1212 doda 6801 SSHPacketHandlerItem *first_item_in_set = cur_item;
1213 maya 3227
1214     if (cur_item == NULL)
1215     return;
1216    
1217     do {
1218 doda 6801 SSHPacketHandlerItem *next_in_set = cur_item->next_in_set;
1219 maya 3227
1220     if (cur_item->active_for_message >= 0) {
1221 doda 6801 SSHPacketHandlerItem *replacement =
1222 maya 3227 cur_item->next_for_message;
1223    
1224     if (replacement == cur_item) {
1225     replacement = NULL;
1226     } else {
1227     replacement->active_for_message =
1228     cur_item->active_for_message;
1229     }
1230     pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1231     replacement;
1232     }
1233     cur_item->next_for_message->last_for_message =
1234     cur_item->last_for_message;
1235     cur_item->last_for_message->next_for_message =
1236     cur_item->next_for_message;
1237    
1238     free(cur_item);
1239     cur_item = next_in_set;
1240     } while (cur_item != first_item_in_set);
1241     }
1242    
1243     static void enque_handler(PTInstVar pvar, int message,
1244     SSHPacketHandler handler)
1245     {
1246     enque_handlers(pvar, 1, &message, &handler);
1247     }
1248    
1249 doda 6801 static void chop_newlines(char *buf)
1250 maya 3227 {
1251     int len = strlen(buf);
1252    
1253     while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1254     buf[len - 1] = 0;
1255     len--;
1256     }
1257     }
1258    
1259     /********************/
1260     /* Message handlers */
1261     /********************/
1262    
1263     static BOOL handle_forwarding_success(PTInstVar pvar)
1264     {
1265     return FALSE;
1266     }
1267    
1268     static BOOL handle_forwarding_failure(PTInstVar pvar)
1269     {
1270     return FALSE;
1271     }
1272    
1273     static void enque_forwarding_request_handlers(PTInstVar pvar)
1274     {
1275     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1276     static const SSHPacketHandler handlers[]
1277     = { handle_forwarding_success, handle_forwarding_failure };
1278    
1279     enque_handlers(pvar, 2, msgs, handlers);
1280     }
1281    
1282     static BOOL handle_auth_failure(PTInstVar pvar)
1283     {
1284 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Authentication failed");
1285 maya 3227
1286     // retry count������ (2005.7.15 yutaka)
1287     pvar->userauth_retry_count++;
1288    
1289     AUTH_set_generic_mode(pvar);
1290     AUTH_advance_to_next_cred(pvar);
1291     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1292     try_send_credentials(pvar);
1293     return FALSE;
1294     }
1295    
1296     static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1297     {
1298     if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1299     if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1300     // �S�������������I������
1301     safefree(pvar->pageant_key);
1302     }
1303     else {
1304     // ������������
1305     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1306     try_send_credentials(pvar);
1307     return TRUE;
1308     }
1309     }
1310     AUTH_destroy_cur_cred(pvar);
1311     return handle_auth_failure(pvar);
1312     }
1313    
1314     static BOOL handle_TIS_challenge(PTInstVar pvar)
1315     {
1316     if (grab_payload(pvar, 4)) {
1317     int len = get_payload_uint32(pvar, 0);
1318    
1319     if (grab_payload(pvar, len)) {
1320 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Received TIS challenge");
1321 maya 3227
1322     AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1323     AUTH_advance_to_next_cred(pvar);
1324     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1325     try_send_credentials(pvar);
1326     }
1327     }
1328     return FALSE;
1329     }
1330    
1331     static BOOL handle_auth_required(PTInstVar pvar)
1332     {
1333 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Server requires authentication");
1334 maya 3227
1335     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1336     try_send_credentials(pvar);
1337     /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1338    
1339     return FALSE;
1340     }
1341    
1342     static BOOL handle_ignore(PTInstVar pvar)
1343     {
1344     if (SSHv1(pvar)) {
1345 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_IGNORE was received.");
1346 maya 3227
1347     if (grab_payload(pvar, 4)
1348     && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1349     /* ignore it! but it must be decompressed */
1350     }
1351     }
1352     else {
1353 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_IGNORE was received.");
1354 maya 3227
1355     // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1356     // Cisco ���[�^���� (2006.11.28 maya)
1357     }
1358     return TRUE;
1359     }
1360    
1361     static BOOL handle_debug(PTInstVar pvar)
1362     {
1363     BOOL always_display;
1364 doda 6801 char *description;
1365 maya 3227 int description_len;
1366     char buf[2048];
1367    
1368     if (SSHv1(pvar)) {
1369 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_DEBUG was received.");
1370 maya 3227
1371     if (grab_payload(pvar, 4)
1372     && grab_payload(pvar, description_len =
1373     get_payload_uint32(pvar, 0))) {
1374     always_display = FALSE;
1375     description = pvar->ssh_state.payload + 4;
1376     description[description_len] = 0;
1377     } else {
1378     return TRUE;
1379     }
1380     } else {
1381 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_DEBUG was received.");
1382 maya 3227
1383     if (grab_payload(pvar, 5)
1384     && grab_payload(pvar,
1385     (description_len = get_payload_uint32(pvar, 1)) + 4)
1386     && grab_payload(pvar,
1387     get_payload_uint32(pvar, 5 + description_len))) {
1388     always_display = pvar->ssh_state.payload[0] != 0;
1389     description = pvar->ssh_state.payload + 5;
1390     description[description_len] = 0;
1391     } else {
1392     return TRUE;
1393     }
1394     }
1395    
1396     chop_newlines(description);
1397     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1398     description);
1399     if (always_display) {
1400     notify_nonfatal_error(pvar, buf);
1401     } else {
1402 doda 6809 logputs(LOG_LEVEL_VERBOSE, buf);
1403 maya 3227 }
1404     return TRUE;
1405     }
1406    
1407     static BOOL handle_disconnect(PTInstVar pvar)
1408     {
1409     int reason_code;
1410 doda 6801 char *description;
1411 maya 3227 int description_len;
1412     char buf[2048];
1413 doda 6801 char *explanation = "";
1414 maya 3227 char uimsg[MAX_UIMSG];
1415    
1416     if (SSHv1(pvar)) {
1417 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_DISCONNECT was received.");
1418 maya 3227
1419     if (grab_payload(pvar, 4)
1420     && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1421     reason_code = -1;
1422     description = pvar->ssh_state.payload + 4;
1423     description[description_len] = 0;
1424     } else {
1425     return TRUE;
1426     }
1427     } else {
1428 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_DISCONNECT was received.");
1429 maya 3227
1430     if (grab_payload(pvar, 8)
1431     && grab_payload(pvar,
1432     (description_len = get_payload_uint32(pvar, 4)) + 4)
1433     && grab_payload(pvar,
1434     get_payload_uint32(pvar, 8 + description_len))) {
1435     reason_code = get_payload_uint32(pvar, 0);
1436     description = pvar->ssh_state.payload + 8;
1437     description[description_len] = 0;
1438     } else {
1439     return TRUE;
1440     }
1441     }
1442    
1443     chop_newlines(description);
1444     if (description[0] == 0) {
1445     description = NULL;
1446     }
1447    
1448     if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1449     UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1450     "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1451     "This often happens when someone is already forwarding that port from the server.");
1452     strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1453     explanation = uimsg;
1454     }
1455    
1456     if (description != NULL) {
1457     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1458     "Server disconnected with message '%s'%s");
1459     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1460     pvar->ts->UIMsg, description,
1461     explanation);
1462     } else {
1463     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1464     "Server disconnected (no reason given).%s");
1465     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1466     pvar->ts->UIMsg, explanation);
1467     }
1468    
1469 maya 5678 if (SSHv2(pvar)) {
1470     // SSH2_MSG_DISCONNECT �������������������������M��������������
1471     notify_fatal_error(pvar, buf, FALSE);
1472     }
1473     else {
1474     // SSH1 ���������d�l�����������������A���O����������������
1475     notify_fatal_error(pvar, buf, TRUE);
1476     }
1477    
1478 maya 3227 return TRUE;
1479     }
1480    
1481     static BOOL handle_unimplemented(PTInstVar pvar)
1482     {
1483     /* Should never receive this since we only send base 2.0 protocol messages */
1484     grab_payload(pvar, 4);
1485     return TRUE;
1486     }
1487    
1488     static BOOL handle_crypt_success(PTInstVar pvar)
1489     {
1490 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Secure mode successfully achieved");
1491 maya 3227 return FALSE;
1492     }
1493    
1494     static BOOL handle_noauth_success(PTInstVar pvar)
1495     {
1496 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Server does not require authentication");
1497 maya 3227 prep_compression(pvar);
1498     return FALSE;
1499     }
1500    
1501     static BOOL handle_auth_success(PTInstVar pvar)
1502     {
1503 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Authentication accepted");
1504 maya 3227 prep_compression(pvar);
1505    
1506     // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1507     start_ssh_heartbeat_thread(pvar);
1508    
1509     return FALSE;
1510     }
1511    
1512     static BOOL handle_server_public_key(PTInstVar pvar)
1513     {
1514     int server_key_public_exponent_len;
1515     int server_key_public_modulus_pos;
1516     int server_key_public_modulus_len;
1517     int host_key_bits_pos;
1518     int host_key_public_exponent_len;
1519     int host_key_public_modulus_pos;
1520     int host_key_public_modulus_len;
1521     int protocol_flags_pos;
1522     int supported_ciphers;
1523 doda 6801 char *inmsg;
1524 maya 3227 Key hostkey;
1525     int supported_types;
1526    
1527 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_SMSG_PUBLIC_KEY was received.");
1528 maya 3227
1529     if (!grab_payload(pvar, 14))
1530     return FALSE;
1531     server_key_public_exponent_len = get_mpint_len(pvar, 12);
1532    
1533     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1534     return FALSE;
1535     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1536     server_key_public_modulus_len =
1537     get_mpint_len(pvar, server_key_public_modulus_pos);
1538    
1539     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1540     return FALSE;
1541     host_key_bits_pos =
1542     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1543     host_key_public_exponent_len =
1544     get_mpint_len(pvar, host_key_bits_pos + 4);
1545    
1546     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1547     return FALSE;
1548     host_key_public_modulus_pos =
1549     host_key_bits_pos + 6 + host_key_public_exponent_len;
1550     host_key_public_modulus_len =
1551     get_mpint_len(pvar, host_key_public_modulus_pos);
1552    
1553     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1554     return FALSE;
1555     protocol_flags_pos =
1556     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1557    
1558     inmsg = pvar->ssh_state.payload;
1559    
1560     CRYPT_set_server_cookie(pvar, inmsg);
1561     if (!CRYPT_set_server_RSA_key(pvar,
1562     get_uint32(inmsg + 8),
1563     pvar->ssh_state.payload + 12,
1564     inmsg + server_key_public_modulus_pos))
1565     return FALSE;
1566     if (!CRYPT_set_host_RSA_key(pvar,
1567     get_uint32(inmsg + host_key_bits_pos),
1568     inmsg + host_key_bits_pos + 4,
1569     inmsg + host_key_public_modulus_pos))
1570     return FALSE;
1571     pvar->ssh_state.server_protocol_flags =
1572     get_uint32(inmsg + protocol_flags_pos);
1573    
1574     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1575     if (!CRYPT_set_supported_ciphers(pvar,
1576     supported_ciphers,
1577     supported_ciphers))
1578     return FALSE;
1579    
1580     // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1581     // RSA ���L������ PAGEANT ���L��������
1582     supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1583     if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1584     supported_types |= (1 << SSH_AUTH_PAGEANT);
1585     }
1586     if (!AUTH_set_supported_auth_types(pvar,
1587     supported_types))
1588     return FALSE;
1589    
1590     /* this must be the LAST THING in this function, since it can cause
1591     host_is_OK to be called. */
1592     hostkey.type = KEY_RSA1;
1593     hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1594     hostkey.exp = inmsg + host_key_bits_pos + 4;
1595     hostkey.mod = inmsg + host_key_public_modulus_pos;
1596     HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1597    
1598     return FALSE;
1599     }
1600    
1601     /*
1602     The ID must have already been found to start with "SSH-". It must
1603     be null-terminated.
1604     */
1605 doda 6801 static BOOL parse_protocol_ID(PTInstVar pvar, char *ID)
1606 maya 3227 {
1607 doda 6801 char *str;
1608 maya 3227
1609     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1610     }
1611    
1612     if (*str != '.') {
1613     return FALSE;
1614     }
1615    
1616     pvar->protocol_major = atoi(ID + 4);
1617     pvar->protocol_minor = atoi(str + 1);
1618    
1619     for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1620     }
1621    
1622     return *str == '-';
1623     }
1624    
1625     /*
1626     On entry, the pvar->protocol_xxx fields hold the server's advertised
1627     protocol number. We replace the fields with the protocol number we will
1628     actually use, or return FALSE if there is no usable protocol version.
1629     */
1630 maya 4682 static int negotiate_protocol(PTInstVar pvar)
1631 maya 3227 {
1632     switch (pvar->protocol_major) {
1633     case 1:
1634 maya 4682 if (pvar->protocol_minor == 99 &&
1635     pvar->settings.ssh_protocol_version == 2) {
1636     // �T�[�o�� 1.99 �����[�U�� SSH2 ���I������������������
1637     // 2.0 ����������
1638     pvar->protocol_major = 2;
1639     pvar->protocol_minor = 0;
1640     return 0;
1641     }
1642    
1643     if (pvar->settings.ssh_protocol_version == 2) {
1644     // �o�[�W��������
1645     return -1;
1646     }
1647    
1648 maya 3227 if (pvar->protocol_minor > 5) {
1649     pvar->protocol_minor = 5;
1650     }
1651    
1652 maya 4682 return 0;
1653 maya 3227
1654     // for SSH2(yutaka)
1655     case 2:
1656 maya 4682 if (pvar->settings.ssh_protocol_version == 1) {
1657     // �o�[�W��������
1658     return -1;
1659     }
1660 maya 3227
1661 maya 4682 return 0; // SSH2 support
1662    
1663 maya 3227 default:
1664 maya 4682 return 1;
1665 maya 3227 }
1666     }
1667    
1668     static void init_protocol(PTInstVar pvar)
1669     {
1670     CRYPT_initialize_random_numbers(pvar);
1671    
1672     // known_hosts�t�@�C�������z�X�g���J������������������
1673     HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1674    
1675     /* while we wait for a response from the server... */
1676    
1677     if (SSHv1(pvar)) {
1678     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1679     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1680     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1681     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1682    
1683     } else { // for SSH2(yutaka)
1684     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1685     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1686     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1687     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1688     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1689     enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1690     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1691     enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1692     enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1693     enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1694     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1695     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1696 doda 6657 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_msg60);
1697 maya 3227
1698     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1699    
1700     // ���[�U�F�������f�B�X�p�b�`���[�`��
1701     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1702     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1703     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1704     enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1705     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1706     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1707     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1708     enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1709     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1710     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1711     enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1712 yutakapon 5829 enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_SSH2_client_global_request);
1713 maya 3227 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1714     enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1715    
1716 yutakapon 5850 client_init_global_confirm();
1717    
1718 maya 3227 }
1719     }
1720    
1721 doda 5928 void server_version_check(PTInstVar pvar)
1722     {
1723     char *server_swver;
1724    
1725     pvar->server_compat_flag = 0;
1726    
1727     if ((server_swver = strchr(pvar->server_version_string+4, '-')) == NULL) {
1728 doda 6809 logputs(LOG_LEVEL_WARNING, "Can't get server software version string.");
1729 doda 5928 return;
1730     }
1731     server_swver++;
1732    
1733     if (strncmp(server_swver, "Cisco-1", 7) == 0) {
1734     pvar->server_compat_flag |= SSH_BUG_DHGEX_LARGE;
1735 doda 6809 logputs(LOG_LEVEL_INFO, "Server version string is matched to \"Cisco-1\", compatibility flag SSH_BUG_DHGEX_LARGE is enabled.");
1736 doda 5928 }
1737     }
1738    
1739 doda 6801 BOOL SSH_handle_server_ID(PTInstVar pvar, char *ID, int ID_len)
1740 maya 3227 {
1741 maya 4546 static char prefix[64];
1742 maya 4682 int negotiate;
1743     char uimsg[MAX_UIMSG];
1744 maya 3227
1745     // initialize SSH2 memory dump (2005.3.7 yutaka)
1746     init_memdump();
1747     push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1748    
1749     if (ID_len <= 0) {
1750     return FALSE;
1751     } else {
1752 maya 4546 int buf_len;
1753 doda 6801 char *buf;
1754 maya 3227
1755 maya 4546 strncpy_s(prefix, sizeof(prefix), "Received server identification string: ", _TRUNCATE);
1756     buf_len = strlen(prefix) + ID_len + 1;
1757 doda 6801 buf = (char *) malloc(buf_len);
1758 maya 3227 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1759     strncat_s(buf, buf_len, ID, _TRUNCATE);
1760     chop_newlines(buf);
1761 doda 6809 logputs(LOG_LEVEL_VERBOSE, buf);
1762 maya 3227 free(buf);
1763    
1764     if (ID[ID_len - 1] != '\n') {
1765     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1766     return FALSE;
1767     } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1768     pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1769     return FALSE;
1770     } else if (strncmp(ID, "SSH-", 4) != 0) {
1771     return FALSE;
1772     } else {
1773     ID[ID_len - 1] = 0;
1774    
1775     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1776     ID[ID_len - 2] = 0;
1777     }
1778    
1779     pvar->ssh_state.server_ID = _strdup(ID);
1780    
1781 maya 4682 if (!parse_protocol_ID(pvar, ID)) {
1782 maya 3227 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1783     "This program does not understand the server's version of the protocol.");
1784 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1785 maya 4682 }
1786     else if ((negotiate = negotiate_protocol(pvar)) == 1) {
1787     UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1788     "This program does not understand the server's version of the protocol.");
1789 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1790 maya 4682 }
1791     else if (negotiate == -1) {
1792     UTIL_get_lang_msg("MSG_SSH_VERSION_MISMATCH", pvar,
1793     "Protocol version mismatch. server:%d.%d client:%d");
1794     _snprintf_s(uimsg, sizeof(uimsg), _TRUNCATE, pvar->ts->UIMsg,
1795     pvar->protocol_major, pvar->protocol_minor, pvar->settings.ssh_protocol_version);
1796 maya 5678 notify_fatal_error(pvar, uimsg, TRUE);
1797 maya 4682 }
1798     else {
1799 maya 3227 char TTSSH_ID[1024];
1800     int TTSSH_ID_len;
1801    
1802 maya 4682 // SSH �o�[�W������ teraterm �����Z�b�g����
1803     // SCP �R�}���h������ (2008.2.3 maya)
1804     pvar->cv->isSSH = pvar->protocol_major;
1805    
1806 maya 3227 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1807     _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1808 maya 4656 "SSH-%d.%d-TTSSH/%d.%d Win32\r\n",
1809 doda 6835 pvar->protocol_major, pvar->protocol_minor,
1810     TTSSH_VERSION_MAJOR, TTSSH_VERSION_MINOR);
1811 maya 3227 TTSSH_ID_len = strlen(TTSSH_ID);
1812    
1813     // for SSH2(yutaka)
1814     // �N���C�A���g�o�[�W�����������i���s���������������j
1815     strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1816     TTSSH_ID, _TRUNCATE);
1817    
1818     // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1819     _snprintf_s(pvar->server_version_string,
1820     sizeof(pvar->server_version_string), _TRUNCATE,
1821     "%s", pvar->ssh_state.server_ID);
1822    
1823 doda 5928 // �T�[�o�o�[�W�������`�F�b�N
1824     server_version_check(pvar);
1825    
1826 doda 6809 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len, 0) != TTSSH_ID_len) {
1827 maya 3227 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1828     "An error occurred while sending the SSH ID string.\n"
1829     "The connection will close.");
1830 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1831 maya 3227 } else {
1832 doda 6809 // ���s������
1833     chop_newlines(pvar->client_version_string);
1834     logprintf(LOG_LEVEL_VERBOSE, "Sent client identification string: %s", pvar->client_version_string);
1835 maya 3227
1836     push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1837     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1838    
1839     // SSH�n���h�����o�^���s��
1840     init_protocol(pvar);
1841    
1842     SSH2_dispatch_init(1);
1843     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1844     SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1845 maya 4867 SSH2_dispatch_add_message(SSH2_MSG_DEBUG);
1846 maya 3227 }
1847     }
1848    
1849     return TRUE;
1850     }
1851     }
1852     }
1853    
1854     static BOOL handle_exit(PTInstVar pvar)
1855     {
1856     if (grab_payload(pvar, 4)) {
1857     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1858     finish_send_packet(pvar);
1859 maya 5678 notify_closed_connection(pvar, "disconnected by server request");
1860 maya 3227 }
1861     return TRUE;
1862     }
1863    
1864     static BOOL handle_data(PTInstVar pvar)
1865     {
1866     if (grab_payload_limited(pvar, 4)) {
1867     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1868     pvar->ssh_state.payload_datastart = 4;
1869     }
1870     return TRUE;
1871     }
1872    
1873     static BOOL handle_channel_open(PTInstVar pvar)
1874     {
1875     int host_len;
1876     int originator_len;
1877    
1878     if ((pvar->ssh_state.
1879     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1880     if (grab_payload(pvar, 8)
1881     && grab_payload(pvar,
1882     8 + (host_len = get_payload_uint32(pvar, 4)))
1883     && grab_payload(pvar, originator_len =
1884     get_payload_uint32(pvar, host_len + 12))) {
1885     int local_port = get_payload_uint32(pvar, 8 + host_len);
1886    
1887     pvar->ssh_state.payload[8 + host_len] = 0;
1888     FWD_open(pvar, get_payload_uint32(pvar, 0),
1889     pvar->ssh_state.payload + 8, local_port,
1890     pvar->ssh_state.payload + 16 + host_len,
1891     originator_len,
1892     NULL);
1893     }
1894     } else {
1895     if (grab_payload(pvar, 8)
1896     && grab_payload(pvar,
1897     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1898     int local_port = get_payload_uint32(pvar, 8 + host_len);
1899    
1900     pvar->ssh_state.payload[8 + host_len] = 0;
1901     FWD_open(pvar, get_payload_uint32(pvar, 0),
1902     pvar->ssh_state.payload + 8, local_port, NULL, 0,
1903     NULL);
1904     }
1905     }
1906    
1907     return TRUE;
1908     }
1909    
1910     static BOOL handle_X11_channel_open(PTInstVar pvar)
1911     {
1912     int originator_len;
1913    
1914     if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1915     if (grab_payload(pvar, 8)
1916     && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1917     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1918     pvar->ssh_state.payload + 8, originator_len, NULL);
1919     }
1920     } else {
1921     if (grab_payload(pvar, 4)) {
1922     FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1923     }
1924     }
1925    
1926     return TRUE;
1927     }
1928    
1929     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1930     {
1931     if (grab_payload(pvar, 8)) {
1932     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1933     get_payload_uint32(pvar, 4));
1934     }
1935     return FALSE;
1936     }
1937    
1938     static BOOL handle_channel_open_failure(PTInstVar pvar)
1939     {
1940     if (grab_payload(pvar, 4)) {
1941 doda 6844 FWD_failed_open(pvar, get_payload_uint32(pvar, 0), -1);
1942 maya 3227 }
1943     return FALSE;
1944     }
1945    
1946     static BOOL handle_channel_data(PTInstVar pvar)
1947     {
1948     int len;
1949    
1950     if (grab_payload(pvar, 8)
1951     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1952     FWDChannel *channel;
1953     int local_channel_num = get_payload_uint32(pvar, 0);
1954     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1955     return FALSE;
1956     }
1957     channel = pvar->fwd_state.channels + local_channel_num;
1958     if (channel->type == TYPE_AGENT) {
1959     SSH_agent_response(pvar, NULL, local_channel_num,
1960     pvar->ssh_state.payload + 8, len);
1961     }
1962     else {
1963     FWD_received_data(pvar, local_channel_num,
1964     pvar->ssh_state.payload + 8, len);
1965     }
1966     }
1967     return TRUE;
1968     }
1969    
1970     static BOOL handle_channel_input_eof(PTInstVar pvar)
1971     {
1972     if (grab_payload(pvar, 4)) {
1973     int local_channel_num = get_payload_uint32(pvar, 0);
1974     FWDChannel *channel;
1975     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1976     return FALSE;
1977     }
1978     channel = pvar->fwd_state.channels + local_channel_num;
1979     if (channel->type == TYPE_AGENT) {
1980     channel->status |= FWD_CLOSED_REMOTE_IN;
1981     SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1982     }
1983     else {
1984     FWD_channel_input_eof(pvar, local_channel_num);
1985     }
1986     }
1987     return TRUE;
1988     }
1989    
1990     static BOOL handle_channel_output_eof(PTInstVar pvar)
1991     {
1992     if (grab_payload(pvar, 4)) {
1993     int local_channel_num = get_payload_uint32(pvar, 0);
1994     FWDChannel *channel;
1995     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1996     return FALSE;
1997     }
1998     channel = pvar->fwd_state.channels + local_channel_num;
1999     if (channel->type == TYPE_AGENT) {
2000     channel->status |= FWD_CLOSED_REMOTE_OUT;
2001     SSH_channel_output_eof(pvar, channel->remote_num);
2002     FWD_free_channel(pvar, local_channel_num);
2003     }
2004     else {
2005     FWD_channel_output_eof(pvar, local_channel_num);
2006     }
2007     }
2008     return TRUE;
2009     }
2010    
2011     static BOOL handle_agent_open(PTInstVar pvar)
2012     {
2013     if (grab_payload(pvar, 4)) {
2014     int remote_id = get_payload_uint32(pvar, 0);
2015     int local_id;
2016    
2017 doda 4233 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
2018 maya 3227 local_id = FWD_agent_open(pvar, remote_id);
2019     if (local_id == -1) {
2020     SSH_fail_channel_open(pvar, remote_id);
2021     }
2022     else {
2023     SSH_confirm_channel_open(pvar, remote_id, local_id);
2024     }
2025     }
2026     else {
2027     SSH_fail_channel_open(pvar, remote_id);
2028     }
2029     }
2030     /*
2031     else {
2032     // ���m��������channel����������������������������
2033     }
2034     */
2035    
2036     return TRUE;
2037     }
2038    
2039    
2040    
2041     // �n���h�����O�������b�Z�[�W����������
2042    
2043     #define HANDLE_MESSAGE_MAX 30
2044     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
2045     static int handle_message_count = 0;
2046     static int handle_message_stage = 0;
2047    
2048     void SSH2_dispatch_init(int stage)
2049     {
2050     handle_message_count = 0;
2051     handle_message_stage = stage;
2052     }
2053    
2054     int SSH2_dispatch_enabled_check(unsigned char message)
2055     {
2056     int i;
2057    
2058     for (i = 0 ; i < handle_message_count ; i++) {
2059     if (handle_messages[i] == message)
2060     return 1;
2061     }
2062     return 0;
2063     }
2064    
2065     void SSH2_dispatch_add_message(unsigned char message)
2066     {
2067     int i;
2068    
2069     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2070     // TODO: error check
2071 doda 6824 logprintf(LOG_LEVEL_ERROR, __FUNCTION__ ": too many handlers. handlers:%d, max:%d",
2072     handle_message_count, HANDLE_MESSAGE_MAX);
2073 maya 3227 return;
2074     }
2075    
2076     // �������o�^�������������b�Z�[�W������������
2077     for (i=0; i<handle_message_count; i++) {
2078     if (handle_messages[i] == message) {
2079     return;
2080     }
2081     }
2082    
2083     handle_messages[handle_message_count++] = message;
2084     }
2085    
2086     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2087     {
2088     unsigned char c;
2089    
2090     for (c = begin ; c <= end ; c++) {
2091     SSH2_dispatch_add_message(c);
2092     }
2093     }
2094    
2095 doda 6982 void SSH1_handle_packet(PTInstVar pvar, char *data, unsigned int len, unsigned int padding)
2096 maya 3227 {
2097 doda 6968 unsigned char message = prep_packet_ssh1(pvar, data, len, padding);
2098 maya 3227
2099     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2100     if (message != SSH_MSG_NONE) {
2101     // ���b�Z�[�W�^�C�v���������n���h�����N��
2102     SSHPacketHandler handler = get_handler(pvar, message);
2103    
2104 doda 6968 if (handler == NULL) {
2105     char buf[1024];
2106 maya 3227
2107 doda 6968 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar, "Unexpected packet type received: %d");
2108     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);
2109     notify_fatal_error(pvar, buf, TRUE);
2110     } else {
2111     if (!handler(pvar)) {
2112     deque_handlers(pvar, message);
2113 maya 3227 }
2114     }
2115 doda 6968 }
2116     }
2117 maya 3227
2118 doda 6983 void SSH2_handle_packet(PTInstVar pvar, char *data, unsigned int len, int etm)
2119 doda 6968 {
2120 doda 6983 unsigned char message = prep_packet_ssh2(pvar, data, len, etm);
2121 doda 6968
2122     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2123     if (message != SSH_MSG_NONE) {
2124     // ���b�Z�[�W�^�C�v���������n���h�����N��
2125     SSHPacketHandler handler = get_handler(pvar, message);
2126    
2127     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2128     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2129     char buf[1024];
2130    
2131     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar, "Unexpected SSH2 message(%d) on current stage(%d)");
2132     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);
2133     notify_fatal_error(pvar, buf, TRUE);
2134     return;
2135     }
2136    
2137 maya 3227 if (handler == NULL) {
2138 doda 6968 unsigned char *outmsg = begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2139 maya 3227
2140 doda 6968 set_uint32(outmsg, pvar->ssh_state.receiver_sequence_number - 1);
2141     finish_send_packet(pvar);
2142 maya 3227
2143 doda 6968 logputs(LOG_LEVEL_VERBOSE, __FUNCTION__ ": SSH2_MSG_UNIMPLEMENTED was sent.");
2144     /* XXX need to decompress incoming packet, but how? */
2145 maya 3227 } else {
2146     if (!handler(pvar)) {
2147     deque_handlers(pvar, message);
2148     }
2149     }
2150     }
2151     }
2152    
2153     static BOOL handle_pty_success(PTInstVar pvar)
2154     {
2155     FWD_enter_interactive_mode(pvar);
2156     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2157     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2158     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2159     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2160 doda 6967 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF, handle_channel_input_eof);
2161     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, handle_channel_output_eof);
2162 maya 3227 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2163     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2164     enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2165     return FALSE;
2166     }
2167    
2168     static BOOL handle_pty_failure(PTInstVar pvar)
2169     {
2170     UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2171     "The server cannot allocate a pseudo-terminal. "
2172     "You may encounter some problems with the terminal.");
2173     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2174     return handle_pty_success(pvar);
2175     }
2176    
2177     static void prep_pty(PTInstVar pvar)
2178     {
2179     int len = strlen(pvar->ts->TermType);
2180 doda 6967 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY, 4 + len + 16 + sizeof(ssh_ttymodes));
2181 maya 3227 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2182     static const SSHPacketHandler handlers[]
2183     = { handle_pty_success, handle_pty_failure };
2184 doda 6799 int x, y;
2185 maya 3227
2186 doda 6799 get_window_pixel_size(pvar, &x, &y);
2187    
2188 maya 3227 set_uint32(outmsg, len);
2189     memcpy(outmsg + 4, pvar->ts->TermType, len);
2190     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2191     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2192 doda 6799 set_uint32(outmsg + 4 + len + 8, x);
2193     set_uint32(outmsg + 4 + len + 12, y);
2194 maya 3227 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2195     finish_send_packet(pvar);
2196    
2197     enque_handlers(pvar, 2, msgs, handlers);
2198    
2199     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2200     finish_send_packet(pvar);
2201     }
2202    
2203     static BOOL handle_agent_request_success(PTInstVar pvar)
2204     {
2205     pvar->agentfwd_enable = TRUE;
2206     prep_pty(pvar);
2207     return FALSE;
2208     }
2209    
2210     static BOOL handle_agent_request_failure(PTInstVar pvar)
2211     {
2212     prep_pty(pvar);
2213     return FALSE;
2214     }
2215    
2216     static void prep_agent_request(PTInstVar pvar)
2217     {
2218     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2219 doda 6967 static const SSHPacketHandler handlers[] = { handle_agent_request_success, handle_agent_request_failure };
2220 maya 3227
2221     enque_handlers(pvar, 2, msgs, handlers);
2222    
2223     begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2224     finish_send_packet(pvar);
2225     }
2226    
2227     static void prep_forwarding(PTInstVar pvar)
2228     {
2229     FWD_prep_forwarding(pvar);
2230    
2231     if (pvar->session_settings.ForwardAgent) {
2232     prep_agent_request(pvar);
2233     }
2234     else {
2235     prep_pty(pvar);
2236     }
2237     }
2238    
2239     //
2240     //
2241     // (2005.7.10 yutaka)
2242     static void enable_send_compression(PTInstVar pvar)
2243     {
2244     static int initialize = 0;
2245    
2246     if (initialize) {
2247     deflateEnd(&pvar->ssh_state.compress_stream);
2248     }
2249     initialize = 1;
2250    
2251     pvar->ssh_state.compress_stream.zalloc = NULL;
2252     pvar->ssh_state.compress_stream.zfree = NULL;
2253     pvar->ssh_state.compress_stream.opaque = NULL;
2254 doda 6967 if (deflateInit(&pvar->ssh_state.compress_stream, pvar->ssh_state.compression_level) != Z_OK) {
2255 maya 3227 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2256     "An error occurred while setting up compression.\n"
2257     "The connection will close.");
2258 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2259 maya 3227 return;
2260     } else {
2261     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2262     if (SSHv2(pvar)) {
2263     pvar->ssh_state.compressing = FALSE;
2264     } else {
2265     pvar->ssh_state.compressing = TRUE;
2266     }
2267     }
2268     }
2269    
2270     static void enable_recv_compression(PTInstVar pvar)
2271     {
2272     static int initialize = 0;
2273    
2274     if (initialize) {
2275     deflateEnd(&pvar->ssh_state.decompress_stream);
2276     }
2277     initialize = 1;
2278    
2279     pvar->ssh_state.decompress_stream.zalloc = NULL;
2280     pvar->ssh_state.decompress_stream.zfree = NULL;
2281     pvar->ssh_state.decompress_stream.opaque = NULL;
2282     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2283     deflateEnd(&pvar->ssh_state.compress_stream);
2284     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2285     "An error occurred while setting up compression.\n"
2286     "The connection will close.");
2287 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2288 maya 3227 return;
2289     } else {
2290     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2291     if (SSHv2(pvar)) {
2292     pvar->ssh_state.decompressing = FALSE;
2293     } else {
2294     pvar->ssh_state.decompressing = TRUE;
2295     }
2296    
2297 doda 6967 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf, &pvar->ssh_state.postdecompress_inbuflen, 1000);
2298 maya 3227 }
2299     }
2300    
2301     static void enable_compression(PTInstVar pvar)
2302     {
2303     enable_send_compression(pvar);
2304     enable_recv_compression(pvar);
2305    
2306     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2307     if (SSHv2(pvar)) {
2308     pvar->ssh_state.compressing = FALSE;
2309     pvar->ssh_state.decompressing = FALSE;
2310     }
2311     }
2312    
2313     static BOOL handle_enable_compression(PTInstVar pvar)
2314     {
2315     enable_compression(pvar);
2316     prep_forwarding(pvar);
2317     return FALSE;
2318     }
2319    
2320     static BOOL handle_disable_compression(PTInstVar pvar)
2321     {
2322     prep_forwarding(pvar);
2323     return FALSE;
2324     }
2325    
2326     static void prep_compression(PTInstVar pvar)
2327     {
2328     if (pvar->session_settings.CompressionLevel > 0) {
2329     // added if statement (2005.7.10 yutaka)
2330     if (SSHv1(pvar)) {
2331     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2332 doda 6967 static const SSHPacketHandler handlers[] = { handle_enable_compression, handle_disable_compression };
2333 maya 3227
2334 doda 6967 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2335 maya 3227
2336     set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2337     finish_send_packet(pvar);
2338    
2339     enque_handlers(pvar, 2, msgs, handlers);
2340     }
2341    
2342 doda 6967 pvar->ssh_state.compression_level = pvar->session_settings.CompressionLevel;
2343 maya 3227
2344     } else {
2345     // added if statement (2005.7.10 yutaka)
2346     if (SSHv1(pvar)) {
2347     prep_forwarding(pvar);
2348     }
2349     }
2350     }
2351    
2352     static void enque_simple_auth_handlers(PTInstVar pvar)
2353     {
2354     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2355 doda 6967 static const SSHPacketHandler handlers[] = { handle_auth_success, handle_auth_failure };
2356 maya 3227
2357     enque_handlers(pvar, 2, msgs, handlers);
2358     }
2359    
2360     static BOOL handle_rsa_challenge(PTInstVar pvar)
2361     {
2362     int challenge_bytes;
2363    
2364     if (!grab_payload(pvar, 2)) {
2365     return FALSE;
2366     }
2367    
2368     challenge_bytes = get_mpint_len(pvar, 0);
2369    
2370     if (grab_payload(pvar, challenge_bytes)) {
2371 doda 6967 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2372 maya 3227
2373     if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2374     if (CRYPT_generate_RSA_challenge_response
2375     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2376    
2377     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2378     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2379     //AUTH_destroy_cur_cred(pvar);
2380    
2381     finish_send_packet(pvar);
2382    
2383     enque_simple_auth_handlers(pvar);
2384     } else {
2385     UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2386     "An error occurred while decrypting the RSA challenge.\n"
2387     "Perhaps the key file is corrupted.");
2388 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2389 maya 3227 }
2390     }
2391     else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2392     int server_key_bits = BN_num_bits(pvar->crypt_state.server_key