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 3090 - (show annotations) (download) (as text)
Fri Jan 4 06:27:51 2008 UTC (16 years, 3 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 209215 byte(s)
SCP構造体のメンバ名を分かりやすくリネーム。

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