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 3102 - (show annotations) (download) (as text)
Fri Feb 1 11:09:08 2008 UTC (16 years, 2 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 211956 byte(s)
SSH SCPダイアログからファイル受信できるようにした。
ただし、ファイル名は手打ち。将来的にSFTPをサポートできたら、
このダイアログは廃止する予定です。

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 for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1557 }
1558
1559 return *str == '-';
1560 }
1561
1562 /*
1563 On entry, the pvar->protocol_xxx fields hold the server's advertised
1564 protocol number. We replace the fields with the protocol number we will
1565 actually use, or return FALSE if there is no usable protocol version.
1566 */
1567 static BOOL negotiate_protocol(PTInstVar pvar)
1568 {
1569 switch (pvar->protocol_major) {
1570 case 1:
1571 if (pvar->protocol_minor > 5) {
1572 pvar->protocol_minor = 5;
1573 }
1574
1575 return TRUE;
1576
1577 // for SSH2(yutaka)
1578 case 2:
1579 return TRUE; // SSH2 support
1580
1581 default:
1582 return FALSE;
1583 }
1584 }
1585
1586 static void init_protocol(PTInstVar pvar)
1587 {
1588 CRYPT_initialize_random_numbers(pvar);
1589
1590 // known_hosts�t�@�C�������z�X�g���J������������������
1591 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname);
1592
1593 /* while we wait for a response from the server... */
1594
1595 if (SSHv1(pvar)) {
1596 enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1597 enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1598 enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1599 enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1600
1601 } else { // for SSH2(yutaka)
1602 enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1603 enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1604 enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1605 enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1606 enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1607 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1608 enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1609 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1610 enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_authrequest);
1611 enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1612 enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1613 enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1614 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1615
1616 enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1617
1618 // ���[�U�F�������f�B�X�p�b�`���[�`��
1619 enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1620 enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1621 enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1622 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1623 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1624 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1625 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1626 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1627 enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1628 enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1629 // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1630 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1631 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1632
1633 }
1634 }
1635
1636 BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1637 {
1638 static const char prefix[] = "Received server prologue string: ";
1639
1640 // initialize SSH2 memory dump (2005.3.7 yutaka)
1641 init_memdump();
1642 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1643
1644 if (ID_len <= 0) {
1645 return FALSE;
1646 } else {
1647 int buf_len = ID_len + NUM_ELEM(prefix);
1648 char FAR *buf = (char FAR *) malloc(buf_len);
1649
1650 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1651 strncat_s(buf, buf_len, ID, _TRUNCATE);
1652 chop_newlines(buf);
1653
1654 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1655
1656 free(buf);
1657
1658
1659 // ���������R�s�[������ (2005.3.9 yutaka)
1660 #if 0
1661 // for calculate SSH2 hash
1662 // �T�[�o�o�[�W�����������i���s���������������j
1663 if (ID_len >= sizeof(pvar->server_version_string))
1664 return FALSE;
1665 strncpy(pvar->server_version_string, ID, ID_len);
1666 #endif
1667
1668
1669 if (ID[ID_len - 1] != '\n') {
1670 pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1671 return FALSE;
1672 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1673 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1674 return FALSE;
1675 } else if (strncmp(ID, "SSH-", 4) != 0) {
1676 return FALSE;
1677 } else {
1678 ID[ID_len - 1] = 0;
1679
1680 if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1681 ID[ID_len - 2] = 0;
1682 }
1683
1684 pvar->ssh_state.server_ID = _strdup(ID);
1685
1686 if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1687 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1688 "This program does not understand the server's version of the protocol.");
1689 notify_fatal_error(pvar, pvar->ts->UIMsg);
1690 } else {
1691 char TTSSH_ID[1024];
1692 int TTSSH_ID_len;
1693 int a, b, c, d;
1694
1695 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1696 get_file_version("ttxssh.dll", &a, &b, &c, &d);
1697
1698 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1699 "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1700 pvar->protocol_major, pvar->protocol_minor, a, b);
1701 TTSSH_ID_len = strlen(TTSSH_ID);
1702
1703 // for SSH2(yutaka)
1704 // �N���C�A���g�o�[�W�����������i���s���������������j
1705 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1706 TTSSH_ID, _TRUNCATE);
1707
1708 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1709 _snprintf_s(pvar->server_version_string,
1710 sizeof(pvar->server_version_string), _TRUNCATE,
1711 "%s", pvar->ssh_state.server_ID);
1712
1713 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1714 0) != TTSSH_ID_len) {
1715 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1716 "An error occurred while sending the SSH ID string.\n"
1717 "The connection will close.");
1718 notify_fatal_error(pvar, pvar->ts->UIMsg);
1719 } else {
1720 // ���s�R�[�h������ (2004.8.4 yutaka)
1721 pvar->client_version_string[--TTSSH_ID_len] = 0;
1722
1723 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1724 push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1725
1726 // SSH�n���h�����o�^���s��
1727 init_protocol(pvar);
1728
1729 SSH2_dispatch_init(1);
1730 SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1731 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1732 }
1733 }
1734
1735 return TRUE;
1736 }
1737 }
1738 }
1739
1740 static BOOL handle_exit(PTInstVar pvar)
1741 {
1742 if (grab_payload(pvar, 4)) {
1743 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1744 finish_send_packet(pvar);
1745 notify_closed_connection(pvar);
1746 }
1747 return TRUE;
1748 }
1749
1750 static BOOL handle_data(PTInstVar pvar)
1751 {
1752 if (grab_payload_limited(pvar, 4)) {
1753 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1754 pvar->ssh_state.payload_datastart = 4;
1755 }
1756 return TRUE;
1757 }
1758
1759 static BOOL handle_channel_open(PTInstVar pvar)
1760 {
1761 int host_len;
1762 int originator_len;
1763
1764 if ((pvar->ssh_state.
1765 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1766 if (grab_payload(pvar, 8)
1767 && grab_payload(pvar,
1768 8 + (host_len = get_payload_uint32(pvar, 4)))
1769 && grab_payload(pvar, originator_len =
1770 get_payload_uint32(pvar, host_len + 12))) {
1771 int local_port = get_payload_uint32(pvar, 8 + host_len);
1772
1773 pvar->ssh_state.payload[8 + host_len] = 0;
1774 FWD_open(pvar, get_payload_uint32(pvar, 0),
1775 pvar->ssh_state.payload + 8, local_port,
1776 pvar->ssh_state.payload + 16 + host_len,
1777 originator_len,
1778 NULL);
1779 }
1780 } else {
1781 if (grab_payload(pvar, 8)
1782 && grab_payload(pvar,
1783 4 + (host_len = get_payload_uint32(pvar, 4)))) {
1784 int local_port = get_payload_uint32(pvar, 8 + host_len);
1785
1786 pvar->ssh_state.payload[8 + host_len] = 0;
1787 FWD_open(pvar, get_payload_uint32(pvar, 0),
1788 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1789 NULL);
1790 }
1791 }
1792
1793 return TRUE;
1794 }
1795
1796 static BOOL handle_X11_channel_open(PTInstVar pvar)
1797 {
1798 int originator_len;
1799
1800 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1801 if (grab_payload(pvar, 8)
1802 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1803 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1804 pvar->ssh_state.payload + 8, originator_len, NULL);
1805 }
1806 } else {
1807 if (grab_payload(pvar, 4)) {
1808 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1809 }
1810 }
1811
1812 return TRUE;
1813 }
1814
1815 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1816 {
1817 if (grab_payload(pvar, 8)) {
1818 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1819 get_payload_uint32(pvar, 4));
1820 }
1821 return FALSE;
1822 }
1823
1824 static BOOL handle_channel_open_failure(PTInstVar pvar)
1825 {
1826 if (grab_payload(pvar, 4)) {
1827 FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1828 }
1829 return FALSE;
1830 }
1831
1832 static BOOL handle_channel_data(PTInstVar pvar)
1833 {
1834 int len;
1835
1836 if (grab_payload(pvar, 8)
1837 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1838 FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1839 pvar->ssh_state.payload + 8, len);
1840 }
1841 return TRUE;
1842 }
1843
1844 static BOOL handle_channel_input_eof(PTInstVar pvar)
1845 {
1846 if (grab_payload(pvar, 4)) {
1847 FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1848 }
1849 return TRUE;
1850 }
1851
1852 static BOOL handle_channel_output_eof(PTInstVar pvar)
1853 {
1854 if (grab_payload(pvar, 4)) {
1855 FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1856 }
1857 return TRUE;
1858 }
1859
1860
1861
1862 // �n���h�����O�������b�Z�[�W����������
1863
1864 #define HANDLE_MESSAGE_MAX 30
1865 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1866 static int handle_message_count = 0;
1867 static int handle_message_stage = 0;
1868
1869 void SSH2_dispatch_init(int stage)
1870 {
1871 handle_message_count = 0;
1872 handle_message_stage = stage;
1873 }
1874
1875 int SSH2_dispatch_enabled_check(unsigned char message)
1876 {
1877 int i;
1878
1879 for (i = 0 ; i < handle_message_count ; i++) {
1880 if (handle_messages[i] == message)
1881 return 1;
1882 }
1883 return 0;
1884 }
1885
1886 void SSH2_dispatch_add_message(unsigned char message)
1887 {
1888
1889 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1890 // TODO: error check
1891 return;
1892 }
1893
1894 handle_messages[handle_message_count++] = message;
1895 }
1896
1897 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1898 {
1899 unsigned char c;
1900
1901 for (c = begin ; c <= end ; c++) {
1902 SSH2_dispatch_add_message(c);
1903 }
1904 }
1905
1906
1907 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1908 int padding)
1909 {
1910 unsigned char message = prep_packet(pvar, data, len, padding);
1911
1912
1913 #ifdef SSH2_DEBUG
1914 // for SSH2(yutaka)
1915 if (SSHv2(pvar)) {
1916 if (pvar->key_done) {
1917 message = message;
1918 }
1919
1920 if (pvar->userauth_success) {
1921 message = message;
1922 }
1923
1924 if (pvar->rekeying) {
1925 message = message;
1926 }
1927 }
1928 #endif
1929
1930 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1931 if (message != SSH_MSG_NONE) {
1932 // ���b�Z�[�W�^�C�v���������n���h�����N��
1933 SSHPacketHandler handler = get_handler(pvar, message);
1934
1935 // for SSH2(yutaka)
1936 if (SSHv2(pvar)) {
1937 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1938 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1939 char buf[1024];
1940
1941 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
1942 "Unexpected SSH2 message(%d) on current stage(%d)");
1943 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1944 pvar->ts->UIMsg, message, handle_message_stage);
1945 notify_fatal_error(pvar, buf);
1946 // abort
1947 }
1948 }
1949
1950 if (handler == NULL) {
1951 if (SSHv1(pvar)) {
1952 char buf[1024];
1953
1954 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
1955 "Unexpected packet type received: %d");
1956 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1957 pvar->ts->UIMsg, message, handle_message_stage);
1958 notify_fatal_error(pvar, buf);
1959 } else {
1960 unsigned char FAR *outmsg =
1961 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
1962
1963 set_uint32(outmsg,
1964 pvar->ssh_state.receiver_sequence_number - 1);
1965 finish_send_packet(pvar);
1966 /* XXX need to decompress incoming packet, but how? */
1967 }
1968 } else {
1969 if (!handler(pvar)) {
1970 deque_handlers(pvar, message);
1971 }
1972 }
1973 }
1974 }
1975
1976 static BOOL handle_pty_success(PTInstVar pvar)
1977 {
1978 FWD_enter_interactive_mode(pvar);
1979 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
1980 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
1981 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
1982 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
1983 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
1984 handle_channel_input_eof);
1985 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
1986 handle_channel_output_eof);
1987 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
1988 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
1989 return FALSE;
1990 }
1991
1992 static BOOL handle_pty_failure(PTInstVar pvar)
1993 {
1994 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
1995 "The server cannot allocate a pseudo-terminal. "
1996 "You may encounter some problems with the terminal.");
1997 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1998 return handle_pty_success(pvar);
1999 }
2000
2001 static void prep_pty(PTInstVar pvar)
2002 {
2003 int len = strlen(pvar->ts->TermType);
2004 unsigned char FAR *outmsg =
2005 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2006 4 + len + 16 + sizeof(ssh_ttymodes));
2007 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2008 static const SSHPacketHandler handlers[]
2009 = { handle_pty_success, handle_pty_failure };
2010
2011 set_uint32(outmsg, len);
2012 memcpy(outmsg + 4, pvar->ts->TermType, len);
2013 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2014 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2015 set_uint32(outmsg + 4 + len + 8, 0);
2016 set_uint32(outmsg + 4 + len + 12, 0);
2017 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2018 finish_send_packet(pvar);
2019
2020 enque_handlers(pvar, 2, msgs, handlers);
2021
2022 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2023 finish_send_packet(pvar);
2024 }
2025
2026 static void prep_forwarding(PTInstVar pvar)
2027 {
2028 FWD_prep_forwarding(pvar);
2029 prep_pty(pvar);
2030 }
2031
2032
2033 //
2034 //
2035 // (2005.7.10 yutaka)
2036 static void enable_send_compression(PTInstVar pvar)
2037 {
2038 static int initialize = 0;
2039
2040 if (initialize) {
2041 deflateEnd(&pvar->ssh_state.compress_stream);
2042 }
2043 initialize = 1;
2044
2045 pvar->ssh_state.compress_stream.zalloc = NULL;
2046 pvar->ssh_state.compress_stream.zfree = NULL;
2047 pvar->ssh_state.compress_stream.opaque = NULL;
2048 if (deflateInit
2049 (&pvar->ssh_state.compress_stream,
2050 pvar->ssh_state.compression_level) != Z_OK) {
2051 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2052 "An error occurred while setting up compression.\n"
2053 "The connection will close.");
2054 notify_fatal_error(pvar, pvar->ts->UIMsg);
2055 return;
2056 } else {
2057 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2058 if (SSHv2(pvar)) {
2059 pvar->ssh_state.compressing = FALSE;
2060 } else {
2061 pvar->ssh_state.compressing = TRUE;
2062 }
2063 }
2064 }
2065
2066 static void enable_recv_compression(PTInstVar pvar)
2067 {
2068 static int initialize = 0;
2069
2070 if (initialize) {
2071 deflateEnd(&pvar->ssh_state.decompress_stream);
2072 }
2073 initialize = 1;
2074
2075 pvar->ssh_state.decompress_stream.zalloc = NULL;
2076 pvar->ssh_state.decompress_stream.zfree = NULL;
2077 pvar->ssh_state.decompress_stream.opaque = NULL;
2078 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2079 deflateEnd(&pvar->ssh_state.compress_stream);
2080 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2081 "An error occurred while setting up compression.\n"
2082 "The connection will close.");
2083 notify_fatal_error(pvar, pvar->ts->UIMsg);
2084 return;
2085 } else {
2086 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2087 if (SSHv2(pvar)) {
2088 pvar->ssh_state.decompressing = FALSE;
2089 } else {
2090 pvar->ssh_state.decompressing = TRUE;
2091 }
2092
2093 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2094 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2095 }
2096 }
2097
2098 static void enable_compression(PTInstVar pvar)
2099 {
2100 enable_send_compression(pvar);
2101 enable_recv_compression(pvar);
2102
2103 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2104 if (SSHv2(pvar)) {
2105 pvar->ssh_state.compressing = FALSE;
2106 pvar->ssh_state.decompressing = FALSE;
2107 }
2108
2109 }
2110
2111 static BOOL handle_enable_compression(PTInstVar pvar)
2112 {
2113 enable_compression(pvar);
2114 prep_forwarding(pvar);
2115 return FALSE;
2116 }
2117
2118 static BOOL handle_disable_compression(PTInstVar pvar)
2119 {
2120 prep_forwarding(pvar);
2121 return FALSE;
2122 }
2123
2124 static void prep_compression(PTInstVar pvar)
2125 {
2126 if (pvar->session_settings.CompressionLevel > 0) {
2127 // added if statement (2005.7.10 yutaka)
2128 if (SSHv1(pvar)) {
2129 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2130 static const SSHPacketHandler handlers[]
2131 = { handle_enable_compression, handle_disable_compression };
2132
2133 unsigned char FAR *outmsg =
2134 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2135
2136 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2137 finish_send_packet(pvar);
2138
2139 enque_handlers(pvar, 2, msgs, handlers);
2140 }
2141
2142 pvar->ssh_state.compression_level =
2143 pvar->session_settings.CompressionLevel;
2144
2145 } else {
2146 // added if statement (2005.7.10 yutaka)
2147 if (SSHv1(pvar)) {
2148 prep_forwarding(pvar);
2149 }
2150 }
2151 }
2152
2153 static void enque_simple_auth_handlers(PTInstVar pvar)
2154 {
2155 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2156 static const SSHPacketHandler handlers[]
2157 = { handle_auth_success, handle_auth_failure };
2158
2159 enque_handlers(pvar, 2, msgs, handlers);
2160 }
2161
2162 static BOOL handle_rsa_challenge(PTInstVar pvar)
2163 {
2164 int challenge_bytes;
2165
2166 if (!grab_payload(pvar, 2)) {
2167 return FALSE;
2168 }
2169
2170 challenge_bytes = get_mpint_len(pvar, 0);
2171
2172 if (grab_payload(pvar, challenge_bytes)) {
2173 unsigned char FAR *outmsg =
2174 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2175
2176 if (CRYPT_generate_RSA_challenge_response
2177 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2178
2179 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2180 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2181 #if 0
2182 //AUTH_destroy_cur_cred(pvar);
2183 #endif
2184
2185 finish_send_packet(pvar);
2186
2187 enque_simple_auth_handlers(pvar);
2188 } else {
2189 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2190 "An error occurred while decrypting the RSA challenge.\n"
2191 "Perhaps the key file is corrupted.");
2192 notify_fatal_error(pvar, pvar->ts->UIMsg);
2193 }
2194 }
2195
2196 return FALSE;
2197 }
2198
2199 #define OBFUSCATING_ROUND_TO 32
2200
2201 static int obfuscating_round_up(PTInstVar pvar, int size)
2202 {
2203 return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2204 }
2205
2206 static void try_send_credentials(PTInstVar pvar)
2207 {
2208 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2209 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2210 static const int RSA_msgs[] =
2211 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2212 static const SSHPacketHandler RSA_handlers[]
2213 = { handle_rsa_challenge, handle_rsa_auth_refused };
2214 static const int TIS_msgs[] =
2215 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2216 static const SSHPacketHandler TIS_handlers[]
2217 = { handle_TIS_challenge, handle_auth_failure };
2218
2219 // SSH2���������������������X�L�b�v
2220 if (SSHv2(pvar))
2221 goto skip_ssh2;
2222
2223 switch (cred->method) {
2224 case SSH_AUTH_NONE:
2225 return;
2226 case SSH_AUTH_PASSWORD:{
2227 int len = strlen(cred->password);
2228 // Round up password length to discourage traffic analysis
2229 int obfuscated_len = obfuscating_round_up(pvar, len);
2230 unsigned char FAR *outmsg =
2231 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2232 4 + obfuscated_len);
2233
2234 notify_verbose_message(pvar,
2235 "Trying PASSWORD authentication...",
2236 LOG_LEVEL_VERBOSE);
2237
2238 set_uint32(outmsg, obfuscated_len);
2239 memcpy(outmsg + 4, cred->password, len);
2240 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2241
2242 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2243 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2244 #if 0
2245 //AUTH_destroy_cur_cred(pvar);
2246 #endif
2247
2248 enque_simple_auth_handlers(pvar);
2249 break;
2250 }
2251 case SSH_AUTH_RHOSTS:{
2252 int len = strlen(cred->rhosts_client_user);
2253 unsigned char FAR *outmsg =
2254 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2255
2256 notify_verbose_message(pvar,
2257 "Trying RHOSTS authentication...",
2258 LOG_LEVEL_VERBOSE);
2259
2260 set_uint32(outmsg, len);
2261 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2262 AUTH_destroy_cur_cred(pvar);
2263 enque_simple_auth_handlers(pvar);
2264 break;
2265 }
2266 case SSH_AUTH_RSA:{
2267 int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2268 unsigned char FAR *outmsg =
2269 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2270
2271 notify_verbose_message(pvar,
2272 "Trying RSA authentication...",
2273 LOG_LEVEL_VERBOSE);
2274
2275 set_ushort16_MSBfirst(outmsg, len * 8);
2276 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2277 /* don't destroy the current credentials yet */
2278 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2279 break;
2280 }
2281 case SSH_AUTH_RHOSTS_RSA:{
2282 int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2283 int name_len = strlen(cred->rhosts_client_user);
2284 int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2285 int index;
2286 unsigned char FAR *outmsg =
2287 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2288 12 + mod_len + name_len + exp_len);
2289
2290 notify_verbose_message(pvar,
2291 "Trying RHOSTS+RSA authentication...",
2292 LOG_LEVEL_VERBOSE);
2293
2294 set_uint32(outmsg, name_len);
2295 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2296 index = 4 + name_len;
2297
2298 set_uint32(outmsg + index, 8 * mod_len);
2299 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2300 BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2301 index += 6 + exp_len;
2302
2303 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2304 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2305 /* don't destroy the current credentials yet */
2306 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2307 break;
2308 }
2309 case SSH_AUTH_TIS:{
2310 if (cred->password == NULL) {
2311 unsigned char FAR *outmsg =
2312 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2313
2314 notify_verbose_message(pvar,
2315 "Trying TIS authentication...",
2316 LOG_LEVEL_VERBOSE);
2317 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2318 } else {
2319 int len = strlen(cred->password);
2320 int obfuscated_len = obfuscating_round_up(pvar, len);
2321 unsigned char FAR *outmsg =
2322 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2323 4 + obfuscated_len);
2324
2325 notify_verbose_message(pvar, "Sending TIS response",
2326 LOG_LEVEL_VERBOSE);
2327
2328 set_uint32(outmsg, obfuscated_len);
2329 memcpy(outmsg + 4, cred->password, len);
2330 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2331 enque_simple_auth_handlers(pvar);
2332 }
2333
2334 AUTH_destroy_cur_cred(pvar);
2335 break;
2336 }
2337 default:
2338 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2339 "Internal error: unsupported authentication method");
2340 notify_fatal_error(pvar, pvar->ts->UIMsg);
2341 return;
2342 }
2343
2344 finish_send_packet(pvar);
2345
2346 skip_ssh2:;
2347 destroy_packet_buf(pvar);
2348
2349 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2350 }
2351 }
2352
2353 static void try_send_user_name(PTInstVar pvar)
2354 {
2355 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2356 char FAR *username = AUTH_get_user_name(pvar);
2357
2358 if (username != NULL) {
2359 int len = strlen(username);
2360 int obfuscated_len = obfuscating_round_up(pvar, len);
2361 unsigned char FAR *outmsg =
2362 begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
2363 char buf[1024] = "Sending user name: ";
2364 static const int msgs[] =
2365 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2366 static const SSHPacketHandler handlers[]
2367 = { handle_noauth_success, handle_auth_required };
2368
2369 set_uint32(outmsg, obfuscated_len);
2370 memcpy(outmsg + 4, username, len);
2371 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2372 finish_send_packet(pvar);
2373
2374 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2375
2376 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2377 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2378
2379 enque_handlers(pvar, 2, msgs, handlers);
2380 }
2381 }
2382 }
2383
2384 static void send_session_key(PTInstVar pvar)
2385 {
2386 int encrypted_session_key_len;
2387 unsigned char FAR *outmsg;
2388
2389 if (SSHv1(pvar)) {
2390 encrypted_session_key_len =
2391 CRYPT_get_encrypted_session_key_len(pvar);
2392 }
2393
2394 if (!CRYPT_choose_ciphers(pvar))
2395 return;
2396
2397 if (SSHv1(pvar)) {
2398 outmsg =
2399 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2400 15 + encrypted_session_key_len);
2401 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2402 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2403 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2404 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2405 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2406 return;
2407 set_uint32(outmsg + 11 + encrypted_session_key_len,
2408 SSH_PROTOFLAG_SCREEN_NUMBER |
2409 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2410 finish_send_packet(pvar);
2411 }
2412
2413 if (!CRYPT_start_encryption(pvar, 1, 1))
2414 return;
2415 notify_established_secure_connection(pvar);
2416
2417 if (SSHv1(pvar)) {
2418 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2419 }
2420
2421 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2422
2423 if (SSHv1(pvar)) {
2424 try_send_user_name(pvar);
2425 }
2426 }
2427
2428 /*************************
2429 END of message handlers
2430 ************************/
2431
2432 void SSH_init(PTInstVar pvar)
2433 {
2434 int i;
2435
2436 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2437 buf_create(&pvar->ssh_state.precompress_outbuf,
2438 &pvar->ssh_state.precompress_outbuflen);
2439 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2440 &pvar->ssh_state.postdecompress_inbuflen);
2441 pvar->ssh_state.payload = NULL;
2442 pvar->ssh_state.compressing = FALSE;
2443 pvar->ssh_state.decompressing = FALSE;
2444 pvar->ssh_state.status_flags =
2445 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2446 pvar->ssh_state.payload_datalen = 0;
2447 pvar->ssh_state.hostname = NULL;
2448 pvar->ssh_state.server_ID = NULL;
2449 pvar->ssh_state.receiver_sequence_number = 0;
2450 pvar->ssh_state.sender_sequence_number = 0;
2451 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2452 pvar->ssh_state.packet_handlers[i] = NULL;
2453 }
2454
2455 // for SSH2(yutaka)
2456 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2457 pvar->userauth_success = 0;
2458 pvar->session_nego_status = 0;
2459 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2460 pvar->rekeying = 0;
2461 pvar->key_done = 0;
2462 pvar->ssh2_autologin = 0; // autologin disabled(default)
2463 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2464 pvar->userauth_retry_count = 0;
2465 pvar->decomp_buffer = NULL;
2466 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2467 pvar->tryed_ssh2_authlist = FALSE;
2468
2469 }
2470
2471 void SSH_open(PTInstVar pvar)
2472 {
2473 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2474 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2475 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2476 }
2477
2478 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2479 {
2480 if (SSHv1(pvar)) {
2481 int len = reason == NULL ? 0 : strlen(reason);
2482 unsigned char FAR *outmsg =
2483 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2484
2485 set_uint32(outmsg, len);
2486 if (reason != NULL) {
2487 memcpy(outmsg + 4, reason, len);
2488 }
2489 finish_send_packet(pvar);
2490
2491 } else { // for SSH2(yutaka)
2492 buffer_t *msg;
2493 unsigned char *outmsg;
2494 int len;
2495 Channel_t *c;
2496
2497 c = ssh2_channel_lookup(pvar->shell_id);
2498 if (c == NULL)
2499 return;
2500
2501 // SSH2 server��channel close���`����
2502 msg = buffer_init();
2503 if (msg == NULL) {
2504 // TODO: error check
2505 return;
2506 }
2507 buffer_put_int(msg, c->remote_id);
2508
2509 len = buffer_len(msg);
2510 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2511 memcpy(outmsg, buffer_ptr(msg), len);
2512 finish_send_packet(pvar);
2513 buffer_free(msg);
2514
2515 }
2516
2517 }
2518
2519 void SSH_notify_host_OK(PTInstVar pvar)
2520 {
2521 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2522 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2523 send_session_key(pvar);
2524 }
2525 }
2526
2527 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2528 {
2529 pvar->ssh_state.win_cols = cols;
2530 pvar->ssh_state.win_rows = rows;
2531
2532 if (SSHv1(pvar)) {
2533 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2534 unsigned char FAR *outmsg =
2535 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2536
2537 set_uint32(outmsg, rows);
2538 set_uint32(outmsg + 4, cols);
2539 set_uint32(outmsg + 8, 0);
2540 set_uint32(outmsg + 12, 0);
2541 finish_send_packet(pvar);
2542 }
2543
2544 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2545 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2546 buffer_t *msg;
2547 char *s;
2548 unsigned char *outmsg;
2549 int len;
2550 Channel_t *c;
2551
2552 c = ssh2_channel_lookup(pvar->shell_id);
2553 if (c == NULL)
2554 return;
2555
2556 msg = buffer_init();
2557 if (msg == NULL) {
2558 // TODO: error check
2559 return;
2560 }
2561 buffer_put_int(msg, c->remote_id);
2562 s = "window-change";
2563 buffer_put_string(msg, s, strlen(s));
2564 buffer_put_char(msg, 0); // wantconfirm
2565 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2566 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2567 buffer_put_int(msg, 480); // XXX:
2568 buffer_put_int(msg, 640); // XXX:
2569 len = buffer_len(msg);
2570 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2571 memcpy(outmsg, buffer_ptr(msg), len);
2572 finish_send_packet(pvar);
2573 buffer_free(msg);
2574
2575 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2576
2577 } else {
2578 // SSH�����������������������B
2579
2580 }
2581
2582 }
2583
2584 int SSH_get_min_packet_size(PTInstVar pvar)
2585 {
2586 if (SSHv1(pvar)) {
2587 return 12;
2588 } else {
2589 int block_size = CRYPT_get_decryption_block_size(pvar);
2590
2591 return max(16, block_size);
2592 }
2593 }
2594
2595 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2596 at least 5 bytes must be decrypted */
2597 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2598 {
2599 if (SSHv2(pvar)) {
2600 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2601 }
2602 }
2603
2604 int SSH_get_clear_MAC_size(PTInstVar pvar)
2605 {
2606 if (SSHv1(pvar)) {
2607 return 0;
2608 } else {
2609 return CRYPT_get_receiver_MAC_size(pvar);
2610 }
2611 }
2612
2613 void SSH_notify_user_name(PTInstVar pvar)
2614 {
2615 try_send_user_name(pvar);
2616 }
2617
2618 void SSH_notify_cred(PTInstVar pvar)
2619 {
2620 try_send_credentials(pvar);
2621 }
2622
2623 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, unsigned int buflen)
2624 {
2625 if (SSHv1(pvar)) {
2626 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2627 return;
2628 }
2629
2630 while (buflen > 0) {
2631 int len =
2632 buflen >
2633 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2634 unsigned char FAR *outmsg =
2635 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2636
2637 set_uint32(outmsg, len);
2638
2639 if (pvar->ssh_state.compressing) {
2640 buf_ensure_size(&pvar->ssh_state.outbuf,
2641 &pvar->ssh_state.outbuflen,
2642 len + (len >> 6) + 50);
2643 pvar->ssh_state.compress_stream.next_in =
2644 pvar->ssh_state.precompress_outbuf;
2645 pvar->ssh_state.compress_stream.avail_in = 5;
2646 pvar->ssh_state.compress_stream.next_out =
2647 pvar->ssh_state.outbuf + 12;
2648 pvar->ssh_state.compress_stream.avail_out =
2649 pvar->ssh_state.outbuflen - 12;
2650
2651 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2652 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2653 "Error compressing packet data");
2654 notify_fatal_error(pvar, pvar->ts->UIMsg);
2655 return;
2656 }
2657
2658 pvar->ssh_state.compress_stream.next_in =
2659 (unsigned char FAR *) buf;
2660 pvar->ssh_state.compress_stream.avail_in = len;
2661
2662 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
2663 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2664 "Error compressing packet data");
2665 notify_fatal_error(pvar, pvar->ts->UIMsg);
2666 return;
2667 }
2668 } else {
2669 memcpy(outmsg + 4, buf, len);
2670 }
2671
2672 finish_send_packet_special(pvar, 1);
2673
2674 buflen -= len;
2675 buf += len;
2676 }
2677
2678 } else { // for SSH2(yutaka)
2679 Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
2680 SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen);
2681 }
2682
2683 }
2684
2685 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
2686 {
2687 int num_bytes = pvar->ssh_state.payload_datalen;
2688
2689 if (num_bytes > len) {
2690 num_bytes = len;
2691 }
2692
2693 if (!pvar->ssh_state.decompressing) {
2694 memcpy(dest,
2695 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
2696 num_bytes);
2697 pvar->ssh_state.payload_datastart += num_bytes;
2698 } else if (num_bytes > 0) {
2699 pvar->ssh_state.decompress_stream.next_out = dest;
2700 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
2701
2702 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
2703 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
2704 "Invalid compressed data in received packet");
2705 notify_fatal_error(pvar, pvar->ts->UIMsg);
2706 return 0;
2707 }
2708 }
2709
2710 pvar->ssh_state.payload_datalen -= num_bytes;
2711
2712 return num_bytes;
2713 }
2714
2715 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
2716 {
2717 char buf[1024];
2718 char buf2[1024];
2719
2720 // added support of SSH2 packet compression (2005.7.10 yutaka)
2721 // support of "Compression delayed" (2006.6.23 maya)
2722 if (pvar->ssh_state.compressing ||
2723 pvar->ctos_compression == COMP_ZLIB ||
2724 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2725 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2726 unsigned long total_out =
2727 pvar->ssh_state.compress_stream.total_out;
2728
2729 if (total_out > 0) {
2730 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2731 "level %d; ratio %.1f (%ld:%ld)");
2732 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2733 pvar->ssh_state.compression_level,
2734 ((double) total_in) / total_out, total_in,
2735 total_out);
2736 } else {
2737 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2738 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2739 pvar->ssh_state.compression_level);
2740 }
2741 } else {
2742 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2743 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2744 }
2745
2746 // support of "Compression delayed" (2006.6.23 maya)
2747 if (pvar->ssh_state.decompressing ||
2748 pvar->stoc_compression == COMP_ZLIB ||
2749 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2750 unsigned long total_in =
2751 pvar->ssh_state.decompress_stream.total_in;
2752 unsigned long total_out =
2753 pvar->ssh_state.decompress_stream.total_out;
2754
2755 if (total_in > 0) {
2756 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2757 "level %d; ratio %.1f (%ld:%ld)");
2758 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2759 pvar->ssh_state.compression_level,
2760 ((double) total_out) / total_in, total_out,
2761 total_in);
2762 } else {
2763 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2764 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2765 pvar->ssh_state.compression_level);
2766 }
2767 } else {
2768 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2769 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2770 }
2771
2772 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
2773 "Upstream %s; Downstream %s");
2774 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
2775 }
2776
2777 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2778 {
2779 strncpy_s(dest, len,
2780 pvar->ssh_state.server_ID == NULL ? "Unknown"
2781 : pvar->ssh_state.server_ID,
2782 _TRUNCATE);
2783 }
2784
2785 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2786 int len)
2787 {
2788 if (pvar->protocol_major == 0) {
2789 strncpy_s(dest, len, "Unknown", _TRUNCATE);
2790 } else {
2791 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
2792 pvar->protocol_minor);
2793 }
2794 }
2795
2796 void SSH_end(PTInstVar pvar)
2797 {
2798 int i;
2799
2800 for (i = 0; i < 256; i++) {
2801 SSHPacketHandlerItem FAR *first_item =
2802 pvar->ssh_state.packet_handlers[i];
2803
2804 if (first_item != NULL) {
2805 SSHPacketHandlerItem FAR *item = first_item;
2806
2807 do {
2808 SSHPacketHandlerItem FAR *cur_item = item;
2809
2810 item = item->next_for_message;
2811 free(cur_item);
2812 } while (item != first_item);
2813 }
2814 pvar->ssh_state.packet_handlers[i] = NULL;
2815 }
2816
2817 free(pvar->ssh_state.hostname);
2818 pvar->ssh_state.hostname = NULL;
2819 free(pvar->ssh_state.server_ID);
2820 pvar->ssh_state.server_ID = NULL;
2821 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2822 buf_destroy(&pvar->ssh_state.precompress_outbuf,
2823 &pvar->ssh_state.precompress_outbuflen);
2824 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2825 &pvar->ssh_state.postdecompress_inbuflen);
2826
2827 // support of "Compression delayed" (2006.6.23 maya)
2828 if (pvar->ssh_state.compressing ||
2829 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2830 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2831 deflateEnd(&pvar->ssh_state.compress_stream);
2832 pvar->ssh_state.compressing = FALSE;
2833 }
2834 // support of "Compression delayed" (2006.6.23 maya)
2835 if (pvar->ssh_state.decompressing ||
2836 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2837 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2838 inflateEnd(&pvar->ssh_state.decompress_stream);
2839 pvar->ssh_state.decompressing = FALSE;
2840 }
2841
2842 #if 1
2843 // SSH2���f�[�^���������� (2004.12.27 yutaka)
2844 if (SSHv2(pvar)) {
2845 if (pvar->kexdh) {
2846 DH_free(pvar->kexdh);
2847 pvar->kexdh = NULL;
2848 }
2849 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
2850 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
2851
2852 if (pvar->my_kex != NULL) {
2853 buffer_free(pvar->my_kex);
2854 pvar->my_kex = NULL;
2855 }
2856 if (pvar->peer_kex != NULL) {
2857 buffer_free(pvar->peer_kex);
2858 pvar->peer_kex = NULL;
2859 }
2860
2861 pvar->we_need = 0;
2862 pvar->key_done = 0;
2863 pvar->rekeying = 0;
2864
2865 if (pvar->session_id != NULL) {
2866 free(pvar->session_id);
2867 pvar->session_id = NULL;
2868 }
2869 pvar->session_id_len = 0;
2870
2871 pvar->userauth_success = 0;
2872 //pvar->remote_id = 0;
2873 pvar->shell_id = 0;
2874 pvar->session_nego_status = 0;
2875
2876 pvar->ssh_heartbeat_tick = 0;
2877
2878 if (pvar->decomp_buffer != NULL) {
2879 buffer_free(pvar->decomp_buffer);
2880 pvar->decomp_buffer = NULL;
2881 }
2882
2883 if (pvar->ssh2_authlist != NULL) { // (2007.4.27 yutaka)
2884 free(pvar->ssh2_authlist);
2885 pvar->ssh2_authlist = NULL;
2886 }
2887
2888 pvar->tryed_ssh2_authlist = FALSE;
2889 }
2890 #endif
2891
2892 }
2893
2894 static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen)
2895 {
2896 buffer_t *msg;
2897 unsigned char *outmsg;
2898 unsigned int len;
2899
2900 // SSH2���������������A�p�P�b�g���������B(2005.6.19 yutaka)
2901 if (pvar->rekeying) {
2902 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
2903 // �������������������B
2904 c = NULL;
2905
2906 return;
2907 }
2908
2909 if (c == NULL)
2910 return;
2911
2912 if ((unsigned int)buflen > c->remote_window) {
2913 unsigned int offset = c->remote_window;
2914 // ���������f�[�^����������������������
2915 ssh2_channel_add_bufchain(c, buf + offset, buflen - offset);
2916 buflen = offset;
2917 }
2918 if (buflen > 0) {
2919 msg = buffer_init();
2920 if (msg == NULL) {
2921 // TODO: error check
2922 return;
2923 }
2924 buffer_put_int(msg, c->remote_id);
2925 buffer_put_string(msg, (char *)buf, buflen);
2926
2927 len = buffer_len(msg);
2928 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
2929 //if (len + 12 >= pvar->ssh_state.outbuflen) *(int *)0 = 0;
2930 memcpy(outmsg, buffer_ptr(msg), len);
2931 finish_send_packet(pvar);
2932 buffer_free(msg);
2933 //debug_print(1, pvar->ssh_state.outbuf, 7 + 4 + 1 + 1 + len);
2934
2935 // remote window size������
2936 if (buflen <= c->remote_window) {
2937 c->remote_window -= buflen;
2938 }
2939 else {
2940 c->remote_window = 0;
2941 }
2942 }
2943 }
2944
2945 /* support for port forwarding */
2946 void SSH_channel_send(PTInstVar pvar, int channel_num,
2947 uint32 remote_channel_num,
2948 unsigned char FAR * buf, int len)
2949 {
2950 if (SSHv1(pvar)) {
2951 unsigned char FAR *outmsg =
2952 begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2953
2954 set_uint32(outmsg, remote_channel_num);
2955 set_uint32(outmsg + 4, len);
2956
2957 if (pvar->ssh_state.compressing) {
2958 buf_ensure_size(&pvar->ssh_state.outbuf,
2959 &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2960 pvar->ssh_state.compress_stream.next_in =
2961 pvar->ssh_state.precompress_outbuf;
2962 pvar->ssh_state.compress_stream.avail_in = 9;
2963 pvar->ssh_state.compress_stream.next_out =
2964 pvar->ssh_state.outbuf + 12;
2965 pvar->ssh_state.compress_stream.avail_out =
2966 pvar->ssh_state.outbuflen - 12;
2967
2968 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2969 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2970 "Error compressing packet data");
2971 notify_fatal_error(pvar, pvar->ts->UIMsg);
2972 return;
2973 }
2974
2975 pvar->ssh_state.compress_stream.next_in =
2976 (unsigned char FAR *) buf;
2977 pvar->ssh_state.compress_stream.avail_in = len;
2978
2979 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2980 Z_OK) {
2981 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2982 "Error compressing packet data");
2983 notify_fatal_error(pvar, pvar->ts->UIMsg);
2984 return;
2985 }
2986 } else {
2987 memcpy(outmsg + 8, buf, len);
2988 }
2989
2990 finish_send_packet_special(pvar, 1);
2991
2992 } else {
2993 // �|�[�g�t�H���[�f�B���O���������N���C�A���g���������M�v�����ASSH���M���������T�[�o���������������B
2994 Channel_t *c = ssh2_local_channel_lookup(channel_num);
2995 SSH2_send_channel_data(pvar, c, buf, len);
2996 }
2997
2998 }
2999
3000 void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
3001 {
3002 if (SSHv1(pvar)) {
3003 unsigned char FAR *outmsg =
3004 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
3005
3006 set_uint32(outmsg, remote_channel_num);
3007 finish_send_packet(pvar);
3008
3009 } else { // SSH2 (2005.6.26 yutaka)
3010 int len;
3011 Channel_t *c = NULL;
3012 buffer_t *msg;
3013 unsigned char *outmsg;
3014
3015 msg = buffer_init();
3016 if (msg == NULL) {
3017 // TODO: error check
3018 return;
3019 }
3020 buffer_put_int(msg, remote_channel_num);
3021 buffer_put_int(msg, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
3022 buffer_put_string(msg, "", 0); // description
3023 buffer_put_string(msg, "", 0); // language tag
3024
3025 len = buffer_len(msg);
3026 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, len);
3027 memcpy(outmsg, buffer_ptr(msg), len);
3028 finish_send_packet(pvar);
3029 buffer_free(msg);
3030
3031 }
3032 }
3033
3034 void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
3035 uint32 local_channel_num)
3036 {
3037 if (SSHv1(pvar)) {
3038 unsigned char FAR *outmsg =
3039 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
3040
3041 set_uint32(outmsg, remote_channel_num);
3042 set_uint32(outmsg + 4, local_channel_num);
3043 finish_send_packet(pvar);
3044
3045 } else {
3046 buffer_t *msg;
3047 unsigned char *outmsg;
3048 int len;
3049 Channel_t *c;
3050
3051 // port-forwarding(remote to local)�����[�J�����������������T�[�o�������B(2005.7.2 yutaka)
3052 c = ssh2_local_channel_lookup(local_channel_num);
3053 if (c == NULL) {
3054 // It is sure to be successful as long as it's not a program bug either.
3055 return;
3056 }
3057
3058 msg = buffer_init();
3059 if (msg == NULL) {
3060 // TODO: error check
3061 return;
3062 }
3063 buffer_put_int(msg, c->remote_id);
3064 buffer_put_int(msg, c->self_id);
3065 buffer_put_int(msg, c->local_window);
3066 buffer_put_int(msg, c->local_maxpacket);
3067
3068 len = buffer_len(msg);
3069 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, len);
3070 memcpy(outmsg, buffer_ptr(msg), len);
3071 finish_send_packet(pvar);
3072 buffer_free(msg);
3073
3074 }
3075 }
3076
3077 void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
3078 {
3079 if (SSHv1(pvar)){
3080 unsigned char FAR *outmsg =
3081 begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
3082
3083 set_uint32(outmsg, remote_channel_num);
3084 finish_send_packet(pvar);
3085
3086 } else {
3087 // SSH2: ���������B
3088
3089 }
3090 }
3091
3092 void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num, uint32 local_channel_num)
3093 {
3094 if (SSHv1(pvar)){
3095 unsigned char FAR *outmsg =
3096 begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
3097
3098 set_uint32(outmsg, remote_channel_num);
3099 finish_send_packet(pvar);
3100
3101 } else {
3102 // SSH2: �`���l���N���[�Y���T�[�o�����m
3103 buffer_t *msg;
3104 unsigned char *outmsg;
3105 int len;
3106 Channel_t *c;
3107
3108 // SSH2���������������A�p�P�b�g���������B(2005.6.21 yutaka)
3109 if (pvar->rekeying) {
3110 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
3111 // �������������������B
3112 c = NULL;
3113
3114 return;
3115 }
3116
3117 c = ssh2_local_channel_lookup(local_channel_num);
3118 if (c == NULL)
3119 return;
3120
3121 msg = buffer_init();
3122 if (msg == NULL) {
3123 // TODO: error check
3124 return;
3125 }
3126 buffer_put_int(msg, c->remote_id); // remote ID
3127
3128 len = buffer_len(msg);
3129 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_EOF, len);
3130 memcpy(outmsg, buffer_ptr(msg), len);
3131 finish_send_packet(pvar);
3132 buffer_free(msg);
3133 }
3134
3135 }
3136
3137 void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
3138 char FAR * to_local_host, int to_local_port)
3139 {
3140 if (SSHv1(pvar)) {
3141 int host_len = strlen(to_local_host);
3142 unsigned char FAR *outmsg =
3143 begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST,
3144 12 + host_len);
3145
3146 set_uint32(outmsg, from_server_port);
3147 set_uint32(outmsg + 4, host_len);
3148 memcpy(outmsg + 8, to_local_host, host_len);
3149 set_uint32(outmsg + 8 + host_len, to_local_port);
3150 finish_send_packet(pvar);
3151
3152 enque_forwarding_request_handlers(pvar);
3153
3154 } else {
3155 // SSH2 port-forwading remote to local (2005.6.21 yutaka)
3156 buffer_t *msg;
3157 char *s;
3158 unsigned char *outmsg;
3159 int len;
3160
3161 msg = buffer_init();
3162 if (msg == NULL) {
3163 // TODO: error check
3164 return;
3165 }
3166 s = "tcpip-forward";
3167 buffer_put_string(msg, s, strlen(s)); // ctype
3168 buffer_put_char(msg, 1); // want reply
3169 s = "0.0.0.0";
3170 buffer_put_string(msg, s, strlen(s));
3171
3172 buffer_put_int(msg, from_server_port); // listening port
3173
3174 len = buffer_len(msg);
3175 outmsg = begin_send_packet(pvar, SSH2_MSG_GLOBAL_REQUEST, len);
3176 memcpy(outmsg, buffer_ptr(msg), len);
3177 finish_send_packet(pvar);
3178 buffer_free(msg);
3179
3180 }
3181 }
3182
3183 void SSH_request_X11_forwarding(PTInstVar pvar,
3184 char FAR * auth_protocol,
3185 unsigned char FAR * auth_data,
3186 int auth_data_len, int screen_num)
3187 {
3188 if (SSHv1(pvar)) {
3189 int protocol_len = strlen(auth_protocol);
3190 int data_len = auth_data_len * 2;
3191 int outmsg_len = 12 + protocol_len + data_len;
3192 unsigned char FAR *outmsg =
3193 begin_send_packet(pvar, SSH_CMSG_X11_REQUEST_FORWARDING, outmsg_len);
3194 int i;
3195 char FAR *auth_data_ptr;
3196
3197 set_uint32(outmsg, protocol_len);
3198 memcpy(outmsg + 4, auth_protocol, protocol_len);
3199 set_uint32(outmsg + 4 + protocol_len, data_len);
3200 auth_data_ptr = outmsg + 8 + protocol_len;
3201 for (i = 0; i < auth_data_len; i++) {
3202 _snprintf_s(auth_data_ptr + i * 2,
3203 outmsg_len - (auth_data_ptr - outmsg) - i * 2,
3204 _TRUNCATE, "%.2x", auth_data[i]);
3205 }
3206 set_uint32(outmsg + 8 + protocol_len + data_len, screen_num);
3207
3208 finish_send_packet(pvar);
3209
3210 enque_forwarding_request_handlers(pvar);
3211
3212 } else {
3213 // SSH2: X11 port-forwarding (2005.7.2 yutaka)
3214 buffer_t *msg;
3215 char *s;
3216 unsigned char *outmsg;
3217 int len;
3218 Channel_t *c;
3219 int newlen;
3220 char *newdata;
3221 int i;
3222
3223 msg = buffer_init();
3224 if (msg == NULL) {
3225 // TODO: error check
3226 return;