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