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 6926 - (hide annotations) (download) (as text)
Wed Aug 30 01:43:34 2017 UTC (6 years, 7 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 267098 byte(s)
SSH_MSG_UNIMPLEMENTED をハンドルしていなかったのを修正 [teraterm:1275]

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