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 5900 - (hide annotations) (download) (as text)
Tue Jun 2 09:07:33 2015 UTC (8 years, 10 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 255264 byte(s)
DH-GEXで要求するgroupサイズの最小値を指定できるようにした。

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