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 8397 - (hide annotations) (download) (as text)
Fri Nov 22 15:14:57 2019 UTC (4 years, 4 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 288978 byte(s)
必要に応じて SSH 認証バナーのエンコードを変換するようにした。

Ticket: #39724

問題:
  SSH認証バナーにUS-ASCII範囲外の文字が入っていると文字化けする。

対処:
  バナーのエンコードを変換するようにした。

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