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 6821 - (hide annotations) (download) (as text)
Mon Jun 26 10:38:04 2017 UTC (6 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 262701 byte(s)
コメント修正 (H-MAC -> HMAC)
<
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 doda 6779 #include "ttcommon.h"
36 maya 3227
37     #include <openssl/bn.h>
38     #include <openssl/evp.h>
39     #include <openssl/dh.h>
40     #include <openssl/engine.h>
41     #include <openssl/rsa.h>
42     #include <openssl/dsa.h>
43     #include <openssl/md5.h>
44     #include <limits.h>
45     #include <malloc.h>
46     #include <string.h>
47     #include <stdlib.h>
48     #include <process.h>
49     #include <time.h>
50 doda 4379 #include <commctrl.h>
51 maya 3227 #include "buffer.h"
52     #include "ssh.h"
53     #include "crypt.h"
54     #include "fwd.h"
55     #include "sftp.h"
56 maya 4304 #include "kex.h"
57 maya 3227
58     #include <sys/types.h>
59     #include <sys/stat.h>
60 maya 5607 #include <sys/utime.h>
61 maya 3227 #include <assert.h>
62    
63     #include <direct.h>
64     #include <io.h>
65    
66     // SSH2 macro
67     #ifdef _DEBUG
68     #define SSH2_DEBUG
69     #endif
70    
71     //#define DONT_WANTCONFIRM 1 // (2005.3.28 yutaka)
72     #undef DONT_WANTCONFIRM // (2008.11.25 maya)
73    
74     //
75     // SSH2 data structure
76     //
77    
78     // channel data structure
79     #define CHANNEL_MAX 100
80    
81 doda 6812 //
82     // msg �� NULL �����������������BNULL �������� "(null)" �������B
83     //
84     #define NonNull(msg) ((msg)?(msg):"(null)")
85 maya 3227
86 yutakapon 5850 static struct global_confirm global_confirms;
87    
88 maya 3227 static Channel_t channels[CHANNEL_MAX];
89    
90     static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
91    
92 yutakapon 6528 static CRITICAL_SECTION g_ssh_scp_lock; /* SCP���M�p���b�N */
93    
94 maya 3227 static void try_send_credentials(PTInstVar pvar);
95     static void prep_compression(PTInstVar pvar);
96    
97     // �����v���g�^�C�v����
98     void SSH2_send_kexinit(PTInstVar pvar);
99     static BOOL handle_SSH2_kexinit(PTInstVar pvar);
100     static void SSH2_dh_kex_init(PTInstVar pvar);
101     static void SSH2_dh_gex_kex_init(PTInstVar pvar);
102 maya 4314 static void SSH2_ecdh_kex_init(PTInstVar pvar);
103 maya 3227 static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
104     static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
105     static BOOL handle_SSH2_newkeys(PTInstVar pvar);
106     static BOOL handle_SSH2_service_accept(PTInstVar pvar);
107     static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
108     static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
109     static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
110     static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
111     static BOOL handle_SSH2_open_failure(PTInstVar pvar);
112 yutakapon 5829 static BOOL handle_SSH2_client_global_request(PTInstVar pvar);
113 maya 3227 static BOOL handle_SSH2_request_success(PTInstVar pvar);
114     static BOOL handle_SSH2_request_failure(PTInstVar pvar);
115     static BOOL handle_SSH2_channel_success(PTInstVar pvar);
116     static BOOL handle_SSH2_channel_failure(PTInstVar pvar);
117     static BOOL handle_SSH2_channel_data(PTInstVar pvar);
118     static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
119     static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
120     static BOOL handle_SSH2_channel_close(PTInstVar pvar);
121     static BOOL handle_SSH2_channel_open(PTInstVar pvar);
122     static BOOL handle_SSH2_window_adjust(PTInstVar pvar);
123     static BOOL handle_SSH2_channel_request(PTInstVar pvar);
124     void SSH2_dispatch_init(int stage);
125     int SSH2_dispatch_enabled_check(unsigned char message);
126     void SSH2_dispatch_add_message(unsigned char message);
127     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);
128     int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
129     static void start_ssh_heartbeat_thread(PTInstVar pvar);
130     void ssh2_channel_send_close(PTInstVar pvar, Channel_t *c);
131     static BOOL SSH_agent_response(PTInstVar pvar, Channel_t *c, int local_channel_num, unsigned char *data, unsigned int buflen);
132 yutakapon 6528 static void ssh2_scp_get_packetlist(Channel_t *c, unsigned char **buf, unsigned int *buflen);
133     static void ssh2_scp_free_packetlist(Channel_t *c);
134 doda 6799 static void get_window_pixel_size(PTInstVar pvar, int *x, int *y);
135 maya 3227
136     //
137 yutakapon 5850 // Global request confirm
138     //
139     static void client_init_global_confirm(void)
140     {
141     memset(&global_confirms, 0, sizeof(global_confirms));
142     global_confirms.ref_count = 0;
143     }
144    
145 yutakapon 5853 void client_register_global_confirm(global_confirm_cb *cb, void *ctx)
146 yutakapon 5850 {
147     struct global_confirm *gc = &global_confirms;
148    
149     if (gc->ref_count == 0) {
150     gc->cb = cb;
151     gc->ctx = ctx;
152     gc->ref_count = 1;
153     }
154     }
155    
156 yutakapon 5853 static int client_global_request_reply(PTInstVar pvar, int type, unsigned int seq, void *ctxt)
157     {
158 yutakapon 5850 struct global_confirm *gc = &global_confirms;
159    
160     if (gc->ref_count >= 1) {
161     if (gc->cb)
162     gc->cb(pvar, type, seq, gc->ctx);
163     gc->ref_count = 0;
164     }
165    
166     return 0;
167 yutakapon 5853 }
168 yutakapon 5850
169     //
170 maya 3227 // channel function
171     //
172     static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack,
173     enum confirm_type type, int local_num)
174     {
175     int i, found;
176     Channel_t *c;
177    
178     found = -1;
179     for (i = 0 ; i < CHANNEL_MAX ; i++) {
180     if (channels[i].used == 0) { // free channel
181     found = i;
182     break;
183     }
184     }
185     if (found == -1) { // not free channel
186     return (NULL);
187     }
188    
189     // setup
190     c = &channels[found];
191     memset(c, 0, sizeof(Channel_t));
192     c->used = 1;
193     c->self_id = i;
194     c->remote_id = -1;
195     c->local_window = window;
196     c->local_window_max = window;
197     c->local_consumed = 0;
198     c->local_maxpacket = maxpack;
199     c->remote_window = 0;
200     c->remote_maxpacket = 0;
201     c->type = type;
202     c->local_num = local_num; // alloc_channel()�����l��������������
203     c->bufchain = NULL;
204     if (type == TYPE_SCP) {
205     c->scp.state = SCP_INIT;
206     c->scp.progress_window = NULL;
207     c->scp.thread = (HANDLE)-1;
208     c->scp.localfp = NULL;
209 maya 5607 c->scp.filemtime = 0;
210     c->scp.fileatime = 0;
211 maya 3227 }
212     if (type == TYPE_AGENT) {
213     c->agent_msg = buffer_init();
214     c->agent_request_len = 0;
215     }
216 maya 5422 c->state = 0;
217 maya 3227
218     return (c);
219     }
220    
221     // remote_window�������������������A�������������o�b�t�@�����X�g�i�������j���������������B
222     static void ssh2_channel_add_bufchain(Channel_t *c, unsigned char *buf, unsigned int buflen)
223     {
224     bufchain_t *p, *old;
225    
226     // allocate new buffer
227     p = malloc(sizeof(bufchain_t));
228     if (p == NULL)
229     return;
230     p->msg = buffer_init();
231     if (p == NULL) {
232     free(p);
233     return;
234     }
235     buffer_put_raw(p->msg, buf, buflen);
236     p->next = NULL;
237    
238     if (c->bufchain == NULL) {
239     c->bufchain = p;
240     } else {
241     old = c->bufchain;
242     while (old->next)
243     old = old->next;
244     old->next = p;
245     }
246     }
247    
248    
249     static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c)
250     {
251     bufchain_t *ch;
252     unsigned int size;
253    
254     while (c->bufchain) {
255     // ����������������
256     ch = c->bufchain;
257     size = buffer_len(ch->msg);
258     if (size >= c->remote_window)
259     break;
260    
261     if (c->local_num == -1) { // shell or SCP
262 yutakapon 5039 SSH2_send_channel_data(pvar, c, buffer_ptr(ch->msg), size, TRUE);
263 maya 3227 } else { // port-forwarding
264 yutakapon 5039 SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size, TRUE);
265 maya 3227 }
266    
267     c->bufchain = ch->next;
268    
269     buffer_free(ch->msg);
270     free(ch);
271     }
272     }
273    
274    
275    
276     // channel close�����`���l���\���������X�g�����p����
277     // (2007.4.26 yutaka)
278     static void ssh2_channel_delete(Channel_t *c)
279     {
280     bufchain_t *ch, *ptr;
281 yutakapon 6586 enum scp_state prev_state;
282 maya 3227
283     ch = c->bufchain;
284     while (ch) {
285     if (ch->msg)
286     buffer_free(ch->msg);
287     ptr = ch;
288     ch = ch->next;
289     free(ptr);
290     }
291    
292     if (c->type == TYPE_SCP) {
293 yutakapon 6586 // SCP���������������������������B
294     prev_state = c->scp.state;
295    
296 maya 3227 c->scp.state = SCP_CLOSING;
297 maya 5607 if (c->scp.localfp != NULL) {
298 maya 3227 fclose(c->scp.localfp);
299 maya 5607 if (c->scp.dir == FROMREMOTE) {
300     if (c->scp.fileatime > 0 && c->scp.filemtime > 0) {
301     struct _utimbuf filetime;
302     filetime.actime = c->scp.fileatime;
303     filetime.modtime = c->scp.filemtime;
304     _utime(c->scp.localfilefull, &filetime);
305     }
306 yutakapon 6586
307     // SCP���M���������������������A���[�J�����������t�@�C�����c�[�����������B
308     // (2017.2.12 yutaka)
309     if (prev_state != SCP_CLOSING)
310     remove(c->scp.localfilefull);
311 maya 5607 }
312     }
313 maya 3227 if (c->scp.progress_window != NULL) {
314     DestroyWindow(c->scp.progress_window);
315     c->scp.progress_window = NULL;
316     }
317     if (c->scp.thread != (HANDLE)-1L) {
318     WaitForSingleObject(c->scp.thread, INFINITE);
319     CloseHandle(c->scp.thread);
320     c->scp.thread = (HANDLE)-1L;
321     }
322 yutakapon 6528
323     ssh2_scp_free_packetlist(c);
324 maya 3227 }
325     if (c->type == TYPE_AGENT) {
326     buffer_free(c->agent_msg);
327     }
328    
329     memset(c, 0, sizeof(Channel_t));
330     c->used = 0;
331     }
332    
333    
334     // connection close������������
335     void ssh2_channel_free(void)
336     {
337     int i;
338     Channel_t *c;
339    
340     for (i = 0 ; i < CHANNEL_MAX ; i++) {
341     c = &channels[i];
342     ssh2_channel_delete(c);
343     }
344    
345     }
346    
347     static Channel_t *ssh2_channel_lookup(int id)
348     {
349     Channel_t *c;
350    
351     if (id < 0 || id >= CHANNEL_MAX) {
352     return (NULL);
353     }
354     c = &channels[id];
355     if (c->used == 0) { // already freed
356     return (NULL);
357     }
358     return (c);
359     }
360    
361     // SSH1��������������channel�\���������ASSH2������Channel_t�����������B
362     // TODO: �����I�����`���l���\������1�������������B
363     // (2005.6.12 yutaka)
364     static Channel_t *ssh2_local_channel_lookup(int local_num)
365     {
366     int i;
367     Channel_t *c;
368    
369     for (i = 0 ; i < CHANNEL_MAX ; i++) {
370     c = &channels[i];
371     if (c->local_num == local_num)
372     return (c);
373     }
374     return (NULL);
375     }
376    
377    
378     //
379     // SSH heartbeat mutex
380     //
381     // TTSSH�� thread-safe �������������A�}���`�X���b�h�������p�P�b�g���M�����������B
382     // �V���O���X���b�h�����R���e�L�X�g�X�C�b�`�������������������������A
383     // ���b�N�������K�v�����������A���������B(2007.12.26 yutaka)
384     //
385     static CRITICAL_SECTION g_ssh_heartbeat_lock; /* �����M�p���b�N */
386    
387     void ssh_heartbeat_lock_initialize(void)
388     {
389     //InitializeCriticalSection(&g_ssh_heartbeat_lock);
390     }
391    
392     void ssh_heartbeat_lock_finalize(void)
393     {
394     //DeleteCriticalSection(&g_ssh_heartbeat_lock);
395     }
396    
397     void ssh_heartbeat_lock(void)
398     {
399     //EnterCriticalSection(&g_ssh_heartbeat_lock);
400     }
401    
402     void ssh_heartbeat_unlock(void)
403     {
404     //LeaveCriticalSection(&g_ssh_heartbeat_lock);
405     }
406    
407    
408     //
409     // SSH memory dump (for debug)
410     //
411     // (2005.3.7 yutaka)
412     //
413     #define MEMTAG_MAX 300
414     #define LOGDUMP "ssh2connect.log"
415     #define LOG_PACKET_DUMP "ssh2packet.log"
416     #define SENDTOME "Please send '"LOGDUMP"' file to Tera Term developer team."
417    
418     typedef struct memtag {
419     char *name;
420     char *desc;
421     time_t time;
422     int len;
423     char *data;
424     } memtag_t;
425    
426     static memtag_t memtags[MEMTAG_MAX];
427     static int memtag_count = 0;
428     static int memtag_use = 0;
429    
430     /* �_���v���C�����t�H�[�}�b�g�\������ */
431     static void displine_memdump(FILE *fp, int addr, int *bytes, int byte_cnt)
432     {
433     int i, c;
434    
435     /* �������A�h���X�\�� */
436     fprintf(fp, "%08X : ", addr);
437    
438     /* �o�C�i���\���i4�o�C�g�������������}���j*/
439     for (i = 0 ; i < byte_cnt ; i++) {
440     if (i > 0 && i % 4 == 0)
441     fprintf(fp, " ");
442    
443     fprintf(fp, "%02X", bytes[i]);
444     }
445    
446     /* ASCII�\���������������������� */
447     fprintf(fp, " %*s%*s", (16-byte_cnt)*2+1, " ", (16-byte_cnt+3)/4, " ");
448    
449     /* ASCII�\�� */
450     for (i = 0 ; i < byte_cnt ; i++) {
451     c = bytes[i];
452     if (isprint(c)) {
453     fprintf(fp, "%c", c);
454     } else {
455     fprintf(fp, ".");
456     }
457     }
458    
459     fprintf(fp, "\n");
460     }
461    
462    
463     /* �_���v���[�`�� */
464     static void dump_memdump(FILE *fp, char *data, int len)
465     {
466     int c, addr;
467     int bytes[16], *ptr;
468     int byte_cnt;
469     int i;
470    
471     addr = 0;
472     byte_cnt = 0;
473     ptr = bytes;
474     for (i = 0 ; i < len ; i++) {
475     c = data[i];
476     *ptr++ = c & 0xff;
477     byte_cnt++;
478    
479     if (byte_cnt == 16) {
480     displine_memdump(fp, addr, bytes, byte_cnt);
481    
482     addr += 16;
483     byte_cnt = 0;
484     ptr = bytes;
485     }
486     }
487    
488     if (byte_cnt > 0) {
489     displine_memdump(fp, addr, bytes, byte_cnt);
490     }
491     }
492    
493     void init_memdump(void)
494     {
495     int i;
496    
497     if (memtag_use > 0)
498     return;
499    
500     for (i = 0 ; i < MEMTAG_MAX ; i++) {
501     memtags[i].name = NULL;
502     memtags[i].desc = NULL;
503     memtags[i].data = NULL;
504     memtags[i].len = 0;
505     }
506     memtag_use++;
507     }
508    
509     void finish_memdump(void)
510     {
511     int i;
512    
513     // initialize�������������������������������B(2005.4.3 yutaka)
514     if (memtag_use <= 0)
515     return;
516     memtag_use--;
517    
518     for (i = 0 ; i < MEMTAG_MAX ; i++) {
519     free(memtags[i].name);
520     free(memtags[i].desc);
521     free(memtags[i].data);
522     memtags[i].len = 0;
523     }
524     memtag_count = 0;
525     }
526    
527     void save_memdump(char *filename)
528     {
529     FILE *fp;
530     int i;
531     time_t t;
532     struct tm *tm;
533    
534     fp = fopen(filename, "w");
535     if (fp == NULL)
536     return;
537    
538     t = time(NULL);
539     tm = localtime(&t);
540    
541     fprintf(fp, "<<< Tera Term SSH2 log dump >>>\n");
542     fprintf(fp, "saved time: %04d/%02d/%02d %02d:%02d:%02d\n",
543     tm->tm_year + 1900,
544     tm->tm_mon + 1,
545     tm->tm_mday,
546     tm->tm_hour,
547     tm->tm_min,
548     tm->tm_sec);
549     fprintf(fp, "\n");
550    
551     for (i = 0 ; i < memtag_count ; i++) {
552     fprintf(fp, "============================================\n");
553     fprintf(fp, "name: %s\n", memtags[i].name);
554     fprintf(fp, "--------------------------------------------\n");
555     fprintf(fp, "description: %s\n", memtags[i].desc);
556     fprintf(fp, "--------------------------------------------\n");
557     fprintf(fp, "time: %s", ctime(&memtags[i].time));
558     fprintf(fp, "============================================\n");
559     dump_memdump(fp, memtags[i].data, memtags[i].len);
560     fprintf(fp, "\n\n\n");
561     }
562    
563     fprintf(fp, "[EOF]\n");
564    
565     fclose(fp);
566     }
567    
568     void push_memdump(char *name, char *desc, char *data, int len)
569     {
570     memtag_t *ptr;
571     char *dp;
572    
573     dp = malloc(len);
574     if (dp == NULL)
575     return;
576     memcpy(dp, data, len);
577    
578     if (memtag_count >= MEMTAG_MAX)
579     return;
580    
581     ptr = &memtags[memtag_count];
582     memtag_count++;
583     ptr->name = _strdup(name);
584     ptr->desc = _strdup(desc);
585     ptr->time = time(NULL);
586     ptr->data = dp;
587     ptr->len = len;
588     }
589    
590     void push_bignum_memdump(char *name, char *desc, BIGNUM *bignum)
591     {
592     int len;
593     char *buf;
594    
595     len = BN_num_bytes(bignum);
596     buf = malloc(len); // allocate
597     if (buf == NULL)
598     return;
599     BN_bn2bin(bignum, buf);
600     push_memdump(name, desc, buf, len); // at push_bignum_memdump()
601     free(buf); // free
602     }
603    
604    
605     //
606     //
607     //
608    
609    
610     static int get_predecryption_amount(PTInstVar pvar)
611     {
612     static int small_block_decryption_sizes[] = { 5, 5, 6, 6, 8 };
613    
614     if (SSHv1(pvar)) {
615     return 0;
616     } else {
617     int block_size = CRYPT_get_decryption_block_size(pvar);
618    
619     if (block_size < 5) {
620     return small_block_decryption_sizes[block_size];
621     } else {
622     return block_size;
623     }
624     }
625     }
626    
627     /* Get up to 'limit' bytes into the payload buffer.
628     'limit' is counted from the start of the payload data.
629     Returns the amount of data in the payload buffer, or
630     -1 if there is an error.
631     We can return more than limit in some cases. */
632     static int buffer_packet_data(PTInstVar pvar, int limit)
633     {
634     if (pvar->ssh_state.payloadlen >= 0) {
635     return pvar->ssh_state.payloadlen;
636     } else {
637     int cur_decompressed_bytes =
638     pvar->ssh_state.decompress_stream.next_out -
639     pvar->ssh_state.postdecompress_inbuf;
640    
641     while (limit > cur_decompressed_bytes) {
642     int result;
643    
644     pvar->ssh_state.payload =
645     pvar->ssh_state.postdecompress_inbuf + 1;
646     if (pvar->ssh_state.postdecompress_inbuflen == cur_decompressed_bytes) {
647     buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
648     &pvar->ssh_state.postdecompress_inbuflen,
649     min(limit, cur_decompressed_bytes * 2));
650     }
651    
652     pvar->ssh_state.decompress_stream.next_out =
653     pvar->ssh_state.postdecompress_inbuf +
654     cur_decompressed_bytes;
655     pvar->ssh_state.decompress_stream.avail_out =
656     min(limit, pvar->ssh_state.postdecompress_inbuflen)
657     - cur_decompressed_bytes;
658    
659     result =
660     inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH);
661     cur_decompressed_bytes =
662     pvar->ssh_state.decompress_stream.next_out -
663     pvar->ssh_state.postdecompress_inbuf;
664    
665     switch (result) {
666     case Z_OK:
667     break;
668     case Z_BUF_ERROR:
669     pvar->ssh_state.payloadlen = cur_decompressed_bytes;
670     return cur_decompressed_bytes;
671     default:
672     UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
673     "Invalid compressed data in received packet");
674 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
675 maya 3227 return -1;
676     }
677     }
678    
679     return cur_decompressed_bytes;
680     }
681     }
682    
683     /* For use by the protocol processing code.
684     Gets N bytes of uncompressed payload. Returns FALSE if data not available
685     and a fatal error has been signaled.
686     The data is available in the payload buffer. This buffer address
687     can change during a call to grab_payload, so take care!
688     The payload pointer is set to point to the first byte of the actual data
689     (after the packet type byte).
690     */
691     static BOOL grab_payload(PTInstVar pvar, int num_bytes)
692     {
693     /* Accept maximum of 4MB of payload data */
694     int in_buffer = buffer_packet_data(pvar, PACKET_MAX_SIZE);
695    
696     if (in_buffer < 0) {
697     return FALSE;
698     } else {
699     pvar->ssh_state.payload_grabbed += num_bytes;
700     if (pvar->ssh_state.payload_grabbed > in_buffer) {
701     char buf[128];
702     UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_ERROR", pvar,
703     "Received truncated packet (%ld > %d) @ grab_payload()");
704     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
705     pvar->ssh_state.payload_grabbed, in_buffer);
706 maya 5678 notify_fatal_error(pvar, buf, TRUE);
707 maya 3227 return FALSE;
708     } else {
709     return TRUE;
710     }
711     }
712     }
713    
714     static BOOL grab_payload_limited(PTInstVar pvar, int num_bytes)
715     {
716     int in_buffer;
717    
718     pvar->ssh_state.payload_grabbed += num_bytes;
719     in_buffer = buffer_packet_data(pvar, pvar->ssh_state.payload_grabbed);
720    
721     if (in_buffer < 0) {
722     return FALSE;
723     } else {
724     if (pvar->ssh_state.payload_grabbed > in_buffer) {
725     char buf[128];
726     UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_LIM_ERROR", pvar,
727     "Received truncated packet (%ld > %d) @ grab_payload_limited()");
728     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
729     pvar->ssh_state.payload_grabbed, in_buffer);
730 maya 5678 notify_fatal_error(pvar, buf, TRUE);
731 maya 3227 return FALSE;
732     } else {
733     return TRUE;
734     }
735     }
736     }
737    
738     #define do_crc(buf, len) (~(uint32)crc32(0xFFFFFFFF, (buf), (len)))
739    
740     /* Decrypt the payload, checksum it, eat the padding, get the packet type
741     and return it.
742     'data' points to the start of the packet --- its length field.
743     'len' is the length of the
744     payload + padding (+ length of CRC for SSHv1). 'padding' is the length
745     of the padding alone. */
746 doda 6801 static int prep_packet(PTInstVar pvar, char *data, int len,
747 maya 3227 int padding)
748     {
749     pvar->ssh_state.payload = data + 4;
750     pvar->ssh_state.payloadlen = len;
751    
752     if (SSHv1(pvar)) {
753     if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
754     UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar,
755     "'CORE insertion attack' detected. Aborting connection.");
756 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
757 maya 3227 }
758    
759     CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
760     /* PKT guarantees that the data is always 4-byte aligned */
761     if (do_crc(pvar->ssh_state.payload, len - 4) !=
762     get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
763     UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
764     "Detected corrupted data; connection terminating.");
765 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
766 maya 3227 return SSH_MSG_NONE;
767     }
768    
769     pvar->ssh_state.payload += padding;
770     pvar->ssh_state.payloadlen -= padding + 4;
771     } else {
772     int already_decrypted = get_predecryption_amount(pvar);
773    
774     CRYPT_decrypt(pvar, data + already_decrypted,
775     (4 + len) - already_decrypted);
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 doda 6801 unsigned char *begin_send_packet(PTInstVar pvar, int type, int len)
865 maya 3227 {
866 doda 6801 unsigned char *buf;
867 maya 3227
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 doda 6801 static int retry_send_packet(PTInstVar pvar, char *data, int len)
898 maya 3227 {
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 doda 6801 static BOOL send_packet_blocking(PTInstVar pvar, char *data, int len)
925 maya 3227 {
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 doda 6801 unsigned char *data;
994 maya 3227 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 doda 6801 const int *messages,
1159     const SSHPacketHandler *handlers)
1160 maya 3227 {
1161 doda 6801 SSHPacketHandlerItem *first_item;
1162     SSHPacketHandlerItem *last_item = NULL;
1163 maya 3227 int i;
1164    
1165     for (i = 0; i < num_msgs; i++) {
1166 doda 6801 SSHPacketHandlerItem *item =
1167     (SSHPacketHandlerItem *)
1168 maya 3227 malloc(sizeof(SSHPacketHandlerItem));
1169 doda 6801 SSHPacketHandlerItem *cur_item =
1170 maya 3227 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 doda 6801 SSHPacketHandlerItem *cur_item =
1203 maya 3227 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 doda 6801 SSHPacketHandlerItem *cur_item =
1216 maya 3227 pvar->ssh_state.packet_handlers[message];
1217 doda 6801 SSHPacketHandlerItem *first_item_in_set = cur_item;
1218 maya 3227
1219     if (cur_item == NULL)
1220     return;
1221    
1222     do {
1223 doda 6801 SSHPacketHandlerItem *next_in_set = cur_item->next_in_set;
1224 maya 3227
1225     if (cur_item->active_for_message >= 0) {
1226 doda 6801 SSHPacketHandlerItem *replacement =
1227 maya 3227 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 doda 6801 static void chop_newlines(char *buf)
1255 maya 3227 {
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 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Authentication failed");
1290 maya 3227
1291     // retry count������ (2005.7.15 yutaka)
1292     pvar->userauth_retry_count++;
1293    
1294     AUTH_set_generic_mode(pvar);
1295     AUTH_advance_to_next_cred(pvar);
1296     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1297     try_send_credentials(pvar);
1298     return FALSE;
1299     }
1300    
1301     static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1302     {
1303     if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1304     if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1305     // �S�������������I������
1306     safefree(pvar->pageant_key);
1307     }
1308     else {
1309     // ������������
1310     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1311     try_send_credentials(pvar);
1312     return TRUE;
1313     }
1314     }
1315     AUTH_destroy_cur_cred(pvar);
1316     return handle_auth_failure(pvar);
1317     }
1318    
1319     static BOOL handle_TIS_challenge(PTInstVar pvar)
1320     {
1321     if (grab_payload(pvar, 4)) {
1322     int len = get_payload_uint32(pvar, 0);
1323    
1324     if (grab_payload(pvar, len)) {
1325 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Received TIS challenge");
1326 maya 3227
1327     AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1328     AUTH_advance_to_next_cred(pvar);
1329     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1330     try_send_credentials(pvar);
1331     }
1332     }
1333     return FALSE;
1334     }
1335    
1336     static BOOL handle_auth_required(PTInstVar pvar)
1337     {
1338 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Server requires authentication");
1339 maya 3227
1340     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1341     try_send_credentials(pvar);
1342     /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1343    
1344     return FALSE;
1345     }
1346    
1347     static BOOL handle_ignore(PTInstVar pvar)
1348     {
1349     if (SSHv1(pvar)) {
1350 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_IGNORE was received.");
1351 maya 3227
1352     if (grab_payload(pvar, 4)
1353     && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1354     /* ignore it! but it must be decompressed */
1355     }
1356     }
1357     else {
1358 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_IGNORE was received.");
1359 maya 3227
1360     // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1361     // Cisco ���[�^���� (2006.11.28 maya)
1362     }
1363     return TRUE;
1364     }
1365    
1366     static BOOL handle_debug(PTInstVar pvar)
1367     {
1368     BOOL always_display;
1369 doda 6801 char *description;
1370 maya 3227 int description_len;
1371     char buf[2048];
1372    
1373     if (SSHv1(pvar)) {
1374 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_DEBUG was received.");
1375 maya 3227
1376     if (grab_payload(pvar, 4)
1377     && grab_payload(pvar, description_len =
1378     get_payload_uint32(pvar, 0))) {
1379     always_display = FALSE;
1380     description = pvar->ssh_state.payload + 4;
1381     description[description_len] = 0;
1382     } else {
1383     return TRUE;
1384     }
1385     } else {
1386 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_DEBUG was received.");
1387 maya 3227
1388     if (grab_payload(pvar, 5)
1389     && grab_payload(pvar,
1390     (description_len = get_payload_uint32(pvar, 1)) + 4)
1391     && grab_payload(pvar,
1392     get_payload_uint32(pvar, 5 + description_len))) {
1393     always_display = pvar->ssh_state.payload[0] != 0;
1394     description = pvar->ssh_state.payload + 5;
1395     description[description_len] = 0;
1396     } else {
1397     return TRUE;
1398     }
1399     }
1400    
1401     chop_newlines(description);
1402     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1403     description);
1404     if (always_display) {
1405     notify_nonfatal_error(pvar, buf);
1406     } else {
1407 doda 6809 logputs(LOG_LEVEL_VERBOSE, buf);
1408 maya 3227 }
1409     return TRUE;
1410     }
1411    
1412     static BOOL handle_disconnect(PTInstVar pvar)
1413     {
1414     int reason_code;
1415 doda 6801 char *description;
1416 maya 3227 int description_len;
1417     char buf[2048];
1418 doda 6801 char *explanation = "";
1419 maya 3227 char uimsg[MAX_UIMSG];
1420    
1421     if (SSHv1(pvar)) {
1422 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_MSG_DISCONNECT was received.");
1423 maya 3227
1424     if (grab_payload(pvar, 4)
1425     && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1426     reason_code = -1;
1427     description = pvar->ssh_state.payload + 4;
1428     description[description_len] = 0;
1429     } else {
1430     return TRUE;
1431     }
1432     } else {
1433 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_DISCONNECT was received.");
1434 maya 3227
1435     if (grab_payload(pvar, 8)
1436     && grab_payload(pvar,
1437     (description_len = get_payload_uint32(pvar, 4)) + 4)
1438     && grab_payload(pvar,
1439     get_payload_uint32(pvar, 8 + description_len))) {
1440     reason_code = get_payload_uint32(pvar, 0);
1441     description = pvar->ssh_state.payload + 8;
1442     description[description_len] = 0;
1443     } else {
1444     return TRUE;
1445     }
1446     }
1447    
1448     chop_newlines(description);
1449     if (description[0] == 0) {
1450     description = NULL;
1451     }
1452    
1453     if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1454     UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1455     "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1456     "This often happens when someone is already forwarding that port from the server.");
1457     strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1458     explanation = uimsg;
1459     }
1460    
1461     if (description != NULL) {
1462     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1463     "Server disconnected with message '%s'%s");
1464     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1465     pvar->ts->UIMsg, description,
1466     explanation);
1467     } else {
1468     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1469     "Server disconnected (no reason given).%s");
1470     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1471     pvar->ts->UIMsg, explanation);
1472     }
1473    
1474 maya 5678 if (SSHv2(pvar)) {
1475     // SSH2_MSG_DISCONNECT �������������������������M��������������
1476     notify_fatal_error(pvar, buf, FALSE);
1477     }
1478     else {
1479     // SSH1 ���������d�l�����������������A���O����������������
1480     notify_fatal_error(pvar, buf, TRUE);
1481     }
1482    
1483 maya 3227 return TRUE;
1484     }
1485    
1486     static BOOL handle_unimplemented(PTInstVar pvar)
1487     {
1488     /* Should never receive this since we only send base 2.0 protocol messages */
1489     grab_payload(pvar, 4);
1490     return TRUE;
1491     }
1492    
1493     static BOOL handle_crypt_success(PTInstVar pvar)
1494     {
1495 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Secure mode successfully achieved");
1496 maya 3227 return FALSE;
1497     }
1498    
1499     static BOOL handle_noauth_success(PTInstVar pvar)
1500     {
1501 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Server does not require authentication");
1502 maya 3227 prep_compression(pvar);
1503     return FALSE;
1504     }
1505    
1506     static BOOL handle_auth_success(PTInstVar pvar)
1507     {
1508 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Authentication accepted");
1509 maya 3227 prep_compression(pvar);
1510    
1511     // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1512     start_ssh_heartbeat_thread(pvar);
1513    
1514     return FALSE;
1515     }
1516    
1517     static BOOL handle_server_public_key(PTInstVar pvar)
1518     {
1519     int server_key_public_exponent_len;
1520     int server_key_public_modulus_pos;
1521     int server_key_public_modulus_len;
1522     int host_key_bits_pos;
1523     int host_key_public_exponent_len;
1524     int host_key_public_modulus_pos;
1525     int host_key_public_modulus_len;
1526     int protocol_flags_pos;
1527     int supported_ciphers;
1528 doda 6801 char *inmsg;
1529 maya 3227 Key hostkey;
1530     int supported_types;
1531    
1532 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH_SMSG_PUBLIC_KEY was received.");
1533 maya 3227
1534     if (!grab_payload(pvar, 14))
1535     return FALSE;
1536     server_key_public_exponent_len = get_mpint_len(pvar, 12);
1537    
1538     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1539     return FALSE;
1540     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1541     server_key_public_modulus_len =
1542     get_mpint_len(pvar, server_key_public_modulus_pos);
1543    
1544     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1545     return FALSE;
1546     host_key_bits_pos =
1547     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1548     host_key_public_exponent_len =
1549     get_mpint_len(pvar, host_key_bits_pos + 4);
1550    
1551     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1552     return FALSE;
1553     host_key_public_modulus_pos =
1554     host_key_bits_pos + 6 + host_key_public_exponent_len;
1555     host_key_public_modulus_len =
1556     get_mpint_len(pvar, host_key_public_modulus_pos);
1557    
1558     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1559     return FALSE;
1560     protocol_flags_pos =
1561     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1562    
1563     inmsg = pvar->ssh_state.payload;
1564    
1565     CRYPT_set_server_cookie(pvar, inmsg);
1566     if (!CRYPT_set_server_RSA_key(pvar,
1567     get_uint32(inmsg + 8),
1568     pvar->ssh_state.payload + 12,
1569     inmsg + server_key_public_modulus_pos))
1570     return FALSE;
1571     if (!CRYPT_set_host_RSA_key(pvar,
1572     get_uint32(inmsg + host_key_bits_pos),
1573     inmsg + host_key_bits_pos + 4,
1574     inmsg + host_key_public_modulus_pos))
1575     return FALSE;
1576     pvar->ssh_state.server_protocol_flags =
1577     get_uint32(inmsg + protocol_flags_pos);
1578    
1579     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1580     if (!CRYPT_set_supported_ciphers(pvar,
1581     supported_ciphers,
1582     supported_ciphers))
1583     return FALSE;
1584    
1585     // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1586     // RSA ���L������ PAGEANT ���L��������
1587     supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1588     if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1589     supported_types |= (1 << SSH_AUTH_PAGEANT);
1590     }
1591     if (!AUTH_set_supported_auth_types(pvar,
1592     supported_types))
1593     return FALSE;
1594    
1595     /* this must be the LAST THING in this function, since it can cause
1596     host_is_OK to be called. */
1597     hostkey.type = KEY_RSA1;
1598     hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1599     hostkey.exp = inmsg + host_key_bits_pos + 4;
1600     hostkey.mod = inmsg + host_key_public_modulus_pos;
1601     HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1602    
1603     return FALSE;
1604     }
1605    
1606     /*
1607     The ID must have already been found to start with "SSH-". It must
1608     be null-terminated.
1609     */
1610 doda 6801 static BOOL parse_protocol_ID(PTInstVar pvar, char *ID)
1611 maya 3227 {
1612 doda 6801 char *str;
1613 maya 3227
1614     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1615     }
1616    
1617     if (*str != '.') {
1618     return FALSE;
1619     }
1620    
1621     pvar->protocol_major = atoi(ID + 4);
1622     pvar->protocol_minor = atoi(str + 1);
1623    
1624     for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1625     }
1626    
1627     return *str == '-';
1628     }
1629    
1630     /*
1631     On entry, the pvar->protocol_xxx fields hold the server's advertised
1632     protocol number. We replace the fields with the protocol number we will
1633     actually use, or return FALSE if there is no usable protocol version.
1634     */
1635 maya 4682 static int negotiate_protocol(PTInstVar pvar)
1636 maya 3227 {
1637     switch (pvar->protocol_major) {
1638     case 1:
1639 maya 4682 if (pvar->protocol_minor == 99 &&
1640     pvar->settings.ssh_protocol_version == 2) {
1641     // �T�[�o�� 1.99 �����[�U�� SSH2 ���I������������������
1642     // 2.0 ����������
1643     pvar->protocol_major = 2;
1644     pvar->protocol_minor = 0;
1645     return 0;
1646     }
1647    
1648     if (pvar->settings.ssh_protocol_version == 2) {
1649     // �o�[�W��������
1650     return -1;
1651     }
1652    
1653 maya 3227 if (pvar->protocol_minor > 5) {
1654     pvar->protocol_minor = 5;
1655     }
1656    
1657 maya 4682 return 0;
1658 maya 3227
1659     // for SSH2(yutaka)
1660     case 2:
1661 maya 4682 if (pvar->settings.ssh_protocol_version == 1) {
1662     // �o�[�W��������
1663     return -1;
1664     }
1665 maya 3227
1666 maya 4682 return 0; // SSH2 support
1667    
1668 maya 3227 default:
1669 maya 4682 return 1;
1670 maya 3227 }
1671     }
1672    
1673     static void init_protocol(PTInstVar pvar)
1674     {
1675     CRYPT_initialize_random_numbers(pvar);
1676    
1677     // known_hosts�t�@�C�������z�X�g���J������������������
1678     HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1679    
1680     /* while we wait for a response from the server... */
1681    
1682     if (SSHv1(pvar)) {
1683     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1684     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1685     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1686     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1687    
1688     } else { // for SSH2(yutaka)
1689     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1690     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1691     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1692     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1693     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1694     enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1695     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1696     enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1697     enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1698     enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1699     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1700     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1701 doda 6657 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_msg60);
1702 maya 3227
1703     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1704    
1705     // ���[�U�F�������f�B�X�p�b�`���[�`��
1706     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1707     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1708     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1709     enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1710     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1711     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1712     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1713     enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1714     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1715     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1716     enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1717 yutakapon 5829 enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_SSH2_client_global_request);
1718 maya 3227 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1719     enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1720    
1721 yutakapon 5850 client_init_global_confirm();
1722    
1723 maya 3227 }
1724     }
1725    
1726 doda 5928 void server_version_check(PTInstVar pvar)
1727     {
1728     char *server_swver;
1729    
1730     pvar->server_compat_flag = 0;
1731    
1732     if ((server_swver = strchr(pvar->server_version_string+4, '-')) == NULL) {
1733 doda 6809 logputs(LOG_LEVEL_WARNING, "Can't get server software version string.");
1734 doda 5928 return;
1735     }
1736     server_swver++;
1737    
1738     if (strncmp(server_swver, "Cisco-1", 7) == 0) {
1739     pvar->server_compat_flag |= SSH_BUG_DHGEX_LARGE;
1740 doda 6809 logputs(LOG_LEVEL_INFO, "Server version string is matched to \"Cisco-1\", compatibility flag SSH_BUG_DHGEX_LARGE is enabled.");
1741 doda 5928 }
1742     }
1743    
1744 doda 6801 BOOL SSH_handle_server_ID(PTInstVar pvar, char *ID, int ID_len)
1745 maya 3227 {
1746 maya 4546 static char prefix[64];
1747 maya 4682 int negotiate;
1748     char uimsg[MAX_UIMSG];
1749 maya 3227
1750     // initialize SSH2 memory dump (2005.3.7 yutaka)
1751     init_memdump();
1752     push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1753    
1754     if (ID_len <= 0) {
1755     return FALSE;
1756     } else {
1757 maya 4546 int buf_len;
1758 doda 6801 char *buf;
1759 maya 3227
1760 maya 4546 strncpy_s(prefix, sizeof(prefix), "Received server identification string: ", _TRUNCATE);
1761     buf_len = strlen(prefix) + ID_len + 1;
1762 doda 6801 buf = (char *) malloc(buf_len);
1763 maya 3227 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1764     strncat_s(buf, buf_len, ID, _TRUNCATE);
1765     chop_newlines(buf);
1766 doda 6809 logputs(LOG_LEVEL_VERBOSE, buf);
1767 maya 3227 free(buf);
1768    
1769     if (ID[ID_len - 1] != '\n') {
1770     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1771     return FALSE;
1772     } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1773     pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1774     return FALSE;
1775     } else if (strncmp(ID, "SSH-", 4) != 0) {
1776     return FALSE;
1777     } else {
1778     ID[ID_len - 1] = 0;
1779    
1780     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1781     ID[ID_len - 2] = 0;
1782     }
1783    
1784     pvar->ssh_state.server_ID = _strdup(ID);
1785    
1786 maya 4682 if (!parse_protocol_ID(pvar, ID)) {
1787 maya 3227 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1788     "This program does not understand the server's version of the protocol.");
1789 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1790 maya 4682 }
1791     else if ((negotiate = negotiate_protocol(pvar)) == 1) {
1792     UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1793     "This program does not understand the server's version of the protocol.");
1794 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1795 maya 4682 }
1796     else if (negotiate == -1) {
1797     UTIL_get_lang_msg("MSG_SSH_VERSION_MISMATCH", pvar,
1798     "Protocol version mismatch. server:%d.%d client:%d");
1799     _snprintf_s(uimsg, sizeof(uimsg), _TRUNCATE, pvar->ts->UIMsg,
1800     pvar->protocol_major, pvar->protocol_minor, pvar->settings.ssh_protocol_version);
1801 maya 5678 notify_fatal_error(pvar, uimsg, TRUE);
1802 maya 4682 }
1803     else {
1804 maya 3227 char TTSSH_ID[1024];
1805     int TTSSH_ID_len;
1806     int a, b, c, d;
1807    
1808 maya 4682 // SSH �o�[�W������ teraterm �����Z�b�g����
1809     // SCP �R�}���h������ (2008.2.3 maya)
1810     pvar->cv->isSSH = pvar->protocol_major;
1811    
1812 maya 3227 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1813     get_file_version("ttxssh.dll", &a, &b, &c, &d);
1814    
1815     _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1816 maya 4656 "SSH-%d.%d-TTSSH/%d.%d Win32\r\n",
1817 maya 3227 pvar->protocol_major, pvar->protocol_minor, a, b);
1818     TTSSH_ID_len = strlen(TTSSH_ID);
1819    
1820     // for SSH2(yutaka)
1821     // �N���C�A���g�o�[�W�����������i���s���������������j
1822     strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1823     TTSSH_ID, _TRUNCATE);
1824    
1825     // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1826     _snprintf_s(pvar->server_version_string,
1827     sizeof(pvar->server_version_string), _TRUNCATE,
1828     "%s", pvar->ssh_state.server_ID);
1829    
1830 doda 5928 // �T�[�o�o�[�W�������`�F�b�N
1831     server_version_check(pvar);
1832    
1833 doda 6809 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len, 0) != TTSSH_ID_len) {
1834 maya 3227 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1835     "An error occurred while sending the SSH ID string.\n"
1836     "The connection will close.");
1837 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1838 maya 3227 } else {
1839 doda 6809 // ���s������
1840     chop_newlines(pvar->client_version_string);
1841     logprintf(LOG_LEVEL_VERBOSE, "Sent client identification string: %s", pvar->client_version_string);
1842 maya 3227
1843     push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1844     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1845    
1846     // SSH�n���h�����o�^���s��
1847     init_protocol(pvar);
1848    
1849     SSH2_dispatch_init(1);
1850     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1851     SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1852 maya 4867 SSH2_dispatch_add_message(SSH2_MSG_DEBUG);
1853 maya 3227 }
1854     }
1855    
1856     return TRUE;
1857     }
1858     }
1859     }
1860    
1861     static BOOL handle_exit(PTInstVar pvar)
1862     {
1863     if (grab_payload(pvar, 4)) {
1864     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1865     finish_send_packet(pvar);
1866 maya 5678 notify_closed_connection(pvar, "disconnected by server request");
1867 maya 3227 }
1868     return TRUE;
1869     }
1870    
1871     static BOOL handle_data(PTInstVar pvar)
1872     {
1873     if (grab_payload_limited(pvar, 4)) {
1874     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1875     pvar->ssh_state.payload_datastart = 4;
1876     }
1877     return TRUE;
1878     }
1879    
1880     static BOOL handle_channel_open(PTInstVar pvar)
1881     {
1882     int host_len;
1883     int originator_len;
1884    
1885     if ((pvar->ssh_state.
1886     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1887     if (grab_payload(pvar, 8)
1888     && grab_payload(pvar,
1889     8 + (host_len = get_payload_uint32(pvar, 4)))
1890     && grab_payload(pvar, originator_len =
1891     get_payload_uint32(pvar, host_len + 12))) {
1892     int local_port = get_payload_uint32(pvar, 8 + host_len);
1893    
1894     pvar->ssh_state.payload[8 + host_len] = 0;
1895     FWD_open(pvar, get_payload_uint32(pvar, 0),
1896     pvar->ssh_state.payload + 8, local_port,
1897     pvar->ssh_state.payload + 16 + host_len,
1898     originator_len,
1899     NULL);
1900     }
1901     } else {
1902     if (grab_payload(pvar, 8)
1903     && grab_payload(pvar,
1904     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1905     int local_port = get_payload_uint32(pvar, 8 + host_len);
1906    
1907     pvar->ssh_state.payload[8 + host_len] = 0;
1908     FWD_open(pvar, get_payload_uint32(pvar, 0),
1909     pvar->ssh_state.payload + 8, local_port, NULL, 0,
1910     NULL);
1911     }
1912     }
1913    
1914     return TRUE;
1915     }
1916    
1917     static BOOL handle_X11_channel_open(PTInstVar pvar)
1918     {
1919     int originator_len;
1920    
1921     if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1922     if (grab_payload(pvar, 8)
1923     && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1924     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1925     pvar->ssh_state.payload + 8, originator_len, NULL);
1926     }
1927     } else {
1928     if (grab_payload(pvar, 4)) {
1929     FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1930     }
1931     }
1932    
1933     return TRUE;
1934     }
1935    
1936     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1937     {
1938     if (grab_payload(pvar, 8)) {
1939     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1940     get_payload_uint32(pvar, 4));
1941     }
1942     return FALSE;
1943     }
1944    
1945     static BOOL handle_channel_open_failure(PTInstVar pvar)
1946     {
1947     if (grab_payload(pvar, 4)) {
1948     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1949     }
1950     return FALSE;
1951     }
1952    
1953     static BOOL handle_channel_data(PTInstVar pvar)
1954     {
1955     int len;
1956    
1957     if (grab_payload(pvar, 8)
1958     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1959     FWDChannel *channel;
1960     int local_channel_num = get_payload_uint32(pvar, 0);
1961     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1962     return FALSE;
1963     }
1964     channel = pvar->fwd_state.channels + local_channel_num;
1965     if (channel->type == TYPE_AGENT) {
1966     SSH_agent_response(pvar, NULL, local_channel_num,
1967     pvar->ssh_state.payload + 8, len);
1968     }
1969     else {
1970     FWD_received_data(pvar, local_channel_num,
1971     pvar->ssh_state.payload + 8, len);
1972     }
1973     }
1974     return TRUE;
1975     }
1976    
1977     static BOOL handle_channel_input_eof(PTInstVar pvar)
1978     {
1979     if (grab_payload(pvar, 4)) {
1980     int local_channel_num = get_payload_uint32(pvar, 0);
1981     FWDChannel *channel;
1982     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1983     return FALSE;
1984     }
1985     channel = pvar->fwd_state.channels + local_channel_num;
1986     if (channel->type == TYPE_AGENT) {
1987     channel->status |= FWD_CLOSED_REMOTE_IN;
1988     SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1989     }
1990     else {
1991     FWD_channel_input_eof(pvar, local_channel_num);
1992     }
1993     }
1994     return TRUE;
1995     }
1996    
1997     static BOOL handle_channel_output_eof(PTInstVar pvar)
1998     {
1999     if (grab_payload(pvar, 4)) {
2000     int local_channel_num = get_payload_uint32(pvar, 0);
2001     FWDChannel *channel;
2002     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
2003     return FALSE;
2004     }
2005     channel = pvar->fwd_state.channels + local_channel_num;
2006     if (channel->type == TYPE_AGENT) {
2007     channel->status |= FWD_CLOSED_REMOTE_OUT;
2008     SSH_channel_output_eof(pvar, channel->remote_num);
2009     FWD_free_channel(pvar, local_channel_num);
2010     }
2011     else {
2012     FWD_channel_output_eof(pvar, local_channel_num);
2013     }
2014     }
2015     return TRUE;
2016     }
2017    
2018     static BOOL handle_agent_open(PTInstVar pvar)
2019     {
2020     if (grab_payload(pvar, 4)) {
2021     int remote_id = get_payload_uint32(pvar, 0);
2022     int local_id;
2023    
2024 doda 4233 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
2025 maya 3227 local_id = FWD_agent_open(pvar, remote_id);
2026     if (local_id == -1) {
2027     SSH_fail_channel_open(pvar, remote_id);
2028     }
2029     else {
2030     SSH_confirm_channel_open(pvar, remote_id, local_id);
2031     }
2032     }
2033     else {
2034     SSH_fail_channel_open(pvar, remote_id);
2035     }
2036     }
2037     /*
2038     else {
2039     // ���m��������channel����������������������������
2040     }
2041     */
2042    
2043     return TRUE;
2044     }
2045    
2046    
2047    
2048     // �n���h�����O�������b�Z�[�W����������
2049    
2050     #define HANDLE_MESSAGE_MAX 30
2051     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
2052     static int handle_message_count = 0;
2053     static int handle_message_stage = 0;
2054    
2055     void SSH2_dispatch_init(int stage)
2056     {
2057     handle_message_count = 0;
2058     handle_message_stage = stage;
2059     }
2060    
2061     int SSH2_dispatch_enabled_check(unsigned char message)
2062     {
2063     int i;
2064    
2065     for (i = 0 ; i < handle_message_count ; i++) {
2066     if (handle_messages[i] == message)
2067     return 1;
2068     }
2069     return 0;
2070     }
2071    
2072     void SSH2_dispatch_add_message(unsigned char message)
2073     {
2074     int i;
2075    
2076     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2077     // TODO: error check
2078     return;
2079     }
2080    
2081     // �������o�^�������������b�Z�[�W������������
2082     for (i=0; i<handle_message_count; i++) {
2083     if (handle_messages[i] == message) {
2084     return;
2085     }
2086     }
2087    
2088     handle_messages[handle_message_count++] = message;
2089     }
2090    
2091     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2092     {
2093     unsigned char c;
2094    
2095     for (c = begin ; c <= end ; c++) {
2096     SSH2_dispatch_add_message(c);
2097     }
2098     }
2099    
2100    
2101 doda 6801 void SSH_handle_packet(PTInstVar pvar, char *data, int len,
2102 maya 3227 int padding)
2103     {
2104     unsigned char message = prep_packet(pvar, data, len, padding);
2105    
2106     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2107     if (message != SSH_MSG_NONE) {
2108     // ���b�Z�[�W�^�C�v���������n���h�����N��
2109     SSHPacketHandler handler = get_handler(pvar, message);
2110    
2111     // for SSH2(yutaka)
2112     if (SSHv2(pvar)) {
2113     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2114     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2115     char buf[1024];
2116    
2117     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2118     "Unexpected SSH2 message(%d) on current stage(%d)");
2119     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2120     pvar->ts->UIMsg, message, handle_message_stage);
2121 maya 5678 notify_fatal_error(pvar, buf, TRUE);
2122 doda 6656 return;
2123 maya 3227 }
2124     }
2125    
2126     if (handler == NULL) {
2127     if (SSHv1(pvar)) {
2128     char buf[1024];
2129    
2130     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2131     "Unexpected packet type received: %d");
2132     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2133     pvar->ts->UIMsg, message, handle_message_stage);
2134 maya 5678 notify_fatal_error(pvar, buf, TRUE);
2135 maya 3227 } else {
2136 doda 6801 unsigned char *outmsg =
2137 maya 3227 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2138    
2139     set_uint32(outmsg,
2140     pvar->ssh_state.receiver_sequence_number - 1);
2141     finish_send_packet(pvar);
2142    
2143 doda 6809 logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().");
2144 maya 3227 /* XXX need to decompress incoming packet, but how? */
2145     }
2146     } else {
2147     if (!handler(pvar)) {
2148     deque_handlers(pvar, message);
2149     }
2150     }
2151     }
2152     }
2153    
2154     static BOOL handle_pty_success(PTInstVar pvar)
2155     {
2156     FWD_enter_interactive_mode(pvar);
2157     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2158     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2159     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2160     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2161     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2162     handle_channel_input_eof);
2163     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2164     handle_channel_output_eof);
2165     enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2166     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2167     enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2168     return FALSE;
2169     }
2170    
2171     static BOOL handle_pty_failure(PTInstVar pvar)
2172     {
2173     UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2174     "The server cannot allocate a pseudo-terminal. "
2175     "You may encounter some problems with the terminal.");
2176     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2177     return handle_pty_success(pvar);
2178     }
2179    
2180     static void prep_pty(PTInstVar pvar)
2181     {
2182     int len = strlen(pvar->ts->TermType);
2183 doda 6801 unsigned char *outmsg =
2184 maya 3227 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2185     4 + len + 16 + sizeof(ssh_ttymodes));
2186     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2187     static const SSHPacketHandler handlers[]
2188     = { handle_pty_success, handle_pty_failure };
2189 doda 6799 int x, y;
2190 maya 3227
2191 doda 6799 get_window_pixel_size(pvar, &x, &y);
2192    
2193 maya 3227 set_uint32(outmsg, len);
2194     memcpy(outmsg + 4, pvar->ts->TermType, len);
2195     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2196     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2197 doda 6799 set_uint32(outmsg + 4 + len + 8, x);
2198     set_uint32(outmsg + 4 + len + 12, y);
2199 maya 3227 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2200     finish_send_packet(pvar);
2201    
2202     enque_handlers(pvar, 2, msgs, handlers);
2203    
2204     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2205     finish_send_packet(pvar);
2206     }
2207    
2208     static BOOL handle_agent_request_success(PTInstVar pvar)
2209     {
2210     pvar->agentfwd_enable = TRUE;
2211     prep_pty(pvar);
2212     return FALSE;
2213     }
2214    
2215     static BOOL handle_agent_request_failure(PTInstVar pvar)
2216     {
2217     prep_pty(pvar);
2218     return FALSE;
2219     }
2220    
2221     static void prep_agent_request(PTInstVar pvar)
2222     {
2223     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2224     static const SSHPacketHandler handlers[]
2225     = { handle_agent_request_success, handle_agent_request_failure };
2226    
2227     enque_handlers(pvar, 2, msgs, handlers);
2228    
2229     begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2230     finish_send_packet(pvar);
2231     }
2232    
2233     static void prep_forwarding(PTInstVar pvar)
2234     {
2235     FWD_prep_forwarding(pvar);
2236    
2237     if (pvar->session_settings.ForwardAgent) {
2238     prep_agent_request(pvar);
2239     }
2240     else {
2241     prep_pty(pvar);
2242     }
2243     }
2244    
2245    
2246     //
2247     //
2248     // (2005.7.10 yutaka)
2249     static void enable_send_compression(PTInstVar pvar)
2250     {
2251     static int initialize = 0;
2252    
2253     if (initialize) {
2254     deflateEnd(&pvar->ssh_state.compress_stream);
2255     }
2256     initialize = 1;
2257    
2258     pvar->ssh_state.compress_stream.zalloc = NULL;
2259     pvar->ssh_state.compress_stream.zfree = NULL;
2260     pvar->ssh_state.compress_stream.opaque = NULL;
2261     if (deflateInit
2262     (&pvar->ssh_state.compress_stream,
2263     pvar->ssh_state.compression_level) != Z_OK) {
2264     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2265     "An error occurred while setting up compression.\n"
2266     "The connection will close.");
2267 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2268 maya 3227 return;
2269     } else {
2270     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2271     if (SSHv2(pvar)) {
2272     pvar->ssh_state.compressing = FALSE;
2273     } else {
2274     pvar->ssh_state.compressing = TRUE;
2275     }
2276     }
2277     }
2278    
2279     static void enable_recv_compression(PTInstVar pvar)
2280     {
2281     static int initialize = 0;
2282    
2283     if (initialize) {
2284     deflateEnd(&pvar->ssh_state.decompress_stream);
2285     }
2286     initialize = 1;
2287    
2288     pvar->ssh_state.decompress_stream.zalloc = NULL;
2289     pvar->ssh_state.decompress_stream.zfree = NULL;
2290     pvar->ssh_state.decompress_stream.opaque = NULL;
2291     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2292     deflateEnd(&pvar->ssh_state.compress_stream);
2293     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2294     "An error occurred while setting up compression.\n"
2295     "The connection will close.");
2296 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2297 maya 3227 return;
2298     } else {
2299     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2300     if (SSHv2(pvar)) {
2301     pvar->ssh_state.decompressing = FALSE;
2302     } else {
2303     pvar->ssh_state.decompressing = TRUE;
2304     }
2305    
2306     buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2307     &pvar->ssh_state.postdecompress_inbuflen, 1000);
2308     }
2309     }
2310    
2311     static void enable_compression(PTInstVar pvar)
2312     {
2313     enable_send_compression(pvar);
2314     enable_recv_compression(pvar);
2315    
2316     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2317     if (SSHv2(pvar)) {
2318     pvar->ssh_state.compressing = FALSE;
2319     pvar->ssh_state.decompressing = FALSE;
2320     }
2321    
2322     }
2323    
2324     static BOOL handle_enable_compression(PTInstVar pvar)
2325     {
2326     enable_compression(pvar);
2327     prep_forwarding(pvar);
2328     return FALSE;
2329     }
2330    
2331     static BOOL handle_disable_compression(PTInstVar pvar)
2332     {
2333     prep_forwarding(pvar);
2334     return FALSE;
2335     }
2336    
2337     static void prep_compression(PTInstVar pvar)
2338     {
2339     if (pvar->session_settings.CompressionLevel > 0) {
2340     // added if statement (2005.7.10 yutaka)
2341     if (SSHv1(pvar)) {
2342     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2343     static const SSHPacketHandler handlers[]
2344     = { handle_enable_compression, handle_disable_compression };
2345    
2346 doda 6801 unsigned char *outmsg =
2347 maya 3227 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2348    
2349     set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2350     finish_send_packet(pvar);
2351    
2352     enque_handlers(pvar, 2, msgs, handlers);
2353     }
2354    
2355     pvar->ssh_state.compression_level =
2356     pvar->session_settings.CompressionLevel;
2357    
2358     } else {
2359     // added if statement (2005.7.10 yutaka)
2360     if (SSHv1(pvar)) {
2361     prep_forwarding(pvar);
2362     }
2363     }
2364     }
2365    
2366     static void enque_simple_auth_handlers(PTInstVar pvar)
2367     {
2368     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2369     static const SSHPacketHandler handlers[]
2370     = { handle_auth_success, handle_auth_failure };
2371    
2372     enque_handlers(pvar, 2, msgs, handlers);
2373     }
2374    
2375     static BOOL handle_rsa_challenge(PTInstVar pvar)
2376     {
2377     int challenge_bytes;
2378    
2379     if (!grab_payload(pvar, 2)) {
2380     return FALSE;
2381     }
2382    
2383     challenge_bytes = get_mpint_len(pvar, 0);
2384    
2385     if (grab_payload(pvar, challenge_bytes)) {
2386 doda 6801 unsigned char *outmsg =
2387 maya 3227 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2388    
2389     if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2390     if (CRYPT_generate_RSA_challenge_response
2391     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2392    
2393     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2394     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2395     #if 0
2396     //AUTH_destroy_cur_cred(pvar);
2397     #endif
2398    
2399     finish_send_packet(pvar);
2400    
2401     enque_simple_auth_handlers(pvar);
2402     } else {
2403     UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2404     "An error occurred while decrypting the RSA challenge.\n"
2405     "Perhaps the key file is corrupted.");
2406 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2407 maya 3227 }
2408     }
2409     else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2410     int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2411     int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2412     int server_key_bytes = (server_key_bits + 7) / 8;
2413     int host_key_bytes = (host_key_bits + 7) / 8;
2414     int session_buf_len = server_key_bytes + host_key_bytes + 8;
2415 doda 6801 char *session_buf = (char *) malloc(session_buf_len);
2416 maya 3227 unsigned char session_id[16];
2417    
2418     unsigned char *hash;
2419     int pubkeylen, hashlen;
2420    
2421     /* Pageant ���n�b�V�����v�Z���������� */
2422     // ���J��������
2423     pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2424     pvar->pageant_keylistlen);
2425     // �Z�b�V����ID������
2426     BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2427     BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2428     session_buf + host_key_bytes);
2429     memcpy(session_buf + server_key_bytes + host_key_bytes,
2430     pvar->crypt_state.server_cookie, 8);
2431     MD5(session_buf, session_buf_len, session_id);
2432     // �n�b�V������������
2433     hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2434     pubkeylen,
2435     pvar->ssh_state.payload,
2436     challenge_bytes + 2,
2437     session_id,
2438     &hashlen);
2439    
2440     // �n�b�V�������M
2441     memcpy(outmsg, hash, 16);
2442     free(hash);
2443    
2444     finish_send_packet(pvar);
2445    
2446     enque_simple_auth_handlers(pvar);
2447     }
2448     }
2449    
2450     return FALSE;
2451     }
2452    
2453     static void try_send_credentials(PTInstVar pvar)
2454     {
2455     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2456 doda 6801 AUTHCred *cred = AUTH_get_cur_cred(pvar);
2457 maya 3227 static const int RSA_msgs[] =
2458     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2459     static const SSHPacketHandler RSA_handlers[]
2460     = { handle_rsa_challenge, handle_rsa_auth_refused };
2461     static const int TIS_msgs[] =
2462     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2463     static const SSHPacketHandler TIS_handlers[]
2464     = { handle_TIS_challenge, handle_auth_failure };
2465    
2466     // SSH2���������������������X�L�b�v
2467     if (SSHv2(pvar))