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