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 9210 - (hide annotations) (download) (as text)
Sat Apr 17 08:36:59 2021 UTC (2 years, 11 months ago) by nmaya
File MIME type: text/x-csrc
File size: 280309 byte(s)
ファイルを分割・コードを移動・関数名を整理・新しい OpenSSH からインポート

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