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

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