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