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 4500 - (hide annotations) (download) (as text)
Wed Jun 15 12:23:52 2011 UTC (12 years, 9 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 244376 byte(s)
SCPファイル受信処理において、スレッドへのポストを無限リトライするようにし、メッセージが空振り
しないようにした。受信処理が途中で停止してしまう問題への対処。


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