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