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 3103 - (show annotations) (download) (as text)
Mon Feb 4 01:21:44 2008 UTC (16 years, 2 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 212082 byte(s)
SCP できるのは SSH2 のみなので、isSSH にはバージョンを格納する。

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