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 6528 - (hide annotations) (download) (as text)
Wed Nov 2 16:12:28 2016 UTC (7 years, 5 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 261621 byte(s)
チケット #34056 SCPダウンロードすると応答なしになる

SCPファイルの受信処理において、スレッドのメッセージキューの使用を廃止して、
代わりに独自のリンクドリスト方式に変更した。

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