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 3092 - (show annotations) (download) (as text)
Sat Jan 5 11:39:33 2008 UTC (16 years, 3 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 210095 byte(s)
_getcwd()使用後にメモリリークをしていたバグを修正。
includeヘッダも追加。

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