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 3084 - (hide annotations) (download) (as text)
Sat Dec 29 10:21:19 2007 UTC (16 years, 3 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 208541 byte(s)
SCPファイル受信処理の一部をスレッド化した。受信処理中でも、シェル操作が行える
レスポンスとなる。
なお、SCPダイアログのUIは今後大幅変更する予定なので、I18N化はまだやりません。

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     FILE *sendfp; // file pointer
95     struct _stat filestat; // file status information
96 yutakapon 3075 HWND progress;
97 yutakapon 3077 HANDLE thread;
98 yutakapon 3084 unsigned int tid;
99 yutakapon 3077 PTInstVar pvar;
100 yutakapon 3083
101     // receiving file
102     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 3075 c->scp.progress = NULL;
199 yutakapon 3083 c->scp.thread = (HANDLE)-1;
200 yutakapon 3084 c->scp.sendfp = 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 3084 if (c->scp.sendfp != NULL)
279     fclose(c->scp.sendfp);
280 yutakapon 3081 if (c->scp.progress != NULL) {
281     DestroyWindow(c->scp.progress);
282     c->scp.progress = NULL;
283     }
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 yutakakn 2728
1463     if (!grab_payload(pvar, 14))
1464     return FALSE;
1465     server_key_public_exponent_len = get_mpint_len(pvar, 12);
1466    
1467     if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1468     return FALSE;
1469     server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1470     server_key_public_modulus_len =
1471     get_mpint_len(pvar, server_key_public_modulus_pos);
1472    
1473     if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1474     return FALSE;
1475     host_key_bits_pos =
1476     server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1477     host_key_public_exponent_len =
1478     get_mpint_len(pvar, host_key_bits_pos + 4);
1479    
1480     if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1481     return FALSE;
1482     host_key_public_modulus_pos =
1483     host_key_bits_pos + 6 + host_key_public_exponent_len;
1484     host_key_public_modulus_len =
1485     get_mpint_len(pvar, host_key_public_modulus_pos);
1486    
1487     if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1488     return FALSE;
1489     protocol_flags_pos =
1490     host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1491    
1492     inmsg = pvar->ssh_state.payload;
1493    
1494     CRYPT_set_server_cookie(pvar, inmsg);
1495 maya 3003 if (!CRYPT_set_server_RSA_key(pvar,
1496     get_uint32(inmsg + 8),
1497     pvar->ssh_state.payload + 12,
1498     inmsg + server_key_public_modulus_pos))
1499 yutakakn 2728 return FALSE;
1500 maya 3003 if (!CRYPT_set_host_RSA_key(pvar,
1501     get_uint32(inmsg + host_key_bits_pos),
1502     inmsg + host_key_bits_pos + 4,
1503     inmsg + host_key_public_modulus_pos))
1504 yutakakn 2728 return FALSE;
1505     pvar->ssh_state.server_protocol_flags =
1506     get_uint32(inmsg + protocol_flags_pos);
1507    
1508     supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1509 maya 3003 if (!CRYPT_set_supported_ciphers(pvar,
1510     supported_ciphers,
1511     supported_ciphers))
1512 yutakakn 2728 return FALSE;
1513 maya 3003 if (!AUTH_set_supported_auth_types(pvar,
1514     get_uint32(inmsg + protocol_flags_pos + 8)))
1515 yutakakn 2728 return FALSE;
1516    
1517     /* this must be the LAST THING in this function, since it can cause
1518     host_is_OK to be called. */
1519 yutakakn 2856 hostkey.type = KEY_RSA1;
1520     hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1521     hostkey.exp = inmsg + host_key_bits_pos + 4;
1522     hostkey.mod = inmsg + host_key_public_modulus_pos;
1523     HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, &hostkey);
1524 yutakakn 2728
1525     return FALSE;
1526     }
1527    
1528     /*
1529     The ID must have already been found to start with "SSH-". It must
1530     be null-terminated.
1531     */
1532     static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1533     {
1534     char FAR *str;
1535    
1536     for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1537     }
1538    
1539     if (*str != '.') {
1540     return FALSE;
1541     }
1542    
1543     pvar->protocol_major = atoi(ID + 4);
1544     pvar->protocol_minor = atoi(str + 1);
1545    
1546     // for SSH2(yutaka)
1547     // 1.99����SSH2�����������s��
1548     if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
1549     // ���[�U�� SSH2 ���I������������������
1550     if (pvar->settings.ssh_protocol_version == 2) {
1551     pvar->protocol_major = 2;
1552     pvar->protocol_minor = 0;
1553     }
1554    
1555     }
1556    
1557     for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1558     }
1559    
1560     return *str == '-';
1561     }
1562    
1563     /*
1564     On entry, the pvar->protocol_xxx fields hold the server's advertised
1565     protocol number. We replace the fields with the protocol number we will
1566     actually use, or return FALSE if there is no usable protocol version.
1567     */
1568     static BOOL negotiate_protocol(PTInstVar pvar)
1569     {
1570     switch (pvar->protocol_major) {
1571     case 1:
1572     if (pvar->protocol_minor > 5) {
1573     pvar->protocol_minor = 5;
1574     }
1575    
1576     return TRUE;
1577    
1578     // for SSH2(yutaka)
1579     case 2:
1580     return TRUE; // SSH2 support
1581    
1582     default:
1583     return FALSE;
1584     }
1585     }
1586    
1587     static void init_protocol(PTInstVar pvar)
1588     {
1589     CRYPT_initialize_random_numbers(pvar);
1590 yutakakn 2856
1591     // known_hosts�t�@�C�������z�X�g���J������������������
1592 yutakakn 2728 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname);
1593 yutakakn 2856
1594 yutakakn 2728 /* while we wait for a response from the server... */
1595    
1596     if (SSHv1(pvar)) {
1597     enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1598     enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1599     enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1600     enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1601    
1602     } else { // for SSH2(yutaka)
1603     enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1604     enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1605     enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1606     enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1607     enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1608 maya 3054 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1609     enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1610 yutakakn 2728 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1611     enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_authrequest);
1612     enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1613     enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1614     enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1615 yutakakn 2782 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1616 yutakakn 2728
1617     enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1618    
1619     // ���[�U�F�������f�B�X�p�b�`���[�`��
1620     enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1621     enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1622     enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1623 maya 2926 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1624 yutakakn 2825 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1625 yutakakn 2728 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1626 yutakakn 2827 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1627 yutakakn 2728 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1628     enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1629     enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1630     // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1631 yutakakn 2825 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1632 yutakakn 2728 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1633    
1634     }
1635     }
1636    
1637     BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1638     {
1639     static const char prefix[] = "Received server prologue string: ";
1640    
1641 yutakakn 2796 // initialize SSH2 memory dump (2005.3.7 yutaka)
1642     init_memdump();
1643 maya 2929 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1644 yutakakn 2796
1645 yutakakn 2728 if (ID_len <= 0) {
1646     return FALSE;
1647     } else {
1648 maya 2992 int buf_len = ID_len + NUM_ELEM(prefix);
1649     char FAR *buf = (char FAR *) malloc(buf_len);
1650 yutakakn 2728
1651 maya 2992 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1652     strncat_s(buf, buf_len, ID, _TRUNCATE);
1653 yutakakn 2728 chop_newlines(buf);
1654    
1655     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1656    
1657     free(buf);
1658    
1659    
1660 yutakakn 2797 // ���������R�s�[������ (2005.3.9 yutaka)
1661     #if 0
1662 yutakakn 2728 // for calculate SSH2 hash
1663     // �T�[�o�o�[�W�����������i���s���������������j
1664 maya 3054 if (ID_len >= sizeof(pvar->server_version_string))
1665 yutakakn 2728 return FALSE;
1666     strncpy(pvar->server_version_string, ID, ID_len);
1667 yutakakn 2797 #endif
1668 yutakakn 2728
1669    
1670     if (ID[ID_len - 1] != '\n') {
1671     pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1672     return FALSE;
1673 maya 3003 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1674 yutakakn 2728 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1675     return FALSE;
1676     } else if (strncmp(ID, "SSH-", 4) != 0) {
1677     return FALSE;
1678     } else {
1679     ID[ID_len - 1] = 0;
1680    
1681     if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1682     ID[ID_len - 2] = 0;
1683     }
1684    
1685     pvar->ssh_state.server_ID = _strdup(ID);
1686    
1687     if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1688 maya 2994 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1689 maya 3003 "This program does not understand the server's version of the protocol.");
1690 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
1691 yutakakn 2728 } else {
1692     char TTSSH_ID[1024];
1693     int TTSSH_ID_len;
1694 yutakakn 2793 int a, b, c, d;
1695 yutakakn 2728
1696 yutakakn 2793 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1697     get_file_version("ttxssh.dll", &a, &b, &c, &d);
1698    
1699 maya 2992 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1700 maya 3003 "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1701     pvar->protocol_major, pvar->protocol_minor, a, b);
1702 yutakakn 2728 TTSSH_ID_len = strlen(TTSSH_ID);
1703    
1704     // for SSH2(yutaka)
1705     // �N���C�A���g�o�[�W�����������i���s���������������j
1706 maya 2992 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1707 maya 3003 TTSSH_ID, _TRUNCATE);
1708 yutakakn 2728
1709 yutakakn 2797 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1710 maya 2992 _snprintf_s(pvar->server_version_string,
1711 maya 3003 sizeof(pvar->server_version_string), _TRUNCATE,
1712     "%s", pvar->ssh_state.server_ID);
1713 yutakakn 2797
1714 yutakakn 2728 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1715 maya 3003 0) != TTSSH_ID_len) {
1716 maya 2994 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1717 maya 3003 "An error occurred while sending the SSH ID string.\n"
1718     "The connection will close.");
1719 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
1720 yutakakn 2728 } else {
1721     // ���s�R�[�h������ (2004.8.4 yutaka)
1722     pvar->client_version_string[--TTSSH_ID_len] = 0;
1723    
1724 yutakakn 2796 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1725     push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1726    
1727 yutakakn 2728 // SSH�n���h�����o�^���s��
1728     init_protocol(pvar);
1729    
1730     SSH2_dispatch_init(1);
1731     SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1732 yutakakn 2796 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1733 yutakakn 2728 }
1734     }
1735    
1736     return TRUE;
1737     }
1738     }
1739     }
1740    
1741     static BOOL handle_exit(PTInstVar pvar)
1742     {
1743     if (grab_payload(pvar, 4)) {
1744     begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1745     finish_send_packet(pvar);
1746     notify_closed_connection(pvar);
1747     }
1748     return TRUE;
1749     }
1750    
1751     static BOOL handle_data(PTInstVar pvar)
1752     {
1753     if (grab_payload_limited(pvar, 4)) {
1754     pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1755     pvar->ssh_state.payload_datastart = 4;
1756     }
1757     return TRUE;
1758     }
1759    
1760     static BOOL handle_channel_open(PTInstVar pvar)
1761     {
1762     int host_len;
1763     int originator_len;
1764    
1765     if ((pvar->ssh_state.
1766     server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1767     if (grab_payload(pvar, 8)
1768 maya 3003 && grab_payload(pvar,
1769     8 + (host_len = get_payload_uint32(pvar, 4)))
1770     && grab_payload(pvar, originator_len =
1771     get_payload_uint32(pvar, host_len + 12))) {
1772 yutakakn 2728 int local_port = get_payload_uint32(pvar, 8 + host_len);
1773    
1774     pvar->ssh_state.payload[8 + host_len] = 0;
1775     FWD_open(pvar, get_payload_uint32(pvar, 0),
1776 maya 3003 pvar->ssh_state.payload + 8, local_port,
1777     pvar->ssh_state.payload + 16 + host_len,
1778 maya 3054 originator_len,
1779 maya 3003 NULL);
1780 yutakakn 2728 }
1781     } else {
1782     if (grab_payload(pvar, 8)
1783 maya 3003 && grab_payload(pvar,
1784     4 + (host_len = get_payload_uint32(pvar, 4)))) {
1785 yutakakn 2728 int local_port = get_payload_uint32(pvar, 8 + host_len);
1786    
1787     pvar->ssh_state.payload[8 + host_len] = 0;
1788     FWD_open(pvar, get_payload_uint32(pvar, 0),
1789 maya 3003 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1790     NULL);
1791 yutakakn 2728 }
1792     }
1793    
1794     return TRUE;
1795     }
1796    
1797     static BOOL handle_X11_channel_open(PTInstVar pvar)
1798     {
1799     int originator_len;
1800    
1801 maya 3003 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1802 yutakakn 2728 if (grab_payload(pvar, 8)
1803 maya 3003 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1804 yutakakn 2728 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1805 maya 3003 pvar->ssh_state.payload + 8, originator_len, NULL);
1806 yutakakn 2728 }
1807     } else {
1808     if (grab_payload(pvar, 4)) {
1809 yutakakn 2829 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1810 yutakakn 2728 }
1811     }
1812    
1813     return TRUE;
1814     }
1815    
1816     static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1817     {
1818     if (grab_payload(pvar, 8)) {
1819     FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1820 maya 3003 get_payload_uint32(pvar, 4));
1821 yutakakn 2728 }
1822     return FALSE;
1823     }
1824    
1825     static BOOL handle_channel_open_failure(PTInstVar pvar)
1826     {
1827     if (grab_payload(pvar, 4)) {
1828     FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1829     }
1830     return FALSE;
1831     }
1832    
1833     static BOOL handle_channel_data(PTInstVar pvar)
1834     {
1835     int len;
1836    
1837     if (grab_payload(pvar, 8)
1838 maya 3003 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1839 yutakakn 2728 FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1840 maya 3003 pvar->ssh_state.payload + 8, len);
1841 yutakakn 2728 }
1842     return TRUE;
1843     }
1844    
1845     static BOOL handle_channel_input_eof(PTInstVar pvar)
1846     {
1847     if (grab_payload(pvar, 4)) {
1848     FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1849     }
1850     return TRUE;
1851     }
1852    
1853     static BOOL handle_channel_output_eof(PTInstVar pvar)
1854     {
1855     if (grab_payload(pvar, 4)) {
1856     FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1857     }
1858     return TRUE;
1859     }
1860    
1861    
1862    
1863     // �n���h�����O�������b�Z�[�W����������
1864    
1865     #define HANDLE_MESSAGE_MAX 30
1866     static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1867     static int handle_message_count = 0;
1868     static int handle_message_stage = 0;
1869    
1870     void SSH2_dispatch_init(int stage)
1871     {
1872     handle_message_count = 0;
1873     handle_message_stage = stage;
1874     }
1875    
1876     int SSH2_dispatch_enabled_check(unsigned char message)
1877     {
1878     int i;
1879    
1880     for (i = 0 ; i < handle_message_count ; i++) {
1881     if (handle_messages[i] == message)
1882     return 1;
1883     }
1884     return 0;
1885     }
1886    
1887     void SSH2_dispatch_add_message(unsigned char message)
1888     {
1889    
1890     if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1891     // TODO: error check
1892     return;
1893     }
1894    
1895     handle_messages[handle_message_count++] = message;
1896     }
1897    
1898     void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1899     {
1900     unsigned char c;
1901    
1902     for (c = begin ; c <= end ; c++) {
1903     SSH2_dispatch_add_message(c);
1904     }
1905     }
1906    
1907    
1908     void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1909     int padding)
1910     {
1911     unsigned char message = prep_packet(pvar, data, len, padding);
1912    
1913    
1914     #ifdef SSH2_DEBUG
1915     // for SSH2(yutaka)
1916     if (SSHv2(pvar)) {
1917     if (pvar->key_done) {
1918     message = message;
1919     }
1920    
1921     if (pvar->userauth_success) {
1922     message = message;
1923     }
1924    
1925     if (pvar->rekeying) {
1926     message = message;
1927     }
1928     }
1929     #endif
1930    
1931     // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1932     if (message != SSH_MSG_NONE) {
1933     // ���b�Z�[�W�^�C�v���������n���h�����N��
1934     SSHPacketHandler handler = get_handler(pvar, message);
1935    
1936     // for SSH2(yutaka)
1937     if (SSHv2(pvar)) {
1938     // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1939     if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1940     char buf[1024];
1941    
1942 maya 2994 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
1943     "Unexpected SSH2 message(%d) on current stage(%d)");
1944 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1945 maya 2942 pvar->ts->UIMsg, message, handle_message_stage);
1946 yutakakn 2728 notify_fatal_error(pvar, buf);
1947     // abort
1948     }
1949     }
1950    
1951     if (handler == NULL) {
1952     if (SSHv1(pvar)) {
1953     char buf[1024];
1954    
1955 maya 2994 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
1956 maya 3003 "Unexpected packet type received: %d");
1957 maya 2992 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1958 maya 2942 pvar->ts->UIMsg, message, handle_message_stage);
1959 yutakakn 2728 notify_fatal_error(pvar, buf);
1960     } else {
1961     unsigned char FAR *outmsg =
1962     begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
1963    
1964     set_uint32(outmsg,
1965 maya 3003 pvar->ssh_state.receiver_sequence_number - 1);
1966 yutakakn 2728 finish_send_packet(pvar);
1967     /* XXX need to decompress incoming packet, but how? */
1968     }
1969     } else {
1970     if (!handler(pvar)) {
1971     deque_handlers(pvar, message);
1972     }
1973     }
1974     }
1975     }
1976    
1977     static BOOL handle_pty_success(PTInstVar pvar)
1978     {
1979     FWD_enter_interactive_mode(pvar);
1980     enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
1981     enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
1982     enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
1983     enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
1984     enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
1985 maya 3003 handle_channel_input_eof);
1986 yutakakn 2728 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
1987 maya 3003 handle_channel_output_eof);
1988 yutakakn 2728 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
1989     enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
1990     return FALSE;
1991     }
1992    
1993     static BOOL handle_pty_failure(PTInstVar pvar)
1994     {
1995 maya 2994 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
1996 maya 3003 "The server cannot allocate a pseudo-terminal. "
1997     "You may encounter some problems with the terminal.");
1998 maya 2942 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1999 yutakakn 2728 return handle_pty_success(pvar);
2000     }
2001    
2002     static void prep_pty(PTInstVar pvar)
2003     {
2004     int len = strlen(pvar->ts->TermType);
2005     unsigned char FAR *outmsg =
2006     begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2007 maya 3003 4 + len + 16 + sizeof(ssh_ttymodes));
2008 yutakakn 2728 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2009     static const SSHPacketHandler handlers[]
2010     = { handle_pty_success, handle_pty_failure };
2011    
2012     set_uint32(outmsg, len);
2013     memcpy(outmsg + 4, pvar->ts->TermType, len);
2014     set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2015     set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2016     set_uint32(outmsg + 4 + len + 8, 0);
2017     set_uint32(outmsg + 4 + len + 12, 0);
2018     memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2019     finish_send_packet(pvar);
2020    
2021     enque_handlers(pvar, 2, msgs, handlers);
2022    
2023     begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2024     finish_send_packet(pvar);
2025     }
2026    
2027     static void prep_forwarding(PTInstVar pvar)
2028     {
2029     FWD_prep_forwarding(pvar);
2030     prep_pty(pvar);
2031     }
2032    
2033 yutakakn 2834
2034     //
2035     //
2036     // (2005.7.10 yutaka)
2037     static void enable_send_compression(PTInstVar pvar)
2038 yutakakn 2728 {
2039 yutakakn 2834 static int initialize = 0;
2040    
2041     if (initialize) {
2042     deflateEnd(&pvar->ssh_state.compress_stream);
2043     }
2044     initialize = 1;
2045    
2046 yutakakn 2728 pvar->ssh_state.compress_stream.zalloc = NULL;
2047     pvar->ssh_state.compress_stream.zfree = NULL;
2048     pvar->ssh_state.compress_stream.opaque = NULL;
2049     if (deflateInit
2050 maya 3003 (&pvar->ssh_state.compress_stream,
2051     pvar->ssh_state.compression_level) != Z_OK) {
2052 maya 2994 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2053 maya 3003 "An error occurred while setting up compression.\n"
2054     "The connection will close.");
2055 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
2056 yutakakn 2728 return;
2057     } else {
2058 yutakakn 2834 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2059     if (SSHv2(pvar)) {
2060     pvar->ssh_state.compressing = FALSE;
2061     } else {
2062     pvar->ssh_state.compressing = TRUE;
2063     }
2064 yutakakn 2728 }
2065 yutakakn 2834 }
2066 yutakakn 2728
2067 yutakakn 2834 static void enable_recv_compression(PTInstVar pvar)
2068     {
2069     static int initialize = 0;
2070    
2071     if (initialize) {
2072     deflateEnd(&pvar->ssh_state.decompress_stream);
2073     }
2074     initialize = 1;
2075    
2076 yutakakn 2728 pvar->ssh_state.decompress_stream.zalloc = NULL;
2077     pvar->ssh_state.decompress_stream.zfree = NULL;
2078     pvar->ssh_state.decompress_stream.opaque = NULL;
2079     if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2080     deflateEnd(&pvar->ssh_state.compress_stream);
2081 maya 2994 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2082 maya 3003 "An error occurred while setting up compression.\n"
2083     "The connection will close.");
2084 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
2085 yutakakn 2728 return;
2086     } else {
2087 yutakakn 2834 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2088     if (SSHv2(pvar)) {
2089     pvar->ssh_state.decompressing = FALSE;
2090     } else {
2091     pvar->ssh_state.decompressing = TRUE;
2092     }
2093    
2094 yutakakn 2728 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2095 maya 3003 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2096 yutakakn 2728 }
2097 yutakakn 2834 }
2098 yutakakn 2833
2099 yutakakn 2834 static void enable_compression(PTInstVar pvar)
2100     {
2101     enable_send_compression(pvar);
2102     enable_recv_compression(pvar);
2103    
2104 yutakakn 2833 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2105     if (SSHv2(pvar)) {
2106     pvar->ssh_state.compressing = FALSE;
2107     pvar->ssh_state.decompressing = FALSE;
2108     }
2109    
2110 yutakakn 2728 }
2111    
2112     static BOOL handle_enable_compression(PTInstVar pvar)
2113     {
2114     enable_compression(pvar);
2115     prep_forwarding(pvar);
2116     return FALSE;
2117     }
2118    
2119     static BOOL handle_disable_compression(PTInstVar pvar)
2120     {
2121     prep_forwarding(pvar);
2122     return FALSE;
2123     }
2124    
2125     static void prep_compression(PTInstVar pvar)
2126     {
2127     if (pvar->session_settings.CompressionLevel > 0) {
2128 yutakakn 2833 // added if statement (2005.7.10 yutaka)
2129     if (SSHv1(pvar)) {
2130     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2131     static const SSHPacketHandler handlers[]
2132     = { handle_enable_compression, handle_disable_compression };
2133 yutakakn 2728
2134 yutakakn 2833 unsigned char FAR *outmsg =
2135     begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2136 yutakakn 2728
2137 yutakakn 2833 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2138     finish_send_packet(pvar);
2139 yutakakn 2728
2140 yutakakn 2833 enque_handlers(pvar, 2, msgs, handlers);
2141     }
2142    
2143 yutakakn 2728 pvar->ssh_state.compression_level =
2144     pvar->session_settings.CompressionLevel;
2145    
2146     } else {
2147 yutakakn 2833 // added if statement (2005.7.10 yutaka)
2148     if (SSHv1(pvar)) {
2149     prep_forwarding(pvar);
2150     }
2151 yutakakn 2728 }
2152     }
2153    
2154     static void enque_simple_auth_handlers(PTInstVar pvar)
2155     {
2156     static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2157     static const SSHPacketHandler handlers[]
2158     = { handle_auth_success, handle_auth_failure };
2159    
2160     enque_handlers(pvar, 2, msgs, handlers);
2161     }
2162    
2163     static BOOL handle_rsa_challenge(PTInstVar pvar)
2164     {
2165     int challenge_bytes;
2166    
2167     if (!grab_payload(pvar, 2)) {
2168     return FALSE;
2169     }
2170    
2171     challenge_bytes = get_mpint_len(pvar, 0);
2172    
2173     if (grab_payload(pvar, challenge_bytes)) {
2174     unsigned char FAR *outmsg =
2175     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2176    
2177     if (CRYPT_generate_RSA_challenge_response
2178     (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2179 yutakakn 2811
2180     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2181     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2182     #if 0
2183     //AUTH_destroy_cur_cred(pvar);
2184     #endif
2185    
2186 yutakakn 2728 finish_send_packet(pvar);
2187    
2188     enque_simple_auth_handlers(pvar);
2189     } else {
2190 maya 2994 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2191 maya 3003 "An error occurred while decrypting the RSA challenge.\n"
2192     "Perhaps the key file is corrupted.");
2193 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
2194 yutakakn 2728 }
2195     }
2196    
2197     return FALSE;
2198     }
2199    
2200     #define OBFUSCATING_ROUND_TO 32
2201    
2202     static int obfuscating_round_up(PTInstVar pvar, int size)
2203     {
2204     return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2205     }
2206    
2207     static void try_send_credentials(PTInstVar pvar)
2208     {
2209     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2210     AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2211     static const int RSA_msgs[] =
2212     { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2213     static const SSHPacketHandler RSA_handlers[]
2214     = { handle_rsa_challenge, handle_rsa_auth_refused };
2215     static const int TIS_msgs[] =
2216     { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2217     static const SSHPacketHandler TIS_handlers[]
2218     = { handle_TIS_challenge, handle_auth_failure };
2219    
2220 yutakakn 2800 // SSH2���������������������X�L�b�v
2221 maya 3054 if (SSHv2(pvar))
2222 yutakakn 2800 goto skip_ssh2;
2223    
2224 yutakakn 2728 switch (cred->method) {
2225     case SSH_AUTH_NONE:
2226     return;
2227     case SSH_AUTH_PASSWORD:{
2228     int len = strlen(cred->password);
2229     // Round up password length to discourage traffic analysis
2230     int obfuscated_len = obfuscating_round_up(pvar, len);
2231     unsigned char FAR *outmsg =
2232     begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2233 maya 3003 4 + obfuscated_len);
2234 yutakakn 2728
2235     notify_verbose_message(pvar,
2236 maya 3003 "Trying PASSWORD authentication...",
2237     LOG_LEVEL_VERBOSE);
2238 yutakakn 2728
2239     set_uint32(outmsg, obfuscated_len);
2240     memcpy(outmsg + 4, cred->password, len);
2241     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2242 yutakakn 2811
2243     // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2244     // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2245     #if 0
2246     //AUTH_destroy_cur_cred(pvar);
2247     #endif
2248    
2249 yutakakn 2728 enque_simple_auth_handlers(pvar);
2250     break;
2251     }
2252     case SSH_AUTH_RHOSTS:{
2253     int len = strlen(cred->rhosts_client_user);
2254     unsigned char FAR *outmsg =
2255     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2256    
2257     notify_verbose_message(pvar,
2258 maya 3003 "Trying RHOSTS authentication...",
2259     LOG_LEVEL_VERBOSE);
2260 yutakakn 2728
2261     set_uint32(outmsg, len);
2262     memcpy(outmsg + 4, cred->rhosts_client_user, len);
2263     AUTH_destroy_cur_cred(pvar);
2264     enque_simple_auth_handlers(pvar);
2265     break;
2266     }
2267     case SSH_AUTH_RSA:{
2268     int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2269     unsigned char FAR *outmsg =
2270     begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2271    
2272     notify_verbose_message(pvar,
2273 maya 3003 "Trying RSA authentication...",
2274     LOG_LEVEL_VERBOSE);
2275 yutakakn 2728
2276     set_ushort16_MSBfirst(outmsg, len * 8);
2277     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2278     /* don't destroy the current credentials yet */
2279     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2280     break;
2281     }
2282     case SSH_AUTH_RHOSTS_RSA:{
2283     int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2284     int name_len = strlen(cred->rhosts_client_user);
2285     int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2286     int index;
2287     unsigned char FAR *outmsg =
2288     begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2289 maya 3003 12 + mod_len + name_len + exp_len);
2290 yutakakn 2728
2291     notify_verbose_message(pvar,
2292 maya 3003 "Trying RHOSTS+RSA authentication...",
2293     LOG_LEVEL_VERBOSE);
2294 yutakakn 2728
2295     set_uint32(outmsg, name_len);
2296     memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2297     index = 4 + name_len;
2298    
2299     set_uint32(outmsg + index, 8 * mod_len);
2300     set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2301     BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2302     index += 6 + exp_len;
2303    
2304     set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2305     BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2306     /* don't destroy the current credentials yet */
2307     enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2308     break;
2309     }
2310     case SSH_AUTH_TIS:{
2311     if (cred->password == NULL) {
2312     unsigned char FAR *outmsg =
2313     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2314    
2315     notify_verbose_message(pvar,
2316 maya 3003 "Trying TIS authentication...",
2317     LOG_LEVEL_VERBOSE);
2318 yutakakn 2728 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2319     } else {
2320     int len = strlen(cred->password);
2321     int obfuscated_len = obfuscating_round_up(pvar, len);
2322     unsigned char FAR *outmsg =
2323     begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2324 maya 3003 4 + obfuscated_len);
2325 yutakakn 2728
2326     notify_verbose_message(pvar, "Sending TIS response",
2327 maya 3003 LOG_LEVEL_VERBOSE);
2328 yutakakn 2728
2329     set_uint32(outmsg, obfuscated_len);
2330     memcpy(outmsg + 4, cred->password, len);
2331     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2332     enque_simple_auth_handlers(pvar);
2333     }
2334 yutakakn 2800
2335 yutakakn 2728 AUTH_destroy_cur_cred(pvar);
2336     break;
2337     }
2338     default:
2339 maya 2994 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2340 maya 3003 "Internal error: unsupported authentication method");
2341 maya 2942 notify_fatal_error(pvar, pvar->ts->UIMsg);
2342 yutakakn 2728 return;
2343     }
2344    
2345     finish_send_packet(pvar);
2346 yutakakn 2800
2347     skip_ssh2:;
2348 yutakakn 2728 destroy_packet_buf(pvar);
2349    
2350     pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2351     }
2352     }
2353    
2354     static void try_send_user_name(PTInstVar pvar)
2355     {
2356     if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2357     char FAR *username = AUTH_get_user_name(pvar);
2358    
2359     if (username != NULL) {
2360     int len = strlen(username);
2361     int obfuscated_len = obfuscating_round_up(pvar, len);
2362     unsigned char FAR *outmsg =
2363     begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
2364     char buf[1024] = "Sending user name: ";
2365     static const int msgs[] =
2366     { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2367     static const SSHPacketHandler handlers[]
2368     = { handle_noauth_success, handle_auth_required };
2369    
2370     set_uint32(outmsg, obfuscated_len);
2371     memcpy(outmsg + 4, username, len);
2372     memset(outmsg + 4 + len, 0, obfuscated_len - len);
2373     finish_send_packet(pvar);
2374    
2375     pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2376    
2377 maya 2992 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2378 yutakakn 2728 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2379    
2380     enque_handlers(pvar, 2, msgs, handlers);
2381     }
2382     }
2383     }
2384    
2385     static void send_session_key(PTInstVar pvar)
2386     {
2387     int encrypted_session_key_len;
2388     unsigned char FAR *outmsg;
2389    
2390     if (SSHv1(pvar)) {
2391     encrypted_session_key_len =
2392     CRYPT_get_encrypted_session_key_len(pvar);
2393     }
2394    
2395     if (!CRYPT_choose_ciphers(pvar))
2396     return;
2397    
2398     if (SSHv1(pvar)) {
2399     outmsg =
2400     begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2401 maya 3003 15 + encrypted_session_key_len);
2402 yutakakn 2728 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2403     memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2404     outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2405     outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2406     if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2407     return;
2408     set_uint32(outmsg + 11 + encrypted_session_key_len,
2409 maya 3003 SSH_PROTOFLAG_SCREEN_NUMBER |
2410     SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2411 yutakakn 2728 finish_send_packet(pvar);
2412     }
2413    
2414     if (!CRYPT_start_encryption(pvar, 1, 1))
2415     return;
2416     notify_established_secure_connection(pvar);
2417    
2418     if (SSHv1(pvar)) {
2419     enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2420     }
2421    
2422     pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2423    
2424     if (SSHv1(pvar)) {
2425     try_send_user_name(pvar);
2426     }
2427     }
2428    
2429     /*************************
2430     END of message handlers
2431     ************************/
2432    
2433     void SSH_init(PTInstVar pvar)
2434     {
2435     int i;
2436    
2437     buf_create(&pvar->ssh_state.outbuf,<