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 3124 - (show annotations) (download) (as text)
Thu Mar 20 14:31:38 2008 UTC (16 years ago) by yutakapon
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 220880 byte(s)
SCP送信後にファイルがロックされることがある問題への対処。

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