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