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 3078 - (hide annotations) (download) (as text)
Wed Dec 26 12:17:29 2007 UTC (16 years, 3 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 203350 byte(s)
SSHハートビートスレッドのパケット送信をモードレスダイアログ内で行うことで、
コンテキストの乱れを発生させないようにする。

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