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 3096 - (show annotations) (download) (as text)
Sat Jan 19 15:02:03 2008 UTC (16 years, 2 months ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 211629 byte(s)
SFTPサポートのためのフレームワークを追加。動作上は影響ありません。

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