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 6967 - (hide annotations) (download) (as text)
Thu Nov 2 11:37:33 2017 UTC (6 years, 5 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 265208 byte(s)
コード整理。

・不用なコードを削除
・インデント修正
・改行位置変更
・空行削除
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     static int prep_packet(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     if (SSHv1(pvar)) {
735     if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
736 doda 6967 UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar, "'CORE insertion attack' detected. Aborting connection.");
737 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
738 maya 3227 }
739    
740     CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
741     /* PKT guarantees that the data is always 4-byte aligned */
742 doda 6967 if (do_crc(pvar->ssh_state.payload, len - 4) != get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
743     UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating.");
744 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
745 maya 3227 return SSH_MSG_NONE;
746     }
747    
748     pvar->ssh_state.payload += padding;
749     pvar->ssh_state.payloadlen -= padding + 4;
750     } else {
751     int already_decrypted = get_predecryption_amount(pvar);
752    
753 doda 6967 CRYPT_decrypt(pvar, data + already_decrypted, (4 + len) - already_decrypted);
754 maya 3227
755 doda 6967 if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) {
756 maya 3227 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
757     "Detected corrupted data; connection terminating.");
758 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
759 maya 3227 return SSH_MSG_NONE;
760     }
761    
762     pvar->ssh_state.payload++;
763     pvar->ssh_state.payloadlen -= padding + 1;
764     }
765    
766     pvar->ssh_state.payload_grabbed = 0;
767    
768     if (SSHv1(pvar)) {
769     if (pvar->ssh_state.decompressing) {
770     if (pvar->ssh_state.decompress_stream.avail_in != 0) {
771     UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
772     "Internal error: a packet was not fully decompressed.\n"
773     "This is a bug, please report it.");
774     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
775     }
776    
777 doda 6967 pvar->ssh_state.decompress_stream.next_in = pvar->ssh_state.payload;
778     pvar->ssh_state.decompress_stream.avail_in = pvar->ssh_state.payloadlen;
779     pvar->ssh_state.decompress_stream.next_out = pvar->ssh_state.postdecompress_inbuf;
780 maya 3227 pvar->ssh_state.payloadlen = -1;
781     } else {
782     pvar->ssh_state.payload++;
783     }
784    
785     if (!grab_payload_limited(pvar, 1)) {
786     return SSH_MSG_NONE;
787     }
788    
789     } else {
790     // support of SSH2 packet compression (2005.7.9 yutaka)
791     // support of "Compression delayed" (2006.6.23 maya)
792     if ((pvar->stoc_compression == COMP_ZLIB ||
793     pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&
794     pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
795     int ret;
796    
797     if (pvar->decomp_buffer == NULL) {
798     pvar->decomp_buffer = buffer_init();
799     if (pvar->decomp_buffer == NULL)
800     return SSH_MSG_NONE;
801     }
802     // ���x�m�������o�b�t�@���g�������������������Y�������B
803     buffer_clear(pvar->decomp_buffer);
804    
805     // packet size��padding�������������y�C���[�h�����������W�J�����B
806     ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
807     pvar->ssh_state.payload,
808     pvar->ssh_state.payloadlen,
809     pvar->decomp_buffer);
810    
811     // �|�C���^���X�V�B
812     pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
813     pvar->ssh_state.payload++;
814     pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
815    
816     } else {
817     pvar->ssh_state.payload++;
818     }
819    
820     if (!grab_payload_limited(pvar, 1)) {
821     return SSH_MSG_NONE;
822     }
823    
824     }
825    
826     pvar->ssh_state.receiver_sequence_number++;
827    
828     return pvar->ssh_state.payload[-1];
829     }
830    
831     /* Create a packet to be sent. The SSH protocol packet type is in 'type';
832     'len' contains the length of the packet payload, in bytes (this
833     does not include the space for any of the packet headers or padding,
834     or for the packet type byte).
835     Returns a pointer to the payload data area, a region of length 'len',
836     to be filled by the caller. */
837 doda 6801 unsigned char *begin_send_packet(PTInstVar pvar, int type, int len)
838 maya 3227 {
839 doda 6801 unsigned char *buf;
840 maya 3227
841     pvar->ssh_state.outgoing_packet_len = len + 1;
842    
843     if (pvar->ssh_state.compressing) {
844     buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
845     &pvar->ssh_state.precompress_outbuflen, 1 + len);
846     buf = pvar->ssh_state.precompress_outbuf;
847     } else {
848     /* For SSHv2,
849     Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
850     + len(payload) + 4(minpadding), rounded up to nearest block_size
851     We only need a reasonable upper bound for the buffer size */
852     buf_ensure_size(&pvar->ssh_state.outbuf,
853     &pvar->ssh_state.outbuflen,
854     len + 30 + CRYPT_get_sender_MAC_size(pvar) +
855     CRYPT_get_encryption_block_size(pvar));
856     buf = pvar->ssh_state.outbuf + 12;
857     }
858    
859     buf[0] = (unsigned char) type;
860     return buf + 1;
861     }
862    
863    
864     // ���M���g���C����������
865     //
866     // WinSock�� send() ���o�b�t�@�T�C�Y(len)�������������l��������������������
867     // ���������������A�����������G���[���������B
868     // �����������ATCP�R�l�N�V�������f�������o���h���B
869     // (2006.12.9 yutaka)
870 doda 6801 static int retry_send_packet(PTInstVar pvar, char *data, int len)
871 maya 3227 {
872     int n;
873     int err;
874    
875     while (len > 0) {
876     n = (pvar->Psend)(pvar->socket, data, len, 0);
877    
878     if (n < 0) {
879     err = WSAGetLastError();
880     if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
881     // send()�����l��0�������A�����G���[������ 10000 �������������A
882     // ���������������������B
883     // PuTTY 0.58���������Q�l�B
884     // (2007.2.4 yutak)
885     return 0; // success
886     }
887     return 1; // error
888     }
889    
890     len -= n;
891     data += n;
892     }
893    
894     return 0; // success
895     }
896    
897 doda 6801 static BOOL send_packet_blocking(PTInstVar pvar, char *data, int len)
898 maya 3227 {
899     // �p�P�b�g���M�����o�b�t�@���g�������������A�u���b�L���O�����M�����������K�v�������B
900     // �m���u���b�L���O�����M����WSAEWOULDBLOCK�����������������A�����o�b�t�@�����M��������
901     // ���������������������������������B(2007.10.30 yutaka)
902     u_long do_block = 0;
903     int code = 0;
904     char *kind = NULL, buf[256];
905    
906 doda 6967 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, 0, 0) == SOCKET_ERROR) {
907     code = WSAGetLastError();
908     kind = "WSAAsyncSelect1";
909     goto error;
910 maya 3227 }
911     if (ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR) {
912 doda 6967 code = WSAGetLastError();
913     kind = "ioctlsocket";
914     goto error;
915 maya 3227 }
916     if (retry_send_packet(pvar, data, len) != 0) {
917 doda 6967 code = WSAGetLastError();
918     kind = "retry_send_packet";
919     goto error;
920 maya 3227 }
921     if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
922     pvar->notification_msg,
923 doda 6967 pvar->notification_events) == SOCKET_ERROR) {
924     code = WSAGetLastError();
925     kind = "WSAAsyncSelect2";
926     goto error;
927 maya 3227 }
928     return TRUE;
929    
930     error:
931     UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
932     "A communications error occurred while sending an SSH packet.\n"
933     "The connection will close. (%s:%d)");
934     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
935     kind, code);
936 maya 5678 notify_fatal_error(pvar, buf, TRUE);
937 maya 3227 return FALSE;
938     }
939    
940     /* if skip_compress is true, then the data has already been compressed
941     into outbuf + 12 */
942 yutakapon 4926 void finish_send_packet_special(PTInstVar pvar, int skip_compress)
943 maya 3227 {
944     unsigned int len = pvar->ssh_state.outgoing_packet_len;
945 doda 6801 unsigned char *data;
946 maya 3227 unsigned int data_length;
947     buffer_t *msg = NULL; // for SSH2 packet compression
948    
949     if (pvar->ssh_state.compressing) {
950     if (!skip_compress) {
951     buf_ensure_size(&pvar->ssh_state.outbuf,
952     &pvar->ssh_state.outbuflen,
953 doda 6967 (int)(len + (len >> 6) + 50 + CRYPT_get_sender_MAC_size(pvar)));
954     pvar->ssh_state.compress_stream.next_in = pvar->ssh_state.precompress_outbuf;
955 maya 3227 pvar->ssh_state.compress_stream.avail_in = len;
956 doda 6967 pvar->ssh_state.compress_stream.next_out = pvar->ssh_state.outbuf + 12;
957     pvar->ssh_state.compress_stream.avail_out = pvar->ssh_state.outbuflen - 12;
958 maya 3227
959     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
960     UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
961     "An error occurred while compressing packet data.\n"
962     "The connection will close.");
963 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
964 maya 3227 return;
965     }
966     }
967    
968 doda 6967 len = pvar->ssh_state.outbuflen - 12 - pvar->ssh_state.compress_stream.avail_out;
969 maya 3227 }
970    
971     if (SSHv1(pvar)) {
972     int padding = 8 - ((len + 4) % 8);
973    
974     data = pvar->ssh_state.outbuf + 8 - padding;
975     data_length = padding + len + 8;
976    
977     set_uint32(data, len + 4);
978     if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
979     CRYPT_set_random_data(pvar, data + 4, padding);
980     } else {
981     memset(data + 4, 0, padding);
982     }
983 doda 6967 set_uint32(data + data_length - 4, do_crc(data + 4, data_length - 8));
984 maya 3227 CRYPT_encrypt(pvar, data + 4, data_length - 4);
985     } else { //for SSH2(yutaka)
986     int block_size = CRYPT_get_encryption_block_size(pvar);
987     unsigned int encryption_size;
988     unsigned int padding;
989     BOOL ret;
990    
991     /*
992     �f�[�^�\��
993     pvar->ssh_state.outbuf:
994     offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
995     <--ignore---> ^^^^^^^^ <---- payload --->
996 doda 6967 packet length
997 maya 3227
998 doda 6967 ^^padding
999 maya 3227
1000 doda 6967 <---------------------------->
1001     SSH2 sending data on TCP
1002 maya 3227
1003     NOTE:
1004     payload = type(1) + raw-data
1005     len = ssh_state.outgoing_packet_len = payload size
1006     */
1007     // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
1008     // support of "Compression delayed" (2006.6.23 maya)
1009     if ((pvar->ctos_compression == COMP_ZLIB ||
1010     pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
1011     pvar->ssh2_keys[MODE_OUT].comp.enabled) {
1012     // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
1013     msg = buffer_init();
1014     if (msg == NULL) {
1015     // TODO: error check
1016 doda 6824 logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_init returns NULL.");
1017 maya 3227 return;
1018     }
1019    
1020     // ���k�������w�b�_�������y�C���[�h�����B
1021     buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
1022     if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
1023     UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1024     "An error occurred while compressing packet data.\n"
1025     "The connection will close.");
1026 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1027 maya 3227 return;
1028     }
1029     data = buffer_ptr(msg);
1030     len = buffer_len(msg) - 5; // 'len' is overwritten.
1031    
1032     } else {
1033     // �����k
1034     data = pvar->ssh_state.outbuf + 7;
1035     }
1036    
1037     // ���M�p�P�b�g�\�z(input parameter: data, len)
1038     if (block_size < 8) {
1039     block_size = 8;
1040     }
1041    
1042     encryption_size = 4 + 1 + len;
1043     padding = block_size - (encryption_size % block_size);
1044     if (padding < 4)
1045     padding += block_size;
1046     encryption_size += padding;
1047     set_uint32(data, encryption_size - 4);
1048     data[4] = (unsigned char) padding;
1049     data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1050 yutakapon 4492 if (msg) {
1051     // �p�P�b�g���k�������A�o�b�t�@���g�������B(2011.6.10 yutaka)
1052     buffer_append_space(msg, padding + EVP_MAX_MD_SIZE);
1053 yutakapon 4495 // realloc()���������A�|�C���^�����������\�������������A���x���������B
1054     data = buffer_ptr(msg);
1055 yutakapon 4492 }
1056 doda 6967
1057 maya 3227 //if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;
1058     CRYPT_set_random_data(pvar, data + 5 + len, padding);
1059     ret = CRYPT_build_sender_MAC(pvar,
1060     pvar->ssh_state.sender_sequence_number,
1061     data, encryption_size,
1062     data + encryption_size);
1063 doda 5262 if (ret == FALSE) { // MAC��������������������������
1064 maya 3227 data_length = encryption_size;
1065     }
1066    
1067 doda 5262 // �p�P�b�g�������������BMAC���~�������������O�B
1068 maya 3227 CRYPT_encrypt(pvar, data, encryption_size);
1069     }
1070    
1071     send_packet_blocking(pvar, data, data_length);
1072    
1073     buffer_free(msg);
1074    
1075     pvar->ssh_state.sender_sequence_number++;
1076    
1077     // ���M�������L�^
1078     pvar->ssh_heartbeat_tick = time(NULL);
1079     }
1080    
1081     static void destroy_packet_buf(PTInstVar pvar)
1082     {
1083     memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1084     if (pvar->ssh_state.compressing) {
1085     memset(pvar->ssh_state.precompress_outbuf, 0,
1086     pvar->ssh_state.precompress_outbuflen);
1087     }
1088     }
1089    
1090     /* The handlers are added to the queue for each message. When one of the
1091     handlers fires, if it returns FALSE, then all handlers in the set are
1092     removed from their queues. */
1093     static void enque_handlers(PTInstVar pvar, int num_msgs,
1094 doda 6801 const int *messages,
1095     const SSHPacketHandler *handlers)
1096 maya 3227 {
1097 doda 6801 SSHPacketHandlerItem *first_item;
1098     SSHPacketHandlerItem *last_item = NULL;
1099 maya 3227 int i;
1100    
1101     for (i = 0; i < num_msgs; i++) {
1102 doda 6801 SSHPacketHandlerItem *item =
1103     (SSHPacketHandlerItem *)
1104 maya 3227 malloc(sizeof(SSHPacketHandlerItem));
1105 doda 6801 SSHPacketHandlerItem *cur_item =
1106 maya 3227 pvar->ssh_state.packet_handlers[messages[i]];
1107    
1108     item->handler = handlers[i];
1109    
1110     if (cur_item == NULL) {
1111     pvar->ssh_state.packet_handlers[messages[i]] = item;
1112     item->next_for_message = item;
1113     item->last_for_message = item;
1114     item->active_for_message = messages[i];
1115     } else {
1116     item->next_for_message = cur_item;
1117     item->last_for_message = cur_item->last_for_message;
1118     cur_item->last_for_message->next_for_message = item;
1119     cur_item->last_for_message = item;
1120     item->active_for_message = -1;
1121     }
1122    
1123     if (last_item != NULL) {
1124     last_item->next_in_set = item;
1125     } else {
1126     first_item = item;
1127     }
1128     last_item = item;
1129     }
1130    
1131     if (last_item != NULL) {
1132     last_item->next_in_set = first_item;
1133     }
1134     }
1135    
1136     static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1137     {
1138 doda 6801 SSHPacketHandlerItem *cur_item =
1139 maya 3227 pvar->ssh_state.packet_handlers[message];
1140    
1141     if (cur_item == NULL) {
1142     return NULL;
1143     } else {
1144     return cur_item->handler;
1145     }
1146     }
1147    
1148     /* Called only by SSH_handle_packet */
1149     static void deque_handlers(PTInstVar pvar, int message)
1150     {
1151 doda 6801 SSHPacketHandlerItem *cur_item =
1152 maya 3227 pvar->ssh_state.packet_handlers[message];
1153 doda 6801 SSHPacketHandlerItem *first_item_in_set = cur_item;
1154 maya 3227
1155     if (cur_item == NULL)
1156     return;
1157    
1158     do {
1159 doda 6801 SSHPacketHandlerItem *next_in_set = cur_item->next_in_set;
1160 maya 3227
1161     if (cur_item->active_for_message >= 0) {
1162 doda 6801 SSHPacketHandlerItem *replacement =
1163 maya 3227 cur_item->next_for_message;
1164    
1165     if (replacement == cur_item) {
1166     replacement = NULL;
1167     } else {
1168     replacement->active_for_message =
1169     cur_item->active_for_message;
1170     }
1171     pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1172     replacement;
1173     }
1174     cur_item->next_for_message->last_for_message =
1175     cur_item->last_for_message;
1176     cur_item->last_for_message->next_for_message =
1177     cur_item->next_for_message;
1178    
1179     free(cur_item);
1180     cur_item = next_in_set;
1181     } while (cur_item != first_item_in_set);
1182     }
1183    
1184     static void enque_handler(PTInstVar pvar, int message,
1185     SSHPacketHandler handler)
1186     {
1187     enque_handlers(pvar, 1, &message, &handler);
1188     }
1189    
1190 doda 6801 static void chop_newlines(char *buf)
1191 maya 3227 {
1192     int len = strlen(buf);
1193    
1194     while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1195     buf[len - 1] = 0;
1196     len--;
1197     }
1198     }
1199    
1200     /********************/
1201     /* Message handlers */
1202     /********************/
1203    
1204     static BOOL handle_forwarding_success(PTInstVar pvar)
1205     {
1206     return FALSE;
1207     }
1208    
1209     static BOOL handle_forwarding_failure(PTInstVar pvar)
1210     {
1211     return FALSE;
1212     }
1213    
1214     static void enque_forwarding_request_handlers(PTInstVar pvar)
1215     {
1216     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1217     static const SSHPacketHandler handlers[]
1218     = { handle_forwarding_success, handle_forwarding_failure };
1219    
1220     enque_handlers(pvar, 2, msgs, handlers);
1221     }
1222    
1223     static BOOL handle_auth_failure(PTInstVar pvar)
1224     {
1225 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Authentication failed");
1226 maya 3227
1227     // retry count������ (2005.7.15 yutaka)
1228     pvar->userauth_retry_count++;
1229    
1230     AUTH_set_generic_mode(pvar);
1231     AUTH_advance_to_next_cred(pvar);
1232     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1233     try_send_credentials(pvar);
1234     return FALSE;
1235     }
1236    
1237     static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1238     {
1239     if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1240     if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1241     // �S�������������I������
1242     safefree(pvar->pageant_key);
1243     }
1244     else {
1245     // ������������
1246     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1247     try_send_credentials(pvar);
1248     return TRUE;
1249     }
1250     }
1251     AUTH_destroy_cur_cred(pvar);
1252     return handle_auth_failure(pvar);
1253     }
1254    
1255     static BOOL handle_TIS_challenge(PTInstVar pvar)
1256     {
1257     if (grab_payload(pvar, 4)) {
1258     int len = get_payload_uint32(pvar, 0);
1259    
1260     if (grab_payload(pvar, len)) {
1261 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Received TIS challenge");
1262 maya 3227
1263     AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1264     AUTH_advance_to_next_cred(pvar);
1265     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1266     try_send_credentials(pvar);
1267     }
1268     }
1269     return FALSE;
1270     }
1271    
1272     static BOOL handle_auth_required(PTInstVar pvar)
1273     {
1274 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Server requires authentication");
1275 maya 3227
1276     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1277     try_send_credentials(pvar);
1278     /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1279    
1280     return FALSE;
1281     }
1282    
1283     static BOOL handle_ignore(PTInstVar pvar)
1284     {
1285     if (SSHv1(pvar)) {
1286 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_IGNORE was received.");
1287 maya 3227
1288     if (grab_payload(pvar, 4)
1289     && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1290     /* ignore it! but it must be decompressed */
1291     }
1292     }
1293     else {
1294 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_IGNORE was received.");
1295 maya 3227
1296     // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1297     // Cisco ���[�^���� (2006.11.28 maya)
1298     }
1299     return TRUE;
1300     }
1301    
1302     static BOOL handle_debug(PTInstVar pvar)
1303     {
1304     BOOL always_display;
1305 doda 6801 char *description;
1306 maya 3227 int description_len;
1307     char buf[2048];
1308    
1309     if (SSHv1(pvar)) {
1310 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_DEBUG was received.");
1311 maya 3227
1312     if (grab_payload(pvar, 4)
1313     && grab_payload(pvar, description_len =
1314     get_payload_uint32(pvar, 0))) {
1315     always_display = FALSE;
1316     description = pvar->ssh_state.payload + 4;
1317     description[description_len] = 0;
1318     } else {
1319     return TRUE;
1320     }
1321     } else {
1322 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_DEBUG was received.");
1323 maya 3227
1324     if (grab_payload(pvar, 5)
1325     && grab_payload(pvar,
1326     (description_len = get_payload_uint32(pvar, 1)) + 4)
1327     && grab_payload(pvar,
1328     get_payload_uint32(pvar, 5 + description_len))) {
1329     always_display = pvar->ssh_state.payload[0] != 0;
1330     description = pvar->ssh_state.payload + 5;
1331     description[description_len] = 0;
1332     } else {
1333     return TRUE;
1334     }
1335     }
1336    
1337     chop_newlines(description);
1338     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1339     description);
1340     if (always_display) {
1341     notify_nonfatal_error(pvar, buf);
1342     } else {
1343 doda 6809 logputs(LOG_LEVEL_VERBOSE, buf);
1344 maya 3227 }
1345     return TRUE;
1346     }
1347    
1348     static BOOL handle_disconnect(PTInstVar pvar)
1349     {
1350     int reason_code;
1351 doda 6801 char *description;
1352 maya 3227 int description_len;
1353     char buf[2048];
1354 doda 6801 char *explanation = "";
1355 maya 3227 char uimsg[MAX_UIMSG];
1356    
1357     if (SSHv1(pvar)) {
1358 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_DISCONNECT was received.");
1359 maya 3227
1360     if (grab_payload(pvar, 4)
1361     && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1362     reason_code = -1;
1363     description = pvar->ssh_state.payload + 4;
1364     description[description_len] = 0;
1365     } else {
1366     return TRUE;
1367     }
1368     } else {
1369 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_DISCONNECT was received.");
1370 maya 3227
1371     if (grab_payload(pvar, 8)
1372     && grab_payload(pvar,
1373     (description_len = get_payload_uint32(pvar, 4)) + 4)
1374     && grab_payload(pvar,
1375     get_payload_uint32(pvar, 8 + description_len))) {
1376     reason_code = get_payload_uint32(pvar, 0);
1377     description = pvar->ssh_state.payload + 8;
1378     description[description_len] = 0;
1379     } else {
1380     return TRUE;
1381     }
1382     }
1383    
1384     chop_newlines(description);
1385     if (description[0] == 0) {
1386     description = NULL;
1387     }
1388    
1389     if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1390     UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1391     "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1392     "This often happens when someone is already forwarding that port from the server.");
1393     strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1394     explanation = uimsg;
1395     }
1396    
1397     if (description != NULL) {
1398     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1399     "Server disconnected with message '%s'%s");
1400     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1401     pvar->ts->UIMsg, description,
1402     explanation);
1403     } else {
1404     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1405     "Server disconnected (no reason given).%s");
1406     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1407     pvar->ts->UIMsg, explanation);
1408     }
1409    
1410 maya 5678 if (SSHv2(pvar)) {
1411     // SSH2_MSG_DISCONNECT �������������������������M��������������
1412     notify_fatal_error(pvar, buf, FALSE);
1413     }
1414     else {
1415     // SSH1 ���������d�l�����������������A���O����������������
1416     notify_fatal_error(pvar, buf, TRUE);
1417     }
1418    
1419 maya 3227 return TRUE;
1420     }
1421    
1422     static BOOL handle_unimplemented(PTInstVar pvar)
1423     {
1424     /* Should never receive this since we only send base 2.0 protocol messages */
1425     grab_payload(pvar, 4);
1426     return TRUE;
1427     }
1428    
1429     static BOOL handle_crypt_success(PTInstVar pvar)
1430     {
1431 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Secure mode successfully achieved");
1432 maya 3227 return FALSE;
1433     }
1434    
1435     static BOOL handle_noauth_success(PTInstVar pvar)
1436     {
1437 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Server does not require authentication");
1438 maya 3227 prep_compression(pvar);
1439     return FALSE;
1440     }
1441    
1442     static BOOL handle_auth_success(PTInstVar pvar)
1443     {
1444 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Authentication accepted");
1445 maya 3227 prep_compression(pvar);
1446    
1447     // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1448     start_ssh_heartbeat_thread(pvar);
1449    
1450     return FALSE;
1451     }
1452    
1453     static BOOL handle_server_public_key(PTInstVar pvar)
1454     {
1455     int server_key_public_exponent_len;
1456     int server_key_public_modulus_pos;
1457     int server_key_public_modulus_len;
1458     int host_key_bits_pos;
1459     int host_key_public_exponent_len;
1460     int host_key_public_modulus_pos;
1461     int host_key_public_modulus_len;
1462     int protocol_flags_pos;
1463     int supported_ciphers;
1464 doda 6801 char *inmsg;
1465 maya 3227 Key hostkey;
1466     int supported_types;
1467    
1468 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_SMSG_PUBLIC_KEY was received.");
1469 maya 3227
1470     if (!grab_payload(pvar, 14))
1471     return FALSE;
1472     server_key_public_exponent_len = get_mpint_len(pvar, 12);
1473    
1474     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1475     return FALSE;
1476     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1477     server_key_public_modulus_len =
1478     get_mpint_len(pvar, server_key_public_modulus_pos);
1479    
1480     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1481     return FALSE;
1482     host_key_bits_pos =
1483     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1484     host_key_public_exponent_len =
1485     get_mpint_len(pvar, host_key_bits_pos + 4);
1486    
1487     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1488     return FALSE;
1489     host_key_public_modulus_pos =
1490     host_key_bits_pos + 6 + host_key_public_exponent_len;
1491     host_key_public_modulus_len =
1492     get_mpint_len(pvar, host_key_public_modulus_pos);
1493    
1494     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1495     return FALSE;
1496     protocol_flags_pos =
1497     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1498    
1499     inmsg = pvar->ssh_state.payload;
1500    
1501     CRYPT_set_server_cookie(pvar, inmsg);
1502     if (!CRYPT_set_server_RSA_key(pvar,
1503     get_uint32(inmsg + 8),
1504     pvar->ssh_state.payload + 12,
1505     inmsg + server_key_public_modulus_pos))
1506     return FALSE;
1507     if (!CRYPT_set_host_RSA_key(pvar,
1508     get_uint32(inmsg + host_key_bits_pos),
1509     inmsg + host_key_bits_pos + 4,
1510     inmsg + host_key_public_modulus_pos))
1511     return FALSE;
1512     pvar->ssh_state.server_protocol_flags =
1513     get_uint32(inmsg + protocol_flags_pos);
1514    
1515     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1516     if (!CRYPT_set_supported_ciphers(pvar,
1517     supported_ciphers,
1518     supported_ciphers))
1519     return FALSE;
1520    
1521     // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1522     // RSA ���L������ PAGEANT ���L��������
1523     supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1524     if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1525     supported_types |= (1 << SSH_AUTH_PAGEANT);
1526     }
1527     if (!AUTH_set_supported_auth_types(pvar,
1528     supported_types))
1529     return FALSE;
1530    
1531     /* this must be the LAST THING in this function, since it can cause
1532     host_is_OK to be called. */
1533     hostkey.type = KEY_RSA1;
1534     hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1535     hostkey.exp = inmsg + host_key_bits_pos + 4;
1536     hostkey.mod = inmsg + host_key_public_modulus_pos;
1537     HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1538    
1539     return FALSE;
1540     }
1541    
1542     /*
1543     The ID must have already been found to start with "SSH-". It must
1544     be null-terminated.
1545     */
1546 doda 6801 static BOOL parse_protocol_ID(PTInstVar pvar, char *ID)
1547 maya 3227 {
1548 doda 6801 char *str;
1549 maya 3227
1550     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1551     }
1552    
1553     if (*str != '.') {
1554     return FALSE;
1555     }
1556    
1557     pvar->protocol_major = atoi(ID + 4);
1558     pvar->protocol_minor = atoi(str + 1);
1559    
1560     for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1561     }
1562    
1563     return *str == '-';
1564     }
1565    
1566     /*
1567     On entry, the pvar->protocol_xxx fields hold the server's advertised
1568     protocol number. We replace the fields with the protocol number we will
1569     actually use, or return FALSE if there is no usable protocol version.
1570     */
1571 maya 4682 static int negotiate_protocol(PTInstVar pvar)
1572 maya 3227 {
1573     switch (pvar->protocol_major) {
1574     case 1:
1575 maya 4682 if (pvar->protocol_minor == 99 &&
1576     pvar->settings.ssh_protocol_version == 2) {
1577     // �T�[�o�� 1.99 �����[�U�� SSH2 ���I������������������
1578     // 2.0 ����������
1579     pvar->protocol_major = 2;
1580     pvar->protocol_minor = 0;
1581     return 0;
1582     }
1583    
1584     if (pvar->settings.ssh_protocol_version == 2) {
1585     // �o�[�W��������
1586     return -1;
1587     }
1588    
1589 maya 3227 if (pvar->protocol_minor > 5) {
1590     pvar->protocol_minor = 5;
1591     }
1592    
1593 maya 4682 return 0;
1594 maya 3227
1595     // for SSH2(yutaka)
1596     case 2:
1597 maya 4682 if (pvar->settings.ssh_protocol_version == 1) {
1598     // �o�[�W��������
1599     return -1;
1600     }
1601 maya 3227
1602 maya 4682 return 0; // SSH2 support
1603    
1604 maya 3227 default:
1605 maya 4682 return 1;
1606 maya 3227 }
1607     }
1608    
1609     static void init_protocol(PTInstVar pvar)
1610     {
1611     CRYPT_initialize_random_numbers(pvar);
1612    
1613     // known_hosts�t�@�C�������z�X�g���J������������������
1614     HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1615    
1616     /* while we wait for a response from the server... */
1617    
1618     if (SSHv1(pvar)) {
1619     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1620     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1621     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1622     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1623    
1624     } else { // for SSH2(yutaka)
1625     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1626     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1627     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1628     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1629     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1630     enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1631     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1632     enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1633     enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1634     enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1635     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1636     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1637 doda 6657 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_msg60);
1638 maya 3227
1639     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1640    
1641     // ���[�U�F�������f�B�X�p�b�`���[�`��
1642     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1643     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1644     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1645     enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1646     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1647     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1648     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1649     enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1650     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1651     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1652     enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1653 yutakapon 5829 enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_SSH2_client_global_request);
1654 maya 3227 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1655     enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1656    
1657 yutakapon 5850 client_init_global_confirm();
1658    
1659 maya 3227 }
1660     }
1661    
1662 doda 5928 void server_version_check(PTInstVar pvar)
1663     {
1664     char *server_swver;
1665    
1666     pvar->server_compat_flag = 0;
1667    
1668     if ((server_swver = strchr(pvar->server_version_string+4, '-')) == NULL) {
1669 doda 6809 logputs(LOG_LEVEL_WARNING, "Can't get server software version string.");
1670 doda 5928 return;
1671     }
1672     server_swver++;
1673    
1674     if (strncmp(server_swver, "Cisco-1", 7) == 0) {
1675     pvar->server_compat_flag |= SSH_BUG_DHGEX_LARGE;
1676 doda 6809 logputs(LOG_LEVEL_INFO, "Server version string is matched to \"Cisco-1\", compatibility flag SSH_BUG_DHGEX_LARGE is enabled.");
1677 doda 5928 }
1678     }
1679    
1680 doda 6801 BOOL SSH_handle_server_ID(PTInstVar pvar, char *ID, int ID_len)
1681 maya 3227 {
1682 maya 4546 static char prefix[64];
1683 maya 4682 int negotiate;
1684     char uimsg[MAX_UIMSG];
1685 maya 3227
1686     // initialize SSH2 memory dump (2005.3.7 yutaka)
1687     init_memdump();
1688     push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1689    
1690     if (ID_len <= 0) {
1691     return FALSE;
1692     } else {
1693 maya 4546 int buf_len;
1694 doda 6801 char *buf;
1695 maya 3227
1696 maya 4546 strncpy_s(prefix, sizeof(prefix), "Received server identification string: ", _TRUNCATE);
1697     buf_len = strlen(prefix) + ID_len + 1;
1698 doda 6801 buf = (char *) malloc(buf_len);
1699 maya 3227 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1700     strncat_s(buf, buf_len, ID, _TRUNCATE);
1701     chop_newlines(buf);
1702 doda 6809 logputs(LOG_LEVEL_VERBOSE, buf);
1703 maya 3227 free(buf);
1704    
1705     if (ID[ID_len - 1] != '\n') {
1706     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1707     return FALSE;
1708     } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1709     pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1710     return FALSE;
1711     } else if (strncmp(ID, "SSH-", 4) != 0) {
1712     return FALSE;
1713     } else {
1714     ID[ID_len - 1] = 0;
1715    
1716     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1717     ID[ID_len - 2] = 0;
1718     }
1719    
1720     pvar->ssh_state.server_ID = _strdup(ID);
1721    
1722 maya 4682 if (!parse_protocol_ID(pvar, ID)) {
1723 maya 3227 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1724     "This program does not understand the server's version of the protocol.");
1725 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1726 maya 4682 }
1727     else if ((negotiate = negotiate_protocol(pvar)) == 1) {
1728     UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1729     "This program does not understand the server's version of the protocol.");
1730 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1731 maya 4682 }
1732     else if (negotiate == -1) {
1733     UTIL_get_lang_msg("MSG_SSH_VERSION_MISMATCH", pvar,
1734     "Protocol version mismatch. server:%d.%d client:%d");
1735     _snprintf_s(uimsg, sizeof(uimsg), _TRUNCATE, pvar->ts->UIMsg,
1736     pvar->protocol_major, pvar->protocol_minor, pvar->settings.ssh_protocol_version);
1737 maya 5678 notify_fatal_error(pvar, uimsg, TRUE);
1738 maya 4682 }
1739     else {
1740 maya 3227 char TTSSH_ID[1024];
1741     int TTSSH_ID_len;
1742    
1743 maya 4682 // SSH �o�[�W������ teraterm �����Z�b�g����
1744     // SCP �R�}���h������ (2008.2.3 maya)
1745     pvar->cv->isSSH = pvar->protocol_major;
1746    
1747 maya 3227 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1748     _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1749 maya 4656 "SSH-%d.%d-TTSSH/%d.%d Win32\r\n",
1750 doda 6835 pvar->protocol_major, pvar->protocol_minor,
1751     TTSSH_VERSION_MAJOR, TTSSH_VERSION_MINOR);
1752 maya 3227 TTSSH_ID_len = strlen(TTSSH_ID);
1753    
1754     // for SSH2(yutaka)
1755     // �N���C�A���g�o�[�W�����������i���s���������������j
1756     strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1757     TTSSH_ID, _TRUNCATE);
1758    
1759     // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1760     _snprintf_s(pvar->server_version_string,
1761     sizeof(pvar->server_version_string), _TRUNCATE,
1762     "%s", pvar->ssh_state.server_ID);
1763    
1764 doda 5928 // �T�[�o�o�[�W�������`�F�b�N
1765     server_version_check(pvar);
1766    
1767 doda 6809 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len, 0) != TTSSH_ID_len) {
1768 maya 3227 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1769     "An error occurred while sending the SSH ID string.\n"
1770     "The connection will close.");
1771 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1772 maya 3227 } else {
1773 doda 6809 // ���s������
1774     chop_newlines(pvar->client_version_string);
1775     logprintf(LOG_LEVEL_VERBOSE, "Sent client identification string: %s", pvar->client_version_string);
1776 maya 3227
1777     push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1778     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1779    
1780     // SSH�n���h�����o�^���s��
1781     init_protocol(pvar);
1782    
1783     SSH2_dispatch_init(1);
1784     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1785     SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1786 maya 4867 SSH2_dispatch_add_message(SSH2_MSG_DEBUG);
1787 maya 3227 }
1788     }
1789    
1790     return TRUE;
1791     }
1792     }
1793     }
1794    
1795     static BOOL handle_exit(PTInstVar pvar)
1796     {
1797     if (grab_payload(pvar, 4)) {
1798     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1799     finish_send_packet(pvar);
1800 maya 5678 notify_closed_connection(pvar, "disconnected by server request");
1801 maya 3227 }
1802     return TRUE;
1803     }
1804    
1805     static BOOL handle_data(PTInstVar pvar)
1806     {
1807     if (grab_payload_limited(pvar, 4)) {
1808     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1809     pvar->ssh_state.payload_datastart = 4;
1810     }
1811     return TRUE;
1812     }
1813    
1814     static BOOL handle_channel_open(PTInstVar pvar)
1815     {
1816     int host_len;
1817     int originator_len;
1818    
1819     if ((pvar->ssh_state.
1820     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1821     if (grab_payload(pvar, 8)
1822     && grab_payload(pvar,
1823     8 + (host_len = get_payload_uint32(pvar, 4)))
1824     && grab_payload(pvar, originator_len =
1825     get_payload_uint32(pvar, host_len + 12))) {
1826     int local_port = get_payload_uint32(pvar, 8 + host_len);
1827    
1828     pvar->ssh_state.payload[8 + host_len] = 0;
1829     FWD_open(pvar, get_payload_uint32(pvar, 0),
1830     pvar->ssh_state.payload + 8, local_port,
1831     pvar->ssh_state.payload + 16 + host_len,
1832     originator_len,
1833     NULL);
1834     }
1835     } else {
1836     if (grab_payload(pvar, 8)
1837     && grab_payload(pvar,
1838     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1839     int local_port = get_payload_uint32(pvar, 8 + host_len);
1840    
1841     pvar->ssh_state.payload[8 + host_len] = 0;
1842     FWD_open(pvar, get_payload_uint32(pvar, 0),
1843     pvar->ssh_state.payload + 8, local_port, NULL, 0,
1844     NULL);
1845     }
1846     }
1847    
1848     return TRUE;
1849     }
1850    
1851     static BOOL handle_X11_channel_open(PTInstVar pvar)
1852     {
1853     int originator_len;
1854    
1855     if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1856     if (grab_payload(pvar, 8)
1857     && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1858     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1859     pvar->ssh_state.payload + 8, originator_len, NULL);
1860     }
1861     } else {
1862     if (grab_payload(pvar, 4)) {
1863     FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1864     }
1865     }
1866    
1867     return TRUE;
1868     }
1869    
1870     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1871     {
1872     if (grab_payload(pvar, 8)) {
1873     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1874     get_payload_uint32(pvar, 4));
1875     }
1876     return FALSE;
1877     }
1878    
1879     static BOOL handle_channel_open_failure(PTInstVar pvar)
1880     {
1881     if (grab_payload(pvar, 4)) {
1882 doda 6844 FWD_failed_open(pvar, get_payload_uint32(pvar, 0), -1);
1883 maya 3227 }
1884     return FALSE;
1885     }
1886    
1887     static BOOL handle_channel_data(PTInstVar pvar)
1888     {
1889     int len;
1890    
1891     if (grab_payload(pvar, 8)
1892     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1893     FWDChannel *channel;
1894     int local_channel_num = get_payload_uint32(pvar, 0);
1895     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1896     return FALSE;
1897     }
1898     channel = pvar->fwd_state.channels + local_channel_num;
1899     if (channel->type == TYPE_AGENT) {
1900     SSH_agent_response(pvar, NULL, local_channel_num,
1901     pvar->ssh_state.payload + 8, len);
1902     }
1903     else {
1904     FWD_received_data(pvar, local_channel_num,
1905     pvar->ssh_state.payload + 8, len);
1906     }
1907     }
1908     return TRUE;
1909     }
1910    
1911     static BOOL handle_channel_input_eof(PTInstVar pvar)
1912     {
1913     if (grab_payload(pvar, 4)) {
1914     int local_channel_num = get_payload_uint32(pvar, 0);
1915     FWDChannel *channel;
1916     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1917     return FALSE;
1918     }
1919     channel = pvar->fwd_state.channels + local_channel_num;
1920     if (channel->type == TYPE_AGENT) {
1921     channel->status |= FWD_CLOSED_REMOTE_IN;
1922     SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1923     }
1924     else {
1925     FWD_channel_input_eof(pvar, local_channel_num);
1926     }
1927     }
1928     return TRUE;
1929     }
1930    
1931     static BOOL handle_channel_output_eof(PTInstVar pvar)
1932     {
1933     if (grab_payload(pvar, 4)) {
1934     int local_channel_num = get_payload_uint32(pvar, 0);
1935     FWDChannel *channel;
1936     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1937     return FALSE;
1938     }
1939     channel = pvar->fwd_state.channels + local_channel_num;
1940     if (channel->type == TYPE_AGENT) {
1941     channel->status |= FWD_CLOSED_REMOTE_OUT;
1942     SSH_channel_output_eof(pvar, channel->remote_num);
1943     FWD_free_channel(pvar, local_channel_num);
1944     }
1945     else {
1946     FWD_channel_output_eof(pvar, local_channel_num);
1947     }
1948     }
1949     return TRUE;
1950     }
1951    
1952     static BOOL handle_agent_open(PTInstVar pvar)
1953     {
1954     if (grab_payload(pvar, 4)) {
1955     int remote_id = get_payload_uint32(pvar, 0);
1956     int local_id;
1957    
1958 doda 4233 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
1959 maya 3227 local_id = FWD_agent_open(pvar, remote_id);
1960     if (local_id == -1) {
1961     SSH_fail_channel_open(pvar, remote_id);
1962     }
1963     else {
1964     SSH_confirm_channel_open(pvar, remote_id, local_id);
1965     }
1966     }
1967     else {
1968     SSH_fail_channel_open(pvar, remote_id);
1969     }
1970     }
1971     /*
1972     else {
1973     // ���m��������channel����������������������������
1974     }
1975     */
1976    
1977     return TRUE;
1978     }
1979    
1980    
1981    
1982     // �n���h�����O�������b�Z�[�W����������
1983    
1984     #define HANDLE_MESSAGE_MAX 30
1985     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1986     static int handle_message_count = 0;
1987     static int handle_message_stage = 0;
1988    
1989     void SSH2_dispatch_init(int stage)
1990     {
1991     handle_message_count = 0;
1992     handle_message_stage = stage;
1993     }
1994    
1995     int SSH2_dispatch_enabled_check(unsigned char message)
1996     {
1997     int i;
1998    
1999     for (i = 0 ; i < handle_message_count ; i++) {
2000     if (handle_messages[i] == message)
2001     return 1;
2002     }
2003     return 0;
2004     }
2005    
2006     void SSH2_dispatch_add_message(unsigned char message)
2007     {
2008     int i;
2009    
2010     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2011     // TODO: error check
2012 doda 6824 logprintf(LOG_LEVEL_ERROR, __FUNCTION__ ": too many handlers. handlers:%d, max:%d",
2013     handle_message_count, HANDLE_MESSAGE_MAX);
2014 maya 3227 return;
2015     }
2016    
2017     // �������o�^�������������b�Z�[�W������������
2018     for (i=0; i<handle_message_count; i++) {
2019     if (handle_messages[i] == message) {
2020     return;
2021     }
2022     }
2023    
2024     handle_messages[handle_message_count++] = message;
2025     }
2026    
2027     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2028     {
2029     unsigned char c;
2030    
2031     for (c = begin ; c <= end ; c++) {
2032     SSH2_dispatch_add_message(c);
2033     }
2034     }
2035    
2036    
2037 doda 6967 void SSH_handle_packet(PTInstVar pvar, char *data, int len, int padding)
2038 maya 3227 {
2039     unsigned char message = prep_packet(pvar, data, len, padding);
2040    
2041     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2042     if (message != SSH_MSG_NONE) {
2043     // ���b�Z�[�W�^�C�v���������n���h�����N��
2044     SSHPacketHandler handler = get_handler(pvar, message);
2045    
2046     // for SSH2(yutaka)
2047     if (SSHv2(pvar)) {
2048     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2049     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2050     char buf[1024];
2051    
2052 doda 6967 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar, "Unexpected SSH2 message(%d) on current stage(%d)");
2053     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);
2054 maya 5678 notify_fatal_error(pvar, buf, TRUE);
2055 doda 6656 return;
2056 maya 3227 }
2057     }
2058    
2059     if (handler == NULL) {
2060     if (SSHv1(pvar)) {
2061     char buf[1024];
2062    
2063 doda 6967 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar, "Unexpected packet type received: %d");
2064     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);
2065 maya 5678 notify_fatal_error(pvar, buf, TRUE);
2066 maya 3227 } else {
2067 doda 6967 unsigned char *outmsg = begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2068 maya 3227
2069 doda 6967 set_uint32(outmsg, pvar->ssh_state.receiver_sequence_number - 1);
2070 maya 3227 finish_send_packet(pvar);
2071    
2072 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().");
2073 maya 3227 /* XXX need to decompress incoming packet, but how? */
2074     }
2075     } else {
2076     if (!handler(pvar)) {
2077     deque_handlers(pvar, message);
2078     }
2079     }
2080     }
2081     }
2082    
2083     static BOOL handle_pty_success(PTInstVar pvar)
2084     {
2085     FWD_enter_interactive_mode(pvar);
2086     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2087     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2088     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2089     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2090 doda 6967 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF, handle_channel_input_eof);
2091     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, handle_channel_output_eof);
2092 maya 3227 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2093     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2094     enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2095     return FALSE;
2096     }
2097    
2098     static BOOL handle_pty_failure(PTInstVar pvar)
2099     {
2100     UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2101     "The server cannot allocate a pseudo-terminal. "
2102     "You may encounter some problems with the terminal.");
2103     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2104     return handle_pty_success(pvar);
2105     }
2106    
2107     static void prep_pty(PTInstVar pvar)
2108     {
2109     int len = strlen(pvar->ts->TermType);
2110 doda 6967 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY, 4 + len + 16 + sizeof(ssh_ttymodes));
2111 maya 3227 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2112     static const SSHPacketHandler handlers[]
2113     = { handle_pty_success, handle_pty_failure };
2114 doda 6799 int x, y;
2115 maya 3227
2116 doda 6799 get_window_pixel_size(pvar, &x, &y);
2117    
2118 maya 3227 set_uint32(outmsg, len);
2119     memcpy(outmsg + 4, pvar->ts->TermType, len);
2120     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2121     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2122 doda 6799 set_uint32(outmsg + 4 + len + 8, x);
2123     set_uint32(outmsg + 4 + len + 12, y);
2124 maya 3227 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2125     finish_send_packet(pvar);
2126    
2127     enque_handlers(pvar, 2, msgs, handlers);
2128    
2129     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2130     finish_send_packet(pvar);
2131     }
2132    
2133     static BOOL handle_agent_request_success(PTInstVar pvar)
2134     {
2135     pvar->agentfwd_enable = TRUE;
2136     prep_pty(pvar);
2137     return FALSE;
2138     }
2139    
2140     static BOOL handle_agent_request_failure(PTInstVar pvar)
2141     {
2142     prep_pty(pvar);
2143     return FALSE;
2144     }
2145    
2146     static void prep_agent_request(PTInstVar pvar)
2147     {
2148     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2149 doda 6967 static const SSHPacketHandler handlers[] = { handle_agent_request_success, handle_agent_request_failure };
2150 maya 3227
2151     enque_handlers(pvar, 2, msgs, handlers);
2152    
2153     begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2154     finish_send_packet(pvar);
2155     }
2156    
2157     static void prep_forwarding(PTInstVar pvar)
2158     {
2159     FWD_prep_forwarding(pvar);
2160    
2161     if (pvar->session_settings.ForwardAgent) {
2162     prep_agent_request(pvar);
2163     }
2164     else {
2165     prep_pty(pvar);
2166     }
2167     }
2168    
2169     //
2170     //
2171     // (2005.7.10 yutaka)
2172     static void enable_send_compression(PTInstVar pvar)
2173     {
2174     static int initialize = 0;
2175    
2176     if (initialize) {
2177     deflateEnd(&pvar->ssh_state.compress_stream);
2178     }
2179     initialize = 1;
2180    
2181     pvar->ssh_state.compress_stream.zalloc = NULL;
2182     pvar->ssh_state.compress_stream.zfree = NULL;
2183     pvar->ssh_state.compress_stream.opaque = NULL;
2184 doda 6967 if (deflateInit(&pvar->ssh_state.compress_stream, pvar->ssh_state.compression_level) != Z_OK) {
2185 maya 3227 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2186     "An error occurred while setting up compression.\n"
2187     "The connection will close.");
2188 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2189 maya 3227 return;
2190     } else {
2191     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2192     if (SSHv2(pvar)) {
2193     pvar->ssh_state.compressing = FALSE;
2194     } else {
2195     pvar->ssh_state.compressing = TRUE;
2196     }
2197     }
2198     }
2199    
2200     static void enable_recv_compression(PTInstVar pvar)
2201     {
2202     static int initialize = 0;
2203    
2204     if (initialize) {
2205     deflateEnd(&pvar->ssh_state.decompress_stream);
2206     }
2207     initialize = 1;
2208    
2209     pvar->ssh_state.decompress_stream.zalloc = NULL;
2210     pvar->ssh_state.decompress_stream.zfree = NULL;
2211     pvar->ssh_state.decompress_stream.opaque = NULL;
2212     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2213     deflateEnd(&pvar->ssh_state.compress_stream);
2214     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2215     "An error occurred while setting up compression.\n"
2216     "The connection will close.");
2217 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2218 maya 3227 return;
2219     } else {
2220     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2221     if (SSHv2(pvar)) {
2222     pvar->ssh_state.decompressing = FALSE;
2223     } else {
2224     pvar->ssh_state.decompressing = TRUE;
2225     }
2226    
2227 doda 6967 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf, &pvar->ssh_state.postdecompress_inbuflen, 1000);
2228 maya 3227 }
2229     }
2230    
2231     static void enable_compression(PTInstVar pvar)
2232     {
2233     enable_send_compression(pvar);
2234     enable_recv_compression(pvar);
2235    
2236     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2237     if (SSHv2(pvar)) {
2238     pvar->ssh_state.compressing = FALSE;
2239     pvar->ssh_state.decompressing = FALSE;
2240     }
2241     }
2242    
2243     static BOOL handle_enable_compression(PTInstVar pvar)
2244     {
2245     enable_compression(pvar);
2246     prep_forwarding(pvar);
2247     return FALSE;
2248     }
2249    
2250     static BOOL handle_disable_compression(PTInstVar pvar)
2251     {
2252     prep_forwarding(pvar);
2253     return FALSE;
2254     }
2255    
2256     static void prep_compression(PTInstVar pvar)
2257     {
2258     if (pvar->session_settings.CompressionLevel > 0) {
2259     // added if statement (2005.7.10 yutaka)
2260     if (SSHv1(pvar)) {
2261     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2262 doda 6967 static const SSHPacketHandler handlers[] = { handle_enable_compression, handle_disable_compression };
2263 maya 3227
2264 doda 6967 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2265 maya 3227
2266     set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2267     finish_send_packet(pvar);
2268    
2269     enque_handlers(pvar, 2, msgs, handlers);
2270     }
2271    
2272 doda 6967 pvar->ssh_state.compression_level = pvar->session_settings.CompressionLevel;
2273 maya 3227
2274     } else {
2275     // added if statement (2005.7.10 yutaka)
2276     if (SSHv1(pvar)) {
2277     prep_forwarding(pvar);
2278     }
2279     }
2280     }
2281    
2282     static void enque_simple_auth_handlers(PTInstVar pvar)
2283     {
2284     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2285 doda 6967 static const SSHPacketHandler handlers[] = { handle_auth_success, handle_auth_failure };
2286 maya 3227
2287     enque_handlers(pvar, 2, msgs, handlers);
2288     }
2289    
2290     static BOOL handle_rsa_challenge(PTInstVar pvar)
2291     {
2292     int challenge_bytes;
2293    
2294     if (!grab_payload(pvar, 2)) {
2295     return FALSE;
2296     }
2297    
2298     challenge_bytes = get_mpint_len(pvar, 0);
2299    
2300     if (grab_payload(pvar, challenge_bytes)) {
2301 doda 6967 unsigned char *outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2302 maya 3227
2303     if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2304     if (CRYPT_generate_RSA_challenge_response
2305     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2306    
2307     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2308     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2309     //AUTH_destroy_cur_cred(pvar);
2310    
2311     finish_send_packet(pvar);
2312    
2313     enque_simple_auth_handlers(pvar);
2314     } else {
2315     UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2316     "An error occurred while decrypting the RSA challenge.\n"
2317     "Perhaps the key file is corrupted.");
2318 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2319 maya 3227 }
2320     }
2321     else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2322     int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2323     int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2324     int server_key_bytes = (server_key_bits + 7) / 8;
2325     int host_key_bytes = (host_key_bits + 7) / 8;
2326     int session_buf_len = server_key_bytes + host_key_bytes + 8;
2327 doda 6801 char *session_buf = (char *) malloc(session_buf_len);
2328 maya 3227 unsigned char session_id[16];
2329    
2330     unsigned char *hash;
2331     int pubkeylen, hashlen;
2332    
2333     /* Pageant ���n�b�V�����v�Z���������� */
2334     // ���J��������
2335 doda 6967 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey, pvar->pageant_keylistlen);
2336 maya 3227 // �Z�b�V����ID������
2337     BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2338 doda 6967 BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n, session_buf + host_key_bytes);
2339     memcpy(session_buf + server_key_bytes + host_key_bytes, pvar->crypt_state.server_cookie, 8);
2340 maya 3227 MD5(session_buf, session_buf_len, session_id);
2341     // �n�b�V������������
2342     hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2343     pubkeylen,
2344     pvar->ssh_state.payload,
2345     challenge_bytes + 2,
2346     session_id,
2347     &hashlen);
2348    
2349     // �n�b�V�������M
2350     memcpy(outmsg, hash, 16);
2351     free(hash);
2352    
2353     finish_send_packet(pvar);
2354    
2355     enque_simple_auth_handlers(pvar);
2356     }
2357     }
2358    
2359     return FALSE;
2360     }
2361    
2362     static void try_send_credentials(PTInstVar pvar)
2363     {
2364     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2365 doda 6801 AUTHCred *cred = AUTH_get_cur_cred(pvar);
2366 maya 3227 static const int RSA_msgs[] =
2367     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2368     static const SSHPacketHandler RSA_handlers[]
2369     = { handle_rsa_challenge, handle_rsa_auth_refused };
2370     static const int TIS_msgs[] =
2371     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2372     static const SSHPacketHandler TIS_handlers[]
2373     = { handle_TIS_challenge, handle_auth_failure };
2374    
2375     // SSH2���������������������X�L�b�v
2376     if (SSHv2(pvar))
2377     goto skip_ssh2;
2378    
2379     switch (cred->method) {
2380     case SSH_AUTH_NONE:
2381     return;
2382     case SSH_AUTH_PASSWORD:{
2383     int len = strlen(cred->password);
2384 doda 6801 unsigned char *outmsg =
2385 maya 3227 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2386 maya 4407 4 + len);
2387 maya 3227
2388 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Trying PASSWORD authentication...");
2389 maya 3227
2390 maya 4407 set_uint32(outmsg, len);
2391 maya 3227 memcpy(outmsg + 4, cred->password, len);
2392    
2393     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2394     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2395     //AUTH_destroy_cur_cred(pvar);
2396    
2397     enque_simple_auth_handlers(pvar);
2398     break;
2399     }
2400     case SSH_AUTH_RHOSTS:{
2401     int len = strlen(cred->rhosts_client_user);
2402 doda 6801 unsigned char *outmsg =
2403 maya 3227 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2404    
2405 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Trying RHOSTS authentication...");
2406 maya 3227
2407     set_uint32(outmsg