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 4494 - (hide annotations) (download) (as text)
Sun Jun 12 11:34:56 2011 UTC (12 years, 10 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 244045 byte(s)
SCPファイル送信の性能改善のため、ファイルバッファを 8KB -> 32KB へ拡張した。
ただし、パケット圧縮なしの場合のみ。

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