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 3077 - (show annotations) (download) (as text)
Wed Dec 26 11:33: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: 202637 byte(s)
SCPスレッドの復活。実際のパケット送信は、モードレスダイアログ内で行うことで、
コンテキストの乱れを発生させないようにする。

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