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 3074 - (hide annotations) (download) (as text)
Mon Dec 24 14:42:50 2007 UTC (16 years, 3 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 200258 byte(s)
SCPによるファイル送信機能を追加した(未完)。
以下、制限事項。
 ・SSH2のみ
 ・GetOpenFileName()に渡すOPENFILENAME_SIZE_VERSION_400とOFN_FORCESHOWHIDDENが未定義であると怒られる。
 ・send_packet_blocking()のioctlsocket()が"10022"のエラーとなることがある。
以下、AIリスト。
 ・zmodemsendのような"scpsend"マクロコマンドを作りたいが、DDE通信でTTSSHのコードを呼び出すことは可能かどうか。
 ・ファイル受信
 ・SFTPへの対応
 ・SSH1への対応

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