Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3081 - (show annotations) (download) (as text)
Thu Dec 27 13:18:47 2007 UTC (16 years, 3 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 204306 byte(s)
SCPのファイル送信中に、TeraTermウィンドウを閉じようとすると、デッドロックとなる問題を修正。
ファイル受信処理(作成途中)のコードも入っていますが、現在動作しません。

1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 Copyright (c) 2004-2005, Yutaka Hirata
4 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 #include "resource.h"
33
34 #include <openssl/bn.h>
35 #include <openssl/evp.h>
36 #include <openssl/dh.h>
37 #include <openssl/engine.h>
38 #include <openssl/rsa.h>
39 #include <openssl/dsa.h>
40 #include <limits.h>
41 #include <malloc.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <process.h>
45 #include <time.h>
46 #include "buffer.h"
47 #include "ssh.h"
48 #include "crypt.h"
49 #include "fwd.h"
50
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 #include <assert.h>
54
55
56 // SSH2 macro
57 #ifdef _DEBUG
58 #define SSH2_DEBUG
59 #endif
60
61 #define DONT_WANTCONFIRM 1 // (2005.3.28 yutaka)
62 #define INTBLOB_LEN 20
63 #define SIGBLOB_LEN (2*INTBLOB_LEN)
64
65 //
66 // SSH2 data structure
67 //
68
69 // channel data structure
70 #define CHANNEL_MAX 100
71
72 enum channel_type {
73 TYPE_SHELL, TYPE_PORTFWD, TYPE_SCP,
74 };
75
76 enum scp_state {
77 SCP_INIT, SCP_TIMESTAMP, SCP_FILEINFO, SCP_DATA, SCP_CLOSING,
78 };
79
80 enum scp_dir {
81 TOLOCAL, FROMREMOTE,
82 };
83
84 typedef struct bufchain {
85 buffer_t *msg;
86 struct bufchain *next;
87 } bufchain_t;
88
89 typedef struct scp {
90 enum scp_dir dir; // transfer direction
91 enum scp_state state; // SCP state
92 char sendfile[MAX_PATH]; // sending filename
93 char sendfilefull[MAX_PATH]; // sending filename fullpath
94 FILE *sendfp; // file pointer
95 struct _stat filestat; // file status information
96 HWND progress;
97 HANDLE thread;
98 PTInstVar pvar;
99 } scp_t;
100
101 typedef struct channel {
102 int used;
103 int self_id;
104 int remote_id;
105 unsigned int local_window;
106 unsigned int local_window_max;
107 unsigned int local_consumed;
108 unsigned int local_maxpacket;
109 unsigned int remote_window;
110 unsigned int remote_maxpacket;
111 enum channel_type type;
112 int local_num;
113 bufchain_t *bufchain;
114 scp_t scp;
115 } Channel_t;
116
117 static Channel_t channels[CHANNEL_MAX];
118
119 static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
120
121 static void try_send_credentials(PTInstVar pvar);
122 static void prep_compression(PTInstVar pvar);
123
124 // �����v���g�^�C�v����
125 void SSH2_send_kexinit(PTInstVar pvar);
126 static BOOL handle_SSH2_kexinit(PTInstVar pvar);
127 static void SSH2_dh_kex_init(PTInstVar pvar);
128 static void SSH2_dh_gex_kex_init(PTInstVar pvar);
129 static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
130 static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
131 static BOOL handle_SSH2_newkeys(PTInstVar pvar);
132 static BOOL handle_SSH2_authrequest(PTInstVar pvar);
133 static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
134 static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
135 static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
136 static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
137 static BOOL handle_SSH2_open_failure(PTInstVar pvar);
138 static BOOL handle_SSH2_request_success(PTInstVar pvar);
139 static BOOL handle_SSH2_request_failure(PTInstVar pvar);
140 static BOOL handle_SSH2_channel_success(PTInstVar pvar);
141 static BOOL handle_SSH2_channel_data(PTInstVar pvar);
142 static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
143 static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
144 static BOOL handle_SSH2_channel_close(PTInstVar pvar);
145 static BOOL handle_SSH2_channel_open(PTInstVar pvar);
146 static BOOL handle_SSH2_window_adjust(PTInstVar pvar);
147 static BOOL handle_SSH2_channel_request(PTInstVar pvar);
148 void SSH2_dispatch_init(int stage);
149 int SSH2_dispatch_enabled_check(unsigned char message);
150 void SSH2_dispatch_add_message(unsigned char message);
151 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);
152 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
153 static void start_ssh_heartbeat_thread(PTInstVar pvar);
154 static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen);
155
156 //
157 // channel function
158 //
159 static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack,
160 enum confirm_type type, int local_num)
161 {
162 int i, found;
163 Channel_t *c;
164
165 found = -1;
166 for (i = 0 ; i < CHANNEL_MAX ; i++) {
167 if (channels[i].used == 0) { // free channel
168 found = i;
169 break;
170 }
171 }
172 if (found == -1) { // not free channel
173 return (NULL);
174 }
175
176 // setup
177 c = &channels[found];
178 memset(c, 0, sizeof(Channel_t));
179 c->used = 1;
180 c->self_id = i;
181 c->remote_id = -1;
182 c->local_window = window;
183 c->local_window_max = window;
184 c->local_consumed = 0;
185 c->local_maxpacket = maxpack;
186 c->remote_window = 0;
187 c->remote_maxpacket = 0;
188 c->type = type;
189 c->local_num = local_num; // alloc_channel()�����l��������������
190 c->bufchain = NULL;
191 if (type == TYPE_SCP) {
192 c->scp.state = SCP_INIT;
193 c->scp.progress = NULL;
194 }
195
196 return (c);
197 }
198
199 // remote_window�������������������A�������������o�b�t�@�����X�g�i�������j���������������B
200 static void ssh2_channel_add_bufchain(Channel_t *c, unsigned char *buf, unsigned int buflen)
201 {
202 bufchain_t *p, *old;
203
204 // allocate new buffer
205 p = malloc(sizeof(bufchain_t));
206 if (p == NULL)
207 return;
208 p->msg = buffer_init();
209 if (p == NULL) {
210 free(p);
211 return;
212 }
213 buffer_put_raw(p->msg, buf, buflen);
214 p->next = NULL;
215
216 if (c->bufchain == NULL) {
217 c->bufchain = p;
218 } else {
219 old = c->bufchain;
220 while (old->next)
221 old = old->next;
222 old->next = p;
223 }
224 }
225
226
227 static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c)
228 {
229 bufchain_t *ch;
230 unsigned int size;
231
232 while (c->bufchain) {
233 // ����������������
234 ch = c->bufchain;
235 size = buffer_len(ch->msg);
236 if (size >= c->remote_window)
237 break;
238
239 SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size);
240
241 c->bufchain = ch->next;
242
243 buffer_free(ch->msg);
244 free(ch);
245 }
246 }
247
248
249
250 // channel close�����`���l���\���������X�g�����p����
251 // (2007.4.26 yutaka)
252 static void ssh2_channel_delete(Channel_t *c)
253 {
254 bufchain_t *ch, *ptr;
255
256 ch = c->bufchain;
257 while (ch) {
258 if (ch->msg)
259 buffer_free(ch->msg);
260 ptr = ch;
261 ch = ch->next;
262 free(ptr);
263 }
264
265 if (c->type == TYPE_SCP) {
266 c->scp.state = SCP_CLOSING;
267 fclose(c->scp.sendfp);
268 if (c->scp.progress != NULL) {
269 DestroyWindow(c->scp.progress);
270 c->scp.progress = NULL;
271 }
272 if (c->scp.thread != (HANDLE)-1L) {
273 WaitForSingleObject(c->scp.thread, INFINITE);
274 CloseHandle(c->scp.thread);
275 c->scp.thread = (HANDLE)-1L;
276 }
277 }
278
279 memset(c, 0, sizeof(Channel_t));
280 c->used = 0;
281 }
282
283
284 // connection close������������
285 void ssh2_channel_free(void)
286 {
287 int i;
288 Channel_t *c;
289
290 for (i = 0 ; i < CHANNEL_MAX ; i++) {
291 c = &channels[i];
292 ssh2_channel_delete(c);
293 }
294
295 }
296
297 static Channel_t *ssh2_channel_lookup(int id)
298 {
299 Channel_t *c;
300
301 if (id < 0 || id >= CHANNEL_MAX) {
302 return (NULL);
303 }
304 c = &channels[id];
305 if (c->used == 0) { // already freed
306 return (NULL);
307 }
308 return (c);
309 }
310
311 // SSH1��������������channel�\���������ASSH2������Channel_t�����������B
312 // TODO: �����I�����`���l���\������1�������������B
313 // (2005.6.12 yutaka)
314 static Channel_t *ssh2_local_channel_lookup(int local_num)
315 {
316 int i;
317 Channel_t *c;
318
319 for (i = 0 ; i < CHANNEL_MAX ; i++) {
320 c = &channels[i];
321 if (c->local_num == local_num)
322 return (c);
323 }
324 return (NULL);
325 }
326
327
328 //
329 // SSH heartbeat mutex
330 //
331 // TTSSH�� thread-safe �������������A�}���`�X���b�h�������p�P�b�g���M�����������B
332 // �V���O���X���b�h�����R���e�L�X�g�X�C�b�`�������������������������A
333 // ���b�N�������K�v�����������A���������B(2007.12.26 yutaka)
334 //
335 static CRITICAL_SECTION g_ssh_heartbeat_lock; /* �����M�p���b�N */
336
337 void ssh_heartbeat_lock_initialize(void)
338 {
339 //InitializeCriticalSection(&g_ssh_heartbeat_lock);
340 }
341
342 void ssh_heartbeat_lock_finalize(void)
343 {
344 //DeleteCriticalSection(&g_ssh_heartbeat_lock);
345 }
346
347 void ssh_heartbeat_lock(void)
348 {
349 //EnterCriticalSection(&g_ssh_heartbeat_lock);
350 }
351
352 void ssh_heartbeat_unlock(void)
353 {
354 //LeaveCriticalSection(&g_ssh_heartbeat_lock);
355 }
356
357
358 //
359 // SSH memory dump (for debug)
360 //
361 // (2005.3.7 yutaka)
362 //
363 #define MEMTAG_MAX 300
364 #define LOGDUMP "ssh2dump.log"
365 #define SENDTOME "Please send '"LOGDUMP"' file to TeraTerm developer team."
366
367 typedef struct memtag {
368 char *name;
369 char *desc;
370 int len;
371 char *data;
372 } memtag_t;
373
374 static memtag_t memtags[MEMTAG_MAX];
375 static int memtag_count = 0;
376 static int memtag_use = 0;
377
378 /* �_���v���C�����t�H�[�}�b�g�\������ */
379 static void displine_memdump(FILE *fp, int addr, int *bytes, int byte_cnt)
380 {
381 int i, c;
382
383 /* �������A�h���X�\�� */
384 fprintf(fp, "%08X : ", addr);
385
386 /* �o�C�i���\���i4�o�C�g�������������}���j*/
387 for (i = 0 ; i < byte_cnt ; i++) {
388 if (i > 0 && i % 4 == 0)
389 fprintf(fp, " ");
390
391 fprintf(fp, "%02X", bytes[i]);
392 }
393
394 /* ASCII�\���������������������� */
395 fprintf(fp, " %*s%*s", (16-byte_cnt)*2+1, " ", (16-byte_cnt+3)/4, " ");
396
397 /* ASCII�\�� */
398 for (i = 0 ; i < byte_cnt ; i++) {
399 c = bytes[i];
400 if (c >= 0x20 && c <= 0x7f) {
401 fprintf(fp, "%c", c);
402 } else {
403 fprintf(fp, ".");
404 }
405 }
406
407 fprintf(fp, "\n");
408 }
409
410
411 /* �_���v���[�`�� */
412 static void dump_memdump(FILE *fp, char *data, int len)
413 {
414 int c, addr;
415 int bytes[16], *ptr;
416 int byte_cnt;
417 int i;
418
419 addr = 0;
420 byte_cnt = 0;
421 ptr = bytes;
422 for (i = 0 ; i < len ; i++) {
423 c = data[i];
424 *ptr++ = c & 0xff;
425 byte_cnt++;
426
427 if (byte_cnt == 16) {
428 displine_memdump(fp, addr, bytes, byte_cnt);
429
430 addr += 16;
431 byte_cnt = 0;
432 ptr = bytes;
433 }
434 }
435
436 if (byte_cnt > 0) {
437 displine_memdump(fp, addr, bytes, byte_cnt);
438 }
439 }
440
441 void init_memdump(void)
442 {
443 int i;
444
445 for (i = 0 ; i < MEMTAG_MAX ; i++) {
446 memtags[i].name = NULL;
447 memtags[i].desc = NULL;
448 memtags[i].data = NULL;
449 memtags[i].len = 0;
450 }
451 memtag_use++;
452 }
453
454 void finish_memdump(void)
455 {
456 int i;
457
458 // initialize�������������������������������B(2005.4.3 yutaka)
459 if (memtag_use <= 0)
460 return;
461 memtag_use--;
462
463 for (i = 0 ; i < MEMTAG_MAX ; i++) {
464 free(memtags[i].name);
465 free(memtags[i].desc);
466 free(memtags[i].data);
467 memtags[i].len = 0;
468 }
469 }
470
471 void save_memdump(char *filename)
472 {
473 FILE *fp;
474 int i;
475 time_t t;
476 struct tm *tm;
477
478 fp = fopen(filename, "w");
479 if (fp == NULL)
480 return;
481
482 t = time(NULL);
483 tm = localtime(&t);
484
485 fprintf(fp, "<<< TeraTerm SSH2 log dump >>>\n");
486 fprintf(fp, "saved time: %04d/%02d/%02d %02d:%02d:%02d\n",
487 tm->tm_year + 1900,
488 tm->tm_mon + 1,
489 tm->tm_mday,
490 tm->tm_hour,
491 tm->tm_min,
492 tm->tm_sec);
493 fprintf(fp, "\n");
494
495 for (i = 0 ; i < memtag_count ; i++) {
496 fprintf(fp, "============================================\n");
497 fprintf(fp, "name: %s\n", memtags[i].name);
498 fprintf(fp, "--------------------------------------------\n");
499 fprintf(fp, "description: %s\n", memtags[i].desc);
500 fprintf(fp, "============================================\n");
501 dump_memdump(fp, memtags[i].data, memtags[i].len);
502 fprintf(fp, "\n\n\n");
503 }
504
505 fprintf(fp, "[EOF]\n");
506
507 fclose(fp);
508 }
509
510 void push_memdump(char *name, char *desc, char *data, int len)
511 {
512 memtag_t *ptr;
513 char *dp;
514
515 dp = malloc(len);
516 if (dp == NULL)
517 return;
518 memcpy(dp, data, len);
519
520 if (memtag_count >= MEMTAG_MAX)
521 return;
522
523 ptr = &memtags[memtag_count];
524 memtag_count++;
525 ptr->name = _strdup(name);
526 ptr->desc = _strdup(desc);
527 ptr->data = dp;
528 ptr->len = len;
529 }
530
531 void push_bignum_memdump(char *name, char *desc, BIGNUM *bignum)
532 {
533 int len;
534 char *buf;
535
536 len = BN_num_bytes(bignum);
537 buf = malloc(len); // allocate
538 if (buf == NULL)
539 return;
540 BN_bn2bin(bignum, buf);
541 push_memdump(name, desc, buf, len); // at push_bignum_memdump()
542 free(buf); // free
543 }
544
545
546 //
547 //
548 //
549
550
551 static int get_predecryption_amount(PTInstVar pvar)
552 {
553 static int small_block_decryption_sizes[] = { 5, 5, 6, 6, 8 };
554
555 if (SSHv1(pvar)) {
556 return 0;
557 } else {
558 int block_size = CRYPT_get_decryption_block_size(pvar);
559
560 if (block_size < 5) {
561 return small_block_decryption_sizes[block_size];
562 } else {
563 return block_size;
564 }
565 }
566 }
567
568 /* Get up to 'limit' bytes into the payload buffer.
569 'limit' is counted from the start of the payload data.
570 Returns the amount of data in the payload buffer, or
571 -1 if there is an error.
572 We can return more than limit in some cases. */
573 static int buffer_packet_data(PTInstVar pvar, int limit)
574 {
575 if (pvar->ssh_state.payloadlen >= 0) {
576 return pvar->ssh_state.payloadlen;
577 } else {
578 int cur_decompressed_bytes =
579 pvar->ssh_state.decompress_stream.next_out -
580 pvar->ssh_state.postdecompress_inbuf;
581
582 while (limit > cur_decompressed_bytes) {
583 int result;
584
585 pvar->ssh_state.payload =
586 pvar->ssh_state.postdecompress_inbuf + 1;
587 if (pvar->ssh_state.postdecompress_inbuflen == cur_decompressed_bytes) {
588 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
589 &pvar->ssh_state.postdecompress_inbuflen,
590 min(limit, cur_decompressed_bytes * 2));
591 }
592
593 pvar->ssh_state.decompress_stream.next_out =
594 pvar->ssh_state.postdecompress_inbuf +
595 cur_decompressed_bytes;
596 pvar->ssh_state.decompress_stream.avail_out =
597 min(limit, pvar->ssh_state.postdecompress_inbuflen)
598 - cur_decompressed_bytes;
599
600 result =
601 inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH);
602 cur_decompressed_bytes =
603 pvar->ssh_state.decompress_stream.next_out -
604 pvar->ssh_state.postdecompress_inbuf;
605
606 switch (result) {
607 case Z_OK:
608 break;
609 case Z_BUF_ERROR:
610 pvar->ssh_state.payloadlen = cur_decompressed_bytes;
611 return cur_decompressed_bytes;
612 default:
613 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
614 "Invalid compressed data in received packet");
615 notify_fatal_error(pvar, pvar->ts->UIMsg);
616 return -1;
617 }
618 }
619
620 return cur_decompressed_bytes;
621 }
622 }
623
624 /* For use by the protocol processing code.
625 Gets N bytes of uncompressed payload. Returns FALSE if data not available
626 and a fatal error has been signaled.
627 The data is available in the payload buffer. This buffer address
628 can change during a call to grab_payload, so take care!
629 The payload pointer is set to point to the first byte of the actual data
630 (after the packet type byte).
631 */
632 static BOOL grab_payload(PTInstVar pvar, int num_bytes)
633 {
634 /* Accept maximum of 4MB of payload data */
635 int in_buffer = buffer_packet_data(pvar, 4 * 1024 * 1024);
636
637 if (in_buffer < 0) {
638 return FALSE;
639 } else {
640 pvar->ssh_state.payload_grabbed += num_bytes;
641 if (pvar->ssh_state.payload_grabbed > in_buffer) {
642 char buf[128];
643 UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_ERROR", pvar,
644 "Received truncated packet (%ld > %d) @ grab_payload()");
645 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
646 pvar->ssh_state.payload_grabbed, in_buffer);
647 notify_fatal_error(pvar, buf);
648 return FALSE;
649 } else {
650 return TRUE;
651 }
652 }
653 }
654
655 static BOOL grab_payload_limited(PTInstVar pvar, int num_bytes)
656 {
657 int in_buffer;
658
659 pvar->ssh_state.payload_grabbed += num_bytes;
660 in_buffer = buffer_packet_data(pvar, pvar->ssh_state.payload_grabbed);
661
662 if (in_buffer < 0) {
663 return FALSE;
664 } else {
665 if (pvar->ssh_state.payload_grabbed > in_buffer) {
666 char buf[128];
667 UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_LIM_ERROR", pvar,
668 "Received truncated packet (%ld > %d) @ grab_payload_limited()");
669 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
670 pvar->ssh_state.payload_grabbed, in_buffer);
671 notify_fatal_error(pvar, buf);
672 return FALSE;
673 } else {
674 return TRUE;
675 }
676 }
677 }
678
679 #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))
680 #define get_uint32(buf) get_uint32_MSBfirst((buf))
681 #define set_uint32(buf, v) set_uint32_MSBfirst((buf), (v))
682 #define get_mpint_len(pvar, offset) ((get_ushort16_MSBfirst((pvar)->ssh_state.payload + (offset)) + 7) >> 3)
683 #define get_ushort16(buf) get_ushort16_MSBfirst((buf))
684
685 #define do_crc(buf, len) (~(uint32)crc32(0xFFFFFFFF, (buf), (len)))
686
687 /* Decrypt the payload, checksum it, eat the padding, get the packet type
688 and return it.
689 'data' points to the start of the packet --- its length field.
690 'len' is the length of the
691 payload + padding (+ length of CRC for SSHv1). 'padding' is the length
692 of the padding alone. */
693 static int prep_packet(PTInstVar pvar, char FAR * data, int len,
694 int padding)
695 {
696 pvar->ssh_state.payload = data + 4;
697 pvar->ssh_state.payloadlen = len;
698
699 if (SSHv1(pvar)) {
700 if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
701 UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar,
702 "'CORE insertion attack' detected. Aborting connection.");
703 notify_fatal_error(pvar, pvar->ts->UIMsg);
704 }
705
706 CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
707 /* PKT guarantees that the data is always 4-byte aligned */
708 if (do_crc(pvar->ssh_state.payload, len - 4) !=
709 get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
710 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
711 "Detected corrupted data; connection terminating.");
712 notify_fatal_error(pvar, pvar->ts->UIMsg);
713 return SSH_MSG_NONE;
714 }
715
716 pvar->ssh_state.payload += padding;
717 pvar->ssh_state.payloadlen -= padding + 4;
718 } else {
719 int already_decrypted = get_predecryption_amount(pvar);
720
721 #if 0
722 CRYPT_decrypt(pvar, data + already_decrypted,
723 len - already_decrypted);
724 #else
725 CRYPT_decrypt(pvar, data + already_decrypted,
726 (4 + len) - already_decrypted);
727 #endif
728
729 if (!CRYPT_verify_receiver_MAC
730 (pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4,
731 data + len + 4)) {
732 UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
733 "Detected corrupted data; connection terminating.");
734 notify_fatal_error(pvar, pvar->ts->UIMsg);
735 return SSH_MSG_NONE;
736 }
737
738 pvar->ssh_state.payload++;
739 pvar->ssh_state.payloadlen -= padding + 1;
740 }
741
742 pvar->ssh_state.payload_grabbed = 0;
743
744 if (SSHv1(pvar)) {
745 if (pvar->ssh_state.decompressing) {
746 if (pvar->ssh_state.decompress_stream.avail_in != 0) {
747 UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
748 "Internal error: a packet was not fully decompressed.\n"
749 "This is a bug, please report it.");
750 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
751 }
752
753 pvar->ssh_state.decompress_stream.next_in =
754 pvar->ssh_state.payload;
755 pvar->ssh_state.decompress_stream.avail_in =
756 pvar->ssh_state.payloadlen;
757 pvar->ssh_state.decompress_stream.next_out =
758 pvar->ssh_state.postdecompress_inbuf;
759 pvar->ssh_state.payloadlen = -1;
760 } else {
761 pvar->ssh_state.payload++;
762 }
763
764 if (!grab_payload_limited(pvar, 1)) {
765 return SSH_MSG_NONE;
766 }
767
768 } else {
769 // support of SSH2 packet compression (2005.7.9 yutaka)
770 // support of "Compression delayed" (2006.6.23 maya)
771 if ((pvar->stoc_compression == COMP_ZLIB ||
772 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&
773 pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
774 int ret;
775
776 if (pvar->decomp_buffer == NULL) {
777 pvar->decomp_buffer = buffer_init();
778 if (pvar->decomp_buffer == NULL)
779 return SSH_MSG_NONE;
780 }
781 // ���x�m�������o�b�t�@���g�������������������Y�������B
782 buffer_clear(pvar->decomp_buffer);
783
784 // packet size��padding�������������y�C���[�h�����������W�J�����B
785 ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
786 pvar->ssh_state.payload,
787 pvar->ssh_state.payloadlen,
788 pvar->decomp_buffer);
789
790 // �|�C���^���X�V�B
791 pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
792 pvar->ssh_state.payload++;
793 pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
794
795 } else {
796 pvar->ssh_state.payload++;
797 }
798
799 if (!grab_payload_limited(pvar, 1)) {
800 return SSH_MSG_NONE;
801 }
802
803 }
804
805 pvar->ssh_state.receiver_sequence_number++;
806
807 return pvar->ssh_state.payload[-1];
808 }
809
810 /* Create a packet to be sent. The SSH protocol packet type is in 'type';
811 'len' contains the length of the packet payload, in bytes (this
812 does not include the space for any of the packet headers or padding,
813 or for the packet type byte).
814 Returns a pointer to the payload data area, a region of length 'len',
815 to be filled by the caller. */
816 static unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len)
817 {
818 unsigned char FAR *buf;
819
820 pvar->ssh_state.outgoing_packet_len = len + 1;
821
822 if (pvar->ssh_state.compressing) {
823 buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
824 &pvar->ssh_state.precompress_outbuflen, 1 + len);
825 buf = pvar->ssh_state.precompress_outbuf;
826 } else {
827 /* For SSHv2,
828 Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
829 + len(payload) + 4(minpadding), rounded up to nearest block_size
830 We only need a reasonable upper bound for the buffer size */
831 buf_ensure_size(&pvar->ssh_state.outbuf,
832 &pvar->ssh_state.outbuflen,
833 len + 30 + CRYPT_get_sender_MAC_size(pvar) +
834 CRYPT_get_encryption_block_size(pvar));
835 buf = pvar->ssh_state.outbuf + 12;
836 }
837
838 buf[0] = (unsigned char) type;
839 return buf + 1;
840 }
841
842 #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0)
843
844 // ���M���g���C����������
845 //
846 // WinSock�� send() ���o�b�t�@�T�C�Y(len)�������������l��������������������
847 // ���������������A�����������G���[���������B
848 // �����������ATCP�R�l�N�V�������f�������o���h���B
849 // (2006.12.9 yutaka)
850 static int retry_send_packet(PTInstVar pvar, char FAR * data, int len)
851 {
852 int n;
853 int err;
854
855 while (len > 0) {
856 n = (pvar->Psend)(pvar->socket, data, len, 0);
857
858 if (n < 0) {
859 err = WSAGetLastError();
860 if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
861 // send()�����l��0�������A�����G���[������ 10000 �������������A
862 // ���������������������B
863 // PuTTY 0.58���������Q�l�B
864 // (2007.2.4 yutak)
865 return 0; // success
866 }
867 return 1; // error
868 }
869
870 len -= n;
871 data += n;
872 }
873
874 return 0; // success
875 }
876
877 static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
878 {
879 // �p�P�b�g���M�����o�b�t�@���g�������������A�u���b�L���O�����M�����������K�v�������B
880 // �m���u���b�L���O�����M����WSAEWOULDBLOCK�����������������A�����o�b�t�@�����M��������
881 // ���������������������������������B(2007.10.30 yutaka)
882 u_long do_block = 0;
883 int code = 0;
884 char *kind = NULL, buf[256];
885
886 #if 0
887 if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
888 0, 0) == SOCKET_ERROR
889 || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR
890 || retry_send_packet(pvar, data, len)
891 || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
892 pvar->notification_msg,
893 pvar->notification_events) ==
894 SOCKET_ERROR) {
895 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
896 "A communications error occurred while sending an SSH packet.\n"
897 "The connection will close.");
898 notify_fatal_error(pvar, pvar->ts->UIMsg);
899 return FALSE;
900 } else {
901 return TRUE;
902 }
903 #else
904 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 return TRUE;
929
930 error:
931 UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
932 "A communications error occurred while sending an SSH packet.\n"
933 "The connection will close. (%s:%d)");
934 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
935 kind, code);
936 notify_fatal_error(pvar, buf);
937 return FALSE;
938 #endif
939 }
940
941 /* if skip_compress is true, then the data has already been compressed
942 into outbuf + 12 */
943 static void finish_send_packet_special(PTInstVar pvar, int skip_compress)
944 {
945 unsigned int len = pvar->ssh_state.outgoing_packet_len;
946 unsigned char FAR *data;
947 unsigned int data_length;
948 buffer_t *msg = NULL; // for SSH2 packet compression
949
950 if (pvar->ssh_state.compressing) {
951 if (!skip_compress) {
952 buf_ensure_size(&pvar->ssh_state.outbuf,
953 &pvar->ssh_state.outbuflen,
954 (int)(len + (len >> 6) + 50 +
955 CRYPT_get_sender_MAC_size(pvar)));
956 pvar->ssh_state.compress_stream.next_in =
957 pvar->ssh_state.precompress_outbuf;
958 pvar->ssh_state.compress_stream.avail_in = len;
959 pvar->ssh_state.compress_stream.next_out =
960 pvar->ssh_state.outbuf + 12;
961 pvar->ssh_state.compress_stream.avail_out =
962 pvar->ssh_state.outbuflen - 12;
963
964 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
965 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
966 "An error occurred while compressing packet data.\n"
967 "The connection will close.");
968 notify_fatal_error(pvar, pvar->ts->UIMsg);
969 return;
970 }
971 }
972
973 len =
974 pvar->ssh_state.outbuflen - 12 -
975 pvar->ssh_state.compress_stream.avail_out;
976 }
977
978 if (SSHv1(pvar)) {
979 int padding = 8 - ((len + 4) % 8);
980
981 data = pvar->ssh_state.outbuf + 8 - padding;
982 data_length = padding + len + 8;
983
984 set_uint32(data, len + 4);
985 if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
986 CRYPT_set_random_data(pvar, data + 4, padding);
987 } else {
988 memset(data + 4, 0, padding);
989 }
990 set_uint32(data + data_length - 4,
991 do_crc(data + 4, data_length - 8));
992 CRYPT_encrypt(pvar, data + 4, data_length - 4);
993 } else { //for SSH2(yutaka)
994 int block_size = CRYPT_get_encryption_block_size(pvar);
995 unsigned int encryption_size;
996 unsigned int padding;
997 BOOL ret;
998
999 /*
1000 �f�[�^�\��
1001 pvar->ssh_state.outbuf:
1002 offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD
1003 <--ignore---> ^^^^^^^^ <---- payload --->
1004 packet length
1005
1006 ^^padding
1007
1008 <---------------------------->
1009 SSH2 sending data on TCP
1010
1011 NOTE:
1012 payload = type(1) + raw-data
1013 len = ssh_state.outgoing_packet_len = payload size
1014 */
1015 // �p�P�b�g���k���L���������A�p�P�b�g�����k�����������M�p�P�b�g���\�z�����B(2005.7.9 yutaka)
1016 // support of "Compression delayed" (2006.6.23 maya)
1017 if ((pvar->ctos_compression == COMP_ZLIB ||
1018 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
1019 pvar->ssh2_keys[MODE_OUT].comp.enabled) {
1020 // �����o�b�t�@�� packet-length(4) + padding(1) + payload(any) �������B
1021 msg = buffer_init();
1022 if (msg == NULL) {
1023 // TODO: error check
1024 return;
1025 }
1026
1027 // ���k�������w�b�_�������y�C���[�h�����B
1028 buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1)
1029 if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
1030 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1031 "An error occurred while compressing packet data.\n"
1032 "The connection will close.");
1033 notify_fatal_error(pvar, pvar->ts->UIMsg);
1034 return;
1035 }
1036 data = buffer_ptr(msg);
1037 len = buffer_len(msg) - 5; // 'len' is overwritten.
1038
1039 } else {
1040 // �����k
1041 data = pvar->ssh_state.outbuf + 7;
1042
1043 }
1044
1045 // ���M�p�P�b�g�\�z(input parameter: data, len)
1046 if (block_size < 8) {
1047 block_size = 8;
1048 }
1049 #if 0
1050 encryption_size = ((len + 8) / block_size + 1) * block_size;
1051 data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1052
1053 set_uint32(data, encryption_size - 4);
1054 padding = encryption_size - len - 5;
1055 data[4] = (unsigned char) padding;
1056 #else
1057 // �������p�P�b�g�����������������A�T�[�o����"Bad packet length"���������������������������B
1058 // (2007.10.29 yutaka)
1059 encryption_size = 4 + 1 + len;
1060 padding = block_size - (encryption_size % block_size);
1061 if (padding < 4)
1062 padding += block_size;
1063 encryption_size += padding;
1064 set_uint32(data, encryption_size - 4);
1065 data[4] = (unsigned char) padding;
1066 data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1067 #endif
1068 //if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;
1069 CRYPT_set_random_data(pvar, data + 5 + len, padding);
1070 ret = CRYPT_build_sender_MAC(pvar,
1071 pvar->ssh_state.sender_sequence_number,
1072 data, encryption_size,
1073 data + encryption_size);
1074 if (ret == FALSE) { // HMAC��������������������������
1075 data_length = encryption_size;
1076 }
1077
1078 // �p�P�b�g�������������BHMAC���~�������������O�B
1079 CRYPT_encrypt(pvar, data, encryption_size);
1080 }
1081
1082 send_packet_blocking(pvar, data, data_length);
1083
1084 buffer_free(msg);
1085
1086 pvar->ssh_state.sender_sequence_number++;
1087
1088 // ���M�������L�^
1089 pvar->ssh_heartbeat_tick = time(NULL);
1090 }
1091
1092 static void destroy_packet_buf(PTInstVar pvar)
1093 {
1094 memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1095 if (pvar->ssh_state.compressing) {
1096 memset(pvar->ssh_state.precompress_outbuf, 0,
1097 pvar->ssh_state.precompress_outbuflen);
1098 }
1099 }
1100
1101 /* The handlers are added to the queue for each message. When one of the
1102 handlers fires, if it returns FALSE, then all handlers in the set are
1103 removed from their queues. */
1104 static void enque_handlers(PTInstVar pvar, int num_msgs,
1105 const int FAR * messages,
1106 const SSHPacketHandler FAR * handlers)
1107 {
1108 SSHPacketHandlerItem FAR *first_item;
1109 SSHPacketHandlerItem FAR *last_item = NULL;
1110 int i;
1111
1112 for (i = 0; i < num_msgs; i++) {
1113 SSHPacketHandlerItem FAR *item =
1114 (SSHPacketHandlerItem FAR *)
1115 malloc(sizeof(SSHPacketHandlerItem));
1116 SSHPacketHandlerItem FAR *cur_item =
1117 pvar->ssh_state.packet_handlers[messages[i]];
1118
1119 item->handler = handlers[i];
1120
1121 if (cur_item == NULL) {
1122 pvar->ssh_state.packet_handlers[messages[i]] = item;
1123 item->next_for_message = item;
1124 item->last_for_message = item;
1125 item->active_for_message = messages[i];
1126 } else {
1127 item->next_for_message = cur_item;
1128 item->last_for_message = cur_item->last_for_message;
1129 cur_item->last_for_message->next_for_message = item;
1130 cur_item->last_for_message = item;
1131 item->active_for_message = -1;
1132 }
1133
1134 if (last_item != NULL) {
1135 last_item->next_in_set = item;
1136 } else {
1137 first_item = item;
1138 }
1139 last_item = item;
1140 }
1141
1142 if (last_item != NULL) {
1143 last_item->next_in_set = first_item;
1144 }
1145 }
1146
1147 static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1148 {
1149 SSHPacketHandlerItem FAR *cur_item =
1150 pvar->ssh_state.packet_handlers[message];
1151
1152 if (cur_item == NULL) {
1153 return NULL;
1154 } else {
1155 return cur_item->handler;
1156 }
1157 }
1158
1159 /* Called only by SSH_handle_packet */
1160 static void deque_handlers(PTInstVar pvar, int message)
1161 {
1162 SSHPacketHandlerItem FAR *cur_item =
1163 pvar->ssh_state.packet_handlers[message];
1164 SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1165
1166 do {
1167 SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1168
1169 if (cur_item->active_for_message >= 0) {
1170 SSHPacketHandlerItem FAR *replacement =
1171 cur_item->next_for_message;
1172
1173 if (replacement == cur_item) {
1174 replacement = NULL;
1175 } else {
1176 replacement->active_for_message =
1177 cur_item->active_for_message;
1178 }
1179 pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1180 replacement;
1181 }
1182 cur_item->next_for_message->last_for_message =
1183 cur_item->last_for_message;
1184 cur_item->last_for_message->next_for_message =
1185 cur_item->next_for_message;
1186
1187 free(cur_item);
1188 cur_item = next_in_set;
1189 } while (cur_item != first_item_in_set);
1190 }
1191
1192 static void enque_handler(PTInstVar pvar, int message,
1193 SSHPacketHandler handler)
1194 {
1195 enque_handlers(pvar, 1, &message, &handler);
1196 }
1197
1198 static void chop_newlines(char FAR * buf)
1199 {
1200 int len = strlen(buf);
1201
1202 while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1203 buf[len - 1] = 0;
1204 len--;
1205 }
1206 }
1207
1208 /********************/
1209 /* Message handlers */
1210 /********************/
1211
1212 static BOOL handle_forwarding_success(PTInstVar pvar)
1213 {
1214 return FALSE;
1215 }
1216
1217 static BOOL handle_forwarding_failure(PTInstVar pvar)
1218 {
1219 return FALSE;
1220 }
1221
1222 static void enque_forwarding_request_handlers(PTInstVar pvar)
1223 {
1224 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1225 static const SSHPacketHandler handlers[]
1226 = { handle_forwarding_success, handle_forwarding_failure };
1227
1228 enque_handlers(pvar, 2, msgs, handlers);
1229 }
1230
1231 static BOOL handle_auth_failure(PTInstVar pvar)
1232 {
1233 notify_verbose_message(pvar, "Authentication failed",
1234 LOG_LEVEL_VERBOSE);
1235
1236 // retry count������ (2005.7.15 yutaka)
1237 pvar->userauth_retry_count++;
1238
1239 AUTH_set_generic_mode(pvar);
1240 AUTH_advance_to_next_cred(pvar);
1241 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1242 try_send_credentials(pvar);
1243 return FALSE;
1244 }
1245
1246 static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1247 {
1248 AUTH_destroy_cur_cred(pvar);
1249 return handle_auth_failure(pvar);
1250 }
1251
1252 static BOOL handle_TIS_challenge(PTInstVar pvar)
1253 {
1254 if (grab_payload(pvar, 4)) {
1255 int len = get_payload_uint32(pvar, 0);
1256
1257 if (grab_payload(pvar, len)) {
1258 notify_verbose_message(pvar, "Received TIS challenge",
1259 LOG_LEVEL_VERBOSE);
1260
1261 AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1262 AUTH_advance_to_next_cred(pvar);
1263 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1264 try_send_credentials(pvar);
1265 }
1266 }
1267 return FALSE;
1268 }
1269
1270 static BOOL handle_auth_required(PTInstVar pvar)
1271 {
1272 notify_verbose_message(pvar, "Server requires authentication",
1273 LOG_LEVEL_VERBOSE);
1274
1275 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1276 try_send_credentials(pvar);
1277 /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1278
1279 return FALSE;
1280 }
1281
1282 static BOOL handle_ignore(PTInstVar pvar)
1283 {
1284 if (SSHv1(pvar)) {
1285 if (grab_payload(pvar, 4)
1286 && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1287 /* ignore it! but it must be decompressed */
1288 }
1289 }
1290 /*
1291 else {
1292 // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1293 // Cisco ���[�^���� (2006.11.28 maya)
1294 }
1295 */
1296 return TRUE;
1297 }
1298
1299 static BOOL handle_debug(PTInstVar pvar)
1300 {
1301 BOOL always_display;
1302 char FAR *description;
1303 int description_len;
1304 char buf[2048];
1305
1306 if (SSHv1(pvar)) {
1307 if (grab_payload(pvar, 4)
1308 && grab_payload(pvar, description_len =
1309 get_payload_uint32(pvar, 0))) {
1310 always_display = FALSE;
1311 description = pvar->ssh_state.payload + 4;
1312 description[description_len] = 0;
1313 } else {
1314 return TRUE;
1315 }
1316 } else {
1317 if (grab_payload(pvar, 5)
1318 && grab_payload(pvar,
1319 (description_len = get_payload_uint32(pvar, 1)) + 4)
1320 && grab_payload(pvar,
1321 get_payload_uint32(pvar, 5 + description_len))) {
1322 always_display = pvar->ssh_state.payload[0] != 0;
1323 description = pvar->ssh_state.payload + 5;
1324 description[description_len] = 0;
1325 } else {
1326 return TRUE;
1327 }
1328 }
1329
1330 chop_newlines(description);
1331 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1332 description);
1333 if (always_display) {
1334 notify_nonfatal_error(pvar, buf);
1335 } else {
1336 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1337 }
1338 return TRUE;
1339 }
1340
1341 static BOOL handle_disconnect(PTInstVar pvar)
1342 {
1343 int reason_code;
1344 char FAR *description;
1345 int description_len;
1346 char buf[2048];
1347 char FAR *explanation = "";
1348 char uimsg[MAX_UIMSG];
1349
1350 if (SSHv1(pvar)) {
1351 if (grab_payload(pvar, 4)
1352 && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1353 reason_code = -1;
1354 description = pvar->ssh_state.payload + 4;
1355 description[description_len] = 0;
1356 } else {
1357 return TRUE;
1358 }
1359 } else {
1360 if (grab_payload(pvar, 8)
1361 && grab_payload(pvar,
1362 (description_len = get_payload_uint32(pvar, 4)) + 4)
1363 && grab_payload(pvar,
1364 get_payload_uint32(pvar, 8 + description_len))) {
1365 reason_code = get_payload_uint32(pvar, 0);
1366 description = pvar->ssh_state.payload + 8;
1367 description[description_len] = 0;
1368 } else {
1369 return TRUE;
1370 }
1371 }
1372
1373 chop_newlines(description);
1374 if (description[0] == 0) {
1375 description = NULL;
1376 }
1377
1378 if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1379 UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1380 "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1381 "This often happens when someone is already forwarding that port from the server.");
1382 strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1383 explanation = uimsg;
1384 }
1385
1386 if (description != NULL) {
1387 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1388 "Server disconnected with message '%s'%s");
1389 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1390 pvar->ts->UIMsg, description,
1391 explanation);
1392 } else {
1393 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1394 "Server disconnected (no reason given).%s");
1395 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1396 pvar->ts->UIMsg, explanation);
1397 }
1398 notify_fatal_error(pvar, buf);
1399
1400 return TRUE;
1401 }
1402
1403 static BOOL handle_unimplemented(PTInstVar pvar)
1404 {
1405 /* Should never receive this since we only send base 2.0 protocol messages */
1406 grab_payload(pvar, 4);
1407 return TRUE;
1408 }
1409
1410 static BOOL handle_crypt_success(PTInstVar pvar)
1411 {
1412 notify_verbose_message(pvar, "Secure mode successfully achieved",
1413 LOG_LEVEL_VERBOSE);
1414 return FALSE;
1415 }
1416
1417 static BOOL handle_noauth_success(PTInstVar pvar)
1418 {
1419 notify_verbose_message(pvar, "Server does not require authentication",
1420 LOG_LEVEL_VERBOSE);
1421 prep_compression(pvar);
1422 return FALSE;
1423 }
1424
1425 static BOOL handle_auth_success(PTInstVar pvar)
1426 {
1427 notify_verbose_message(pvar, "Authentication accepted",
1428 LOG_LEVEL_VERBOSE);
1429 prep_compression(pvar);
1430
1431 // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1432 start_ssh_heartbeat_thread(pvar);
1433
1434 return FALSE;
1435 }
1436
1437 static BOOL handle_server_public_key(PTInstVar pvar)
1438 {
1439 int server_key_public_exponent_len;
1440 int server_key_public_modulus_pos;
1441 int server_key_public_modulus_len;
1442 int host_key_bits_pos;
1443 int host_key_public_exponent_len;
1444 int host_key_public_modulus_pos;
1445 int host_key_public_modulus_len;
1446 int protocol_flags_pos;
1447 int supported_ciphers;
1448 char FAR *inmsg;
1449 Key hostkey;
1450
1451 if (!grab_payload(pvar, 14))
1452 return FALSE;
1453 server_key_public_exponent_len = get_mpint_len(pvar, 12);
1454
1455 if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1456 return FALSE;
1457 server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1458 server_key_public_modulus_len =
1459 get_mpint_len(pvar, server_key_public_modulus_pos);
1460
1461 if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1462 return FALSE;
1463 host_key_bits_pos =
1464 server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1465 host_key_public_exponent_len =
1466 get_mpint_len(pvar, host_key_bits_pos + 4);
1467
1468 if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1469 return FALSE;
1470 host_key_public_modulus_pos =
1471 host_key_bits_pos + 6 + host_key_public_exponent_len;
1472 host_key_public_modulus_len =
1473 get_mpint_len(pvar, host_key_public_modulus_pos);
1474
1475 if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1476 return FALSE;
1477 protocol_flags_pos =
1478 host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1479
1480 inmsg = pvar->ssh_state.payload;
1481
1482 CRYPT_set_server_cookie(pvar, inmsg);
1483 if (!CRYPT_set_server_RSA_key(pvar,
1484 get_uint32(inmsg + 8),
1485 pvar->ssh_state.payload + 12,
1486 inmsg + server_key_public_modulus_pos))
1487 return FALSE;
1488 if (!CRYPT_set_host_RSA_key(pvar,
1489 get_uint32(inmsg + host_key_bits_pos),
1490 inmsg + host_key_bits_pos + 4,
1491 inmsg + host_key_public_modulus_pos))
1492 return FALSE;
1493 pvar->ssh_state.server_protocol_flags =
1494 get_uint32(inmsg + protocol_flags_pos);
1495
1496 supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1497 if (!CRYPT_set_supported_ciphers(pvar,
1498 supported_ciphers,
1499 supported_ciphers))
1500 return FALSE;
1501 if (!AUTH_set_supported_auth_types(pvar,
1502 get_uint32(inmsg + protocol_flags_pos + 8)))
1503 return FALSE;
1504
1505 /* this must be the LAST THING in this function, since it can cause
1506 host_is_OK to be called. */
1507 hostkey.type = KEY_RSA1;
1508 hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1509 hostkey.exp = inmsg + host_key_bits_pos + 4;
1510 hostkey.mod = inmsg + host_key_public_modulus_pos;
1511 HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, &hostkey);
1512
1513 return FALSE;
1514 }
1515
1516 /*
1517 The ID must have already been found to start with "SSH-". It must
1518 be null-terminated.
1519 */
1520 static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1521 {
1522 char FAR *str;
1523
1524 for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1525 }
1526
1527 if (*str != '.') {
1528 return FALSE;
1529 }
1530
1531 pvar->protocol_major = atoi(ID + 4);
1532 pvar->protocol_minor = atoi(str + 1);
1533
1534 // for SSH2(yutaka)
1535 // 1.99����SSH2�����������s��
1536 if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
1537 // ���[�U�� SSH2 ���I������������������
1538 if (pvar->settings.ssh_protocol_version == 2) {
1539 pvar->protocol_major = 2;
1540 pvar->protocol_minor = 0;
1541 }
1542
1543 }
1544
1545 for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1546 }
1547
1548 return *str == '-';
1549 }
1550
1551 /*
1552 On entry, the pvar->protocol_xxx fields hold the server's advertised
1553 protocol number. We replace the fields with the protocol number we will
1554 actually use, or return FALSE if there is no usable protocol version.
1555 */
1556 static BOOL negotiate_protocol(PTInstVar pvar)
1557 {
1558 switch (pvar->protocol_major) {
1559 case 1:
1560 if (pvar->protocol_minor > 5) {
1561 pvar->protocol_minor = 5;
1562 }
1563
1564 return TRUE;
1565
1566 // for SSH2(yutaka)
1567 case 2:
1568 return TRUE; // SSH2 support
1569
1570 default:
1571 return FALSE;
1572 }
1573 }
1574
1575 static void init_protocol(PTInstVar pvar)
1576 {
1577 CRYPT_initialize_random_numbers(pvar);
1578
1579 // known_hosts�t�@�C�������z�X�g���J������������������
1580 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname);
1581
1582 /* while we wait for a response from the server... */
1583
1584 if (SSHv1(pvar)) {
1585 enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1586 enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1587 enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1588 enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1589
1590 } else { // for SSH2(yutaka)
1591 enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1592 enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1593 enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1594 enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1595 enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1596 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1597 enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1598 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1599 enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_authrequest);
1600 enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1601 enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1602 enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1603 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1604
1605 enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1606
1607 // ���[�U�F�������f�B�X�p�b�`���[�`��
1608 enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1609 enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1610 enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1611 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1612 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1613 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1614 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1615 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1616 enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1617 enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1618 // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1619 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1620 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1621
1622 }
1623 }
1624
1625 BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1626 {
1627 static const char prefix[] = "Received server prologue string: ";
1628
1629 // initialize SSH2 memory dump (2005.3.7 yutaka)
1630 init_memdump();
1631 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1632
1633 if (ID_len <= 0) {
1634 return FALSE;
1635 } else {
1636 int buf_len = ID_len + NUM_ELEM(prefix);
1637 char FAR *buf = (char FAR *) malloc(buf_len);
1638
1639 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1640 strncat_s(buf, buf_len, ID, _TRUNCATE);
1641 chop_newlines(buf);
1642
1643 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1644
1645 free(buf);
1646
1647
1648 // ���������R�s�[������ (2005.3.9 yutaka)
1649 #if 0
1650 // for calculate SSH2 hash
1651 // �T�[�o�o�[�W�����������i���s���������������j
1652 if (ID_len >= sizeof(pvar->server_version_string))
1653 return FALSE;
1654 strncpy(pvar->server_version_string, ID, ID_len);
1655 #endif
1656
1657
1658 if (ID[ID_len - 1] != '\n') {
1659 pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1660 return FALSE;
1661 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1662 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1663 return FALSE;
1664 } else if (strncmp(ID, "SSH-", 4) != 0) {
1665 return FALSE;
1666 } else {
1667 ID[ID_len - 1] = 0;
1668
1669 if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1670 ID[ID_len - 2] = 0;
1671 }
1672
1673 pvar->ssh_state.server_ID = _strdup(ID);
1674
1675 if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1676 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1677 "This program does not understand the server's version of the protocol.");
1678 notify_fatal_error(pvar, pvar->ts->UIMsg);
1679 } else {
1680 char TTSSH_ID[1024];
1681 int TTSSH_ID_len;
1682 int a, b, c, d;
1683
1684 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1685 get_file_version("ttxssh.dll", &a, &b, &c, &d);
1686
1687 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1688 "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1689 pvar->protocol_major, pvar->protocol_minor, a, b);
1690 TTSSH_ID_len = strlen(TTSSH_ID);
1691
1692 // for SSH2(yutaka)
1693 // �N���C�A���g�o�[�W�����������i���s���������������j
1694 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1695 TTSSH_ID, _TRUNCATE);
1696
1697 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1698 _snprintf_s(pvar->server_version_string,
1699 sizeof(pvar->server_version_string), _TRUNCATE,
1700 "%s", pvar->ssh_state.server_ID);
1701
1702 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1703 0) != TTSSH_ID_len) {
1704 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1705 "An error occurred while sending the SSH ID string.\n"
1706 "The connection will close.");
1707 notify_fatal_error(pvar, pvar->ts->UIMsg);
1708 } else {
1709 // ���s�R�[�h������ (2004.8.4 yutaka)
1710 pvar->client_version_string[--TTSSH_ID_len] = 0;
1711
1712 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1713 push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1714
1715 // SSH�n���h�����o�^���s��
1716 init_protocol(pvar);
1717
1718 SSH2_dispatch_init(1);
1719 SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1720 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1721 }
1722 }
1723
1724 return TRUE;
1725 }
1726 }
1727 }
1728
1729 static BOOL handle_exit(PTInstVar pvar)
1730 {
1731 if (grab_payload(pvar, 4)) {
1732 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1733 finish_send_packet(pvar);
1734 notify_closed_connection(pvar);
1735 }
1736 return TRUE;
1737 }
1738
1739 static BOOL handle_data(PTInstVar pvar)
1740 {
1741 if (grab_payload_limited(pvar, 4)) {
1742 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1743 pvar->ssh_state.payload_datastart = 4;
1744 }
1745 return TRUE;
1746 }
1747
1748 static BOOL handle_channel_open(PTInstVar pvar)
1749 {
1750 int host_len;
1751 int originator_len;
1752
1753 if ((pvar->ssh_state.
1754 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1755 if (grab_payload(pvar, 8)
1756 && grab_payload(pvar,
1757 8 + (host_len = get_payload_uint32(pvar, 4)))
1758 && grab_payload(pvar, originator_len =
1759 get_payload_uint32(pvar, host_len + 12))) {
1760 int local_port = get_payload_uint32(pvar, 8 + host_len);
1761
1762 pvar->ssh_state.payload[8 + host_len] = 0;
1763 FWD_open(pvar, get_payload_uint32(pvar, 0),
1764 pvar->ssh_state.payload + 8, local_port,
1765 pvar->ssh_state.payload + 16 + host_len,
1766 originator_len,
1767 NULL);
1768 }
1769 } else {
1770 if (grab_payload(pvar, 8)
1771 && grab_payload(pvar,
1772 4 + (host_len = get_payload_uint32(pvar, 4)))) {
1773 int local_port = get_payload_uint32(pvar, 8 + host_len);
1774
1775 pvar->ssh_state.payload[8 + host_len] = 0;
1776 FWD_open(pvar, get_payload_uint32(pvar, 0),
1777 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1778 NULL);
1779 }
1780 }
1781
1782 return TRUE;
1783 }
1784
1785 static BOOL handle_X11_channel_open(PTInstVar pvar)
1786 {
1787 int originator_len;
1788
1789 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1790 if (grab_payload(pvar, 8)
1791 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1792 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1793 pvar->ssh_state.payload + 8, originator_len, NULL);
1794 }
1795 } else {
1796 if (grab_payload(pvar, 4)) {
1797 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1798 }
1799 }
1800
1801 return TRUE;
1802 }
1803
1804 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1805 {
1806 if (grab_payload(pvar, 8)) {
1807 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1808 get_payload_uint32(pvar, 4));
1809 }
1810 return FALSE;
1811 }
1812
1813 static BOOL handle_channel_open_failure(PTInstVar pvar)
1814 {
1815 if (grab_payload(pvar, 4)) {
1816 FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1817 }
1818 return FALSE;
1819 }
1820
1821 static BOOL handle_channel_data(PTInstVar pvar)
1822 {
1823 int len;
1824
1825 if (grab_payload(pvar, 8)
1826 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1827 FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1828 pvar->ssh_state.payload + 8, len);
1829 }
1830 return TRUE;
1831 }
1832
1833 static BOOL handle_channel_input_eof(PTInstVar pvar)
1834 {
1835 if (grab_payload(pvar, 4)) {
1836 FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1837 }
1838 return TRUE;
1839 }
1840
1841 static BOOL handle_channel_output_eof(PTInstVar pvar)
1842 {
1843 if (grab_payload(pvar, 4)) {
1844 FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1845 }
1846 return TRUE;
1847 }
1848
1849
1850
1851 // �n���h�����O�������b�Z�[�W����������
1852
1853 #define HANDLE_MESSAGE_MAX 30
1854 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1855 static int handle_message_count = 0;
1856 static int handle_message_stage = 0;
1857
1858 void SSH2_dispatch_init(int stage)
1859 {
1860 handle_message_count = 0;
1861 handle_message_stage = stage;
1862 }
1863
1864 int SSH2_dispatch_enabled_check(unsigned char message)
1865 {
1866 int i;
1867
1868 for (i = 0 ; i < handle_message_count ; i++) {
1869 if (handle_messages[i] == message)
1870 return 1;
1871 }
1872 return 0;
1873 }
1874
1875 void SSH2_dispatch_add_message(unsigned char message)
1876 {
1877
1878 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1879 // TODO: error check
1880 return;
1881 }
1882
1883 handle_messages[handle_message_count++] = message;
1884 }
1885
1886 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1887 {
1888 unsigned char c;
1889
1890 for (c = begin ; c <= end ; c++) {
1891 SSH2_dispatch_add_message(c);
1892 }
1893 }
1894
1895
1896 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1897 int padding)
1898 {
1899 unsigned char message = prep_packet(pvar, data, len, padding);
1900
1901
1902 #ifdef SSH2_DEBUG
1903 // for SSH2(yutaka)
1904 if (SSHv2(pvar)) {
1905 if (pvar->key_done) {
1906 message = message;
1907 }
1908
1909 if (pvar->userauth_success) {
1910 message = message;
1911 }
1912
1913 if (pvar->rekeying) {
1914 message = message;
1915 }
1916 }
1917 #endif
1918
1919 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1920 if (message != SSH_MSG_NONE) {
1921 // ���b�Z�[�W�^�C�v���������n���h�����N��
1922 SSHPacketHandler handler = get_handler(pvar, message);
1923
1924 // for SSH2(yutaka)
1925 if (SSHv2(pvar)) {
1926 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1927 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1928 char buf[1024];
1929
1930 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
1931 "Unexpected SSH2 message(%d) on current stage(%d)");
1932 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1933 pvar->ts->UIMsg, message, handle_message_stage);
1934 notify_fatal_error(pvar, buf);
1935 // abort
1936 }
1937 }
1938
1939 if (handler == NULL) {
1940 if (SSHv1(pvar)) {
1941 char buf[1024];
1942
1943 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
1944 "Unexpected packet type received: %d");
1945 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1946 pvar->ts->UIMsg, message, handle_message_stage);
1947 notify_fatal_error(pvar, buf);
1948 } else {
1949 unsigned char FAR *outmsg =
1950 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
1951
1952 set_uint32(outmsg,
1953 pvar->ssh_state.receiver_sequence_number - 1);
1954 finish_send_packet(pvar);
1955 /* XXX need to decompress incoming packet, but how? */
1956 }
1957 } else {
1958 if (!handler(pvar)) {
1959 deque_handlers(pvar, message);
1960 }
1961 }
1962 }
1963 }
1964
1965 static BOOL handle_pty_success(PTInstVar pvar)
1966 {
1967 FWD_enter_interactive_mode(pvar);
1968 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
1969 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
1970 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
1971 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
1972 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
1973 handle_channel_input_eof);
1974 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
1975 handle_channel_output_eof);
1976 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
1977 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
1978 return FALSE;
1979 }
1980
1981 static BOOL handle_pty_failure(PTInstVar pvar)
1982 {
1983 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
1984 "The server cannot allocate a pseudo-terminal. "
1985 "You may encounter some problems with the terminal.");
1986 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1987 return handle_pty_success(pvar);
1988 }
1989
1990 static void prep_pty(PTInstVar pvar)
1991 {
1992 int len = strlen(pvar->ts->TermType);
1993 unsigned char FAR *outmsg =
1994 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
1995 4 + len + 16 + sizeof(ssh_ttymodes));
1996 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1997 static const SSHPacketHandler handlers[]
1998 = { handle_pty_success, handle_pty_failure };
1999
2000 set_uint32(outmsg, len);
2001 memcpy(outmsg + 4, pvar->ts->TermType, len);
2002 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2003 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2004 set_uint32(outmsg + 4 + len + 8, 0);
2005 set_uint32(outmsg + 4 + len + 12, 0);
2006 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2007 finish_send_packet(pvar);
2008
2009 enque_handlers(pvar, 2, msgs, handlers);
2010
2011 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2012 finish_send_packet(pvar);
2013 }
2014
2015 static void prep_forwarding(PTInstVar pvar)
2016 {
2017 FWD_prep_forwarding(pvar);
2018 prep_pty(pvar);
2019 }
2020
2021
2022 //
2023 //
2024 // (2005.7.10 yutaka)
2025 static void enable_send_compression(PTInstVar pvar)
2026 {
2027 static int initialize = 0;
2028
2029 if (initialize) {
2030 deflateEnd(&pvar->ssh_state.compress_stream);
2031 }
2032 initialize = 1;
2033
2034 pvar->ssh_state.compress_stream.zalloc = NULL;
2035 pvar->ssh_state.compress_stream.zfree = NULL;
2036 pvar->ssh_state.compress_stream.opaque = NULL;
2037 if (deflateInit
2038 (&pvar->ssh_state.compress_stream,
2039 pvar->ssh_state.compression_level) != Z_OK) {
2040 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2041 "An error occurred while setting up compression.\n"
2042 "The connection will close.");
2043 notify_fatal_error(pvar, pvar->ts->UIMsg);
2044 return;
2045 } else {
2046 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2047 if (SSHv2(pvar)) {
2048 pvar->ssh_state.compressing = FALSE;
2049 } else {
2050 pvar->ssh_state.compressing = TRUE;
2051 }
2052 }
2053 }
2054
2055 static void enable_recv_compression(PTInstVar pvar)
2056 {
2057 static int initialize = 0;
2058
2059 if (initialize) {
2060 deflateEnd(&pvar->ssh_state.decompress_stream);
2061 }
2062 initialize = 1;
2063
2064 pvar->ssh_state.decompress_stream.zalloc = NULL;
2065 pvar->ssh_state.decompress_stream.zfree = NULL;
2066 pvar->ssh_state.decompress_stream.opaque = NULL;
2067 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2068 deflateEnd(&pvar->ssh_state.compress_stream);
2069 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2070 "An error occurred while setting up compression.\n"
2071 "The connection will close.");
2072 notify_fatal_error(pvar, pvar->ts->UIMsg);
2073 return;
2074 } else {
2075 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2076 if (SSHv2(pvar)) {
2077 pvar->ssh_state.decompressing = FALSE;
2078 } else {
2079 pvar->ssh_state.decompressing = TRUE;
2080 }
2081
2082 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2083 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2084 }
2085 }
2086
2087 static void enable_compression(PTInstVar pvar)
2088 {
2089 enable_send_compression(pvar);
2090 enable_recv_compression(pvar);
2091
2092 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2093 if (SSHv2(pvar)) {
2094 pvar->ssh_state.compressing = FALSE;
2095 pvar->ssh_state.decompressing = FALSE;
2096 }
2097
2098 }
2099
2100 static BOOL handle_enable_compression(PTInstVar pvar)
2101 {
2102 enable_compression(pvar);
2103 prep_forwarding(pvar);
2104 return FALSE;
2105 }
2106
2107 static BOOL handle_disable_compression(PTInstVar pvar)
2108 {
2109 prep_forwarding(pvar);
2110 return FALSE;
2111 }
2112
2113 static void prep_compression(PTInstVar pvar)
2114 {
2115 if (pvar->session_settings.CompressionLevel > 0) {
2116 // added if statement (2005.7.10 yutaka)
2117 if (SSHv1(pvar)) {
2118 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2119 static const SSHPacketHandler handlers[]
2120 = { handle_enable_compression, handle_disable_compression };
2121
2122 unsigned char FAR *outmsg =
2123 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2124
2125 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2126 finish_send_packet(pvar);
2127
2128 enque_handlers(pvar, 2, msgs, handlers);
2129 }
2130
2131 pvar->ssh_state.compression_level =
2132 pvar->session_settings.CompressionLevel;
2133
2134 } else {
2135 // added if statement (2005.7.10 yutaka)
2136 if (SSHv1(pvar)) {
2137 prep_forwarding(pvar);
2138 }
2139 }
2140 }
2141
2142 static void enque_simple_auth_handlers(PTInstVar pvar)
2143 {
2144 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2145 static const SSHPacketHandler handlers[]
2146 = { handle_auth_success, handle_auth_failure };
2147
2148 enque_handlers(pvar, 2, msgs, handlers);
2149 }
2150
2151 static BOOL handle_rsa_challenge(PTInstVar pvar)
2152 {
2153 int challenge_bytes;
2154
2155 if (!grab_payload(pvar, 2)) {
2156 return FALSE;
2157 }
2158
2159 challenge_bytes = get_mpint_len(pvar, 0);
2160
2161 if (grab_payload(pvar, challenge_bytes)) {
2162 unsigned char FAR *outmsg =
2163 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2164
2165 if (CRYPT_generate_RSA_challenge_response
2166 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2167
2168 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2169 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2170 #if 0
2171 //AUTH_destroy_cur_cred(pvar);
2172 #endif
2173
2174 finish_send_packet(pvar);
2175
2176 enque_simple_auth_handlers(pvar);
2177 } else {
2178 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2179 "An error occurred while decrypting the RSA challenge.\n"
2180 "Perhaps the key file is corrupted.");
2181 notify_fatal_error(pvar, pvar->ts->UIMsg);
2182 }
2183 }
2184
2185 return FALSE;
2186 }
2187
2188 #define OBFUSCATING_ROUND_TO 32
2189
2190 static int obfuscating_round_up(PTInstVar pvar, int size)
2191 {
2192 return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2193 }
2194
2195 static void try_send_credentials(PTInstVar pvar)
2196 {
2197 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2198 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2199 static const int RSA_msgs[] =
2200 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2201 static const SSHPacketHandler RSA_handlers[]
2202 = { handle_rsa_challenge, handle_rsa_auth_refused };
2203 static const int TIS_msgs[] =
2204 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2205 static const SSHPacketHandler TIS_handlers[]
2206 = { handle_TIS_challenge, handle_auth_failure };
2207
2208 // SSH2���������������������X�L�b�v
2209 if (SSHv2(pvar))
2210 goto skip_ssh2;
2211
2212 switch (cred->method) {
2213 case SSH_AUTH_NONE:
2214 return;
2215 case SSH_AUTH_PASSWORD:{
2216 int len = strlen(cred->password);
2217 // Round up password length to discourage traffic analysis
2218 int obfuscated_len = obfuscating_round_up(pvar, len);
2219 unsigned char FAR *outmsg =
2220 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2221 4 + obfuscated_len);
2222
2223 notify_verbose_message(pvar,
2224 "Trying PASSWORD authentication...",
2225 LOG_LEVEL_VERBOSE);
2226
2227 set_uint32(outmsg, obfuscated_len);
2228 memcpy(outmsg + 4, cred->password, len);
2229 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2230
2231 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2232 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2233 #if 0
2234 //AUTH_destroy_cur_cred(pvar);
2235 #endif
2236
2237 enque_simple_auth_handlers(pvar);
2238 break;
2239 }
2240 case SSH_AUTH_RHOSTS:{
2241 int len = strlen(cred->rhosts_client_user);
2242 unsigned char FAR *outmsg =
2243 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2244
2245 notify_verbose_message(pvar,
2246 "Trying RHOSTS authentication...",
2247 LOG_LEVEL_VERBOSE);
2248
2249 set_uint32(outmsg, len);
2250 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2251 AUTH_destroy_cur_cred(pvar);
2252 enque_simple_auth_handlers(pvar);
2253 break;
2254 }
2255 case SSH_AUTH_RSA:{
2256 int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2257 unsigned char FAR *outmsg =
2258 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2259
2260 notify_verbose_message(pvar,
2261 "Trying RSA authentication...",
2262 LOG_LEVEL_VERBOSE);
2263
2264 set_ushort16_MSBfirst(outmsg, len * 8);
2265 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2266 /* don't destroy the current credentials yet */
2267 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2268 break;
2269 }
2270 case SSH_AUTH_RHOSTS_RSA:{
2271 int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2272 int name_len = strlen(cred->rhosts_client_user);
2273 int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2274 int index;
2275 unsigned char FAR *outmsg =
2276 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2277 12 + mod_len + name_len + exp_len);
2278
2279 notify_verbose_message(pvar,
2280 "Trying RHOSTS+RSA authentication...",
2281 LOG_LEVEL_VERBOSE);
2282
2283 set_uint32(outmsg, name_len);
2284 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2285 index = 4 + name_len;
2286
2287 set_uint32(outmsg + index, 8 * mod_len);
2288 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2289 BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2290 index += 6 + exp_len;
2291
2292 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2293 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2294 /* don't destroy the current credentials yet */
2295 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2296 break;
2297 }
2298 case SSH_AUTH_TIS:{
2299 if (cred->password == NULL) {
2300 unsigned char FAR *outmsg =
2301 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2302
2303 notify_verbose_message(pvar,
2304 "Trying TIS authentication...",
2305 LOG_LEVEL_VERBOSE);
2306 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2307 } else {
2308 int len = strlen(cred->password);
2309 int obfuscated_len = obfuscating_round_up(pvar, len);
2310 unsigned char FAR *outmsg =
2311 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2312 4 + obfuscated_len);
2313
2314 notify_verbose_message(pvar, "Sending TIS response",
2315 LOG_LEVEL_VERBOSE);
2316
2317 set_uint32(outmsg, obfuscated_len);
2318 memcpy(outmsg + 4, cred->password, len);
2319 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2320 enque_simple_auth_handlers(pvar);
2321 }
2322
2323 AUTH_destroy_cur_cred(pvar);
2324 break;
2325 }
2326 default:
2327 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2328 "Internal error: unsupported authentication method");
2329 notify_fatal_error(pvar, pvar->ts->UIMsg);
2330 return;
2331 }
2332
2333 finish_send_packet(pvar);
2334
2335 skip_ssh2:;
2336 destroy_packet_buf(pvar);
2337
2338 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2339 }
2340 }
2341
2342 static void try_send_user_name(PTInstVar pvar)
2343 {
2344 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2345 char FAR *username = AUTH_get_user_name(pvar);
2346
2347 if (username != NULL) {
2348 int len = strlen(username);
2349 int obfuscated_len = obfuscating_round_up(pvar, len);
2350 unsigned char FAR *outmsg =
2351 begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
2352 char buf[1024] = "Sending user name: ";
2353 static const int msgs[] =
2354 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2355 static const SSHPacketHandler handlers[]
2356 = { handle_noauth_success, handle_auth_required };
2357
2358 set_uint32(outmsg, obfuscated_len);
2359 memcpy(outmsg + 4, username, len);
2360 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2361 finish_send_packet(pvar);
2362
2363 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2364
2365 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2366 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2367
2368 enque_handlers(pvar, 2, msgs, handlers);
2369 }
2370 }
2371 }
2372
2373 static void send_session_key(PTInstVar pvar)
2374 {
2375 int encrypted_session_key_len;
2376 unsigned char FAR *outmsg;
2377
2378 if (SSHv1(pvar)) {
2379 encrypted_session_key_len =
2380 CRYPT_get_encrypted_session_key_len(pvar);
2381 }
2382
2383 if (!CRYPT_choose_ciphers(pvar))
2384 return;
2385
2386 if (SSHv1(pvar)) {
2387 outmsg =
2388 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2389 15 + encrypted_session_key_len);
2390 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2391 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2392 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2393 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2394 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2395 return;
2396 set_uint32(outmsg + 11 + encrypted_session_key_len,
2397 SSH_PROTOFLAG_SCREEN_NUMBER |
2398 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2399 finish_send_packet(pvar);
2400 }
2401
2402 if (!CRYPT_start_encryption(pvar, 1, 1))
2403 return;
2404 notify_established_secure_connection(pvar);
2405
2406 if (SSHv1(pvar)) {
2407 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2408 }
2409
2410 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2411
2412 if (SSHv1(pvar)) {
2413 try_send_user_name(pvar);
2414 }
2415 }
2416
2417 /*************************
2418 END of message handlers
2419 ************************/
2420
2421 void SSH_init(PTInstVar pvar)
2422 {
2423 int i;
2424
2425 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2426 buf_create(&pvar->ssh_state.precompress_outbuf,
2427 &pvar->ssh_state.precompress_outbuflen);
2428 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2429 &pvar->ssh_state.postdecompress_inbuflen);
2430 pvar->ssh_state.payload = NULL;
2431 pvar->ssh_state.compressing = FALSE;
2432 pvar->ssh_state.decompressing = FALSE;
2433 pvar->ssh_state.status_flags =
2434 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2435 pvar->ssh_state.payload_datalen = 0;
2436 pvar->ssh_state.hostname = NULL;
2437 pvar->ssh_state.server_ID = NULL;
2438 pvar->ssh_state.receiver_sequence_number = 0;
2439 pvar->ssh_state.sender_sequence_number = 0;
2440 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2441 pvar->ssh_state.packet_handlers[i] = NULL;
2442 }
2443
2444 // for SSH2(yutaka)
2445 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2446 pvar->userauth_success = 0;
2447 pvar->session_nego_status = 0;
2448 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2449 pvar->rekeying = 0;
2450 pvar->key_done = 0;
2451 pvar->ssh2_autologin = 0; // autologin disabled(default)
2452 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2453 pvar->userauth_retry_count = 0;
2454 pvar->decomp_buffer = NULL;
2455 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2456 pvar->tryed_ssh2_authlist = FALSE;
2457
2458 }
2459
2460 void SSH_open(PTInstVar pvar)
2461 {
2462 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2463 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2464 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2465 }
2466
2467 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2468 {
2469 if (SSHv1(pvar)) {
2470 int len = reason == NULL ? 0 : strlen(reason);
2471 unsigned char FAR *outmsg =
2472 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2473
2474 set_uint32(outmsg, len);
2475 if (reason != NULL) {
2476 memcpy(outmsg + 4, reason, len);
2477 }
2478 finish_send_packet(pvar);
2479
2480 } else { // for SSH2(yutaka)
2481 buffer_t *msg;
2482 unsigned char *outmsg;
2483 int len;
2484 Channel_t *c;
2485
2486 c = ssh2_channel_lookup(pvar->shell_id);
2487 if (c == NULL)
2488 return;
2489
2490 // SSH2 server��channel close���`����
2491 msg = buffer_init();
2492 if (msg == NULL) {
2493 // TODO: error check
2494 return;
2495 }
2496 buffer_put_int(msg, c->remote_id);
2497
2498 len = buffer_len(msg);
2499 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2500 memcpy(outmsg, buffer_ptr(msg), len);
2501 finish_send_packet(pvar);
2502 buffer_free(msg);
2503
2504 }
2505
2506 }
2507
2508 void SSH_notify_host_OK(PTInstVar pvar)
2509 {
2510 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2511 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2512 send_session_key(pvar);
2513 }
2514 }
2515
2516 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2517 {
2518 pvar->ssh_state.win_cols = cols;
2519 pvar->ssh_state.win_rows = rows;
2520
2521 if (SSHv1(pvar)) {
2522 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2523 unsigned char FAR *outmsg =
2524 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2525
2526 set_uint32(outmsg, rows);
2527 set_uint32(outmsg + 4, cols);
2528 set_uint32(outmsg + 8, 0);
2529 set_uint32(outmsg + 12, 0);
2530 finish_send_packet(pvar);
2531 }
2532
2533 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2534 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2535 buffer_t *msg;
2536 char *s;
2537 unsigned char *outmsg;
2538 int len;
2539 Channel_t *c;
2540
2541 c = ssh2_channel_lookup(pvar->shell_id);
2542 if (c == NULL)
2543 return;
2544
2545 msg = buffer_init();
2546 if (msg == NULL) {
2547 // TODO: error check
2548 return;
2549 }
2550 buffer_put_int(msg, c->remote_id);
2551 s = "window-change";
2552 buffer_put_string(msg, s, strlen(s));
2553 buffer_put_char(msg, 0); // wantconfirm
2554 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2555 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2556 buffer_put_int(msg, 480); // XXX:
2557 buffer_put_int(msg, 640); // XXX:
2558 len = buffer_len(msg);
2559 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2560 memcpy(outmsg, buffer_ptr(msg), len);
2561 finish_send_packet(pvar);
2562 buffer_free(msg);
2563
2564 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2565
2566 } else {
2567 // SSH�����������������������B
2568
2569 }
2570
2571 }
2572
2573 int SSH_get_min_packet_size(PTInstVar pvar)
2574 {
2575 if (SSHv1(pvar)) {
2576 return 12;
2577 } else {
2578 int block_size = CRYPT_get_decryption_block_size(pvar);
2579
2580 return max(16, block_size);
2581 }
2582 }
2583
2584 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2585 at least 5 bytes must be decrypted */
2586 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2587 {
2588 if (SSHv2(pvar)) {
2589 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2590 }
2591 }
2592
2593 int SSH_get_clear_MAC_size(PTInstVar pvar)
2594 {
2595 if (SSHv1(pvar)) {
2596 return 0;
2597 } else {
2598 return CRYPT_get_receiver_MAC_size(pvar);
2599 }
2600 }
2601
2602 void SSH_notify_user_name(PTInstVar pvar)
2603 {
2604 try_send_user_name(pvar);
2605 }
2606
2607 void SSH_notify_cred(PTInstVar pvar)
2608 {
2609 try_send_credentials(pvar);
2610 }
2611
2612 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, unsigned int buflen)
2613 {
2614 if (SSHv1(pvar)) {
2615 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2616 return;
2617 }
2618
2619 while (buflen > 0) {
2620 int len =
2621 buflen >
2622 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2623 unsigned char FAR *outmsg =
2624 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2625
2626 set_uint32(outmsg, len);
2627
2628 if (pvar->ssh_state.compressing) {
2629 buf_ensure_size(&pvar->ssh_state.outbuf,
2630 &pvar->ssh_state.outbuflen,
2631 len + (len >> 6) + 50);
2632 pvar->ssh_state.compress_stream.next_in =
2633 pvar->ssh_state.precompress_outbuf;
2634 pvar->ssh_state.compress_stream.avail_in = 5;
2635 pvar->ssh_state.compress_stream.next_out =
2636 pvar->ssh_state.outbuf + 12;
2637 pvar->ssh_state.compress_stream.avail_out =
2638 pvar->ssh_state.outbuflen - 12;
2639
2640 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2641 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2642 "Error compressing packet data");
2643 notify_fatal_error(pvar, pvar->ts->UIMsg);
2644 return;
2645 }
2646
2647 pvar->ssh_state.compress_stream.next_in =
2648 (unsigned char FAR *) buf;
2649 pvar->ssh_state.compress_stream.avail_in = len;
2650
2651 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
2652 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2653 "Error compressing packet data");
2654 notify_fatal_error(pvar, pvar->ts->UIMsg);
2655 return;
2656 }
2657 } else {
2658 memcpy(outmsg + 4, buf, len);
2659 }
2660
2661 finish_send_packet_special(pvar, 1);
2662
2663 buflen -= len;
2664 buf += len;
2665 }
2666
2667 } else { // for SSH2(yutaka)
2668 Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
2669 SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen);
2670 }
2671
2672 }
2673
2674 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
2675 {
2676 int num_bytes = pvar->ssh_state.payload_datalen;
2677
2678 if (num_bytes > len) {
2679 num_bytes = len;
2680 }
2681
2682 if (!pvar->ssh_state.decompressing) {
2683 memcpy(dest,
2684 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
2685 num_bytes);
2686 pvar->ssh_state.payload_datastart += num_bytes;
2687 } else if (num_bytes > 0) {
2688 pvar->ssh_state.decompress_stream.next_out = dest;
2689 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
2690
2691 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
2692 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
2693 "Invalid compressed data in received packet");
2694 notify_fatal_error(pvar, pvar->ts->UIMsg);
2695 return 0;
2696 }
2697 }
2698
2699 pvar->ssh_state.payload_datalen -= num_bytes;
2700
2701 return num_bytes;
2702 }
2703
2704 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
2705 {
2706 char buf[1024];
2707 char buf2[1024];
2708
2709 // added support of SSH2 packet compression (2005.7.10 yutaka)
2710 // support of "Compression delayed" (2006.6.23 maya)
2711 if (pvar->ssh_state.compressing ||
2712 pvar->ctos_compression == COMP_ZLIB ||
2713 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2714 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2715 unsigned long total_out =
2716 pvar->ssh_state.compress_stream.total_out;
2717
2718 if (total_out > 0) {
2719 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2720 "level %d; ratio %.1f (%ld:%ld)");
2721 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2722 pvar->ssh_state.compression_level,
2723 ((double) total_in) / total_out, total_in,
2724 total_out);
2725 } else {
2726 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2727 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2728 pvar->ssh_state.compression_level);
2729 }
2730 } else {
2731 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2732 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2733 }
2734
2735 // support of "Compression delayed" (2006.6.23 maya)
2736 if (pvar->ssh_state.decompressing ||
2737 pvar->stoc_compression == COMP_ZLIB ||
2738 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2739 unsigned long total_in =
2740 pvar->ssh_state.decompress_stream.total_in;
2741 unsigned long total_out =
2742 pvar->ssh_state.decompress_stream.total_out;
2743
2744 if (total_in > 0) {
2745 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2746 "level %d; ratio %.1f (%ld:%ld)");
2747 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2748 pvar->ssh_state.compression_level,
2749 ((double) total_out) / total_in, total_out,
2750 total_in);
2751 } else {
2752 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2753 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2754 pvar->ssh_state.compression_level);
2755 }
2756 } else {
2757 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2758 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2759 }
2760
2761 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
2762 "Upstream %s; Downstream %s");
2763 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
2764 }
2765
2766 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2767 {
2768 strncpy_s(dest, len,
2769 pvar->ssh_state.server_ID == NULL ? "Unknown"
2770 : pvar->ssh_state.server_ID,
2771 _TRUNCATE);
2772 }
2773
2774 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2775 int len)
2776 {
2777 if (pvar->protocol_major == 0) {
2778 strncpy_s(dest, len, "Unknown", _TRUNCATE);
2779 } else {
2780 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
2781 pvar->protocol_minor);
2782 }
2783 }
2784
2785 void SSH_end(PTInstVar pvar)
2786 {
2787 int i;
2788
2789 for (i = 0; i < 256; i++) {
2790 SSHPacketHandlerItem FAR *first_item =
2791 pvar->ssh_state.packet_handlers[i];
2792
2793 if (first_item != NULL) {
2794 SSHPacketHandlerItem FAR *item = first_item;
2795
2796 do {
2797 SSHPacketHandlerItem FAR *cur_item = item;
2798
2799 item = item->next_for_message;
2800 free(cur_item);
2801 } while (item != first_item);
2802 }
2803 pvar->ssh_state.packet_handlers[i] = NULL;
2804 }
2805
2806 free(pvar->ssh_state.hostname);
2807 pvar->ssh_state.hostname = NULL;
2808 free(pvar->ssh_state.server_ID);
2809 pvar->ssh_state.server_ID = NULL;
2810 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2811 buf_destroy(&pvar->ssh_state.precompress_outbuf,
2812 &pvar->ssh_state.precompress_outbuflen);
2813 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2814 &pvar->ssh_state.postdecompress_inbuflen);
2815
2816 // support of "Compression delayed" (2006.6.23 maya)
2817 if (pvar->ssh_state.compressing ||
2818 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2819 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2820 deflateEnd(&pvar->ssh_state.compress_stream);
2821 pvar->ssh_state.compressing = FALSE;
2822 }
2823 // support of "Compression delayed" (2006.6.23 maya)
2824 if (pvar->ssh_state.decompressing ||
2825 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2826 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2827 inflateEnd(&pvar->ssh_state.decompress_stream);
2828 pvar->ssh_state.decompressing = FALSE;
2829 }
2830
2831 #if 1
2832 // SSH2���f�[�^���������� (2004.12.27 yutaka)
2833 if (SSHv2(pvar)) {
2834 if (pvar->kexdh) {
2835 DH_free(pvar->kexdh);
2836 pvar->kexdh = NULL;
2837 }
2838 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
2839 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
2840
2841 if (pvar->my_kex != NULL) {
2842 buffer_free(pvar->my_kex);
2843 pvar->my_kex = NULL;
2844 }
2845 if (pvar->peer_kex != NULL) {
2846 buffer_free(pvar->peer_kex);
2847 pvar->peer_kex = NULL;
2848 }
2849
2850 pvar->we_need = 0;
2851 pvar->key_done = 0;
2852 pvar->rekeying = 0;
2853
2854 if (pvar->session_id != NULL) {
2855 free(pvar->session_id);
2856 pvar->session_id = NULL;
2857 }
2858 pvar->session_id_len = 0;
2859
2860 pvar->userauth_success = 0;
2861 //pvar->remote_id = 0;
2862 pvar->shell_id = 0;
2863 pvar->session_nego_status = 0;
2864
2865 pvar->ssh_heartbeat_tick = 0;
2866
2867 if (pvar->decomp_buffer != NULL) {
2868 buffer_free(pvar->decomp_buffer);
2869 pvar->decomp_buffer = NULL;
2870 }
2871
2872 if (pvar->ssh2_authlist != NULL) { // (2007.4.27 yutaka)
2873 free(pvar->ssh2_authlist);
2874 pvar->ssh2_authlist = NULL;
2875 }
2876
2877 pvar->tryed_ssh2_authlist = FALSE;
2878 }
2879 #endif
2880
2881 }
2882
2883 static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen)
2884 {
2885 buffer_t *msg;
2886 unsigned char *outmsg;
2887 unsigned int len;
2888
2889 // SSH2���������������A�p�P�b�g���������B(2005.6.19 yutaka)
2890 if (pvar->rekeying) {
2891 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
2892 // �������������������B
2893 c = NULL;
2894
2895 return;
2896 }
2897
2898 if (c == NULL)
2899 return;
2900
2901 if ((unsigned int)buflen > c->remote_window) {
2902 unsigned int offset = c->remote_window;
2903 // ���������f�[�^����������������������
2904 ssh2_channel_add_bufchain(c, buf + offset, buflen - offset);
2905 buflen = offset;
2906 }
2907 if (buflen > 0) {
2908 msg = buffer_init();
2909 if (msg == NULL) {
2910 // TODO: error check
2911 return;
2912 }
2913 buffer_put_int(msg, c->remote_id);
2914 buffer_put_string(msg, (char *)buf, buflen);
2915
2916 len = buffer_len(msg);
2917 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
2918 //if (len + 12 >= pvar->ssh_state.outbuflen) *(int *)0 = 0;
2919 memcpy(outmsg, buffer_ptr(msg), len);
2920 finish_send_packet(pvar);
2921 buffer_free(msg);
2922 //debug_print(1, pvar->ssh_state.outbuf, 7 + 4 + 1 + 1 + len);
2923
2924 // remote window size������
2925 if (buflen <= c->remote_window) {
2926 c->remote_window -= buflen;
2927 }
2928 else {
2929 c->remote_window = 0;
2930 }
2931 }
2932 }
2933
2934 /* support for port forwarding */
2935 void SSH_channel_send(PTInstVar pvar, int channel_num,
2936 uint32 remote_channel_num,
2937 unsigned char FAR * buf, int len)
2938 {
2939 if (SSHv1(pvar)) {
2940 unsigned char FAR *outmsg =
2941 begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2942
2943 set_uint32(outmsg, remote_channel_num);
2944 set_uint32(outmsg + 4, len);
2945
2946 if (pvar->ssh_state.compressing) {
2947 buf_ensure_size(&pvar->ssh_state.outbuf,
2948 &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2949 pvar->ssh_state.compress_stream.next_in =
2950 pvar->ssh_state.precompress_outbuf;
2951 pvar->ssh_state.compress_stream.avail_in = 9;
2952 pvar->ssh_state.compress_stream.next_out =
2953 pvar->ssh_state.outbuf + 12;
2954 pvar->ssh_state.compress_stream.avail_out =
2955 pvar->ssh_state.outbuflen - 12;
2956
2957 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2958 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2959 "Error compressing packet data");
2960 notify_fatal_error(pvar, pvar->ts->UIMsg);
2961 return;
2962 }
2963
2964 pvar->ssh_state.compress_stream.next_in =
2965 (unsigned char FAR *) buf;
2966 pvar->ssh_state.compress_stream.avail_in = len;
2967
2968 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2969 Z_OK) {
2970 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2971 "Error compressing packet data");
2972 notify_fatal_error(pvar, pvar->ts->UIMsg);
2973 return;
2974 }
2975 } else {
2976 memcpy(outmsg + 8, buf, len);
2977 }
2978
2979 finish_send_packet_special(pvar, 1);
2980
2981 } else {
2982 // �|�[�g�t�H���[�f�B���O���������N���C�A���g���������M�v�����ASSH���M���������T�[�o���������������B
2983 Channel_t *c = ssh2_local_channel_lookup(channel_num);
2984 SSH2_send_channel_data(pvar, c, buf, len);
2985 }
2986
2987 }
2988
2989 void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
2990 {
2991 if (SSHv1(pvar)) {
2992 unsigned char FAR *outmsg =
2993 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
2994
2995 set_uint32(outmsg, remote_channel_num);
2996 finish_send_packet(pvar);
2997
2998 } else { // SSH2 (2005.6.26 yutaka)
2999 int len;
3000 Channel_t *c = NULL;
3001 buffer_t *msg;
3002 unsigned char *outmsg;
3003
3004 msg = buffer_init();
3005 if (msg == NULL) {
3006 // TODO: error check
3007 return;
3008 }
3009 buffer_put_int(msg, remote_channel_num);
3010 buffer_put_int(msg, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
3011 buffer_put_string(msg, "", 0); // description
3012 buffer_put_string(msg, "", 0); // language tag
3013
3014 len = buffer_len(msg);
3015 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, len);
3016 memcpy(outmsg, buffer_ptr(msg), len);
3017 finish_send_packet(pvar);
3018 buffer_free(msg);
3019
3020 }
3021 }
3022
3023 void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
3024 uint32 local_channel_num)
3025 {
3026 if (SSHv1(pvar)) {
3027 unsigned char FAR *outmsg =
3028 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
3029
3030 set_uint32(outmsg, remote_channel_num);
3031 set_uint32(outmsg + 4, local_channel_num);
3032 finish_send_packet(pvar);
3033
3034 } else {
3035 buffer_t *msg;
3036 unsigned char *outmsg;
3037 int len;
3038 Channel_t *c;
3039
3040 // port-forwarding(remote to local)�����[�J�����������������T�[�o�������B(2005.7.2 yutaka)
3041 c = ssh2_local_channel_lookup(local_channel_num);
3042 if (c == NULL) {
3043 // It is sure to be successful as long as it's not a program bug either.
3044 return;
3045 }
3046
3047 msg = buffer_init();
3048 if (msg == NULL) {
3049 // TODO: error check
3050 return;
3051 }
3052 buffer_put_int(msg, c->remote_id);
3053 buffer_put_int(msg, c->self_id);
3054 buffer_put_int(msg, c->local_window);
3055 buffer_put_int(msg, c->local_maxpacket);
3056
3057 len = buffer_len(msg);
3058 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, len);
3059 memcpy(outmsg, buffer_ptr(msg), len);
3060 finish_send_packet(pvar);
3061 buffer_free(msg);
3062
3063 }
3064 }
3065
3066 void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
3067 {
3068 if (SSHv1(pvar)){
3069 unsigned char FAR *outmsg =
3070 begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
3071
3072 set_uint32(outmsg, remote_channel_num);
3073 finish_send_packet(pvar);
3074
3075 } else {
3076 // SSH2: ���������B
3077
3078 }
3079 }
3080
3081 void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num, uint32 local_channel_num)
3082 {
3083 if (SSHv1(pvar)){
3084 unsigned char FAR *outmsg =
3085 begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
3086
3087 set_uint32(outmsg, remote_channel_num);
3088 finish_send_packet(pvar);
3089
3090 } else {
3091 // SSH2: �`���l���N���[�Y���T�[�o�����m
3092 buffer_t *msg;
3093 unsigned char *outmsg;
3094 int len;
3095 Channel_t *c;
3096
3097 // SSH2���������������A�p�P�b�g���������B(2005.6.21 yutaka)
3098 if (pvar->rekeying) {
3099 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
3100 // �������������������B
3101 c = NULL;
3102
3103 return;
3104 }
3105
3106 c = ssh2_local_channel_lookup(local_channel_num);
3107 if (c == NULL)
3108 return;
3109
3110 msg = buffer_init();
3111 if (msg == NULL) {
3112 // TODO: error check
3113 return;
3114 }
3115 buffer_put_int(msg, c->remote_id); // remote ID
3116
3117 len = buffer_len(msg);
3118 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_EOF, len);
3119 memcpy(outmsg, buffer_ptr(msg), len);
3120 finish_send_packet(pvar);
3121 buffer_free(msg);
3122 }
3123
3124 }
3125
3126 void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
3127 char FAR * to_local_host, int to_local_port)
3128 {
3129 if (SSHv1(pvar)) {
3130 int host_len = strlen(to_local_host);
3131 unsigned char FAR *outmsg =
3132 begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST,
3133 12 + host_len);
3134
3135 set_uint32(outmsg, from_server_port);
3136 set_uint32(outmsg + 4, host_len);
3137 memcpy(outmsg + 8, to_local_host, host_len);
3138 set_uint32(outmsg + 8 + host_len, to_local_port);
3139 finish_send_packet(pvar);
3140
3141 enque_forwarding_request_handlers(pvar);
3142
3143 } else {
3144 // SSH2 port-forwading remote to local (2005.6.21 yutaka)
3145 buffer_t *msg;
3146 char *s;
3147 unsigned char *outmsg;
3148 int len;
3149
3150 msg = buffer_init();
3151 if (msg == NULL) {
3152 // TODO: error check
3153 return;
3154 }
3155 s = "tcpip-forward";
3156 buffer_put_string(msg, s, strlen(s)); // ctype
3157 buffer_put_char(msg, 1); // want reply
3158 s = "0.0.0.0";
3159 buffer_put_string(msg, s, strlen(s));
3160
3161 buffer_put_int(msg, from_server_port); // listening port
3162
3163 len = buffer_len(msg);
3164 outmsg = begin_send_packet(pvar, SSH2_MSG_GLOBAL_REQUEST, len);
3165 memcpy(outmsg, buffer_ptr(msg), len);
3166 finish_send_packet(pvar);
3167 buffer_free(msg);
3168
3169 }
3170 }
3171
3172 void SSH_request_X11_forwarding(PTInstVar pvar,
3173 char FAR * auth_protocol,
3174 unsigned char FAR * auth_data,
3175 int auth_data_len, int screen_num)
3176 {
3177 if (SSHv1(pvar)) {
3178 int protocol_len = strlen(auth_protocol);
3179 int data_len = auth_data_len * 2;
3180 int outmsg_len = 12 + protocol_len + data_len;
3181 unsigned char FAR *outmsg =
3182 begin_send_packet(pvar, SSH_CMSG_X11_REQUEST_FORWARDING, outmsg_len);
3183 int i;
3184 char FAR *auth_data_ptr;
3185
3186 set_uint32(outmsg, protocol_len);
3187 memcpy(outmsg + 4, auth_protocol, protocol_len);
3188 set_uint32(outmsg + 4 + protocol_len, data_len);
3189 auth_data_ptr = outmsg + 8 + protocol_len;
3190 for (i = 0; i < auth_data_len; i++) {
3191 _snprintf_s(auth_data_ptr + i * 2,
3192 outmsg_len - (auth_data_ptr - outmsg) - i * 2,
3193 _TRUNCATE, "%.2x", auth_data[i]);
3194 }
3195 set_uint32(outmsg + 8 + protocol_len + data_len, screen_num);
3196
3197 finish_send_packet(pvar);
3198
3199 enque_forwarding_request_handlers(pvar);
3200
3201 } else {
3202 // SSH2: X11 port-forwarding (2005.7.2 yutaka)
3203 buffer_t *msg;
3204 char *s;
3205 unsigned char *outmsg;
3206 int len;
3207 Channel_t *c;
3208 int newlen;
3209 char *newdata;
3210 int i;
3211
3212 msg = buffer_init();
3213 if (msg == NULL) {
3214 // TODO: error check
3215 return;
3216 }
3217
3218 c = ssh2_channel_lookup(pvar->shell_id);
3219 if (c == NULL)
3220 return;
3221
3222 // making the fake data
3223 newlen = 2 * auth_data_len + 1;
3224 newdata = malloc(newlen);
3225 if (newdata == NULL)
3226 return;
3227 for (i = 0 ; i < auth_data_len ; i++) {
3228 _snprintf_s(newdata + i*2, newlen - i*2, _TRUNCATE, "%02x", auth_data[i]);
3229 }
3230 newdata[newlen - 1] = '\0';
3231
3232 buffer_put_int(msg, c->remote_id);
3233 s = "x11-req";