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 5844 - (hide annotations) (download) (as text)
Fri May 1 13:06:54 2015 UTC (8 years, 11 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 254035 byte(s)
teraterm.iniの CipherOrder, KexOrder, MacOrder, CompOrderの
先頭が"0"だった場合に、BOFでプログラムが落ちないようにした。

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