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