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 3162 - (show annotations) (download) (as text)
Wed Nov 19 13:39:09 2008 UTC (15 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 226533 byte(s)
同じ名前のラベルが定義されていたので修正

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