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