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 6779 - (hide annotations) (download) (as text)
Tue Jun 6 08:39:15 2017 UTC (6 years, 10 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 265727 byte(s)
ログ出力強化 (エージェント転送関連)

・エラーをデバッグログに記録するようにした
・不正な(大きすぎる)エージェント要求を通知するようにした
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 maya 3227
131 yutakapon 6528
132 maya 3227 //
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     static int prep_packet(PTInstVar pvar, char FAR * data, int len,
743     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 yutakapon 4926 unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len)
861 maya 3227 {
862     unsigned char FAR *buf;
863    
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     static int retry_send_packet(PTInstVar pvar, char FAR * data, int len)
894     {
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     static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
921     {
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     unsigned char FAR *data;
990     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     const int FAR * messages,
1155     const SSHPacketHandler FAR * handlers)
1156     {
1157     SSHPacketHandlerItem FAR *first_item;
1158     SSHPacketHandlerItem FAR *last_item = NULL;
1159     int i;
1160    
1161     for (i = 0; i < num_msgs; i++) {
1162     SSHPacketHandlerItem FAR *item =
1163     (SSHPacketHandlerItem FAR *)
1164     malloc(sizeof(SSHPacketHandlerItem));
1165     SSHPacketHandlerItem FAR *cur_item =
1166     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     SSHPacketHandlerItem FAR *cur_item =
1199     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     SSHPacketHandlerItem FAR *cur_item =
1212     pvar->ssh_state.packet_handlers[message];
1213     SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1214    
1215     if (cur_item == NULL)
1216     return;
1217    
1218     do {
1219     SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1220    
1221     if (cur_item->active_for_message >= 0) {
1222     SSHPacketHandlerItem FAR *replacement =
1223     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     static void chop_newlines(char FAR * buf)
1251     {
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     notify_verbose_message(pvar, "Authentication failed",
1286     LOG_LEVEL_VERBOSE);
1287    
1288     // retry count������ (2005.7.15 yutaka)
1289     pvar->userauth_retry_count++;
1290    
1291     AUTH_set_generic_mode(pvar);
1292     AUTH_advance_to_next_cred(pvar);
1293     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1294     try_send_credentials(pvar);
1295     return FALSE;
1296     }
1297    
1298     static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1299     {
1300     if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1301     if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1302     // �S�������������I������
1303     safefree(pvar->pageant_key);
1304     }
1305     else {
1306     // ������������
1307     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1308     try_send_credentials(pvar);
1309     return TRUE;
1310     }
1311     }
1312     AUTH_destroy_cur_cred(pvar);
1313     return handle_auth_failure(pvar);
1314     }
1315    
1316     static BOOL handle_TIS_challenge(PTInstVar pvar)
1317     {
1318     if (grab_payload(pvar, 4)) {
1319     int len = get_payload_uint32(pvar, 0);
1320    
1321     if (grab_payload(pvar, len)) {
1322     notify_verbose_message(pvar, "Received TIS challenge",
1323     LOG_LEVEL_VERBOSE);
1324    
1325     AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1326     AUTH_advance_to_next_cred(pvar);
1327     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1328     try_send_credentials(pvar);
1329     }
1330     }
1331     return FALSE;
1332     }
1333    
1334     static BOOL handle_auth_required(PTInstVar pvar)
1335     {
1336     notify_verbose_message(pvar, "Server requires authentication",
1337     LOG_LEVEL_VERBOSE);
1338    
1339     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1340     try_send_credentials(pvar);
1341     /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1342    
1343     return FALSE;
1344     }
1345    
1346     static BOOL handle_ignore(PTInstVar pvar)
1347     {
1348     if (SSHv1(pvar)) {
1349     notify_verbose_message(pvar, "SSH_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1350    
1351     if (grab_payload(pvar, 4)
1352     && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1353     /* ignore it! but it must be decompressed */
1354     }
1355     }
1356     else {
1357     notify_verbose_message(pvar, "SSH2_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1358    
1359     // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1360     // Cisco ���[�^���� (2006.11.28 maya)
1361     }
1362     return TRUE;
1363     }
1364    
1365     static BOOL handle_debug(PTInstVar pvar)
1366     {
1367     BOOL always_display;
1368     char FAR *description;
1369     int description_len;
1370     char buf[2048];
1371    
1372     if (SSHv1(pvar)) {
1373     notify_verbose_message(pvar, "SSH_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1374    
1375     if (grab_payload(pvar, 4)
1376     && grab_payload(pvar, description_len =
1377     get_payload_uint32(pvar, 0))) {
1378     always_display = FALSE;
1379     description = pvar->ssh_state.payload + 4;
1380     description[description_len] = 0;
1381     } else {
1382     return TRUE;
1383     }
1384     } else {
1385     notify_verbose_message(pvar, "SSH2_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1386    
1387     if (grab_payload(pvar, 5)
1388     && grab_payload(pvar,
1389     (description_len = get_payload_uint32(pvar, 1)) + 4)
1390     && grab_payload(pvar,
1391     get_payload_uint32(pvar, 5 + description_len))) {
1392     always_display = pvar->ssh_state.payload[0] != 0;
1393     description = pvar->ssh_state.payload + 5;
1394     description[description_len] = 0;
1395     } else {
1396     return TRUE;
1397     }
1398     }
1399    
1400     chop_newlines(description);
1401     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1402     description);
1403     if (always_display) {
1404     notify_nonfatal_error(pvar, buf);
1405     } else {
1406     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1407     }
1408     return TRUE;
1409     }
1410    
1411     static BOOL handle_disconnect(PTInstVar pvar)
1412     {
1413     int reason_code;
1414     char FAR *description;
1415     int description_len;
1416     char buf[2048];
1417     char FAR *explanation = "";
1418     char uimsg[MAX_UIMSG];
1419    
1420     if (SSHv1(pvar)) {
1421     notify_verbose_message(pvar, "SSH_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1422    
1423     if (grab_payload(pvar, 4)
1424     && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1425     reason_code = -1;
1426     description = pvar->ssh_state.payload + 4;
1427     description[description_len] = 0;
1428     } else {
1429     return TRUE;
1430     }
1431     } else {
1432     notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1433    
1434     if (grab_payload(pvar, 8)
1435     && grab_payload(pvar,
1436     (description_len = get_payload_uint32(pvar, 4)) + 4)
1437     && grab_payload(pvar,
1438     get_payload_uint32(pvar, 8 + description_len))) {
1439     reason_code = get_payload_uint32(pvar, 0);
1440     description = pvar->ssh_state.payload + 8;
1441     description[description_len] = 0;
1442     } else {
1443     return TRUE;
1444     }
1445     }
1446    
1447     chop_newlines(description);
1448     if (description[0] == 0) {
1449     description = NULL;
1450     }
1451    
1452     if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1453     UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1454     "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1455     "This often happens when someone is already forwarding that port from the server.");
1456     strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1457     explanation = uimsg;
1458     }
1459    
1460     if (description != NULL) {
1461     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1462     "Server disconnected with message '%s'%s");
1463     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1464     pvar->ts->UIMsg, description,
1465     explanation);
1466     } else {
1467     UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1468     "Server disconnected (no reason given).%s");
1469     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1470     pvar->ts->UIMsg, explanation);
1471     }
1472    
1473 maya 5678 if (SSHv2(pvar)) {
1474     // SSH2_MSG_DISCONNECT �������������������������M��������������
1475     notify_fatal_error(pvar, buf, FALSE);
1476     }
1477     else {
1478     // SSH1 ���������d�l�����������������A���O����������������
1479     notify_fatal_error(pvar, buf, TRUE);
1480     }
1481    
1482 maya 3227 return TRUE;
1483     }
1484    
1485     static BOOL handle_unimplemented(PTInstVar pvar)
1486     {
1487     /* Should never receive this since we only send base 2.0 protocol messages */
1488     grab_payload(pvar, 4);
1489     return TRUE;
1490     }
1491    
1492     static BOOL handle_crypt_success(PTInstVar pvar)
1493     {
1494     notify_verbose_message(pvar, "Secure mode successfully achieved",
1495     LOG_LEVEL_VERBOSE);
1496     return FALSE;
1497     }
1498    
1499     static BOOL handle_noauth_success(PTInstVar pvar)
1500     {
1501     notify_verbose_message(pvar, "Server does not require authentication",
1502     LOG_LEVEL_VERBOSE);
1503     prep_compression(pvar);
1504     return FALSE;
1505     }
1506    
1507     static BOOL handle_auth_success(PTInstVar pvar)
1508     {
1509     notify_verbose_message(pvar, "Authentication accepted",
1510     LOG_LEVEL_VERBOSE);
1511     prep_compression(pvar);
1512    
1513     // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1514     start_ssh_heartbeat_thread(pvar);
1515    
1516     return FALSE;
1517     }
1518    
1519     static BOOL handle_server_public_key(PTInstVar pvar)
1520     {
1521     int server_key_public_exponent_len;
1522     int server_key_public_modulus_pos;
1523     int server_key_public_modulus_len;
1524     int host_key_bits_pos;
1525     int host_key_public_exponent_len;
1526     int host_key_public_modulus_pos;
1527     int host_key_public_modulus_len;
1528     int protocol_flags_pos;
1529     int supported_ciphers;
1530     char FAR *inmsg;
1531     Key hostkey;
1532     int supported_types;
1533    
1534     notify_verbose_message(pvar, "SSH_SMSG_PUBLIC_KEY was received.", LOG_LEVEL_VERBOSE);
1535    
1536     if (!grab_payload(pvar, 14))
1537     return FALSE;
1538     server_key_public_exponent_len = get_mpint_len(pvar, 12);
1539    
1540     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1541     return FALSE;
1542     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1543     server_key_public_modulus_len =
1544     get_mpint_len(pvar, server_key_public_modulus_pos);
1545    
1546     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1547     return FALSE;
1548     host_key_bits_pos =
1549     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1550     host_key_public_exponent_len =
1551     get_mpint_len(pvar, host_key_bits_pos + 4);
1552    
1553     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1554     return FALSE;
1555     host_key_public_modulus_pos =
1556     host_key_bits_pos + 6 + host_key_public_exponent_len;
1557     host_key_public_modulus_len =
1558     get_mpint_len(pvar, host_key_public_modulus_pos);
1559    
1560     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1561     return FALSE;
1562     protocol_flags_pos =
1563     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1564    
1565     inmsg = pvar->ssh_state.payload;
1566    
1567     CRYPT_set_server_cookie(pvar, inmsg);
1568     if (!CRYPT_set_server_RSA_key(pvar,
1569     get_uint32(inmsg + 8),
1570     pvar->ssh_state.payload + 12,
1571     inmsg + server_key_public_modulus_pos))
1572     return FALSE;
1573     if (!CRYPT_set_host_RSA_key(pvar,
1574     get_uint32(inmsg + host_key_bits_pos),
1575     inmsg + host_key_bits_pos + 4,
1576     inmsg + host_key_public_modulus_pos))
1577     return FALSE;
1578     pvar->ssh_state.server_protocol_flags =
1579     get_uint32(inmsg + protocol_flags_pos);
1580    
1581     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1582     if (!CRYPT_set_supported_ciphers(pvar,
1583     supported_ciphers,
1584     supported_ciphers))
1585     return FALSE;
1586    
1587     // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1588     // RSA ���L������ PAGEANT ���L��������
1589     supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1590     if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1591     supported_types |= (1 << SSH_AUTH_PAGEANT);
1592     }
1593     if (!AUTH_set_supported_auth_types(pvar,
1594     supported_types))
1595     return FALSE;
1596    
1597     /* this must be the LAST THING in this function, since it can cause
1598     host_is_OK to be called. */
1599     hostkey.type = KEY_RSA1;
1600     hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1601     hostkey.exp = inmsg + host_key_bits_pos + 4;
1602     hostkey.mod = inmsg + host_key_public_modulus_pos;
1603     HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1604    
1605     return FALSE;
1606     }
1607    
1608     /*
1609     The ID must have already been found to start with "SSH-". It must
1610     be null-terminated.
1611     */
1612     static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1613     {
1614     char FAR *str;
1615    
1616     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1617     }
1618    
1619     if (*str != '.') {
1620     return FALSE;
1621     }
1622    
1623     pvar->protocol_major = atoi(ID + 4);
1624     pvar->protocol_minor = atoi(str + 1);
1625    
1626     for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1627     }
1628    
1629     return *str == '-';
1630     }
1631    
1632     /*
1633     On entry, the pvar->protocol_xxx fields hold the server's advertised
1634     protocol number. We replace the fields with the protocol number we will
1635     actually use, or return FALSE if there is no usable protocol version.
1636     */
1637 maya 4682 static int negotiate_protocol(PTInstVar pvar)
1638 maya 3227 {
1639     switch (pvar->protocol_major) {
1640     case 1:
1641 maya 4682 if (pvar->protocol_minor == 99 &&
1642     pvar->settings.ssh_protocol_version == 2) {
1643     // �T�[�o�� 1.99 �����[�U�� SSH2 ���I������������������
1644     // 2.0 ����������
1645     pvar->protocol_major = 2;
1646     pvar->protocol_minor = 0;
1647     return 0;
1648     }
1649    
1650     if (pvar->settings.ssh_protocol_version == 2) {
1651     // �o�[�W��������
1652     return -1;
1653     }
1654    
1655 maya 3227 if (pvar->protocol_minor > 5) {
1656     pvar->protocol_minor = 5;
1657     }
1658    
1659 maya 4682 return 0;
1660 maya 3227
1661     // for SSH2(yutaka)
1662     case 2:
1663 maya 4682 if (pvar->settings.ssh_protocol_version == 1) {
1664     // �o�[�W��������
1665     return -1;
1666     }
1667 maya 3227
1668 maya 4682 return 0; // SSH2 support
1669    
1670 maya 3227 default:
1671 maya 4682 return 1;
1672 maya 3227 }
1673     }
1674    
1675     static void init_protocol(PTInstVar pvar)
1676     {
1677     CRYPT_initialize_random_numbers(pvar);
1678    
1679     // known_hosts�t�@�C�������z�X�g���J������������������
1680     HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1681    
1682     /* while we wait for a response from the server... */
1683    
1684     if (SSHv1(pvar)) {
1685     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1686     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1687     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1688     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1689    
1690     } else { // for SSH2(yutaka)
1691     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1692     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1693     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1694     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1695     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1696     enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1697     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1698     enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1699     enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1700     enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1701     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1702     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1703 doda 6657 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_msg60);
1704 maya 3227
1705     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1706    
1707     // ���[�U�F�������f�B�X�p�b�`���[�`��
1708     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1709     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1710     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1711     enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1712     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1713     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1714     enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1715     enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1716     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1717     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1718     enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1719 yutakapon 5829 enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_SSH2_client_global_request);
1720 maya 3227 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1721     enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1722    
1723 yutakapon 5850 client_init_global_confirm();
1724    
1725 maya 3227 }
1726     }
1727    
1728 doda 5928 void server_version_check(PTInstVar pvar)
1729     {
1730     char *server_swver;
1731    
1732     pvar->server_compat_flag = 0;
1733    
1734     if ((server_swver = strchr(pvar->server_version_string+4, '-')) == NULL) {
1735     notify_verbose_message(pvar, "Can't get server software version string.", LOG_LEVEL_WARNING);
1736     return;
1737     }
1738     server_swver++;
1739    
1740     if (strncmp(server_swver, "Cisco-1", 7) == 0) {
1741     pvar->server_compat_flag |= SSH_BUG_DHGEX_LARGE;
1742     notify_verbose_message(pvar, "Server version string is matched to \"Cisco-1\", compatibility flag SSH_BUG_DHGEX_LARGE is enabled.", LOG_LEVEL_INFO);
1743     }
1744     }
1745    
1746 maya 3227 BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1747     {
1748 maya 4546 static char prefix[64];
1749 maya 4682 int negotiate;
1750     char uimsg[MAX_UIMSG];
1751 maya 3227
1752     // initialize SSH2 memory dump (2005.3.7 yutaka)
1753     init_memdump();
1754     push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1755    
1756     if (ID_len <= 0) {
1757     return FALSE;
1758     } else {
1759 maya 4546 int buf_len;
1760     char FAR *buf;
1761 maya 3227
1762 maya 4546 strncpy_s(prefix, sizeof(prefix), "Received server identification string: ", _TRUNCATE);
1763     buf_len = strlen(prefix) + ID_len + 1;
1764     buf = (char FAR *) malloc(buf_len);
1765 maya 3227 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1766     strncat_s(buf, buf_len, ID, _TRUNCATE);
1767     chop_newlines(buf);
1768     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1769     free(buf);
1770    
1771     if (ID[ID_len - 1] != '\n') {
1772     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1773     return FALSE;
1774     } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1775     pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1776     return FALSE;
1777     } else if (strncmp(ID, "SSH-", 4) != 0) {
1778     return FALSE;
1779     } else {
1780     ID[ID_len - 1] = 0;
1781    
1782     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1783     ID[ID_len - 2] = 0;
1784     }
1785    
1786     pvar->ssh_state.server_ID = _strdup(ID);
1787    
1788 maya 4682 if (!parse_protocol_ID(pvar, ID)) {
1789 maya 3227 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1790     "This program does not understand the server's version of the protocol.");
1791 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1792 maya 4682 }
1793     else if ((negotiate = negotiate_protocol(pvar)) == 1) {
1794     UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1795     "This program does not understand the server's version of the protocol.");
1796 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1797 maya 4682 }
1798     else if (negotiate == -1) {
1799     UTIL_get_lang_msg("MSG_SSH_VERSION_MISMATCH", pvar,
1800     "Protocol version mismatch. server:%d.%d client:%d");
1801     _snprintf_s(uimsg, sizeof(uimsg), _TRUNCATE, pvar->ts->UIMsg,
1802     pvar->protocol_major, pvar->protocol_minor, pvar->settings.ssh_protocol_version);
1803 maya 5678 notify_fatal_error(pvar, uimsg, TRUE);
1804 maya 4682 }
1805     else {
1806 maya 3227 char TTSSH_ID[1024];
1807     int TTSSH_ID_len;
1808     int a, b, c, d;
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     get_file_version("ttxssh.dll", &a, &b, &c, &d);
1816    
1817     _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1818 maya 4656 "SSH-%d.%d-TTSSH/%d.%d Win32\r\n",
1819 maya 3227 pvar->protocol_major, pvar->protocol_minor, a, b);
1820     TTSSH_ID_len = strlen(TTSSH_ID);
1821    
1822     // for SSH2(yutaka)
1823     // �N���C�A���g�o�[�W�����������i���s���������������j
1824     strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1825     TTSSH_ID, _TRUNCATE);
1826    
1827     // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1828     _snprintf_s(pvar->server_version_string,
1829     sizeof(pvar->server_version_string), _TRUNCATE,
1830     "%s", pvar->ssh_state.server_ID);
1831    
1832 doda 5928 // �T�[�o�o�[�W�������`�F�b�N
1833     server_version_check(pvar);
1834    
1835 maya 3227 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1836     0) != TTSSH_ID_len) {
1837     UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1838     "An error occurred while sending the SSH ID string.\n"
1839     "The connection will close.");
1840 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
1841 maya 3227 } else {
1842     // ���s�R�[�h������ (2004.8.4 yutaka)
1843 maya 4656 pvar->client_version_string[--TTSSH_ID_len] = 0; // \n
1844     pvar->client_version_string[--TTSSH_ID_len] = 0; // \r
1845 maya 3227
1846 maya 4546 strncpy_s(prefix, sizeof(prefix), "Sent client identification string: ", _TRUNCATE);
1847     buf_len = strlen(prefix) + strlen(pvar->client_version_string) + 1;
1848     buf = (char FAR *) malloc(buf_len);
1849     strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1850     strncat_s(buf, buf_len, pvar->client_version_string, _TRUNCATE);
1851     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1852     free(buf);
1853    
1854 maya 3227 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1855     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1856    
1857     // SSH�n���h�����o�^���s��
1858     init_protocol(pvar);
1859    
1860     SSH2_dispatch_init(1);
1861     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1862     SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1863 maya 4867 SSH2_dispatch_add_message(SSH2_MSG_DEBUG);
1864 maya 3227 }
1865     }
1866    
1867     return TRUE;
1868     }
1869     }
1870     }
1871    
1872     static BOOL handle_exit(PTInstVar pvar)
1873     {
1874     if (grab_payload(pvar, 4)) {
1875     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1876     finish_send_packet(pvar);
1877 maya 5678 notify_closed_connection(pvar, "disconnected by server request");
1878 maya 3227 }
1879     return TRUE;
1880     }
1881    
1882     static BOOL handle_data(PTInstVar pvar)
1883     {
1884     if (grab_payload_limited(pvar, 4)) {
1885     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1886     pvar->ssh_state.payload_datastart = 4;
1887     }
1888     return TRUE;
1889     }
1890    
1891     static BOOL handle_channel_open(PTInstVar pvar)
1892     {
1893     int host_len;
1894     int originator_len;
1895    
1896     if ((pvar->ssh_state.
1897     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1898     if (grab_payload(pvar, 8)
1899     && grab_payload(pvar,
1900     8 + (host_len = get_payload_uint32(pvar, 4)))
1901     && grab_payload(pvar, originator_len =
1902     get_payload_uint32(pvar, host_len + 12))) {
1903     int local_port = get_payload_uint32(pvar, 8 + host_len);
1904    
1905     pvar->ssh_state.payload[8 + host_len] = 0;
1906     FWD_open(pvar, get_payload_uint32(pvar, 0),
1907     pvar->ssh_state.payload + 8, local_port,
1908     pvar->ssh_state.payload + 16 + host_len,
1909     originator_len,
1910     NULL);
1911     }
1912     } else {
1913     if (grab_payload(pvar, 8)
1914     && grab_payload(pvar,
1915     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1916     int local_port = get_payload_uint32(pvar, 8 + host_len);
1917    
1918     pvar->ssh_state.payload[8 + host_len] = 0;
1919     FWD_open(pvar, get_payload_uint32(pvar, 0),
1920     pvar->ssh_state.payload + 8, local_port, NULL, 0,
1921     NULL);
1922     }
1923     }
1924    
1925     return TRUE;
1926     }
1927    
1928     static BOOL handle_X11_channel_open(PTInstVar pvar)
1929     {
1930     int originator_len;
1931    
1932     if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1933     if (grab_payload(pvar, 8)
1934     && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1935     FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1936     pvar->ssh_state.payload + 8, originator_len, NULL);
1937     }
1938     } else {
1939     if (grab_payload(pvar, 4)) {
1940     FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1941     }
1942     }
1943    
1944     return TRUE;
1945     }
1946    
1947     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1948     {
1949     if (grab_payload(pvar, 8)) {
1950     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1951     get_payload_uint32(pvar, 4));
1952     }
1953     return FALSE;
1954     }
1955    
1956     static BOOL handle_channel_open_failure(PTInstVar pvar)
1957     {
1958     if (grab_payload(pvar, 4)) {
1959     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1960     }
1961     return FALSE;
1962     }
1963    
1964     static BOOL handle_channel_data(PTInstVar pvar)
1965     {
1966     int len;
1967    
1968     if (grab_payload(pvar, 8)
1969     && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1970     FWDChannel *channel;
1971     int local_channel_num = get_payload_uint32(pvar, 0);
1972     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1973     return FALSE;
1974     }
1975     channel = pvar->fwd_state.channels + local_channel_num;
1976     if (channel->type == TYPE_AGENT) {
1977     SSH_agent_response(pvar, NULL, local_channel_num,
1978     pvar->ssh_state.payload + 8, len);
1979     }
1980     else {
1981     FWD_received_data(pvar, local_channel_num,
1982     pvar->ssh_state.payload + 8, len);
1983     }
1984     }
1985     return TRUE;
1986     }
1987    
1988     static BOOL handle_channel_input_eof(PTInstVar pvar)
1989     {
1990     if (grab_payload(pvar, 4)) {
1991     int local_channel_num = get_payload_uint32(pvar, 0);
1992     FWDChannel *channel;
1993     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1994     return FALSE;
1995     }
1996     channel = pvar->fwd_state.channels + local_channel_num;
1997     if (channel->type == TYPE_AGENT) {
1998     channel->status |= FWD_CLOSED_REMOTE_IN;
1999     SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
2000     }
2001     else {
2002     FWD_channel_input_eof(pvar, local_channel_num);
2003     }
2004     }
2005     return TRUE;
2006     }
2007    
2008     static BOOL handle_channel_output_eof(PTInstVar pvar)
2009     {
2010     if (grab_payload(pvar, 4)) {
2011     int local_channel_num = get_payload_uint32(pvar, 0);
2012     FWDChannel *channel;
2013     if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
2014     return FALSE;
2015     }
2016     channel = pvar->fwd_state.channels + local_channel_num;
2017     if (channel->type == TYPE_AGENT) {
2018     channel->status |= FWD_CLOSED_REMOTE_OUT;
2019     SSH_channel_output_eof(pvar, channel->remote_num);
2020     FWD_free_channel(pvar, local_channel_num);
2021     }
2022     else {
2023     FWD_channel_output_eof(pvar, local_channel_num);
2024     }
2025     }
2026     return TRUE;
2027     }
2028    
2029     static BOOL handle_agent_open(PTInstVar pvar)
2030     {
2031     if (grab_payload(pvar, 4)) {
2032     int remote_id = get_payload_uint32(pvar, 0);
2033     int local_id;
2034    
2035 doda 4233 if (pvar->agentfwd_enable && FWD_agent_forward_confirm(pvar)) {
2036 maya 3227 local_id = FWD_agent_open(pvar, remote_id);
2037     if (local_id == -1) {
2038     SSH_fail_channel_open(pvar, remote_id);
2039     }
2040     else {
2041     SSH_confirm_channel_open(pvar, remote_id, local_id);
2042     }
2043     }
2044     else {
2045     SSH_fail_channel_open(pvar, remote_id);
2046     }
2047     }
2048     /*
2049     else {
2050     // ���m��������channel����������������������������
2051     }
2052     */
2053    
2054     return TRUE;
2055     }
2056    
2057    
2058    
2059     // �n���h�����O�������b�Z�[�W����������
2060    
2061     #define HANDLE_MESSAGE_MAX 30
2062     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
2063     static int handle_message_count = 0;
2064     static int handle_message_stage = 0;
2065    
2066     void SSH2_dispatch_init(int stage)
2067     {
2068     handle_message_count = 0;
2069     handle_message_stage = stage;
2070     }
2071    
2072     int SSH2_dispatch_enabled_check(unsigned char message)
2073     {
2074     int i;
2075    
2076     for (i = 0 ; i < handle_message_count ; i++) {
2077     if (handle_messages[i] == message)
2078     return 1;
2079     }
2080     return 0;
2081     }
2082    
2083     void SSH2_dispatch_add_message(unsigned char message)
2084     {
2085     int i;
2086    
2087     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2088     // TODO: error check
2089     return;
2090     }
2091    
2092     // �������o�^�������������b�Z�[�W������������
2093     for (i=0; i<handle_message_count; i++) {
2094     if (handle_messages[i] == message) {
2095     return;
2096     }
2097     }
2098    
2099     handle_messages[handle_message_count++] = message;
2100     }
2101    
2102     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2103     {
2104     unsigned char c;
2105    
2106     for (c = begin ; c <= end ; c++) {
2107     SSH2_dispatch_add_message(c);
2108     }
2109     }
2110    
2111    
2112     void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
2113     int padding)
2114     {
2115     unsigned char message = prep_packet(pvar, data, len, padding);
2116    
2117     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
2118     if (message != SSH_MSG_NONE) {
2119     // ���b�Z�[�W�^�C�v���������n���h�����N��
2120     SSHPacketHandler handler = get_handler(pvar, message);
2121    
2122     // for SSH2(yutaka)
2123     if (SSHv2(pvar)) {
2124     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
2125     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2126     char buf[1024];
2127    
2128     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2129     "Unexpected SSH2 message(%d) on current stage(%d)");
2130     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2131     pvar->ts->UIMsg, message, handle_message_stage);
2132 maya 5678 notify_fatal_error(pvar, buf, TRUE);
2133 doda 6656 return;
2134 maya 3227 }
2135     }
2136    
2137     if (handler == NULL) {
2138     if (SSHv1(pvar)) {
2139     char buf[1024];
2140    
2141     UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2142     "Unexpected packet type received: %d");
2143     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2144     pvar->ts->UIMsg, message, handle_message_stage);
2145 maya 5678 notify_fatal_error(pvar, buf, TRUE);
2146 maya 3227 } else {
2147     unsigned char FAR *outmsg =
2148     begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2149    
2150     set_uint32(outmsg,
2151     pvar->ssh_state.receiver_sequence_number - 1);
2152     finish_send_packet(pvar);
2153    
2154     notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2155     /* XXX need to decompress incoming packet, but how? */
2156     }
2157     } else {
2158     if (!handler(pvar)) {
2159     deque_handlers(pvar, message);
2160     }
2161     }
2162     }
2163     }
2164    
2165     static BOOL handle_pty_success(PTInstVar pvar)
2166     {
2167     FWD_enter_interactive_mode(pvar);
2168     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2169     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2170     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2171     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2172     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2173     handle_channel_input_eof);
2174     enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2175     handle_channel_output_eof);
2176     enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2177     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2178     enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2179     return FALSE;
2180     }
2181    
2182     static BOOL handle_pty_failure(PTInstVar pvar)
2183     {
2184     UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2185     "The server cannot allocate a pseudo-terminal. "
2186     "You may encounter some problems with the terminal.");
2187     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2188     return handle_pty_success(pvar);
2189     }
2190    
2191     static void prep_pty(PTInstVar pvar)
2192     {
2193     int len = strlen(pvar->ts->TermType);
2194     unsigned char FAR *outmsg =
2195     begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2196     4 + len + 16 + sizeof(ssh_ttymodes));
2197     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2198     static const SSHPacketHandler handlers[]
2199     = { handle_pty_success, handle_pty_failure };
2200    
2201     set_uint32(outmsg, len);
2202     memcpy(outmsg + 4, pvar->ts->TermType, len);
2203     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2204     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2205     set_uint32(outmsg + 4 + len + 8, 0);
2206     set_uint32(outmsg + 4 + len + 12, 0);
2207     memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2208     finish_send_packet(pvar);
2209    
2210     enque_handlers(pvar, 2, msgs, handlers);
2211    
2212     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2213     finish_send_packet(pvar);
2214     }
2215    
2216     static BOOL handle_agent_request_success(PTInstVar pvar)
2217     {
2218     pvar->agentfwd_enable = TRUE;
2219     prep_pty(pvar);
2220     return FALSE;
2221     }
2222    
2223     static BOOL handle_agent_request_failure(PTInstVar pvar)
2224     {
2225     prep_pty(pvar);
2226     return FALSE;
2227     }
2228    
2229     static void prep_agent_request(PTInstVar pvar)
2230     {
2231     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2232     static const SSHPacketHandler handlers[]
2233     = { handle_agent_request_success, handle_agent_request_failure };
2234    
2235     enque_handlers(pvar, 2, msgs, handlers);
2236    
2237     begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2238     finish_send_packet(pvar);
2239     }
2240    
2241     static void prep_forwarding(PTInstVar pvar)
2242     {
2243     FWD_prep_forwarding(pvar);
2244    
2245     if (pvar->session_settings.ForwardAgent) {
2246     prep_agent_request(pvar);
2247     }
2248     else {
2249     prep_pty(pvar);
2250     }
2251     }
2252    
2253    
2254     //
2255     //
2256     // (2005.7.10 yutaka)
2257     static void enable_send_compression(PTInstVar pvar)
2258     {
2259     static int initialize = 0;
2260    
2261     if (initialize) {
2262     deflateEnd(&pvar->ssh_state.compress_stream);
2263     }
2264     initialize = 1;
2265    
2266     pvar->ssh_state.compress_stream.zalloc = NULL;
2267     pvar->ssh_state.compress_stream.zfree = NULL;
2268     pvar->ssh_state.compress_stream.opaque = NULL;
2269     if (deflateInit
2270     (&pvar->ssh_state.compress_stream,
2271     pvar->ssh_state.compression_level) != Z_OK) {
2272     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2273     "An error occurred while setting up compression.\n"
2274     "The connection will close.");
2275 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2276 maya 3227 return;
2277     } else {
2278     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2279     if (SSHv2(pvar)) {
2280     pvar->ssh_state.compressing = FALSE;
2281     } else {
2282     pvar->ssh_state.compressing = TRUE;
2283     }
2284     }
2285     }
2286    
2287     static void enable_recv_compression(PTInstVar pvar)
2288     {
2289     static int initialize = 0;
2290    
2291     if (initialize) {
2292     deflateEnd(&pvar->ssh_state.decompress_stream);
2293     }
2294     initialize = 1;
2295    
2296     pvar->ssh_state.decompress_stream.zalloc = NULL;
2297     pvar->ssh_state.decompress_stream.zfree = NULL;
2298     pvar->ssh_state.decompress_stream.opaque = NULL;
2299     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2300     deflateEnd(&pvar->ssh_state.compress_stream);
2301     UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2302     "An error occurred while setting up compression.\n"
2303     "The connection will close.");
2304 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2305 maya 3227 return;
2306     } else {
2307     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2308     if (SSHv2(pvar)) {
2309     pvar->ssh_state.decompressing = FALSE;
2310     } else {
2311     pvar->ssh_state.decompressing = TRUE;
2312     }
2313    
2314     buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2315     &pvar->ssh_state.postdecompress_inbuflen, 1000);
2316     }
2317     }
2318    
2319     static void enable_compression(PTInstVar pvar)
2320     {
2321     enable_send_compression(pvar);
2322     enable_recv_compression(pvar);
2323    
2324     // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2325     if (SSHv2(pvar)) {
2326     pvar->ssh_state.compressing = FALSE;
2327     pvar->ssh_state.decompressing = FALSE;
2328     }
2329    
2330     }
2331    
2332     static BOOL handle_enable_compression(PTInstVar pvar)
2333     {
2334     enable_compression(pvar);
2335     prep_forwarding(pvar);
2336     return FALSE;
2337     }
2338    
2339     static BOOL handle_disable_compression(PTInstVar pvar)
2340     {
2341     prep_forwarding(pvar);
2342     return FALSE;
2343     }
2344    
2345     static void prep_compression(PTInstVar pvar)
2346     {
2347     if (pvar->session_settings.CompressionLevel > 0) {
2348     // added if statement (2005.7.10 yutaka)
2349     if (SSHv1(pvar)) {
2350     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2351     static const SSHPacketHandler handlers[]
2352     = { handle_enable_compression, handle_disable_compression };
2353    
2354     unsigned char FAR *outmsg =
2355     begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2356    
2357     set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2358     finish_send_packet(pvar);
2359    
2360     enque_handlers(pvar, 2, msgs, handlers);
2361     }
2362    
2363     pvar->ssh_state.compression_level =
2364     pvar->session_settings.CompressionLevel;
2365    
2366     } else {
2367     // added if statement (2005.7.10 yutaka)
2368     if (SSHv1(pvar)) {
2369     prep_forwarding(pvar);
2370     }
2371     }
2372     }
2373    
2374     static void enque_simple_auth_handlers(PTInstVar pvar)
2375     {
2376     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2377     static const SSHPacketHandler handlers[]
2378     = { handle_auth_success, handle_auth_failure };
2379    
2380     enque_handlers(pvar, 2, msgs, handlers);
2381     }
2382    
2383     static BOOL handle_rsa_challenge(PTInstVar pvar)
2384     {
2385     int challenge_bytes;
2386    
2387     if (!grab_payload(pvar, 2)) {
2388     return FALSE;
2389     }
2390    
2391     challenge_bytes = get_mpint_len(pvar, 0);
2392    
2393     if (grab_payload(pvar, challenge_bytes)) {
2394     unsigned char FAR *outmsg =
2395     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2396    
2397     if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2398     if (CRYPT_generate_RSA_challenge_response
2399     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2400    
2401     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2402     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2403     #if 0
2404     //AUTH_destroy_cur_cred(pvar);
2405     #endif
2406    
2407     finish_send_packet(pvar);
2408    
2409     enque_simple_auth_handlers(pvar);
2410     } else {
2411     UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2412     "An error occurred while decrypting the RSA challenge.\n"
2413     "Perhaps the key file is corrupted.");
2414 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
2415 maya 3227 }
2416     }
2417     else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2418     int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2419     int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2420     int server_key_bytes = (server_key_bits + 7) / 8;
2421     int host_key_bytes = (host_key_bits + 7) / 8;
2422     int session_buf_len = server_key_bytes + host_key_bytes + 8;
2423     char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2424     unsigned char session_id[16];
2425    
2426     unsigned char *hash;
2427     int pubkeylen, hashlen;
2428    
2429     /* Pageant ���n�b�V�����v�Z���������� */
2430     // ���J��������
2431     pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2432     pvar->pageant_keylistlen);
2433     // �Z�b�V����ID������
2434     BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2435     BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2436     session_buf + host_key_bytes);
2437     memcpy(session_buf + server_key_bytes + host_key_bytes,
2438     pvar->crypt_state.server_cookie, 8);
2439     MD5(session_buf, session_buf_len, session_id);
2440     // �n�b�V������������
2441     hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2442     pubkeylen,
2443     pvar->ssh_state.payload,
2444     challenge_bytes + 2,
2445     session_id,
2446     &hashlen);
2447    
2448     // �n�b�V�������M
2449     memcpy(outmsg, hash, 16);
2450     free(hash);
2451    
2452     finish_send_packet(pvar);
2453    
2454     enque_simple_auth_handlers(pvar);
2455     }
2456     }
2457    
2458     return FALSE;
2459     }
2460    
2461     static void try_send_credentials(PTInstVar pvar)
2462     {
2463     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2464     AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2465     static const int RSA_msgs[] =
2466     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2467     static const SSHPacketHandler RSA_handlers[]
2468     = { handle_rsa_challenge, handle_rsa_auth_refused };
2469     static const int TIS_msgs[] =
2470     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2471     static const SSHPacketHandler TIS_handlers[]
2472     = { handle_TIS_challenge, handle_auth_failure };
2473    
2474     // SSH2���������������������X�L�b�v
2475     if (SSHv2(pvar))
2476     goto skip_ssh2;
2477    
2478     switch (cred->method) {
2479     case SSH_AUTH_NONE:
2480     return;
2481     case SSH_AUTH_PASSWORD:{
2482     int len = strlen(cred->password);
2483     unsigned char FAR *outmsg =
2484     begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2485 maya 4407 4 + len);
2486 maya 3227
2487     notify_verbose_message(pvar,
2488     "Trying PASSWORD authentication...",
2489     LOG_LEVEL_VERBOSE);
2490    
2491 maya 4407 set_uint32(outmsg, len);
2492 maya 3227 memcpy(outmsg + 4, cred->password, len);
2493    
2494     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2495     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2496     #if 0
2497