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 6811 - (hide annotations) (download) (as text)
Mon Jun 19 12:51:25 2017 UTC (6 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 259825 byte(s)
SSH2_MSG_CHANNEL_REQUEST の取り扱いまわりを修正

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