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