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 3108 - (hide annotations) (download) (as text)
Tue Feb 12 23:11:49 2008 UTC (16 years, 2 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 218474 byte(s)
Pageant 対応処理を追加した。
SSH2 はひととおり対応済み。
SSH1 は実装途中。

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