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 4476 - (hide annotations) (download) (as text)
Mon May 30 13:04:11 2011 UTC (12 years, 10 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 242500 byte(s)
SSH2の場合にはポート転送以外のチャネルでFWD_free_channelを呼んではいけないのに呼んでいたのを修正
  http://sourceforge.jp/ticket/browse.php?group_id=1412&tid=25169
  ただし、別の問題が残っている模様
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     #endif
1101     //if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;
1102     CRYPT_set_random_data(pvar, data + 5 + len, padding);
1103     ret = CRYPT_build_sender_MAC(pvar,
1104     pvar->ssh_state.sender_sequence_number,
1105     data, encryption_size,
1106     data + encryption_size);
1107     if (ret == FALSE) { // HMAC��������������������������
1108     data_length = encryption_size;
1109     }
1110    
1111     // �p�P�b�g�������������BHMAC���~�������������O�B
1112     CRYPT_encrypt(pvar, data, encryption_size);
1113     }
1114    
1115     send_packet_blocking(pvar, data, data_length);
1116    
1117     buffer_free(msg);
1118    
1119     pvar->ssh_state.sender_sequence_number++;
1120    
1121     // ���M�������L�^
1122     pvar->ssh_heartbeat_tick = time(NULL);
1123     }
1124    
1125     static void destroy_packet_buf(PTInstVar pvar)
1126     {
1127     memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1128     if (pvar->ssh_state.compressing) {
1129     memset(pvar->ssh_state.precompress_outbuf, 0,
1130     pvar->ssh_state.precompress_outbuflen);
1131     }
1132     }
1133    
1134     /* The handlers are added to the queue for each message. When one of the
1135     handlers fires, if it returns FALSE, then all handlers in the set are
1136     removed from their queues. */
1137     static void enque_handlers(PTInstVar pvar, int num_msgs,
1138     const int FAR * messages,
1139     const SSHPacketHandler FAR * handlers)
1140     {
1141     SSHPacketHandlerItem FAR *first_item;
1142     SSHPacketHandlerItem FAR *last_item = NULL;
1143     int i;
1144    
1145     for (i = 0; i < num_msgs; i++) {
1146     SSHPacketHandlerItem FAR *item =
1147     (SSHPacketHandlerItem FAR *)
1148     malloc(sizeof(SSHPacketHandlerItem));
1149     SSHPacketHandlerItem FAR *cur_item =
1150     pvar->ssh_state.packet_handlers[messages[i]];
1151    
1152     item->handler = handlers[i];
1153    
1154     if (cur_item == NULL) {
1155     pvar->ssh_state.packet_handlers[messages[i]] = item;
1156     item->next_for_message = item;
1157     item->last_for_message = item;
1158     item->active_for_message = messages[i];
1159     } else {
1160     item->next_for_message = cur_item;
1161     item->last_for_message = cur_item->last_for_message;
1162     cur_item->last_for_message->next_for_message = item;
1163     cur_item->last_for_message = item;
1164     item->active_for_message = -1;
1165     }
1166    
1167     if (last_item != NULL) {
1168     last_item->next_in_set = item;
1169     } else {
1170     first_item = item;
1171     }
1172     last_item = item;
1173     }
1174    
1175     if (last_item != NULL) {
1176     last_item->next_in_set = first_item;
1177     }
1178     }
1179    
1180     static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1181     {
1182     SSHPacketHandlerItem FAR *cur_item =
1183     pvar->ssh_state.packet_handlers[message];
1184    
1185     if (cur_item == NULL) {
1186     return NULL;
1187     } else {
1188     return cur_item->handler;
1189     }
1190     }
1191    
1192     /* Called only by SSH_handle_packet */
1193     static void deque_handlers(PTInstVar pvar, int message)
1194     {
1195     SSHPacketHandlerItem FAR *cur_item =
1196     pvar->ssh_state.packet_handlers[message];
1197     SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1198    
1199     if (cur_item == NULL)
1200     return;
1201    
1202     do {
1203     SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1204    
1205     if (cur_item->active_for_message >= 0) {
1206     SSHPacketHandlerItem FAR *replacement =
1207     cur_item->next_for_message;
1208    
1209     if (replacement == cur_item) {
1210     replacement = NULL;
1211     } else {
1212     replacement->active_for_message =
1213     cur_item->active_for_message;
1214     }
1215     pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1216     replacement;
1217     }
1218     cur_item->next_for_message->last_for_message =
1219     cur_item->last_for_message;
1220     cur_item->last_for_message->next_for_message =
1221     cur_item->next_for_message;
1222    
1223     free(cur_item);
1224     cur_item = next_in_set;
1225     } while (cur_item != first_item_in_set);
1226     }
1227    
1228     static void enque_handler(PTInstVar pvar, int message,
1229     SSHPacketHandler handler)
1230     {
1231     enque_handlers(pvar, 1, &message, &handler);
1232     }
1233    
1234     static void chop_newlines(char FAR * buf)
1235     {
1236     int len = strlen(buf);
1237    
1238     while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1239     buf[len - 1] = 0;
1240     len--;
1241     }
1242     }
1243    
1244     /********************/
1245     /* Message handlers */
1246     /********************/
1247    
1248     static BOOL handle_forwarding_success(PTInstVar pvar)
1249     {
1250     return FALSE;
1251     }
1252    
1253     static BOOL handle_forwarding_failure(PTInstVar pvar)
1254     {
1255     return FALSE;
1256     }
1257    
1258     static void enque_forwarding_request_handlers(PTInstVar pvar)
1259     {
1260     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1261     static const SSHPacketHandler handlers[]
1262     = { handle_forwarding_success, handle_forwarding_failure };
1263    
1264     enque_handlers(pvar, 2, msgs, handlers);
1265     }
1266    
1267     static BOOL handle_auth_failure(PTInstVar pvar)
1268     {
1269     notify_verbose_message(pvar, "Authentication failed",
1270     LOG_LEVEL_VERBOSE);
1271    
1272     // retry count������ (2005.7.15 yutaka)
1273     pvar->userauth_retry_count++;
1274    
1275     AUTH_set_generic_mode(pvar);
1276     AUTH_advance_to_next_cred(pvar);
1277     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1278     try_send_credentials(pvar);
1279     return FALSE;
1280     }
1281    
1282     static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1283     {
1284     if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1285     if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1286     // �S�������������I������
1287     safefree(pvar->pageant_key);
1288     }
1289     else {
1290     // ������������
1291     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1292     try_send_credentials(pvar);
1293     return TRUE;
1294     }
1295     }
1296     AUTH_destroy_cur_cred(pvar);
1297     return handle_auth_failure(pvar);
1298     }
1299    
1300     static BOOL handle_TIS_challenge(PTInstVar pvar)
1301     {
1302     if (grab_payload(pvar, 4)) {
1303     int len = get_payload_uint32(pvar, 0);
1304    
1305     if (grab_payload(pvar, len)) {
1306     notify_verbose_message(pvar, "Received TIS challenge",
1307     LOG_LEVEL_VERBOSE);
1308    
1309     AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1310     AUTH_advance_to_next_cred(pvar);
1311     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1312     try_send_credentials(pvar);
1313     }
1314     }
1315     return FALSE;
1316     }
1317    
1318     static BOOL handle_auth_required(PTInstVar pvar)
1319     {
1320     notify_verbose_message(pvar, "Server requires authentication",
1321     LOG_LEVEL_VERBOSE);
1322    
1323     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1324     try_send_credentials(pvar);
1325     /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1326    
1327     return FALSE;
1328     }
1329    
1330     static BOOL handle_ignore(PTInstVar pvar)
1331     {
1332     if (SSHv1(pvar)) {
1333     notify_verbose_message(pvar, "SSH_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1334    
1335     if (grab_payload(pvar, 4)
1336     && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1337     /* ignore it! but it must be decompressed */
1338     }
1339     }
1340     else {
1341     notify_verbose_message(pvar, "SSH2_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1342    
1343     // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1344     // Cisco ���[�^���� (2006.11.28 maya)
1345     }
1346     return TRUE;
1347     }
1348    
1349     static BOOL handle_debug(PTInstVar pvar)
1350     {
1351     BOOL always_display;
1352     char FAR *description;
1353     int description_len;
1354     char buf[2048];
1355    
1356     if (SSHv1(pvar)) {
1357     notify_verbose_message(pvar, "SSH_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1358    
1359     if (grab_payload(pvar, 4)
1360     && grab_payload(pvar, description_len =
1361     get_payload_uint32(pvar, 0))) {
1362     always_display = FALSE;
1363     description = pvar->ssh_state.payload + 4;
1364     description[description_len] = 0;
1365     } else {
1366     return TRUE;
1367     }
1368     } else {
1369     notify_verbose_message(pvar, "SSH2_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1370    
1371     if (grab_payload(pvar, 5)
1372     && grab_payload(pvar,
1373     (description_len = get_payload_uint32(pvar, 1)) + 4)
1374     && grab_payload(pvar,
1375     get_payload_uint32(pvar, 5 + description_len))) {
1376     always_display = pvar->ssh_state.payload[0] != 0;
1377     description = pvar->ssh_state.payload + 5;
1378     description[description_len] = 0;
1379     } else {
1380     return TRUE;
1381     }
1382     }
1383    
1384     chop_newlines(description);
1385     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1386     description);
1387     if (always_display) {
1388     notify_nonfatal_error(pvar, buf);
1389     } else {
1390     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1391     }
1392     return TRUE;
1393     }
1394    
1395     static BOOL handle_disconnect(PTInstVar pvar)
1396     {
1397     int reason_code;
1398     char FAR *description;
1399     int description_len;
1400     char buf[2048];
1401     char FAR *explanation = "";
1402     char uimsg[MAX_UIMSG];
1403    
1404     if (SSHv1(pvar)) {
1405     notify_verbose_message(pvar, "SSH_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1406    
1407     if (grab_payload(pvar, 4)
1408     && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1409     reason_code = -1;
1410     description = pvar->ssh_state.payload + 4;
1411     description[description_len] = 0;
1412     } else {
1413     return TRUE;
1414     }
1415     } else {
1416     notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1417    
1418     if (grab_payload(pvar, 8)
1419     && grab_payload(pvar,
1420     (description_len = get_payload_uint32(pvar, 4)) + 4)
1421     && grab_payload(pvar,
1422     get_payload_uint32(pvar, 8 + description_len))) {
1423     reason_code = get_payload_uint32(pvar, 0);
1424     description = pvar->ssh_state.payload + 8;
1425     description[description_len] = 0;
1426     } else {
1427     return TRUE;
1428     }
1429     }
1430    
1431     chop_newlines(description);
1432     if (description[0] == 0) {
1433     description = NULL;
1434     }
1435    
1436     if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1437     UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1438     "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1439     "This often happens when someone is already forwarding that port from the server.");
1440     strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1441     explanation = uimsg;
1442     }
1443    
1444     if (description != NULL) {
1445     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1446     "Server disconnected with message '%s'%s");
1447     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1448     pvar->ts->UIMsg, description,
1449     explanation);
1450     } else {
1451     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1452     "Server disconnected (no reason given).%s");
1453     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1454     pvar->ts->UIMsg, explanation);
1455     }
1456     notify_fatal_error(pvar, buf);
1457    
1458     return TRUE;
1459     }
1460    
1461     static BOOL handle_unimplemented(PTInstVar pvar)
1462     {
1463     /* Should never receive this since we only send base 2.0 protocol messages */
1464     grab_payload(pvar, 4);
1465     return TRUE;
1466     }
1467    
1468     static BOOL handle_crypt_success(PTInstVar pvar)
1469     {
1470     notify_verbose_message(pvar, "Secure mode successfully achieved",
1471     LOG_LEVEL_VERBOSE);
1472     return FALSE;
1473     }
1474    
1475     static BOOL handle_noauth_success(PTInstVar pvar)
1476     {
1477     notify_verbose_message(pvar, "Server does not require authentication",
1478     LOG_LEVEL_VERBOSE);
1479     prep_compression(pvar);
1480     return FALSE;
1481     }
1482    
1483     static BOOL handle_auth_success(PTInstVar pvar)
1484     {
1485     notify_verbose_message(pvar, "Authentication accepted",
1486     LOG_LEVEL_VERBOSE);
1487     prep_compression(pvar);
1488    
1489     // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1490     start_ssh_heartbeat_thread(pvar);
1491    
1492     return FALSE;
1493     }
1494    
1495     static BOOL handle_server_public_key(PTInstVar pvar)
1496     {
1497     int server_key_public_exponent_len;
1498     int server_key_public_modulus_pos;
1499     int server_key_public_modulus_len;
1500     int host_key_bits_pos;
1501     int host_key_public_exponent_len;
1502     int host_key_public_modulus_pos;
1503     int host_key_public_modulus_len;
1504     int protocol_flags_pos;
1505     int supported_ciphers;
1506     char FAR *inmsg;
1507     Key hostkey;
1508     int supported_types;
1509    
1510     notify_verbose_message(pvar, "SSH_SMSG_PUBLIC_KEY was received.", LOG_LEVEL_VERBOSE);
1511    
1512     if (!grab_payload(pvar, 14))
1513     return FALSE;
1514     server_key_public_exponent_len = get_mpint_len(pvar, 12);
1515    
1516     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1517     return FALSE;
1518     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1519     server_key_public_modulus_len =
1520     get_mpint_len(pvar, server_key_public_modulus_pos);
1521    
1522     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1523     return FALSE;
1524     host_key_bits_pos =
1525     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1526     host_key_public_exponent_len =
1527     get_mpint_len(pvar, host_key_bits_pos + 4);
1528    
1529     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1530     return FALSE;
1531     host_key_public_modulus_pos =
1532     host_key_bits_pos + 6 + host_key_public_exponent_len;
1533     host_key_public_modulus_len =
1534     get_mpint_len(pvar, host_key_public_modulus_pos);
1535    
1536     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1537     return FALSE;
1538     protocol_flags_pos =
1539     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1540    
1541     inmsg = pvar->ssh_state.payload;
1542    
1543     CRYPT_set_server_cookie(pvar, inmsg);
1544     if (!CRYPT_set_server_RSA_key(pvar,
1545     get_uint32(inmsg + 8),
1546     pvar->ssh_state.payload + 12,
1547     inmsg + server_key_public_modulus_pos))
1548     return FALSE;
1549     if (!CRYPT_set_host_RSA_key(pvar,
1550     get_uint32(inmsg + host_key_bits_pos),
1551     inmsg + host_key_bits_pos + 4,
1552     inmsg + host_key_public_modulus_pos))
1553     return FALSE;
1554     pvar->ssh_state.server_protocol_flags =
1555     get_uint32(inmsg + protocol_flags_pos);
1556    
1557     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1558     if (!CRYPT_set_supported_ciphers(pvar,
1559     supported_ciphers,
1560     supported_ciphers))
1561     return FALSE;
1562    
1563     // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1564     // RSA ���L������ PAGEANT ���L��������
1565     supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1566     if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1567     supported_types |= (1 << SSH_AUTH_PAGEANT);
1568     }
1569     if (!AUTH_set_supported_auth_types(pvar,
1570     supported_types))
1571     return FALSE;
1572    
1573     /* this must be the LAST THING in this function, since it can cause
1574     host_is_OK to be called. */
1575     hostkey.type = KEY_RSA1;
1576     hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1577     hostkey.exp = inmsg + host_key_bits_pos + 4;
1578     hostkey.mod = inmsg + host_key_public_modulus_pos;
1579     HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1580    
1581     return FALSE;
1582     }
1583    
1584     /*
1585     The ID must have already been found to start with "SSH-". It must
1586     be null-terminated.
1587     */
1588     static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1589     {
1590     char FAR *str;
1591    
1592     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1593     }
1594    
1595     if (*str != '.') {
1596     return FALSE;
1597     }
1598    
1599     pvar->protocol_major = atoi(ID + 4);
1600     pvar->protocol_minor = atoi(str + 1);
1601    
1602     // for SSH2(yutaka)
1603     // 1.99����SSH2�����������s��
1604     if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
1605     // ���[�U�� SSH2 ���I������������������
1606     if (pvar->settings.ssh_protocol_version == 2) {
1607     pvar->protocol_major = 2;
1608     pvar->protocol_minor = 0;
1609     }
1610    
1611     }
1612    
1613     // SSH �o�[�W������ teraterm �����Z�b�g����
1614     // SCP �R�}���h������ (2008.2.3 maya)
1615     pvar->cv->isSSH = pvar->protocol_major;
1616    
1617     for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1618     }
1619    
1620     return *str == '-';
1621     }
1622    
1623     /*
1624     On entry, the pvar->protocol_xxx fields hold the server's advertised
1625     protocol number. We replace the fields with the protocol number we will
1626     actually use, or return FALSE if there is no usable protocol version.
1627     */
1628     static BOOL negotiate_protocol(PTInstVar pvar)
1629     {
1630     switch (pvar->protocol_major) {
1631     case 1:
1632     if (pvar->protocol_minor > 5) {
1633     pvar->protocol_minor = 5;
1634     }
1635    
1636     return TRUE;
1637    
1638     // for SSH2(yutaka)
1639     case 2:
1640     return TRUE; // SSH2 support
1641    
1642     default:
1643     return FALSE;
1644     }
1645     }
1646    
1647     static void init_protocol(PTInstVar pvar)
1648     {
1649     CRYPT_initialize_random_numbers(pvar);
1650    
1651     // known_hosts�t�@�C�������z�X�g���J������������������
1652     HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1653    
1654     /* while we wait for a response from the server... */
1655    
1656     if (SSHv1(pvar)) {
1657     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1658     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1659     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1660     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1661    
1662     } else { // for SSH2(yutaka)
1663     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1664     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1665     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1666     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1667     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1668     enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1669     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1670     enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1671     enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1672     enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1673     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1674     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1675     enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1676 yutakapon 4152 enque_handler(pvar, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, handle_SSH2_userauth_passwd_changereq);
1677 maya 3227
1678     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1679    
1680     // ���[�U�F�������f�B�X�p�b�`���[�`��
1681     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1682     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1683     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1684     enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1685     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1686     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1687     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1688     enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1689     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1690     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1691     enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1692     // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1693     enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1694     enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1695    
1696     }
1697     }
1698    
1699     BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1700     {
1701     static const char prefix[] = "Received server prologue string: ";
1702    
1703     // initialize SSH2 memory dump (2005.3.7 yutaka)
1704     init_memdump();
1705     push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1706    
1707     if (ID_len <= 0) {
1708     return FALSE;
1709     } else {
1710     int buf_len = ID_len + NUM_ELEM(prefix);
1711     char FAR *buf = (char FAR *) malloc(buf_len);
1712    
1713     strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1714     strncat_s(buf, buf_len, ID, _TRUNCATE);
1715     chop_newlines(buf);
1716    
1717     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1718    
1719     free(buf);
1720    
1721    
1722     // ���������R�s�[������ (2005.3.9 yutaka)
1723     #if 0
1724     // for calculate SSH2 hash
1725     // �T�[�o�o�[�W�����������i���s���������������j
1726     if (ID_len >= sizeof(pvar->server_version_string))
1727     return FALSE;
1728     strncpy(pvar->server_version_string, ID, ID_len);
1729     #endif
1730    
1731    
1732     if (ID[ID_len - 1] != '\n') {
1733     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1734     return FALSE;
1735     } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1736     pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1737     return FALSE;
1738     } else if (strncmp(ID, "SSH-", 4) != 0) {
1739     return FALSE;
1740     } else {
1741     ID[ID_len - 1] = 0;
1742    
1743     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1744     ID[ID_len - 2] = 0;
1745     }
1746    
1747     pvar->ssh_state.server_ID = _strdup(ID);
1748    
1749     if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1750     UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1751     "This program does not understand the server's version of the protocol.");
1752     notify_fatal_error(pvar, pvar->ts->UIMsg);
1753     } else {
1754     char TTSSH_ID[1024];
1755     int TTSSH_ID_len;
1756     int a, b, c, d;
1757    
1758     // �������g���o�[�W�������������� (2005.3.3 yutaka)
1759     get_file_version("ttxssh.dll", &a, &b, &c, &d);
1760    
1761     _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1762     "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1763     pvar->protocol_major, pvar->protocol_minor, a, b);
1764     TTSSH_ID_len = strlen(TTSSH_ID);
1765    
1766     // for SSH2(yutaka)
1767     // �N���C�A���g�o�[�W�����������i���s���������������j
1768     strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1769     TTSSH_ID, _TRUNCATE);
1770    
1771     // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1772     _snprintf_s(pvar->server_version_string,
1773     sizeof(pvar->server_version_string), _TRUNCATE,
1774     "%s", pvar->ssh_state.server_ID);
1775    
1776     if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1777     0) != TTSSH_ID_len) {
1778     UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1779     "An error occurred while sending the SSH ID string.\n"
1780     "The connection will close.");
1781     notify_fatal_error(pvar, pvar->ts->UIMsg);
1782     } else {
1783     // ���s�R�[�h������ (2004.8.4 yutaka)
1784     pvar->client_version_string[--TTSSH_ID_len] = 0;
1785    
1786     push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1787     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1788    
1789     // SSH�n���h�����o�^���s��
1790     init_protocol(pvar);
1791    
1792     SSH2_dispatch_init(1);
1793     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1794     SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1795     }
1796     }
1797    
1798     return TRUE;
1799     }
1800     }
1801     }
1802    
1803     static BOOL handle_exit(PTInstVar pvar)
1804     {
1805     if (grab_payload(pvar, 4)) {
1806     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1807     finish_send_packet(pvar);
1808     notify_closed_connection(pvar);
1809     }
1810     return TRUE;
1811     }
1812    
1813     static BOOL handle_data(PTInstVar pvar)
1814     {
1815     if (grab_payload_limited(pvar, 4)) {
1816     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1817     pvar->ssh_state.payload_datastart = 4;
1818     }
1819     return TRUE;
1820     }
1821    
1822     static BOOL handle_channel_open(PTInstVar pvar)
1823     {
1824     int host_len;
1825     int originator_len;
1826    
1827     if ((pvar->ssh_state.
1828     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1829     if (grab_payload(pvar, 8)
1830     && grab_payload(pvar,
1831     8 + (host_len = get_payload_uint32(pvar, 4)))
1832     && grab_payload(pvar, originator_len =
1833     get_payload_uint32(pvar, host_len + 12))) {
1834     int local_port = get_payload_uint32(pvar, 8 + host_len);
1835    
1836     pvar->ssh_state.payload[8 + host_len] = 0;
1837     FWD_open(pvar, get_payload_uint32(pvar, 0),
1838     pvar->ssh_state.payload + 8, local_port,
1839     pvar->ssh_state.payload + 16 + host_len,
1840     originator_len,
1841     NULL);
1842     }
1843     } else {
1844     if (grab_payload(pvar, 8)
1845     && grab_payload(pvar,
1846     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1847     int local_port = get_payload_uint32(pvar, 8 + host_len);
1848    
1849     pvar->ssh_state.payload[8 + host_len] = 0;
1850     FWD_open(pvar, get_payload_uint32(pvar, 0),
1851     pvar->ssh_state.payload + 8, local_port, NULL, 0,
1852     NULL);
1853     }
1854     }
1855    
1856     return TRUE;
1857     }
1858    
1859     static BOOL handle_X11_channel_open(PTInstVar pvar)
1860     {
1861     int originator_len;
1862    
1863     if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1864     if (grab_payload(pvar, 8)
1865     && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1866     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1867     pvar->ssh_state.payload + 8, originator_len, NULL);
1868     }
1869     } else {
1870     if (grab_payload(pvar, 4)) {
1871     FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1872     }
1873     }
1874    
1875     return TRUE;
1876     }
1877    
1878     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1879     {
1880     if (grab_payload(pvar, 8)) {
1881     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1882     get_payload_uint32(pvar, 4));
1883     }
1884     return FALSE;
1885     }
1886    
1887     static BOOL handle_channel_open_failure(PTInstVar pvar)
1888     {
1889     if (grab_payload(pvar, 4)) {
1890     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1891     }
1892     return FALSE;
1893     }
1894    
1895     static BOOL handle_channel_data(PTInstVar pvar)
1896     {
1897     int len;
1898    
1899     if (grab_payload(pvar, 8)
1900     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1901     FWDChannel *channel;
1902     int local_channel_num = get_payload_uint32(pvar, 0);
1903     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1904     return FALSE;
1905     }
1906     channel = pvar->fwd_state.channels + local_channel_num;
1907     if (channel->type == TYPE_AGENT) {
1908     SSH_agent_response(pvar, NULL, local_channel_num,
1909     pvar->ssh_state.payload + 8, len);
1910     }
1911     else {
1912     FWD_received_data(pvar, local_channel_num,
1913     pvar->ssh_state.payload + 8, len);
1914     }
1915     }
1916     return TRUE;
1917     }
1918    
1919     static BOOL handle_channel_input_eof(PTInstVar pvar)
1920     {
1921     if (grab_payload(pvar, 4)) {
1922     int local_channel_num = get_payload_uint32(pvar, 0);
1923     FWDChannel *channel;
1924     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1925     return FALSE;
1926     }
1927     channel = pvar->fwd_state.channels + local_channel_num;
1928     if (channel->type == TYPE_AGENT) {
1929     channel->status |= FWD_CLOSED_REMOTE_IN;
1930     SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1931     }
1932     else {
1933     FWD_channel_input_eof(pvar, local_channel_num);
1934     }
1935     }
1936     return TRUE;
1937     }
1938    
1939     static BOOL handle_channel_output_eof(PTInstVar pvar)
1940     {
1941     if (grab_payload(pvar, 4)) {
1942     int local_channel_num = get_payload_uint32(pvar, 0);
1943     FWDChannel *channel;
1944     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1945     return FALSE;
1946     }
1947     channel = pvar->fwd_state.channels + local_channel_num;
1948     if (channel->type == TYPE_AGENT) {
1949     channel->status |= FWD_CLOSED_REMOTE_OUT;
1950     SSH_channel_output_eof(pvar, channel->remote_num);
1951     FWD_free_channel(pvar, local_channel_num);
1952     }
1953     else {
1954     FWD_channel_output_eof(pvar, local_channel_num);
1955     }
1956     }
1957     return TRUE;
1958     }
1959    
1960     static BOOL handle_agent_open(PTInstVar pvar)
1961     {
1962     if (grab_payload(pvar, 4)) {
1963     int remote_id = get_payload_uint32(pvar, 0);
1964     int local_id;
1965    
1966 doda 4233 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
1967 maya 3227 local_id = FWD_agent_open(pvar, remote_id);
1968     if (local_id == -1) {
1969     SSH_fail_channel_open(pvar, remote_id);
1970     }
1971     else {
1972     SSH_confirm_channel_open(pvar, remote_id, local_id);
1973     }
1974     }
1975     else {
1976     SSH_fail_channel_open(pvar, remote_id);
1977     }
1978     }
1979     /*
1980     else {
1981     // ���m��������channel����������������������������
1982     }
1983     */
1984    
1985     return TRUE;
1986     }
1987    
1988    
1989    
1990     // �n���h�����O�������b�Z�[�W����������
1991    
1992     #define HANDLE_MESSAGE_MAX 30
1993     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1994     static int handle_message_count = 0;
1995     static int handle_message_stage = 0;
1996    
1997     void SSH2_dispatch_init(int stage)
1998     {
1999     handle_message_count = 0;
2000     handle_message_stage = stage;
2001     }
2002    
2003     int SSH2_dispatch_enabled_check(unsigned char message)
2004     {
2005     int i;
2006    
2007     for (i = 0 ; i < handle_message_count ; i++) {
2008     if (handle_messages[i] == message)
2009     return 1;
2010     }
2011     return 0;
2012     }
2013    
2014     void SSH2_dispatch_add_message(unsigned char message)
2015     {
2016     int i;
2017    
2018     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2019     // TODO: error check
2020     return;
2021     }
2022    
2023     // �������o�^�������������b�Z�[�W������������
2024     for (i=0; i<handle_message_count; i++) {
2025     if (handle_messages[i] == message) {
2026     return;
2027     }
2028     }
2029    
2030     handle_messages[handle_message_count++] = message;
2031     }
2032    
2033     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2034     {
2035     unsigned char c;
2036    
2037     for (c = begin ; c <= end ; c++) {
2038     SSH2_dispatch_add_message(c);
2039     }
2040     }
2041    
2042    
2043     void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
2044     int padding)
2045     {
2046     unsigned char message = prep_packet(pvar, data, len, padding);
2047    
2048    
2049     #ifdef SSH2_DEBUG
2050     // for SSH2(yutaka)
2051     if (SSHv2(pvar)) {
2052     if (pvar->key_done) {
2053     message = message;
2054     }
2055    
2056     if (pvar->userauth_success) {
2057     message = message;
2058     }
2059    
2060     if (pvar->rekeying) {
2061     message = message;
2062     }
2063     }
2064     #endif
2065    
2066     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2067     if (message != SSH_MSG_NONE) {
2068     // ���b�Z�[�W�^�C�v���������n���h�����N��
2069     SSHPacketHandler handler = get_handler(pvar, message);
2070    
2071     // for SSH2(yutaka)
2072     if (SSHv2(pvar)) {
2073     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2074     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2075     char buf[1024];
2076    
2077     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2078     "Unexpected SSH2 message(%d) on current stage(%d)");
2079     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2080     pvar->ts->UIMsg, message, handle_message_stage);
2081     notify_fatal_error(pvar, buf);
2082     // abort
2083     }
2084     }
2085    
2086     if (handler == NULL) {
2087     if (SSHv1(pvar)) {
2088     char buf[1024];
2089    
2090     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2091     "Unexpected packet type received: %d");
2092     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2093     pvar->ts->UIMsg, message, handle_message_stage);
2094     notify_fatal_error(pvar, buf);
2095     } else {
2096     unsigned char FAR *outmsg =
2097     begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2098    
2099     set_uint32(outmsg,
2100     pvar->ssh_state.receiver_sequence_number - 1);
2101     finish_send_packet(pvar);
2102    
2103     notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2104     /* XXX need to decompress incoming packet, but how? */
2105     }
2106     } else {
2107     if (!handler(pvar)) {
2108     deque_handlers(pvar, message);
2109     }
2110     }
2111     }
2112     }
2113    
2114     static BOOL handle_pty_success(PTInstVar pvar)
2115     {
2116     FWD_enter_interactive_mode(pvar);
2117     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2118     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2119     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2120     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2121     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2122     handle_channel_input_eof);
2123     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2124     handle_channel_output_eof);
2125     enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2126     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2127     enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2128     return FALSE;
2129     }
2130    
2131     static BOOL handle_pty_failure(PTInstVar pvar)
2132     {
2133     UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2134     "The server cannot allocate a pseudo-terminal. "
2135     "You may encounter some problems with the terminal.");
2136     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2137     return handle_pty_success(pvar);
2138     }
2139    
2140     static void prep_pty(PTInstVar pvar)
2141     {
2142     int len = strlen(pvar->ts->TermType);
2143     unsigned char FAR *outmsg =
2144     begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2145     4 + len + 16 + sizeof(ssh_ttymodes));
2146     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2147     static const SSHPacketHandler handlers[]
2148     = { handle_pty_success, handle_pty_failure };
2149    
2150     set_uint32(outmsg, len);
2151     memcpy(outmsg + 4, pvar->ts->TermType, len);
2152     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2153     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2154     set_uint32(outmsg + 4 + len + 8, 0);
2155     set_uint32(outmsg + 4 + len + 12, 0);
2156     memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2157     finish_send_packet(pvar);
2158    
2159     enque_handlers(pvar, 2, msgs, handlers);
2160    
2161     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2162     finish_send_packet(pvar);
2163     }
2164    
2165     static BOOL handle_agent_request_success(PTInstVar pvar)
2166     {
2167     pvar->agentfwd_enable = TRUE;
2168     prep_pty(pvar);
2169     return FALSE;
2170     }
2171    
2172     static BOOL handle_agent_request_failure(PTInstVar pvar)
2173     {
2174     prep_pty(pvar);
2175     return FALSE;
2176     }
2177    
2178     static void prep_agent_request(PTInstVar pvar)
2179     {
2180     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2181     static const SSHPacketHandler handlers[]
2182     = { handle_agent_request_success, handle_agent_request_failure };
2183    
2184     enque_handlers(pvar, 2, msgs, handlers);
2185    
2186     begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2187     finish_send_packet(pvar);
2188     }
2189    
2190     static void prep_forwarding(PTInstVar pvar)
2191     {
2192     FWD_prep_forwarding(pvar);
2193    
2194     if (pvar->session_settings.ForwardAgent) {
2195     prep_agent_request(pvar);
2196     }
2197     else {
2198     prep_pty(pvar);
2199     }
2200     }
2201    
2202    
2203     //
2204     //
2205     // (2005.7.10 yutaka)
2206     static void enable_send_compression(PTInstVar pvar)
2207     {
2208     static int initialize = 0;
2209    
2210     if (initialize) {
2211     deflateEnd(&pvar->ssh_state.compress_stream);
2212     }
2213     initialize = 1;
2214    
2215     pvar->ssh_state.compress_stream.zalloc = NULL;
2216     pvar->ssh_state.compress_stream.zfree = NULL;
2217     pvar->ssh_state.compress_stream.opaque = NULL;
2218     if (deflateInit
2219     (&pvar->ssh_state.compress_stream,
2220     pvar->ssh_state.compression_level) != Z_OK) {
2221     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2222     "An error occurred while setting up compression.\n"
2223     "The connection will close.");
2224     notify_fatal_error(pvar, pvar->ts->UIMsg);
2225     return;
2226     } else {
2227     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2228     if (SSHv2(pvar)) {
2229     pvar->ssh_state.compressing = FALSE;
2230     } else {
2231     pvar->ssh_state.compressing = TRUE;
2232     }
2233     }
2234     }
2235    
2236     static void enable_recv_compression(PTInstVar pvar)
2237     {
2238     static int initialize = 0;
2239    
2240     if (initialize) {
2241     deflateEnd(&pvar->ssh_state.decompress_stream);
2242     }
2243     initialize = 1;
2244    
2245     pvar->ssh_state.decompress_stream.zalloc = NULL;
2246     pvar->ssh_state.decompress_stream.zfree = NULL;
2247     pvar->ssh_state.decompress_stream.opaque = NULL;
2248     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2249     deflateEnd(&pvar->ssh_state.compress_stream);
2250     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2251     "An error occurred while setting up compression.\n"
2252     "The connection will close.");
2253     notify_fatal_error(pvar, pvar->ts->UIMsg);
2254     return;
2255     } else {
2256     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2257     if (SSHv2(pvar)) {
2258     pvar->ssh_state.decompressing = FALSE;
2259     } else {
2260     pvar->ssh_state.decompressing = TRUE;
2261     }
2262    
2263     buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2264     &pvar->ssh_state.postdecompress_inbuflen, 1000);
2265     }
2266     }
2267    
2268     static void enable_compression(PTInstVar pvar)
2269     {
2270     enable_send_compression(pvar);
2271     enable_recv_compression(pvar);
2272    
2273     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2274     if (SSHv2(pvar)) {
2275     pvar->ssh_state.compressing = FALSE;
2276     pvar->ssh_state.decompressing = FALSE;
2277     }
2278    
2279     }
2280    
2281     static BOOL handle_enable_compression(PTInstVar pvar)
2282     {
2283     enable_compression(pvar);
2284     prep_forwarding(pvar);
2285     return FALSE;
2286     }
2287    
2288     static BOOL handle_disable_compression(PTInstVar pvar)
2289     {
2290     prep_forwarding(pvar);
2291     return FALSE;
2292     }
2293    
2294     static void prep_compression(PTInstVar pvar)
2295     {
2296     if (pvar->session_settings.CompressionLevel > 0) {
2297     // added if statement (2005.7.10 yutaka)
2298     if (SSHv1(pvar)) {
2299     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2300     static const SSHPacketHandler handlers[]
2301     = { handle_enable_compression, handle_disable_compression };
2302    
2303     unsigned char FAR *outmsg =
2304     begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2305    
2306     set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2307     finish_send_packet(pvar);
2308    
2309     enque_handlers(pvar, 2, msgs, handlers);
2310     }
2311    
2312     pvar->ssh_state.compression_level =
2313     pvar->session_settings.CompressionLevel;
2314    
2315     } else {
2316     // added if statement (2005.7.10 yutaka)
2317     if (SSHv1(pvar)) {
2318     prep_forwarding(pvar);
2319     }
2320     }
2321     }
2322    
2323     static void enque_simple_auth_handlers(PTInstVar pvar)
2324     {
2325     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2326     static const SSHPacketHandler handlers[]
2327     = { handle_auth_success, handle_auth_failure };
2328    
2329     enque_handlers(pvar, 2, msgs, handlers);
2330     }
2331    
2332     static BOOL handle_rsa_challenge(PTInstVar pvar)
2333     {
2334     int challenge_bytes;
2335    
2336     if (!grab_payload(pvar, 2)) {
2337     return FALSE;
2338     }
2339    
2340     challenge_bytes = get_mpint_len(pvar, 0);
2341    
2342     if (grab_payload(pvar, challenge_bytes)) {
2343     unsigned char FAR *outmsg =
2344     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2345    
2346     if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2347     if (CRYPT_generate_RSA_challenge_response
2348     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2349    
2350     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2351     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2352     #if 0
2353     //AUTH_destroy_cur_cred(pvar);
2354     #endif
2355    
2356     finish_send_packet(pvar);
2357    
2358     enque_simple_auth_handlers(pvar);
2359     } else {
2360     UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2361     "An error occurred while decrypting the RSA challenge.\n"
2362     "Perhaps the key file is corrupted.");
2363     notify_fatal_error(pvar, pvar->ts->UIMsg);
2364     }
2365     }
2366     else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2367     int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2368     int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2369     int server_key_bytes = (server_key_bits + 7) / 8;
2370     int host_key_bytes = (host_key_bits + 7) / 8;
2371     int session_buf_len = server_key_bytes + host_key_bytes + 8;
2372     char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2373     unsigned char session_id[16];
2374    
2375     unsigned char *hash;
2376     int pubkeylen, hashlen;
2377    
2378     /* Pageant ���n�b�V�����v�Z���������� */
2379     // ���J��������
2380     pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2381     pvar->pageant_keylistlen);
2382     // �Z�b�V����ID������
2383     BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2384     BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2385     session_buf + host_key_bytes);
2386     memcpy(session_buf + server_key_bytes + host_key_bytes,
2387     pvar->crypt_state.server_cookie, 8);
2388     MD5(session_buf, session_buf_len, session_id);
2389     // �n�b�V������������
2390     hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2391     pubkeylen,
2392     pvar->ssh_state.payload,
2393     challenge_bytes + 2,
2394     session_id,
2395     &hashlen);
2396    
2397     // �n�b�V�������M
2398     memcpy(outmsg, hash, 16);
2399     free(hash);
2400    
2401     finish_send_packet(pvar);
2402    
2403     enque_simple_auth_handlers(pvar);
2404     }
2405     }
2406    
2407     return FALSE;
2408     }
2409    
2410     static void try_send_credentials(PTInstVar pvar)
2411     {
2412     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2413     AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2414     static const int RSA_msgs[] =
2415     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2416     static const SSHPacketHandler RSA_handlers[]
2417     = { handle_rsa_challenge, handle_rsa_auth_refused };
2418     static const int TIS_msgs[] =
2419     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2420     static const SSHPacketHandler TIS_handlers[]
2421     = { handle_TIS_challenge, handle_auth_failure };
2422    
2423     // SSH2���������������������X�L�b�v
2424     if (SSHv2(pvar))
2425     goto skip_ssh2;
2426    
2427     switch (cred->method) {
2428     case SSH_AUTH_NONE:
2429     return;
2430     case SSH_AUTH_PASSWORD:{
2431     int len = strlen(cred->password);
2432     unsigned char FAR *outmsg =
2433     begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2434 maya 4407 4 + len);
2435 maya 3227
2436     notify_verbose_message(pvar,
2437     "Trying PASSWORD authentication...",
2438     LOG_LEVEL_VERBOSE);
2439    
2440 maya 4407 set_uint32(outmsg, len);
2441 maya 3227 memcpy(outmsg + 4, cred->password, len);
2442    
2443     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2444     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2445     #if 0
2446     //AUTH_destroy_cur_cred(pvar);
2447     #endif
2448    
2449     enque_simple_auth_handlers(pvar);
2450     break;
2451     }
2452     case SSH_AUTH_RHOSTS:{
2453     int len = strlen(cred->rhosts_client_user);
2454     unsigned char FAR *outmsg =
2455     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2456    
2457     notify_verbose_message(pvar,
2458     "Trying RHOSTS authentication...",
2459     LOG_LEVEL_VERBOSE);
2460    
2461     set_uint32(outmsg, len);
2462     memcpy(outmsg + 4, cred->rhosts_client_user, len);
2463     AUTH_destroy_cur_cred(pvar);
2464     enque_simple_auth_handlers(pvar);
2465     break;
2466     }
2467     case SSH_AUTH_RSA:{
2468 maya 4307 int len = BN_num_bytes(cred->key_pair->rsa->n);
2469 maya 3227 unsigned char FAR *outmsg =
2470     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2471    
2472     notify_verbose_message(pvar,
2473     "Trying RSA authentication...",
2474     LOG_LEVEL_VERBOSE);
2475    
2476     set_ushort16_MSBfirst(outmsg, len * 8);
2477 maya 4307 BN_bn2bin(cred->key_pair->rsa->n, outmsg + 2);
2478 maya 3227 /* don't destroy the current credentials yet */
2479     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2480     break;
2481     }
2482     case SSH_AUTH_RHOSTS_RSA:{
2483 maya 4307 int mod_len = BN_num_bytes(cred->key_pair->rsa->n);
2484 maya 3227 int name_len = strlen(cred->rhosts_client_user);
2485 maya 4307 int exp_len = BN_num_bytes(cred->key_pair->rsa->e);
2486 maya 3227 int index;
2487     unsigned char FAR *outmsg =
2488     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2489     12 + mod_len + name_len + exp_len);
2490    
2491     notify_verbose_message(pvar,
2492     "Trying RHOSTS+RSA authentication...",
2493     LOG_LEVEL_VERBOSE);
2494    
2495     set_uint32(outmsg, name_len);
2496     memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2497     index = 4 + name_len;
2498    
2499     set_uint32(outmsg + index, 8 * mod_len);
2500     set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2501 maya 4307 BN_bn2bin(cred->key_pair->rsa->e, outmsg + index + 6);
2502 maya 3227 index += 6 + exp_len;
2503    
2504     set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2505 maya 4307 BN_bn2bin(cred->key_pair->rsa->n, outmsg + index + 2);
2506 maya 3227 /* don't destroy the current credentials yet */
2507     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2508     break;
2509     }
2510     case SSH_AUTH_PAGEANT:{
2511     unsigned char FAR *outmsg;
2512     unsigned char *pubkey;
2513     int len, bn_bytes;
2514    
2515     if (pvar->pageant_keycurrent != 0) {
2516     // ���O�������X�L�b�v
2517     pvar->pageant_curkey += 4;
2518     len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2519     bn_bytes = (len + 7) / 8;
2520     pvar->pageant_curkey += 2 + bn_bytes;
2521     len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2522     bn_bytes = (len + 7) / 8;
2523     pvar->pageant_curkey += 2 + bn_bytes;
2524     // ���O�������R�����g���X�L�b�v
2525     len = get_uint32_MSBfirst(pvar->pageant_curkey);
2526     pvar->pageant_curkey += 4 + len;
2527     // �����������u������
2528     }
2529     pubkey = pvar->pageant_curkey + 4;
2530     len = get_ushort16_MSBfirst(pubkey);
2531     bn_bytes = (len + 7) / 8;
2532     pubkey += 2 + bn_bytes;
2533     len = get_ushort16_MSBfirst(pubkey);
2534     bn_bytes = (len + 7) / 8;
2535     pubkey += 2;
2536     outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2537    
2538     notify_verbose_message(pvar,
2539     "Trying RSA authentication...",
2540     LOG_LEVEL_VERBOSE);
2541    
2542     set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2543     memcpy(outmsg + 2, pubkey, bn_bytes);
2544     /* don't destroy the current credentials yet */
2545    
2546     pvar->pageant_keycurrent++;
2547    
2548     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2549     break;
2550     }
2551     case SSH_AUTH_TIS:{
2552     if (cred->password == NULL) {
2553     unsigned char FAR *outmsg =
2554     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2555    
2556     notify_verbose_message(pvar,
2557 maya 4407 "Trying TIS authentication...",
2558