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