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