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 4229 - (hide annotations) (download) (as text)
Sat Dec 18 13:04:43 2010 UTC (13 years, 3 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 256771 byte(s)
SSH エージェント転送の要求がクライアントから来たとき、Pageant に取り次ぐかどうかユーザに確認するようにした。
  クライアントから CHANNEL_OPEN が来た時点で MessageBox をはさんでいる
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 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     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 yutakapon 4152 enque_handler(pvar, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, handle_SSH2_userauth_passwd_changereq);
1675 maya 3227
1676     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1677    
1678     // ���[�U�F�������f�B�X�p�b�`���[�`��
1679     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1680     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1681     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1682     enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1683     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1684     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1685     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1686     enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1687     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1688     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1689     enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1690     // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1691     enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1692     enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1693    
1694     }
1695     }
1696    
1697     BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1698     {
1699     static const char prefix[] = "Received server prologue string: ";
1700    
1701     // initialize SSH2 memory dump (2005.3.7 yutaka)
1702     init_memdump();
1703     push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1704    
1705     if (ID_len <= 0) {
1706     return FALSE;
1707     } else {
1708     int buf_len = ID_len + NUM_ELEM(prefix);
1709     char FAR *buf = (char FAR *) malloc(buf_len);
1710    
1711     strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1712     strncat_s(buf, buf_len, ID, _TRUNCATE);
1713     chop_newlines(buf);
1714    
1715     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1716    
1717     free(buf);
1718    
1719    
1720     // ���������R�s�[������ (2005.3.9 yutaka)
1721     #if 0
1722     // for calculate SSH2 hash
1723     // �T�[�o�o�[�W�����������i���s���������������j
1724     if (ID_len >= sizeof(pvar->server_version_string))
1725     return FALSE;
1726     strncpy(pvar->server_version_string, ID, ID_len);
1727     #endif
1728    
1729    
1730     if (ID[ID_len - 1] != '\n') {
1731     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1732     return FALSE;
1733     } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1734     pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1735     return FALSE;
1736     } else if (strncmp(ID, "SSH-", 4) != 0) {
1737     return FALSE;
1738     } else {
1739     ID[ID_len - 1] = 0;
1740    
1741     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1742     ID[ID_len - 2] = 0;
1743     }
1744    
1745     pvar->ssh_state.server_ID = _strdup(ID);
1746    
1747     if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1748     UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1749     "This program does not understand the server's version of the protocol.");
1750     notify_fatal_error(pvar, pvar->ts->UIMsg);
1751     } else {
1752     char TTSSH_ID[1024];
1753     int TTSSH_ID_len;
1754     int a, b, c, d;
1755    
1756     // �������g���o�[�W�������������� (2005.3.3 yutaka)
1757     get_file_version("ttxssh.dll", &a, &b, &c, &d);
1758    
1759     _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1760     "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1761     pvar->protocol_major, pvar->protocol_minor, a, b);
1762     TTSSH_ID_len = strlen(TTSSH_ID);
1763    
1764     // for SSH2(yutaka)
1765     // �N���C�A���g�o�[�W�����������i���s���������������j
1766     strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1767     TTSSH_ID, _TRUNCATE);
1768    
1769     // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1770     _snprintf_s(pvar->server_version_string,
1771     sizeof(pvar->server_version_string), _TRUNCATE,
1772     "%s", pvar->ssh_state.server_ID);
1773    
1774     if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1775     0) != TTSSH_ID_len) {
1776     UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1777     "An error occurred while sending the SSH ID string.\n"
1778     "The connection will close.");
1779     notify_fatal_error(pvar, pvar->ts->UIMsg);
1780     } else {
1781     // ���s�R�[�h������ (2004.8.4 yutaka)
1782     pvar->client_version_string[--TTSSH_ID_len] = 0;
1783    
1784     push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1785     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1786    
1787     // SSH�n���h�����o�^���s��
1788     init_protocol(pvar);
1789    
1790     SSH2_dispatch_init(1);
1791     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1792     SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1793     }
1794     }
1795    
1796     return TRUE;
1797     }
1798     }
1799     }
1800    
1801     static BOOL handle_exit(PTInstVar pvar)
1802     {
1803     if (grab_payload(pvar, 4)) {
1804     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1805     finish_send_packet(pvar);
1806     notify_closed_connection(pvar);
1807     }
1808     return TRUE;
1809     }
1810    
1811     static BOOL handle_data(PTInstVar pvar)
1812     {
1813     if (grab_payload_limited(pvar, 4)) {
1814     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1815     pvar->ssh_state.payload_datastart = 4;
1816     }
1817     return TRUE;
1818     }
1819    
1820     static BOOL handle_channel_open(PTInstVar pvar)
1821     {
1822     int host_len;
1823     int originator_len;
1824    
1825     if ((pvar->ssh_state.
1826     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1827     if (grab_payload(pvar, 8)
1828     && grab_payload(pvar,
1829     8 + (host_len = get_payload_uint32(pvar, 4)))
1830     && grab_payload(pvar, originator_len =
1831     get_payload_uint32(pvar, host_len + 12))) {
1832     int local_port = get_payload_uint32(pvar, 8 + host_len);
1833    
1834     pvar->ssh_state.payload[8 + host_len] = 0;
1835     FWD_open(pvar, get_payload_uint32(pvar, 0),
1836     pvar->ssh_state.payload + 8, local_port,
1837     pvar->ssh_state.payload + 16 + host_len,
1838     originator_len,
1839     NULL);
1840     }
1841     } else {
1842     if (grab_payload(pvar, 8)
1843     && grab_payload(pvar,
1844     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1845     int local_port = get_payload_uint32(pvar, 8 + host_len);
1846    
1847     pvar->ssh_state.payload[8 + host_len] = 0;
1848     FWD_open(pvar, get_payload_uint32(pvar, 0),
1849     pvar->ssh_state.payload + 8, local_port, NULL, 0,
1850     NULL);
1851     }
1852     }
1853    
1854     return TRUE;
1855     }
1856    
1857     static BOOL handle_X11_channel_open(PTInstVar pvar)
1858     {
1859     int originator_len;
1860    
1861     if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1862     if (grab_payload(pvar, 8)
1863     && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1864     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1865     pvar->ssh_state.payload + 8, originator_len, NULL);
1866     }
1867     } else {
1868     if (grab_payload(pvar, 4)) {
1869     FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1870     }
1871     }
1872    
1873     return TRUE;
1874     }
1875    
1876     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1877     {
1878     if (grab_payload(pvar, 8)) {
1879     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1880     get_payload_uint32(pvar, 4));
1881     }
1882     return FALSE;
1883     }
1884    
1885     static BOOL handle_channel_open_failure(PTInstVar pvar)
1886     {
1887     if (grab_payload(pvar, 4)) {
1888     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1889     }
1890     return FALSE;
1891     }
1892    
1893     static BOOL handle_channel_data(PTInstVar pvar)
1894     {
1895     int len;
1896    
1897     if (grab_payload(pvar, 8)
1898     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1899     FWDChannel *channel;
1900     int local_channel_num = get_payload_uint32(pvar, 0);
1901     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1902     return FALSE;
1903     }
1904     channel = pvar->fwd_state.channels + local_channel_num;
1905     if (channel->type == TYPE_AGENT) {
1906     SSH_agent_response(pvar, NULL, local_channel_num,
1907     pvar->ssh_state.payload + 8, len);
1908     }
1909     else {
1910     FWD_received_data(pvar, local_channel_num,
1911     pvar->ssh_state.payload + 8, len);
1912     }
1913     }
1914     return TRUE;
1915     }
1916    
1917     static BOOL handle_channel_input_eof(PTInstVar pvar)
1918     {
1919     if (grab_payload(pvar, 4)) {
1920     int local_channel_num = get_payload_uint32(pvar, 0);
1921     FWDChannel *channel;
1922     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1923     return FALSE;
1924     }
1925     channel = pvar->fwd_state.channels + local_channel_num;
1926     if (channel->type == TYPE_AGENT) {
1927     channel->status |= FWD_CLOSED_REMOTE_IN;
1928     SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1929     }
1930     else {
1931     FWD_channel_input_eof(pvar, local_channel_num);
1932     }
1933     }
1934     return TRUE;
1935     }
1936    
1937     static BOOL handle_channel_output_eof(PTInstVar pvar)
1938     {
1939     if (grab_payload(pvar, 4)) {
1940     int local_channel_num = get_payload_uint32(pvar, 0);
1941     FWDChannel *channel;
1942     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1943     return FALSE;
1944     }
1945     channel = pvar->fwd_state.channels + local_channel_num;
1946     if (channel->type == TYPE_AGENT) {
1947     channel->status |= FWD_CLOSED_REMOTE_OUT;
1948     SSH_channel_output_eof(pvar, channel->remote_num);
1949     FWD_free_channel(pvar, local_channel_num);
1950     }
1951     else {
1952     FWD_channel_output_eof(pvar, local_channel_num);
1953     }
1954     }
1955     return TRUE;
1956     }
1957    
1958     static BOOL handle_agent_open(PTInstVar pvar)
1959     {
1960     if (grab_payload(pvar, 4)) {
1961     int remote_id = get_payload_uint32(pvar, 0);
1962     int local_id;
1963    
1964 maya 4229 if (pvar->agentfwd_enable && FWD_agent_forword_confirm(pvar)) {
1965 maya 3227 local_id = FWD_agent_open(pvar, remote_id);
1966     if (local_id == -1) {
1967     SSH_fail_channel_open(pvar, remote_id);
1968     }
1969     else {
1970     SSH_confirm_channel_open(pvar, remote_id, local_id);
1971     }
1972     }
1973     else {
1974     SSH_fail_channel_open(pvar, remote_id);
1975     }
1976     }
1977     /*
1978     else {
1979     // ���m��������channel����������������������������
1980     }
1981     */
1982    
1983     return TRUE;
1984     }
1985    
1986    
1987    
1988     // �n���h�����O�������b�Z�[�W����������
1989    
1990     #define HANDLE_MESSAGE_MAX 30
1991     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1992     static int handle_message_count = 0;
1993     static int handle_message_stage = 0;
1994    
1995     void SSH2_dispatch_init(int stage)
1996     {
1997     handle_message_count = 0;
1998     handle_message_stage = stage;
1999     }
2000    
2001     int SSH2_dispatch_enabled_check(unsigned char message)
2002     {
2003     int i;
2004    
2005     for (i = 0 ; i < handle_message_count ; i++) {
2006     if (handle_messages[i] == message)
2007     return 1;
2008     }
2009     return 0;
2010     }
2011    
2012     void SSH2_dispatch_add_message(unsigned char message)
2013     {
2014     int i;
2015    
2016     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2017     // TODO: error check
2018     return;
2019     }
2020    
2021     // �������o�^�������������b�Z�[�W������������
2022     for (i=0; i<handle_message_count; i++) {
2023     if (handle_messages[i] == message) {
2024     return;
2025     }
2026     }
2027    
2028     handle_messages[handle_message_count++] = message;
2029     }
2030    
2031     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2032     {
2033     unsigned char c;
2034    
2035     for (c = begin ; c <= end ; c++) {
2036     SSH2_dispatch_add_message(c);
2037     }
2038     }
2039    
2040    
2041     void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
2042     int padding)
2043     {
2044     unsigned char message = prep_packet(pvar, data, len, padding);
2045    
2046    
2047     #ifdef SSH2_DEBUG
2048     // for SSH2(yutaka)
2049     if (SSHv2(pvar)) {
2050     if (pvar->key_done) {
2051     message = message;
2052     }
2053    
2054     if (pvar->userauth_success) {
2055     message = message;
2056     }
2057    
2058     if (pvar->rekeying) {
2059     message = message;
2060     }
2061     }
2062     #endif
2063    
2064     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2065     if (message != SSH_MSG_NONE) {
2066     // ���b�Z�[�W�^�C�v���������n���h�����N��
2067     SSHPacketHandler handler = get_handler(pvar, message);
2068    
2069     // for SSH2(yutaka)
2070     if (SSHv2(pvar)) {
2071     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2072     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2073     char buf[1024];
2074    
2075     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2076     "Unexpected SSH2 message(%d) on current stage(%d)");
2077     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2078     pvar->ts->UIMsg, message, handle_message_stage);
2079     notify_fatal_error(pvar, buf);
2080     // abort
2081     }
2082     }
2083    
2084     if (handler == NULL) {
2085     if (SSHv1(pvar)) {
2086     char buf[1024];
2087    
2088     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2089     "Unexpected packet type received: %d");
2090     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2091     pvar->ts->UIMsg, message, handle_message_stage);
2092     notify_fatal_error(pvar, buf);
2093     } else {
2094     unsigned char FAR *outmsg =
2095     begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2096    
2097     set_uint32(outmsg,
2098     pvar->ssh_state.receiver_sequence_number - 1);
2099     finish_send_packet(pvar);
2100    
2101     notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2102     /* XXX need to decompress incoming packet, but how? */
2103     }
2104     } else {
2105     if (!handler(pvar)) {
2106     deque_handlers(pvar, message);
2107     }
2108     }
2109     }
2110     }
2111    
2112     static BOOL handle_pty_success(PTInstVar pvar)
2113     {
2114     FWD_enter_interactive_mode(pvar);
2115     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2116     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2117     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2118     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2119     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2120     handle_channel_input_eof);
2121     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2122     handle_channel_output_eof);
2123     enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2124     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2125     enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2126     return FALSE;
2127     }
2128    
2129     static BOOL handle_pty_failure(PTInstVar pvar)
2130     {
2131     UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2132     "The server cannot allocate a pseudo-terminal. "
2133     "You may encounter some problems with the terminal.");
2134     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2135     return handle_pty_success(pvar);
2136     }
2137    
2138     static void prep_pty(PTInstVar pvar)
2139     {
2140     int len = strlen(pvar->ts->TermType);
2141     unsigned char FAR *outmsg =
2142     begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2143     4 + len + 16 + sizeof(ssh_ttymodes));
2144     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2145     static const SSHPacketHandler handlers[]
2146     = { handle_pty_success, handle_pty_failure };
2147    
2148     set_uint32(outmsg, len);
2149     memcpy(outmsg + 4, pvar->ts->TermType, len);
2150     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2151     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2152     set_uint32(outmsg + 4 + len + 8, 0);
2153     set_uint32(outmsg + 4 + len + 12, 0);
2154     memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2155     finish_send_packet(pvar);
2156    
2157     enque_handlers(pvar, 2, msgs, handlers);
2158    
2159     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2160     finish_send_packet(pvar);
2161     }
2162    
2163     static BOOL handle_agent_request_success(PTInstVar pvar)
2164     {
2165     pvar->agentfwd_enable = TRUE;
2166     prep_pty(pvar);
2167     return FALSE;
2168     }
2169    
2170     static BOOL handle_agent_request_failure(PTInstVar pvar)
2171     {
2172     prep_pty(pvar);
2173     return FALSE;
2174     }
2175    
2176     static void prep_agent_request(PTInstVar pvar)
2177     {
2178     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2179     static const SSHPacketHandler handlers[]
2180     = { handle_agent_request_success, handle_agent_request_failure };
2181    
2182     enque_handlers(pvar, 2, msgs, handlers);
2183    
2184     begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2185     finish_send_packet(pvar);
2186     }
2187    
2188     static void prep_forwarding(PTInstVar pvar)
2189     {
2190     FWD_prep_forwarding(pvar);
2191    
2192     if (pvar->session_settings.ForwardAgent) {
2193     prep_agent_request(pvar);
2194     }
2195     else {
2196     prep_pty(pvar);
2197     }
2198     }
2199    
2200    
2201     //
2202     //
2203     // (2005.7.10 yutaka)
2204     static void enable_send_compression(PTInstVar pvar)
2205     {
2206     static int initialize = 0;
2207    
2208     if (initialize) {
2209     deflateEnd(&pvar->ssh_state.compress_stream);
2210     }
2211     initialize = 1;
2212    
2213     pvar->ssh_state.compress_stream.zalloc = NULL;
2214     pvar->ssh_state.compress_stream.zfree = NULL;
2215     pvar->ssh_state.compress_stream.opaque = NULL;
2216     if (deflateInit
2217     (&pvar->ssh_state.compress_stream,
2218     pvar->ssh_state.compression_level) != Z_OK) {
2219     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2220     "An error occurred while setting up compression.\n"
2221     "The connection will close.");
2222     notify_fatal_error(pvar, pvar->ts->UIMsg);
2223     return;
2224     } else {
2225     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2226     if (SSHv2(pvar)) {
2227     pvar->ssh_state.compressing = FALSE;
2228     } else {
2229     pvar->ssh_state.compressing = TRUE;
2230     }
2231     }
2232     }
2233    
2234     static void enable_recv_compression(PTInstVar pvar)
2235     {
2236     static int initialize = 0;
2237    
2238     if (initialize) {
2239     deflateEnd(&pvar->ssh_state.decompress_stream);
2240     }
2241     initialize = 1;
2242    
2243     pvar->ssh_state.decompress_stream.zalloc = NULL;
2244     pvar->ssh_state.decompress_stream.zfree = NULL;
2245     pvar->ssh_state.decompress_stream.opaque = NULL;
2246     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2247     deflateEnd(&pvar->ssh_state.compress_stream);
2248     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2249     "An error occurred while setting up compression.\n"
2250     "The connection will close.");
2251     notify_fatal_error(pvar, pvar->ts->UIMsg);
2252     return;
2253     } else {
2254     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2255     if (SSHv2(pvar)) {
2256     pvar->ssh_state.decompressing = FALSE;
2257     } else {
2258     pvar->ssh_state.decompressing = TRUE;
2259     }
2260    
2261     buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2262     &pvar->ssh_state.postdecompress_inbuflen, 1000);
2263     }
2264     }
2265    
2266     static void enable_compression(PTInstVar pvar)
2267     {
2268     enable_send_compression(pvar);
2269     enable_recv_compression(pvar);
2270    
2271     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2272     if (SSHv2(pvar)) {
2273     pvar->ssh_state.compressing = FALSE;
2274     pvar->ssh_state.decompressing = FALSE;
2275     }
2276    
2277     }
2278    
2279     static BOOL handle_enable_compression(PTInstVar pvar)
2280     {
2281     enable_compression(pvar);
2282     prep_forwarding(pvar);
2283     return FALSE;
2284     }
2285    
2286     static BOOL handle_disable_compression(PTInstVar pvar)
2287     {
2288     prep_forwarding(pvar);
2289     return FALSE;
2290     }
2291    
2292     static void prep_compression(PTInstVar pvar)
2293     {
2294     if (pvar->session_settings.CompressionLevel > 0) {
2295     // added if statement (2005.7.10 yutaka)
2296     if (SSHv1(pvar)) {
2297     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2298     static const SSHPacketHandler handlers[]
2299     = { handle_enable_compression, handle_disable_compression };
2300    
2301     unsigned char FAR *outmsg =
2302     begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2303    
2304     set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2305     finish_send_packet(pvar);
2306    
2307     enque_handlers(pvar, 2, msgs, handlers);
2308     }
2309    
2310     pvar->ssh_state.compression_level =
2311     pvar->session_settings.CompressionLevel;
2312    
2313     } else {
2314     // added if statement (2005.7.10 yutaka)
2315     if (SSHv1(pvar)) {
2316     prep_forwarding(pvar);
2317     }
2318     }
2319     }
2320    
2321     static void enque_simple_auth_handlers(PTInstVar pvar)
2322     {
2323     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2324     static const SSHPacketHandler handlers[]
2325     = { handle_auth_success, handle_auth_failure };
2326    
2327     enque_handlers(pvar, 2, msgs, handlers);
2328     }
2329    
2330     static BOOL handle_rsa_challenge(PTInstVar pvar)
2331     {
2332     int challenge_bytes;
2333    
2334     if (!grab_payload(pvar, 2)) {
2335     return FALSE;
2336     }
2337    
2338     challenge_bytes = get_mpint_len(pvar, 0);
2339    
2340     if (grab_payload(pvar, challenge_bytes)) {
2341     unsigned char FAR *outmsg =
2342     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2343    
2344     if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2345     if (CRYPT_generate_RSA_challenge_response
2346     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2347    
2348     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2349     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2350     #if 0
2351     //AUTH_destroy_cur_cred(pvar);
2352     #endif
2353    
2354     finish_send_packet(pvar);
2355    
2356     enque_simple_auth_handlers(pvar);
2357     } else {
2358     UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2359     "An error occurred while decrypting the RSA challenge.\n"
2360     "Perhaps the key file is corrupted.");
2361     notify_fatal_error(pvar, pvar->ts->UIMsg);
2362     }
2363     }
2364     else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2365     int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2366     int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2367     int server_key_bytes = (server_key_bits + 7) / 8;
2368     int host_key_bytes = (host_key_bits + 7) / 8;
2369     int session_buf_len = server_key_bytes + host_key_bytes + 8;
2370     char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2371     unsigned char session_id[16];
2372    
2373     unsigned char *hash;
2374     int pubkeylen, hashlen;
2375    
2376     /* Pageant ���n�b�V�����v�Z���������� */
2377     // ���J��������
2378     pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2379     pvar->pageant_keylistlen);
2380     // �Z�b�V����ID������
2381     BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2382     BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2383     session_buf + host_key_bytes);
2384     memcpy(session_buf + server_key_bytes + host_key_bytes,
2385     pvar->crypt_state.server_cookie, 8);
2386     MD5(session_buf, session_buf_len, session_id);
2387     // �n�b�V������������
2388     hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2389     pubkeylen,
2390     pvar->ssh_state.payload,
2391     challenge_bytes + 2,
2392     session_id,
2393     &hashlen);
2394    
2395     // �n�b�V�������M
2396     memcpy(outmsg, hash, 16);
2397     free(hash);
2398    
2399     finish_send_packet(pvar);
2400    
2401     enque_simple_auth_handlers(pvar);
2402     }
2403     }
2404    
2405     return FALSE;
2406     }
2407    
2408     #define OBFUSCATING_ROUND_TO 32
2409    
2410     static int obfuscating_round_up(PTInstVar pvar, int size)
2411     {
2412     return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2413     }
2414    
2415     static void try_send_credentials(PTInstVar pvar)
2416     {
2417     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2418     AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2419     static const int RSA_msgs[] =
2420     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2421     static const SSHPacketHandler RSA_handlers[]
2422     = { handle_rsa_challenge, handle_rsa_auth_refused };
2423     static const int TIS_msgs[] =
2424     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2425     static const SSHPacketHandler TIS_handlers[]
2426     = { handle_TIS_challenge, handle_auth_failure };
2427    
2428     // SSH2���������������������X�L�b�v
2429     if (SSHv2(pvar))
2430     goto skip_ssh2;
2431    
2432     switch (cred->method) {
2433     case SSH_AUTH_NONE:
2434     return;
2435     case SSH_AUTH_PASSWORD:{
2436     int len = strlen(cred->password);
2437     // Round up password length to discourage traffic analysis
2438     int obfuscated_len = obfuscating_round_up(pvar, len);
2439     unsigned char FAR *outmsg =
2440     begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2441     4 + obfuscated_len);
2442    
2443     notify_verbose_message(pvar,
2444     "Trying PASSWORD authentication...",
2445     LOG_LEVEL_VERBOSE);
2446    
2447     set_uint32(outmsg, obfuscated_len);
2448     memcpy(outmsg + 4, cred->password, len);
2449     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2450    
2451     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2452     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2453     #if 0
2454     //AUTH_destroy_cur_cred(pvar);
2455     #endif
2456    
2457     enque_simple_auth_handlers(pvar);
2458     break;
2459     }
2460     case SSH_AUTH_RHOSTS:{
2461     int len = strlen(cred->rhosts_client_user);
2462     unsigned char FAR *outmsg =
2463     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2464    
2465     notify_verbose_message(pvar,
2466     "Trying RHOSTS authentication...",
2467     LOG_LEVEL_VERBOSE);
2468    
2469     set_uint32(outmsg, len);
2470     memcpy(outmsg + 4, cred->rhosts_client_user, len);
2471     AUTH_destroy_cur_cred(pvar);
2472     enque_simple_auth_handlers(pvar);
2473     break;
2474     }
2475     case SSH_AUTH_RSA:{
2476     int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2477     unsigned char FAR *outmsg =
2478     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2479    
2480     notify_verbose_message(pvar,
2481     "Trying RSA authentication...",
2482     LOG_LEVEL_VERBOSE);
2483    
2484     set_ushort16_MSBfirst(outmsg, len * 8);
2485     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2486     /* don't destroy the current credentials yet */
2487     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2488     break;
2489     }
2490     case SSH_AUTH_RHOSTS_RSA:{
2491     int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2492     int name_len = strlen(cred->rhosts_client_user);
2493     int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2494     int index;
2495     unsigned char FAR *outmsg =
2496     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2497     12 + mod_len + name_len + exp_len);
2498    
2499     notify_verbose_message(pvar,
2500     "Trying RHOSTS+RSA authentication...",
2501     LOG_LEVEL_VERBOSE);
2502    
2503     set_uint32(outmsg, name_len);
2504     memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2505     index = 4 + name_len;
2506    
2507     set_uint32(outmsg + index, 8 * mod_len);
2508     set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2509     BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2510     index += 6 + exp_len;
2511    
2512     set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2513     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2514     /* don't destroy the current credentials yet */
2515     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2516     break;
2517     }
2518     case SSH_AUTH_PAGEANT:{
2519     unsigned char FAR *outmsg;
2520     unsigned char *pubkey;
2521     int len, bn_bytes;
2522    
2523     if (pvar->pageant_keycurrent != 0) {
2524     // ���O�������X�L�b�v
2525     pvar->pageant_curkey += 4;
2526     len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2527     bn_bytes = (len + 7) / 8;
2528     pvar->pageant_curkey += 2 + bn_bytes;
2529     len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2530     bn_bytes = (len + 7) / 8;
2531     pvar->pageant_curkey += 2 + bn_bytes;
2532     // ���O�������R�����g���X�L�b�v
2533     len = get_uint32_MSBfirst(pvar->pageant_curkey);
2534     pvar->pageant_curkey += 4 + len;
2535     // �����������u������
2536     }
2537     pubkey = pvar->pageant_curkey + 4;
2538     len = get_ushort16_MSBfirst(pubkey);
2539     bn_bytes = (len + 7) / 8;
2540     pubkey += 2 + bn_bytes;
2541     len = get_ushort16_MSBfirst(pubkey);
2542     bn_bytes = (len + 7) / 8;
2543     pubkey += 2;
2544     outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2545    
2546     notify_verbose_message(pvar,
2547     "Trying RSA authentication...",
2548     LOG_LEVEL_VERBOSE);
2549    
2550     set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2551     memcpy(outmsg + 2, pubkey, bn_bytes);
2552     /* don't destroy the current credentials yet */
2553    
2554     pvar->pageant_keycurrent++;
2555    
2556     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2557     break;
2558     }
2559     case SSH_AUTH_TIS:{
2560     if (cred->password == NULL) {
2561     unsigned char FAR *outmsg =
2562     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2563    
2564     notify_verbose_message(pvar,
2565     "Trying TIS authentication...",