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 6717 - (hide annotations) (download) (as text)
Fri May 12 12:42:07 2017 UTC (6 years, 11 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 264168 byte(s)
シェルではなくサブシステムを起動する機能の追加 ticket:37165
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     CRYPT_decrypt(pvar, data + already_decrypted,
770     (4 + len) - already_decrypted);
771    
772     if (!CRYPT_verify_receiver_MAC
773     (pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4,
774     data + len + 4)) {
775     UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
776     "Detected corrupted data; connection terminating.");
777 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
778 maya 3227 return SSH_MSG_NONE;
779     }
780    
781     pvar->ssh_state.payload++;
782     pvar->ssh_state.payloadlen -= padding + 1;
783     }
784    
785     pvar->ssh_state.payload_grabbed = 0;
786    
787     if (SSHv1(pvar)) {
788     if (pvar->ssh_state.decompressing) {
789     if (pvar->ssh_state.decompress_stream.avail_in != 0) {
790     UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
791     "Internal error: a packet was not fully decompressed.\n"
792     "This is a bug, please report it.");
793     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
794     }
795    
796     pvar->ssh_state.decompress_stream.next_in =
797     pvar->ssh_state.payload;
798     pvar->ssh_state.decompress_stream.avail_in =
799     pvar->ssh_state.payloadlen;
800     pvar->ssh_state.decompress_stream.next_out =
801     pvar->ssh_state.postdecompress_inbuf;
802     pvar->ssh_state.payloadlen = -1;
803     } else {
804     pvar->ssh_state.payload++;
805     }
806    
807     if (!grab_payload_limited(pvar, 1)) {
808     return SSH_MSG_NONE;
809     }
810    
811     } else {
812     // support of SSH2 packet compression (2005.7.9 yutaka)
813     // support of "Compression delayed" (2006.6.23 maya)
814     if ((pvar->stoc_compression == COMP_ZLIB ||
815     pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&
816     pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
817     int ret;
818    
819     if (pvar->decomp_buffer == NULL) {
820     pvar->decomp_buffer = buffer_init();
821     if (pvar->decomp_buffer == NULL)
822     return SSH_MSG_NONE;
823     }
824     // ���x�m�������o�b�t�@���g�������������������Y�������B
825     buffer_clear(pvar->decomp_buffer);
826    
827     // packet size��padding�������������y�C���[�h�����������W�J�����B
828     ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
829     pvar->ssh_state.payload,
830     pvar->ssh_state.payloadlen,
831     pvar->decomp_buffer);
832    
833     // �|�C���^���X�V�B
834     pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
835     pvar->ssh_state.payload++;
836     pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
837    
838     } else {
839     pvar->ssh_state.payload++;
840     }
841    
842     if (!grab_payload_limited(pvar, 1)) {
843     return SSH_MSG_NONE;
844     }
845    
846     }
847    
848     pvar->ssh_state.receiver_sequence_number++;
849    
850     return pvar->ssh_state.payload[-1];
851     }
852    
853     /* Create a packet to be sent. The SSH protocol packet type is in 'type';
854     'len' contains the length of the packet payload, in bytes (this
855     does not include the space for any of the packet headers or padding,
856     or for the packet type byte).
857     Returns a pointer to the payload data area, a region of length 'len',
858     to be filled by the caller. */
859 yutakapon 4926 unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len)
860 maya 3227 {
861     unsigned char FAR *buf;
862    
863     pvar->ssh_state.outgoing_packet_len = len + 1;
864    
865     if (pvar->ssh_state.compressing) {
866     buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
867     &pvar->ssh_state.precompress_outbuflen, 1 + len);
868     buf = pvar->ssh_state.precompress_outbuf;
869     } else {
870     /* For SSHv2,
871     Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
872     + len(payload) + 4(minpadding), rounded up to nearest block_size
873     We only need a reasonable upper bound for the buffer size */
874     buf_ensure_size(&pvar->ssh_state.outbuf,
875     &pvar->ssh_state.outbuflen,
876     len + 30 + CRYPT_get_sender_MAC_size(pvar) +
877     CRYPT_get_encryption_block_size(pvar));
878     buf = pvar->ssh_state.outbuf + 12;
879     }
880    
881     buf[0] = (unsigned char) type;
882     return buf + 1;
883     }
884    
885    
886     // ���M���g���C����������
887     //
888     // WinSock�� send() ���o�b�t�@�T�C�Y(len)�������������l��������������������
889     // ���������������A�����������G���[���������B
890     // �����������ATCP�R�l�N�V�������f�������o���h���B
891     // (2006.12.9 yutaka)
892     static int retry_send_packet(PTInstVar pvar, char FAR * data, int len)
893     {
894     int n;
895     int err;
896    
897     while (len > 0) {
898     n = (pvar->Psend)(pvar->socket, data, len, 0);
899    
900     if (n < 0) {
901     err = WSAGetLastError();
902     if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
903     // send()�����l��0�������A�����G���[������ 10000 �������������A
904     // ���������������������B
905     // PuTTY 0.58���������Q�l�B
906     // (2007.2.4 yutak)
907     return 0; // success
908     }
909     return 1; // error
910     }
911    
912     len -= n;
913     data += n;
914     }
915    
916     return 0; // success
917     }
918    
919     static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
920     {
921     // �p�P�b�g���M�����o�b�t�@���g�������������A�u���b�L���O�����M�����������K�v�������B
922     // �m���u���b�L���O�����M����WSAEWOULDBLOCK�����������������A�����o�b�t�@�����M��������
923     // ���������������������������������B(2007.10.30 yutaka)
924     u_long do_block = 0;
925     int code = 0;
926     char *kind = NULL, buf[256];
927    
928     #if 0
929     if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
930     0, 0) == SOCKET_ERROR
931     || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR
932     || retry_send_packet(pvar, data, len)
933     || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
934     pvar->notification_msg,
935     pvar->notification_events) ==
936     SOCKET_ERROR) {
937     UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
938     "A communications error occurred while sending an SSH packet.\n"
939     "The connection will close.");
940 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
941 maya 3227 return FALSE;
942     } else {
943     return TRUE;
944     }
945     #else
946     if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
947     0, 0) == SOCKET_ERROR) {
948     code = WSAGetLastError();
949     kind = "WSAAsyncSelect1";
950     goto error;
951     }
952     if (ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR) {
953     code = WSAGetLastError();
954     kind = "ioctlsocket";
955     goto error;
956     }
957     if (retry_send_packet(pvar, data, len) != 0) {
958     code = WSAGetLastError();
959     kind = "retry_send_packet";
960     goto error;
961     }
962     if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
963     pvar->notification_msg,
964     pvar->notification_events) ==
965     SOCKET_ERROR) {
966     code = WSAGetLastError();
967     kind = "WSAAsyncSelect2";
968     goto error;
969     }
970     return TRUE;
971    
972     error:
973     UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
974     "A communications error occurred while sending an SSH packet.\n"
975     "The connection will close. (%s:%d)");
976     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
977     kind, code);
978 maya 5678 notify_fatal_error(pvar, buf, TRUE);
979 maya 3227 return FALSE;
980     #endif
981     }
982    
983     /* if skip_compress is true, then the data has already been compressed
984     into outbuf + 12 */
985 yutakapon 4926 void finish_send_packet_special(PTInstVar pvar, int skip_compress)
986 maya 3227 {
987     unsigned int len = pvar->ssh_state.outgoing_packet_len;
988     unsigned char FAR *data;
989     unsigned int data_length;
990     buffer_t *msg = NULL; // for SSH2 packet compression
991    
992     if (pvar->ssh_state.compressing) {
993     if (!skip_compress) {
994     buf_ensure_size(&pvar->ssh_state.outbuf,
995     &pvar->ssh_state.outbuflen,
996     (int)(len + (len >> 6) + 50 +
997     CRYPT_get_sender_MAC_size(pvar)));
998     pvar->ssh_state.compress_stream.next_in =
999     pvar->ssh_state.precompress_outbuf;
1000     pvar->ssh_state.compress_stream.avail_in = len;
1001     pvar->ssh_state.compress_stream.next_out =
1002     pvar->ssh_state.outbuf + 12;
1003     pvar->ssh_state.compress_stream.avail_out =
1004     pvar->ssh_state.outbuflen - 12;
1005    
1006     if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
1007     UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1008     "An error occurred while compressing packet data.\n"
1009     "The connection will close.");
1010 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1011 maya 3227 return;
1012     }
1013     }
1014    
1015     len =
1016     pvar->ssh_state.outbuflen - 12 -
1017     pvar->ssh_state.compress_stream.avail_out;
1018     }
1019    
1020     if (SSHv1(pvar)) {
1021     int padding = 8 - ((len + 4) % 8);
1022    
1023     data = pvar->ssh_state.outbuf + 8 - padding;
1024     data_length = padding + len + 8;
1025    
1026     set_uint32(data, len + 4);
1027     if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
1028     CRYPT_set_random_data(pvar, data + 4, padding);
1029     } else {
1030     memset(data + 4, 0, padding);
1031     }
1032     set_uint32(data + data_length - 4,
1033     do_crc(data + 4, data_length - 8));
1034     CRYPT_encrypt(pvar, data + 4, data_length - 4);
1035     } else { //for SSH2(yutaka)
1036     int block_size = CRYPT_get_encryption_block_size(pvar);
1037     unsigned int encryption_size;
1038     unsigned int padding;
1039     BOOL ret;
1040    
1041     /*
1042     �f�[�^�\��
1043     pvar->ssh_state.outbuf:
1044     offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
1045     <--ignore---> ^^^^^^^^ <---- payload --->
1046     packet length
1047    
1048     ^^padding
1049    
1050     <---------------------------->
1051     SSH2 sending data on TCP
1052    
1053     NOTE:
1054     payload = type(1) + raw-data
1055     len = ssh_state.outgoing_packet_len = payload size
1056     */
1057     // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
1058     // support of "Compression delayed" (2006.6.23 maya)
1059     if ((pvar->ctos_compression == COMP_ZLIB ||
1060     pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
1061     pvar->ssh2_keys[MODE_OUT].comp.enabled) {
1062     // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
1063     msg = buffer_init();
1064     if (msg == NULL) {
1065     // TODO: error check
1066     return;
1067     }
1068    
1069     // ���k�������w�b�_�������y�C���[�h�����B
1070     buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
1071     if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
1072     UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1073     "An error occurred while compressing packet data.\n"
1074     "The connection will close.");
1075 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1076 maya 3227 return;
1077     }
1078     data = buffer_ptr(msg);
1079     len = buffer_len(msg) - 5; // 'len' is overwritten.
1080    
1081     } else {
1082     // �����k
1083     data = pvar->ssh_state.outbuf + 7;
1084    
1085     }
1086    
1087     // ���M�p�P�b�g�\�z(input parameter: data, len)
1088     if (block_size < 8) {
1089     block_size = 8;
1090     }
1091     #if 0
1092     encryption_size = ((len + 8) / block_size + 1) * block_size;
1093     data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1094    
1095     set_uint32(data, encryption_size - 4);
1096     padding = encryption_size - len - 5;
1097     data[4] = (unsigned char) padding;
1098     #else
1099     // �������p�P�b�g�����������������A�T�[�o����"Bad packet length"���������������������������B
1100     // (2007.10.29 yutaka)
1101     encryption_size = 4 + 1 + len;
1102     padding = block_size - (encryption_size % block_size);
1103     if (padding < 4)
1104     padding += block_size;
1105     encryption_size += padding;
1106     set_uint32(data, encryption_size - 4);
1107     data[4] = (unsigned char) padding;
1108     data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1109 yutakapon 4492 if (msg) {
1110     // �p�P�b�g���k�������A�o�b�t�@���g�������B(2011.6.10 yutaka)
1111     buffer_append_space(msg, padding + EVP_MAX_MD_SIZE);
1112 yutakapon 4495 // realloc()���������A�|�C���^�����������\�������������A���x���������B
1113     data = buffer_ptr(msg);
1114 yutakapon 4492 }
1115 maya 3227 #endif
1116     //if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;
1117     CRYPT_set_random_data(pvar, data + 5 + len, padding);
1118     ret = CRYPT_build_sender_MAC(pvar,
1119     pvar->ssh_state.sender_sequence_number,
1120     data, encryption_size,
1121     data + encryption_size);
1122 doda 5262 if (ret == FALSE) { // MAC��������������������������
1123 maya 3227 data_length = encryption_size;
1124     }
1125    
1126 doda 5262 // �p�P�b�g�������������BMAC���~�������������O�B
1127 maya 3227 CRYPT_encrypt(pvar, data, encryption_size);
1128     }
1129    
1130     send_packet_blocking(pvar, data, data_length);
1131    
1132     buffer_free(msg);
1133    
1134     pvar->ssh_state.sender_sequence_number++;
1135    
1136     // ���M�������L�^
1137     pvar->ssh_heartbeat_tick = time(NULL);
1138     }
1139    
1140     static void destroy_packet_buf(PTInstVar pvar)
1141     {
1142     memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1143     if (pvar->ssh_state.compressing) {
1144     memset(pvar->ssh_state.precompress_outbuf, 0,
1145     pvar->ssh_state.precompress_outbuflen);
1146     }
1147     }
1148    
1149     /* The handlers are added to the queue for each message. When one of the
1150     handlers fires, if it returns FALSE, then all handlers in the set are
1151     removed from their queues. */
1152     static void enque_handlers(PTInstVar pvar, int num_msgs,
1153     const int FAR * messages,
1154     const SSHPacketHandler FAR * handlers)
1155     {
1156     SSHPacketHandlerItem FAR *first_item;
1157     SSHPacketHandlerItem FAR *last_item = NULL;
1158     int i;
1159    
1160     for (i = 0; i < num_msgs; i++) {
1161     SSHPacketHandlerItem FAR *item =
1162     (SSHPacketHandlerItem FAR *)
1163     malloc(sizeof(SSHPacketHandlerItem));
1164     SSHPacketHandlerItem FAR *cur_item =
1165     pvar->ssh_state.packet_handlers[messages[i]];
1166    
1167     item->handler = handlers[i];
1168    
1169     if (cur_item == NULL) {
1170     pvar->ssh_state.packet_handlers[messages[i]] = item;
1171     item->next_for_message = item;
1172     item->last_for_message = item;
1173     item->active_for_message = messages[i];
1174     } else {
1175     item->next_for_message = cur_item;
1176     item->last_for_message = cur_item->last_for_message;
1177     cur_item->last_for_message->next_for_message = item;
1178     cur_item->last_for_message = item;
1179     item->active_for_message = -1;
1180     }
1181    
1182     if (last_item != NULL) {
1183     last_item->next_in_set = item;
1184     } else {
1185     first_item = item;
1186     }
1187     last_item = item;
1188     }
1189    
1190     if (last_item != NULL) {
1191     last_item->next_in_set = first_item;
1192     }
1193     }
1194    
1195     static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1196     {
1197     SSHPacketHandlerItem FAR *cur_item =
1198     pvar->ssh_state.packet_handlers[message];
1199    
1200     if (cur_item == NULL) {
1201     return NULL;
1202     } else {
1203     return cur_item->handler;
1204     }
1205     }
1206    
1207     /* Called only by SSH_handle_packet */
1208     static void deque_handlers(PTInstVar pvar, int message)
1209     {
1210     SSHPacketHandlerItem FAR *cur_item =
1211     pvar->ssh_state.packet_handlers[message];
1212     SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1213    
1214     if (cur_item == NULL)
1215     return;
1216    
1217     do {
1218     SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1219    
1220     if (cur_item->active_for_message >= 0) {
1221     SSHPacketHandlerItem FAR *replacement =
1222     cur_item->next_for_message;
1223    
1224     if (replacement == cur_item) {
1225     replacement = NULL;
1226     } else {
1227     replacement->active_for_message =
1228     cur_item->active_for_message;
1229     }
1230     pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1231     replacement;
1232     }
1233     cur_item->next_for_message->last_for_message =
1234     cur_item->last_for_message;
1235     cur_item->last_for_message->next_for_message =
1236     cur_item->next_for_message;
1237    
1238     free(cur_item);
1239     cur_item = next_in_set;
1240     } while (cur_item != first_item_in_set);
1241     }
1242    
1243     static void enque_handler(PTInstVar pvar, int message,
1244     SSHPacketHandler handler)
1245     {
1246     enque_handlers(pvar, 1, &message, &handler);
1247     }
1248    
1249     static void chop_newlines(char FAR * buf)
1250     {
1251     int len = strlen(buf);
1252    
1253     while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1254     buf[len - 1] = 0;
1255     len--;
1256     }
1257     }
1258    
1259     /********************/
1260     /* Message handlers */
1261     /********************/
1262    
1263     static BOOL handle_forwarding_success(PTInstVar pvar)
1264     {
1265     return FALSE;
1266     }
1267    
1268     static BOOL handle_forwarding_failure(PTInstVar pvar)
1269     {
1270     return FALSE;
1271     }
1272    
1273     static void enque_forwarding_request_handlers(PTInstVar pvar)
1274     {
1275     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1276     static const SSHPacketHandler handlers[]
1277     = { handle_forwarding_success, handle_forwarding_failure };
1278    
1279     enque_handlers(pvar, 2, msgs, handlers);
1280     }
1281    
1282     static BOOL handle_auth_failure(PTInstVar pvar)
1283     {
1284     notify_verbose_message(pvar, "Authentication failed",
1285     LOG_LEVEL_VERBOSE);
1286    
1287     // retry count������ (2005.7.15 yutaka)
1288     pvar->userauth_retry_count++;
1289    
1290     AUTH_set_generic_mode(pvar);
1291     AUTH_advance_to_next_cred(pvar);
1292     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1293     try_send_credentials(pvar);
1294     return FALSE;
1295     }
1296    
1297     static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1298     {
1299     if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1300     if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1301     // �S�������������I������
1302     safefree(pvar->pageant_key);
1303     }
1304     else {
1305     // ������������
1306     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1307     try_send_credentials(pvar);
1308     return TRUE;
1309     }
1310     }
1311     AUTH_destroy_cur_cred(pvar);
1312     return handle_auth_failure(pvar);
1313     }
1314    
1315     static BOOL handle_TIS_challenge(PTInstVar pvar)
1316     {
1317     if (grab_payload(pvar, 4)) {
1318     int len = get_payload_uint32(pvar, 0);
1319    
1320     if (grab_payload(pvar, len)) {
1321     notify_verbose_message(pvar, "Received TIS challenge",
1322     LOG_LEVEL_VERBOSE);
1323    
1324     AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1325     AUTH_advance_to_next_cred(pvar);
1326     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1327     try_send_credentials(pvar);
1328     }
1329     }
1330     return FALSE;
1331     }
1332    
1333     static BOOL handle_auth_required(PTInstVar pvar)
1334     {
1335     notify_verbose_message(pvar, "Server requires authentication",
1336     LOG_LEVEL_VERBOSE);
1337    
1338     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1339     try_send_credentials(pvar);
1340     /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1341    
1342     return FALSE;
1343     }
1344    
1345     static BOOL handle_ignore(PTInstVar pvar)
1346     {
1347     if (SSHv1(pvar)) {
1348     notify_verbose_message(pvar, "SSH_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1349    
1350     if (grab_payload(pvar, 4)
1351     && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1352     /* ignore it! but it must be decompressed */
1353     }
1354     }
1355     else {
1356     notify_verbose_message(pvar, "SSH2_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1357    
1358     // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1359     // Cisco ���[�^���� (2006.11.28 maya)
1360     }
1361     return TRUE;
1362     }
1363    
1364     static BOOL handle_debug(PTInstVar pvar)
1365     {
1366     BOOL always_display;
1367     char FAR *description;
1368     int description_len;
1369     char buf[2048];
1370    
1371     if (SSHv1(pvar)) {
1372     notify_verbose_message(pvar, "SSH_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1373    
1374     if (grab_payload(pvar, 4)
1375     && grab_payload(pvar, description_len =
1376     get_payload_uint32(pvar, 0))) {
1377     always_display = FALSE;
1378     description = pvar->ssh_state.payload + 4;
1379     description[description_len] = 0;
1380     } else {
1381     return TRUE;
1382     }
1383     } else {
1384     notify_verbose_message(pvar, "SSH2_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1385    
1386     if (grab_payload(pvar, 5)
1387     && grab_payload(pvar,
1388     (description_len = get_payload_uint32(pvar, 1)) + 4)
1389     && grab_payload(pvar,
1390     get_payload_uint32(pvar, 5 + description_len))) {
1391     always_display = pvar->ssh_state.payload[0] != 0;
1392     description = pvar->ssh_state.payload + 5;
1393     description[description_len] = 0;
1394     } else {
1395     return TRUE;
1396     }
1397     }
1398    
1399     chop_newlines(description);
1400     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1401     description);
1402     if (always_display) {
1403     notify_nonfatal_error(pvar, buf);
1404     } else {
1405     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1406     }
1407     return TRUE;
1408     }
1409    
1410     static BOOL handle_disconnect(PTInstVar pvar)
1411     {
1412     int reason_code;
1413     char FAR *description;
1414     int description_len;
1415     char buf[2048];
1416     char FAR *explanation = "";
1417     char uimsg[MAX_UIMSG];
1418    
1419     if (SSHv1(pvar)) {
1420     notify_verbose_message(pvar, "SSH_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1421    
1422     if (grab_payload(pvar, 4)
1423     && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1424     reason_code = -1;
1425     description = pvar->ssh_state.payload + 4;
1426     description[description_len] = 0;
1427     } else {
1428     return TRUE;
1429     }
1430     } else {
1431     notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1432    
1433     if (grab_payload(pvar, 8)
1434     && grab_payload(pvar,
1435     (description_len = get_payload_uint32(pvar, 4)) + 4)
1436     && grab_payload(pvar,
1437     get_payload_uint32(pvar, 8 + description_len))) {
1438     reason_code = get_payload_uint32(pvar, 0);
1439     description = pvar->ssh_state.payload + 8;
1440     description[description_len] = 0;
1441     } else {
1442     return TRUE;
1443     }
1444     }
1445    
1446     chop_newlines(description);
1447     if (description[0] == 0) {
1448     description = NULL;
1449     }
1450    
1451     if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1452     UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1453     "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1454     "This often happens when someone is already forwarding that port from the server.");
1455     strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1456     explanation = uimsg;
1457     }
1458    
1459     if (description != NULL) {
1460     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1461     "Server disconnected with message '%s'%s");
1462     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1463     pvar->ts->UIMsg, description,
1464     explanation);
1465     } else {
1466     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1467     "Server disconnected (no reason given).%s");
1468     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1469     pvar->ts->UIMsg, explanation);
1470     }
1471    
1472 maya 5678 if (SSHv2(pvar)) {
1473     // SSH2_MSG_DISCONNECT �������������������������M��������������
1474     notify_fatal_error(pvar, buf, FALSE);
1475     }
1476     else {
1477     // SSH1 ���������d�l�����������������A���O����������������
1478     notify_fatal_error(pvar, buf, TRUE);
1479     }
1480    
1481 maya 3227 return TRUE;
1482     }
1483    
1484     static BOOL handle_unimplemented(PTInstVar pvar)
1485     {
1486     /* Should never receive this since we only send base 2.0 protocol messages */
1487     grab_payload(pvar, 4);
1488     return TRUE;
1489     }
1490    
1491     static BOOL handle_crypt_success(PTInstVar pvar)
1492     {
1493     notify_verbose_message(pvar, "Secure mode successfully achieved",
1494     LOG_LEVEL_VERBOSE);
1495     return FALSE;
1496     }
1497    
1498     static BOOL handle_noauth_success(PTInstVar pvar)
1499     {
1500     notify_verbose_message(pvar, "Server does not require authentication",
1501     LOG_LEVEL_VERBOSE);
1502     prep_compression(pvar);
1503     return FALSE;
1504     }
1505    
1506     static BOOL handle_auth_success(PTInstVar pvar)
1507     {
1508     notify_verbose_message(pvar, "Authentication accepted",
1509     LOG_LEVEL_VERBOSE);
1510     prep_compression(pvar);
1511    
1512     // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1513     start_ssh_heartbeat_thread(pvar);
1514    
1515     return FALSE;
1516     }
1517    
1518     static BOOL handle_server_public_key(PTInstVar pvar)
1519     {
1520     int server_key_public_exponent_len;
1521     int server_key_public_modulus_pos;
1522     int server_key_public_modulus_len;
1523     int host_key_bits_pos;
1524     int host_key_public_exponent_len;
1525     int host_key_public_modulus_pos;
1526     int host_key_public_modulus_len;
1527     int protocol_flags_pos;
1528     int supported_ciphers;
1529     char FAR *inmsg;
1530     Key hostkey;
1531     int supported_types;
1532    
1533     notify_verbose_message(pvar, "SSH_SMSG_PUBLIC_KEY was received.", LOG_LEVEL_VERBOSE);
1534    
1535     if (!grab_payload(pvar, 14))
1536     return FALSE;
1537     server_key_public_exponent_len = get_mpint_len(pvar, 12);
1538    
1539     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1540     return FALSE;
1541     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1542     server_key_public_modulus_len =
1543     get_mpint_len(pvar, server_key_public_modulus_pos);
1544    
1545     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1546     return FALSE;
1547     host_key_bits_pos =
1548     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1549     host_key_public_exponent_len =
1550     get_mpint_len(pvar, host_key_bits_pos + 4);
1551    
1552     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1553     return FALSE;
1554     host_key_public_modulus_pos =
1555     host_key_bits_pos + 6 + host_key_public_exponent_len;
1556     host_key_public_modulus_len =
1557     get_mpint_len(pvar, host_key_public_modulus_pos);
1558    
1559     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1560     return FALSE;
1561     protocol_flags_pos =
1562     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1563    
1564     inmsg = pvar->ssh_state.payload;
1565    
1566     CRYPT_set_server_cookie(pvar, inmsg);
1567     if (!CRYPT_set_server_RSA_key(pvar,
1568     get_uint32(inmsg + 8),
1569     pvar->ssh_state.payload + 12,
1570     inmsg + server_key_public_modulus_pos))
1571     return FALSE;
1572     if (!CRYPT_set_host_RSA_key(pvar,
1573     get_uint32(inmsg + host_key_bits_pos),
1574     inmsg + host_key_bits_pos + 4,
1575     inmsg + host_key_public_modulus_pos))
1576     return FALSE;
1577     pvar->ssh_state.server_protocol_flags =
1578     get_uint32(inmsg + protocol_flags_pos);
1579    
1580     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1581     if (!CRYPT_set_supported_ciphers(pvar,
1582     supported_ciphers,
1583     supported_ciphers))
1584     return FALSE;
1585    
1586     // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1587     // RSA ���L������ PAGEANT ���L��������
1588     supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1589     if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1590     supported_types |= (1 << SSH_AUTH_PAGEANT);
1591     }
1592     if (!AUTH_set_supported_auth_types(pvar,
1593     supported_types))
1594     return FALSE;
1595    
1596     /* this must be the LAST THING in this function, since it can cause
1597     host_is_OK to be called. */
1598     hostkey.type = KEY_RSA1;
1599     hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1600     hostkey.exp = inmsg + host_key_bits_pos + 4;
1601     hostkey.mod = inmsg + host_key_public_modulus_pos;
1602     HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1603    
1604     return FALSE;
1605     }
1606    
1607     /*
1608     The ID must have already been found to start with "SSH-". It must
1609     be null-terminated.
1610     */
1611     static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1612     {
1613     char FAR *str;
1614    
1615     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1616     }
1617    
1618     if (*str != '.') {
1619     return FALSE;
1620     }
1621    
1622     pvar->protocol_major = atoi(ID + 4);
1623     pvar->protocol_minor = atoi(str + 1);
1624    
1625     for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1626     }
1627    
1628     return *str == '-';
1629     }
1630    
1631     /*
1632     On entry, the pvar->protocol_xxx fields hold the server's advertised
1633     protocol number. We replace the fields with the protocol number we will
1634     actually use, or return FALSE if there is no usable protocol version.
1635     */
1636 maya 4682 static int negotiate_protocol(PTInstVar pvar)
1637 maya 3227 {
1638     switch (pvar->protocol_major) {
1639     case 1:
1640 maya 4682 if (pvar->protocol_minor == 99 &&
1641     pvar->settings.ssh_protocol_version == 2) {
1642     // �T�[�o�� 1.99 �����[�U�� SSH2 ���I������������������
1643     // 2.0 ����������
1644     pvar->protocol_major = 2;
1645     pvar->protocol_minor = 0;
1646     return 0;
1647     }
1648    
1649     if (pvar->settings.ssh_protocol_version == 2) {
1650     // �o�[�W��������
1651     return -1;
1652     }
1653    
1654 maya 3227 if (pvar->protocol_minor > 5) {
1655     pvar->protocol_minor = 5;
1656     }
1657    
1658 maya 4682 return 0;
1659 maya 3227
1660     // for SSH2(yutaka)
1661     case 2:
1662 maya 4682 if (pvar->settings.ssh_protocol_version == 1) {
1663     // �o�[�W��������
1664     return -1;
1665     }
1666 maya 3227
1667 maya 4682 return 0; // SSH2 support
1668    
1669 maya 3227 default:
1670 maya 4682 return 1;
1671 maya 3227 }
1672     }
1673    
1674     static void init_protocol(PTInstVar pvar)
1675     {
1676     CRYPT_initialize_random_numbers(pvar);
1677    
1678     // known_hosts�t�@�C�������z�X�g���J������������������
1679     HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1680    
1681     /* while we wait for a response from the server... */
1682    
1683     if (SSHv1(pvar)) {
1684     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1685     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1686     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1687     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1688    
1689     } else { // for SSH2(yutaka)
1690     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1691     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1692     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1693     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1694     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1695     enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1696     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1697     enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1698     enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1699     enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1700     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1701     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1702 doda 6657 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_msg60);
1703 maya 3227
1704     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1705    
1706     // ���[�U�F�������f�B�X�p�b�`���[�`��
1707     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1708     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1709     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1710     enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1711     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1712     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1713     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1714     enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1715     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1716     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1717     enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1718 yutakapon 5829 enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_SSH2_client_global_request);
1719 maya 3227 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1720     enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1721    
1722 yutakapon 5850 client_init_global_confirm();
1723    
1724 maya 3227 }
1725     }
1726    
1727 doda 5928 void server_version_check(PTInstVar pvar)
1728     {
1729     char *server_swver;
1730    
1731     pvar->server_compat_flag = 0;
1732    
1733     if ((server_swver = strchr(pvar->server_version_string+4, '-')) == NULL) {
1734     notify_verbose_message(pvar, "Can't get server software version string.", LOG_LEVEL_WARNING);
1735     return;
1736     }
1737     server_swver++;
1738    
1739     if (strncmp(server_swver, "Cisco-1", 7) == 0) {
1740     pvar->server_compat_flag |= SSH_BUG_DHGEX_LARGE;
1741     notify_verbose_message(pvar, "Server version string is matched to \"Cisco-1\", compatibility flag SSH_BUG_DHGEX_LARGE is enabled.", LOG_LEVEL_INFO);
1742     }
1743     }
1744    
1745 maya 3227 BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1746     {
1747 maya 4546 static char prefix[64];
1748 maya 4682 int negotiate;
1749     char uimsg[MAX_UIMSG];
1750 maya 3227
1751     // initialize SSH2 memory dump (2005.3.7 yutaka)
1752     init_memdump();
1753     push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1754    
1755     if (ID_len <= 0) {
1756     return FALSE;
1757     } else {
1758 maya 4546 int buf_len;
1759     char FAR *buf;
1760 maya 3227
1761 maya 4546 strncpy_s(prefix, sizeof(prefix), "Received server identification string: ", _TRUNCATE);
1762     buf_len = strlen(prefix) + ID_len + 1;
1763     buf = (char FAR *) malloc(buf_len);
1764 maya 3227 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1765     strncat_s(buf, buf_len, ID, _TRUNCATE);
1766     chop_newlines(buf);
1767     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1768     free(buf);
1769    
1770     if (ID[ID_len - 1] != '\n') {
1771     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1772     return FALSE;
1773     } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1774     pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1775     return FALSE;
1776     } else if (strncmp(ID, "SSH-", 4) != 0) {
1777     return FALSE;
1778     } else {
1779     ID[ID_len - 1] = 0;
1780    
1781     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1782     ID[ID_len - 2] = 0;
1783     }
1784    
1785     pvar->ssh_state.server_ID = _strdup(ID);
1786    
1787 maya 4682 if (!parse_protocol_ID(pvar, ID)) {
1788 maya 3227 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1789     "This program does not understand the server's version of the protocol.");
1790 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1791 maya 4682 }
1792     else if ((negotiate = negotiate_protocol(pvar)) == 1) {
1793     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 == -1) {
1798     UTIL_get_lang_msg("MSG_SSH_VERSION_MISMATCH", pvar,
1799     "Protocol version mismatch. server:%d.%d client:%d");
1800     _snprintf_s(uimsg, sizeof(uimsg), _TRUNCATE, pvar->ts->UIMsg,
1801     pvar->protocol_major, pvar->protocol_minor, pvar->settings.ssh_protocol_version);
1802 maya 5678 notify_fatal_error(pvar, uimsg, TRUE);
1803 maya 4682 }
1804     else {
1805 maya 3227 char TTSSH_ID[1024];
1806     int TTSSH_ID_len;
1807     int a, b, c, d;
1808    
1809 maya 4682 // SSH �o�[�W������ teraterm �����Z�b�g����
1810     // SCP �R�}���h������ (2008.2.3 maya)
1811     pvar->cv->isSSH = pvar->protocol_major;
1812    
1813 maya 3227 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1814     get_file_version("ttxssh.dll", &a, &b, &c, &d);
1815    
1816     _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1817 maya 4656 "SSH-%d.%d-TTSSH/%d.%d Win32\r\n",
1818 maya 3227 pvar->protocol_major, pvar->protocol_minor, a, b);
1819     TTSSH_ID_len = strlen(TTSSH_ID);
1820    
1821     // for SSH2(yutaka)
1822     // �N���C�A���g�o�[�W�����������i���s���������������j
1823     strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1824     TTSSH_ID, _TRUNCATE);
1825    
1826     // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1827     _snprintf_s(pvar->server_version_string,
1828     sizeof(pvar->server_version_string), _TRUNCATE,
1829     "%s", pvar->ssh_state.server_ID);
1830    
1831 doda 5928 // �T�[�o�o�[�W�������`�F�b�N
1832     server_version_check(pvar);
1833    
1834 maya 3227 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1835     0) != TTSSH_ID_len) {
1836     UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1837     "An error occurred while sending the SSH ID string.\n"
1838     "The connection will close.");
1839 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1840 maya 3227 } else {
1841     // ���s�R�[�h������ (2004.8.4 yutaka)
1842 maya 4656 pvar->client_version_string[--TTSSH_ID_len] = 0; // \n
1843     pvar->client_version_string[--TTSSH_ID_len] = 0; // \r
1844 maya 3227
1845 maya 4546 strncpy_s(prefix, sizeof(prefix), "Sent client identification string: ", _TRUNCATE);
1846     buf_len = strlen(prefix) + strlen(pvar->client_version_string) + 1;
1847     buf = (char FAR *) malloc(buf_len);
1848     strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1849     strncat_s(buf, buf_len, pvar->client_version_string, _TRUNCATE);
1850     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1851     free(buf);
1852    
1853 maya 3227 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1854     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1855    
1856     // SSH�n���h�����o�^���s��
1857     init_protocol(pvar);
1858    
1859     SSH2_dispatch_init(1);
1860     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1861     SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1862 maya 4867 SSH2_dispatch_add_message(SSH2_MSG_DEBUG);
1863 maya 3227 }
1864     }
1865    
1866     return TRUE;
1867     }
1868     }
1869     }
1870    
1871     static BOOL handle_exit(PTInstVar pvar)
1872     {
1873     if (grab_payload(pvar, 4)) {
1874     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1875     finish_send_packet(pvar);
1876 maya 5678 notify_closed_connection(pvar, "disconnected by server request");
1877 maya 3227 }
1878     return TRUE;
1879     }
1880    
1881     static BOOL handle_data(PTInstVar pvar)
1882     {
1883     if (grab_payload_limited(pvar, 4)) {
1884     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1885     pvar->ssh_state.payload_datastart = 4;
1886     }
1887     return TRUE;
1888     }
1889    
1890     static BOOL handle_channel_open(PTInstVar pvar)
1891     {
1892     int host_len;
1893     int originator_len;
1894    
1895     if ((pvar->ssh_state.
1896     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1897     if (grab_payload(pvar, 8)
1898     && grab_payload(pvar,
1899     8 + (host_len = get_payload_uint32(pvar, 4)))
1900     && grab_payload(pvar, originator_len =
1901     get_payload_uint32(pvar, host_len + 12))) {
1902     int local_port = get_payload_uint32(pvar, 8 + host_len);
1903    
1904     pvar->ssh_state.payload[8 + host_len] = 0;
1905     FWD_open(pvar, get_payload_uint32(pvar, 0),
1906     pvar->ssh_state.payload + 8, local_port,
1907     pvar->ssh_state.payload + 16 + host_len,
1908     originator_len,
1909     NULL);
1910     }
1911     } else {
1912     if (grab_payload(pvar, 8)
1913     && grab_payload(pvar,
1914     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1915     int local_port = get_payload_uint32(pvar, 8 + host_len);
1916    
1917     pvar->ssh_state.payload[8 + host_len] = 0;
1918     FWD_open(pvar, get_payload_uint32(pvar, 0),
1919     pvar->ssh_state.payload + 8, local_port, NULL, 0,
1920     NULL);
1921     }
1922     }
1923    
1924     return TRUE;
1925     }
1926    
1927     static BOOL handle_X11_channel_open(PTInstVar pvar)
1928     {
1929     int originator_len;
1930    
1931     if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1932     if (grab_payload(pvar, 8)
1933     && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1934     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1935     pvar->ssh_state.payload + 8, originator_len, NULL);
1936     }
1937     } else {
1938     if (grab_payload(pvar, 4)) {
1939     FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1940     }
1941     }
1942    
1943     return TRUE;
1944     }
1945    
1946     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1947     {
1948     if (grab_payload(pvar, 8)) {
1949     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1950     get_payload_uint32(pvar, 4));
1951     }
1952     return FALSE;
1953     }
1954    
1955     static BOOL handle_channel_open_failure(PTInstVar pvar)
1956     {
1957     if (grab_payload(pvar, 4)) {
1958     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1959     }
1960     return FALSE;
1961     }
1962    
1963     static BOOL handle_channel_data(PTInstVar pvar)
1964     {
1965     int len;
1966    
1967     if (grab_payload(pvar, 8)
1968     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1969     FWDChannel *channel;
1970     int local_channel_num = get_payload_uint32(pvar, 0);
1971     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1972     return FALSE;
1973     }
1974     channel = pvar->fwd_state.channels + local_channel_num;
1975     if (channel->type == TYPE_AGENT) {
1976     SSH_agent_response(pvar, NULL, local_channel_num,
1977     pvar->ssh_state.payload + 8, len);
1978     }
1979     else {
1980     FWD_received_data(pvar, local_channel_num,
1981     pvar->ssh_state.payload + 8, len);
1982     }
1983     }
1984     return TRUE;
1985     }
1986    
1987     static BOOL handle_channel_input_eof(PTInstVar pvar)
1988     {
1989     if (grab_payload(pvar, 4)) {
1990     int local_channel_num = get_payload_uint32(pvar, 0);
1991     FWDChannel *channel;
1992     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1993     return FALSE;
1994     }
1995     channel = pvar->fwd_state.channels + local_channel_num;
1996     if (channel->type == TYPE_AGENT) {
1997     channel->status |= FWD_CLOSED_REMOTE_IN;
1998     SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1999     }
2000     else {
2001     FWD_channel_input_eof(pvar, local_channel_num);
2002     }
2003     }
2004     return TRUE;
2005     }
2006    
2007     static BOOL handle_channel_output_eof(PTInstVar pvar)
2008     {
2009     if (grab_payload(pvar, 4)) {
2010     int local_channel_num = get_payload_uint32(pvar, 0);
2011     FWDChannel *channel;
2012     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
2013     return FALSE;
2014     }
2015     channel = pvar->fwd_state.channels + local_channel_num;
2016     if (channel->type == TYPE_AGENT) {
2017     channel->status |= FWD_CLOSED_REMOTE_OUT;
2018     SSH_channel_output_eof(pvar, channel->remote_num);
2019     FWD_free_channel(pvar, local_channel_num);
2020     }
2021     else {
2022     FWD_channel_output_eof(pvar, local_channel_num);
2023     }
2024     }
2025     return TRUE;
2026     }
2027    
2028     static BOOL handle_agent_open(PTInstVar pvar)
2029     {
2030     if (grab_payload(pvar, 4)) {
2031     int remote_id = get_payload_uint32(pvar, 0);
2032     int local_id;
2033    
2034 doda 4233 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
2035 maya 3227 local_id = FWD_agent_open(pvar, remote_id);
2036     if (local_id == -1) {
2037     SSH_fail_channel_open(pvar, remote_id);
2038     }
2039     else {
2040     SSH_confirm_channel_open(pvar, remote_id, local_id);
2041     }
2042     }
2043     else {
2044     SSH_fail_channel_open(pvar, remote_id);
2045     }
2046     }
2047     /*
2048     else {
2049     // ���m��������channel����������������������������
2050     }
2051     */
2052    
2053     return TRUE;
2054     }
2055    
2056    
2057    
2058     // �n���h�����O�������b�Z�[�W����������
2059    
2060     #define HANDLE_MESSAGE_MAX 30
2061     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
2062     static int handle_message_count = 0;
2063     static int handle_message_stage = 0;
2064    
2065     void SSH2_dispatch_init(int stage)
2066     {
2067     handle_message_count = 0;
2068     handle_message_stage = stage;
2069     }
2070    
2071     int SSH2_dispatch_enabled_check(unsigned char message)
2072     {
2073     int i;
2074    
2075     for (i = 0 ; i < handle_message_count ; i++) {
2076     if (handle_messages[i] == message)
2077     return 1;
2078     }
2079     return 0;
2080     }
2081    
2082     void SSH2_dispatch_add_message(unsigned char message)
2083     {
2084     int i;
2085    
2086     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2087     // TODO: error check
2088     return;
2089     }
2090    
2091     // �������o�^�������������b�Z�[�W������������
2092     for (i=0; i<handle_message_count; i++) {
2093     if (handle_messages[i] == message) {
2094     return;
2095     }
2096     }
2097    
2098     handle_messages[handle_message_count++] = message;
2099     }
2100    
2101     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2102     {
2103     unsigned char c;
2104    
2105     for (c = begin ; c <= end ; c++) {
2106     SSH2_dispatch_add_message(c);
2107     }
2108     }
2109    
2110    
2111     void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
2112     int padding)
2113     {
2114     unsigned char message = prep_packet(pvar, data, len, padding);
2115    
2116    
2117     #ifdef SSH2_DEBUG
2118     // for SSH2(yutaka)
2119     if (SSHv2(pvar)) {
2120     if (pvar->key_done) {
2121     message = message;
2122     }
2123    
2124     if (pvar->userauth_success) {
2125     message = message;
2126     }
2127    
2128     if (pvar->rekeying) {
2129     message = message;
2130     }
2131     }
2132     #endif
2133    
2134     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2135     if (message != SSH_MSG_NONE) {
2136     // ���b�Z�[�W�^�C�v���������n���h�����N��
2137     SSHPacketHandler handler = get_handler(pvar, message);
2138    
2139     // for SSH2(yutaka)
2140     if (SSHv2(pvar)) {
2141     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2142     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2143     char buf[1024];
2144    
2145     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2146     "Unexpected SSH2 message(%d) on current stage(%d)");
2147     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2148     pvar->ts->UIMsg, message, handle_message_stage);
2149 maya 5678 notify_fatal_error(pvar, buf, TRUE);
2150 doda 6656 return;
2151 maya 3227 }
2152     }
2153    
2154     if (handler == NULL) {
2155     if (SSHv1(pvar)) {
2156     char buf[1024];
2157    
2158     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2159     "Unexpected packet type received: %d");
2160     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2161     pvar->ts->UIMsg, message, handle_message_stage);
2162 maya 5678 notify_fatal_error(pvar, buf, TRUE);
2163 maya 3227 } else {
2164     unsigned char FAR *outmsg =
2165     begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2166    
2167     set_uint32(outmsg,
2168     pvar->ssh_state.receiver_sequence_number - 1);
2169     finish_send_packet(pvar);
2170    
2171     notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2172     /* XXX need to decompress incoming packet, but how? */
2173     }
2174     } else {
2175     if (!handler(pvar)) {
2176     deque_handlers(pvar, message);
2177     }
2178     }
2179     }
2180     }
2181    
2182     static BOOL handle_pty_success(PTInstVar pvar)
2183     {
2184     FWD_enter_interactive_mode(pvar);
2185     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2186     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2187     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2188     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2189     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2190     handle_channel_input_eof);
2191     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2192     handle_channel_output_eof);
2193     enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2194     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2195     enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2196     return FALSE;
2197     }
2198    
2199     static BOOL handle_pty_failure(PTInstVar pvar)
2200     {
2201     UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2202     "The server cannot allocate a pseudo-terminal. "
2203     "You may encounter some problems with the terminal.");
2204     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2205     return handle_pty_success(pvar);
2206     }
2207    
2208     static void prep_pty(PTInstVar pvar)
2209     {
2210     int len = strlen(pvar->ts->TermType);
2211     unsigned char FAR *outmsg =
2212     begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2213     4 + len + 16 + sizeof(ssh_ttymodes));
2214     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2215     static const SSHPacketHandler handlers[]
2216     = { handle_pty_success, handle_pty_failure };
2217    
2218     set_uint32(outmsg, len);
2219     memcpy(outmsg + 4, pvar->ts->TermType, len);
2220     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2221     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2222     set_uint32(outmsg + 4 + len + 8, 0);
2223     set_uint32(outmsg + 4 + len + 12, 0);
2224     memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2225     finish_send_packet(pvar);
2226    
2227     enque_handlers(pvar, 2, msgs, handlers);
2228    
2229     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2230     finish_send_packet(pvar);
2231     }
2232    
2233     static BOOL handle_agent_request_success(PTInstVar pvar)
2234     {
2235     pvar->agentfwd_enable = TRUE;
2236     prep_pty(pvar);
2237     return FALSE;
2238     }
2239    
2240     static BOOL handle_agent_request_failure(PTInstVar pvar)
2241     {
2242     prep_pty(pvar);
2243     return FALSE;
2244     }
2245    
2246     static void prep_agent_request(PTInstVar pvar)
2247     {
2248     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2249     static const SSHPacketHandler handlers[]
2250     = { handle_agent_request_success, handle_agent_request_failure };
2251    
2252     enque_handlers(pvar, 2, msgs, handlers);
2253    
2254     begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2255     finish_send_packet(pvar);
2256     }
2257    
2258     static void prep_forwarding(PTInstVar pvar)
2259     {
2260     FWD_prep_forwarding(pvar);
2261    
2262     if (pvar->session_settings.ForwardAgent) {
2263     prep_agent_request(pvar);
2264     }
2265     else {
2266     prep_pty(pvar);
2267     }
2268     }
2269    
2270    
2271     //
2272     //
2273     // (2005.7.10 yutaka)
2274     static void enable_send_compression(PTInstVar pvar)
2275     {
2276     static int initialize = 0;
2277    
2278     if (initialize) {
2279     deflateEnd(&pvar->ssh_state.compress_stream);
2280     }
2281     initialize = 1;
2282    
2283     pvar->ssh_state.compress_stream.zalloc = NULL;
2284     pvar->ssh_state.compress_stream.zfree = NULL;
2285     pvar->ssh_state.compress_stream.opaque = NULL;
2286     if (deflateInit
2287     (&pvar->ssh_state.compress_stream,
2288     pvar->ssh_state.compression_level) != Z_OK) {
2289     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2290     "An error occurred while setting up compression.\n"
2291     "The connection will close.");
2292 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2293 maya 3227 return;
2294     } else {
2295     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2296     if (SSHv2(pvar)) {
2297     pvar->ssh_state.compressing = FALSE;
2298     } else {
2299     pvar->ssh_state.compressing = TRUE;
2300     }
2301     }
2302     }
2303    
2304     static void enable_recv_compression(PTInstVar pvar)
2305     {
2306     static int initialize = 0;
2307    
2308     if (initialize) {
2309     deflateEnd(&pvar->ssh_state.decompress_stream);
2310     }
2311     initialize = 1;
2312    
2313     pvar->ssh_state.decompress_stream.zalloc = NULL;
2314     pvar->ssh_state.decompress_stream.zfree = NULL;
2315     pvar->ssh_state.decompress_stream.opaque = NULL;
2316     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2317     deflateEnd(&pvar->ssh_state.compress_stream);
2318     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2319     "An error occurred while setting up compression.\n"
2320     "The connection will close.");
2321 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2322 maya 3227 return;
2323     } else {
2324     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2325     if (SSHv2(pvar)) {
2326     pvar->ssh_state.decompressing = FALSE;
2327     } else {
2328     pvar->ssh_state.decompressing = TRUE;
2329     }
2330    
2331     buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2332     &pvar->ssh_state.postdecompress_inbuflen, 1000);
2333     }
2334     }
2335    
2336     static void enable_compression(PTInstVar pvar)
2337     {
2338     enable_send_compression(pvar);
2339     enable_recv_compression(pvar);
2340    
2341     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2342     if (SSHv2(pvar)) {
2343     pvar->ssh_state.compressing = FALSE;
2344     pvar->ssh_state.decompressing = FALSE;
2345     }
2346    
2347     }
2348    
2349     static BOOL handle_enable_compression(PTInstVar pvar)
2350     {
2351     enable_compression(pvar);
2352     prep_forwarding(pvar);
2353     return FALSE;
2354     }
2355    
2356     static BOOL handle_disable_compression(PTInstVar pvar)
2357     {
2358     prep_forwarding(pvar);
2359     return FALSE;
2360     }
2361    
2362     static void prep_compression(PTInstVar pvar)
2363     {
2364     if (pvar->session_settings.CompressionLevel > 0) {
2365     // added if statement (2005.7.10 yutaka)
2366     if (SSHv1(pvar)) {
2367     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2368     static const SSHPacketHandler handlers[]
2369     = { handle_enable_compression, handle_disable_compression };
2370    
2371     unsigned char FAR *outmsg =
2372     begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2373    
2374     set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2375     finish_send_packet(pvar);
2376    
2377     enque_handlers(pvar, 2, msgs, handlers);
2378     }
2379    
2380     pvar->ssh_state.compression_level =
2381     pvar->session_settings.CompressionLevel;
2382    
2383     } else {
2384     // added if statement (2005.7.10 yutaka)
2385     if (SSHv1(pvar)) {
2386     prep_forwarding(pvar);
2387     }
2388     }
2389     }
2390    
2391     static void enque_simple_auth_handlers(PTInstVar pvar)
2392     {
2393     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2394     static const SSHPacketHandler handlers[]
2395     = { handle_auth_success, handle_auth_failure };
2396    
2397     enque_handlers(pvar, 2, msgs, handlers);
2398     }
2399    
2400     static BOOL handle_rsa_challenge(PTInstVar pvar)
2401     {
2402     int challenge_bytes;
2403    
2404     if (!grab_payload(pvar, 2)) {
2405     return FALSE;
2406     }
2407    
2408     challenge_bytes = get_mpint_len(pvar, 0);
2409    
2410     if (grab_payload(pvar, challenge_bytes)) {
2411     unsigned char FAR *outmsg =
2412     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2413    
2414     if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2415     if (CRYPT_generate_RSA_challenge_response
2416     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2417    
2418     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2419     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2420     #if 0
2421     //AUTH_destroy_cur_cred(pvar);
2422     #endif
2423    
2424     finish_send_packet(pvar);
2425    
2426     enque_simple_auth_handlers(pvar);
2427     } else {
2428     UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2429     "An error occurred while decrypting the RSA challenge.\n"
2430     "Perhaps the key file is corrupted.");
2431 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2432 maya 3227 }
2433     }
2434     else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2435     int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2436     int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2437     int server_key_bytes = (server_key_bits + 7) / 8;
2438     int host_key_bytes = (host_key_bits + 7) / 8;
2439     int session_buf_len = server_key_bytes + host_key_bytes + 8;
2440     char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2441     unsigned char session_id[16];
2442    
2443     unsigned char *hash;
2444     int pubkeylen, hashlen;
2445    
2446     /* Pageant ���n�b�V�����v�Z���������� */
2447     // ���J��������
2448     pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2449     pvar->pageant_keylistlen);
2450     // �Z�b�V����ID������
2451     BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2452     BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2453     session_buf + host_key_bytes);
2454     memcpy(session_buf + server_key_bytes + host_key_bytes,
2455     pvar->crypt_state.server_cookie, 8);
2456     MD5(session_buf, session_buf_len, session_id);
2457     // �n�b�V������������
2458     hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2459     pubkeylen,
2460     pvar->ssh_state.payload,
2461     challenge_bytes + 2,
2462     session_id,
2463     &hashlen);
2464    
2465     // �n�b�V�������M
2466     memcpy(outmsg, hash, 16);
2467     free(hash);
2468    
2469     finish_send_packet(pvar);
2470    
2471     enque_simple_auth_handlers(pvar);
2472     }
2473     }
2474    
2475     return FALSE;
2476     }
2477    
2478     static void try_send_credentials(PTInstVar pvar)
2479     {
2480     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2481     AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2482     static const int RSA_msgs[] =
2483     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2484     static const SSHPacketHandler RSA_handlers[]
2485     = { handle_rsa_challenge, handle_rsa_auth_refused };
2486     static const int TIS_msgs[] =
2487     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2488     static const SSHPacketHandler TIS_handlers[]
2489     = { handle_TIS_challenge, handle_auth_failure };
2490    
2491     // SSH2���������������������X�L�b�v
2492     if (SSHv2(pvar))
2493     goto skip_ssh2;
2494    
2495     switch (cred->method) {
2496     case SSH_AUTH_NONE:
2497     return;
2498     case SSH_AUTH_PASSWORD:{
2499     int len = strlen(cred->password);
2500     unsigned char FAR *outmsg =
2501     begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2502 maya 4407 4 + len);
2503 maya 3227
2504     notify_verbose_message(pvar,
2505