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 3850 - (hide annotations) (download) (as text)
Mon Apr 12 08:29:53 2010 UTC (14 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 251634 byte(s)
3DES-CTR, BLOWFISH-CTR, CAST128-CTR 共通鍵暗号方式をサポート。

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