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 3089 - (hide annotations) (download) (as text)
Thu Jan 3 16:15:40 2008 UTC (16 years, 3 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 208895 byte(s)
SCPファイル送信の転送先パス指定対応。

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