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