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