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 7134 - (hide annotations) (download) (as text)
Thu Jun 14 10:57:17 2018 UTC (5 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 271212 byte(s)
Local to Remote の scp で、scp 先 path を host:/some/where とした時に
相手先で host への ssh 接続を行い、そこで scp を起動するようにした。

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