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 3145 - (show annotations) (download) (as text)
Thu Sep 11 06:19:49 2008 UTC (15 years, 7 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 224790 byte(s)
SSH2 RSA 接続で、サーバの鍵が短すぎるときのエラーメッセージを変更した。

1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 Copyright (c) 2004-2005, Yutaka Hirata
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
8
9 Redistributions of source code must retain the above copyright notice, this list of
10 conditions and the following disclaimer.
11
12 Redistributions in binary form must reproduce the above copyright notice, this list
13 of conditions and the following disclaimer in the documentation and/or other materials
14 provided with the distribution.
15
16 The name of Robert O'Callahan may not be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "ttxssh.h"
31 #include "util.h"
32 #include "resource.h"
33 #include "libputty.h"
34
35 #include <openssl/bn.h>
36 #include <openssl/evp.h>
37 #include <openssl/dh.h>
38 #include <openssl/engine.h>
39 #include <openssl/rsa.h>
40 #include <openssl/dsa.h>
41 #include <openssl/md5.h>
42 #include <limits.h>
43 #include <malloc.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <process.h>
47 #include <time.h>
48 #include "buffer.h"
49 #include "ssh.h"
50 #include "crypt.h"
51 #include "fwd.h"
52 #include "sftp.h"
53
54 #include <sys/types.h>
55 #include <sys/stat.h>
56 #include <assert.h>
57
58 #include <direct.h>
59 #include <io.h>
60
61 // SSH2 macro
62 #ifdef _DEBUG
63 #define SSH2_DEBUG
64 #endif
65
66 #define DONT_WANTCONFIRM 1 // (2005.3.28 yutaka)
67 #define INTBLOB_LEN 20
68 #define SIGBLOB_LEN (2*INTBLOB_LEN)
69
70 //
71 // SSH2 data structure
72 //
73
74 // channel data structure
75 #define CHANNEL_MAX 100
76
77 enum channel_type {
78 TYPE_SHELL, TYPE_PORTFWD, TYPE_SCP, TYPE_SFTP,
79 };
80
81 enum scp_state {
82 SCP_INIT, SCP_TIMESTAMP, SCP_FILEINFO, SCP_DATA, SCP_CLOSING,
83 };
84
85 typedef struct bufchain {
86 buffer_t *msg;
87 struct bufchain *next;
88 } bufchain_t;
89
90 typedef struct scp {
91 enum scp_dir dir; // transfer direction
92 enum scp_state state; // SCP state
93 char localfile[MAX_PATH]; // local filename
94 char localfilefull[MAX_PATH]; // local filename fullpath
95 char remotefile[MAX_PATH]; // remote filename
96 FILE *localfp; // file pointer for local file
97 struct _stat filestat; // file status information
98 HWND progress_window;
99 HANDLE thread;
100 unsigned int thread_id;
101 PTInstVar pvar;
102 // for receiving file
103 long long filetotalsize;
104 long long filercvsize;
105 } scp_t;
106
107 typedef struct channel {
108 int used;
109 int self_id;
110 int remote_id;
111 unsigned int local_window;
112 unsigned int local_window_max;
113 unsigned int local_consumed;
114 unsigned int local_maxpacket;
115 unsigned int remote_window;
116 unsigned int remote_maxpacket;
117 enum channel_type type;
118 int local_num;
119 bufchain_t *bufchain;
120 scp_t scp;
121 } Channel_t;
122
123 static Channel_t channels[CHANNEL_MAX];
124
125 static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
126
127 static void try_send_credentials(PTInstVar pvar);
128 static void prep_compression(PTInstVar pvar);
129
130 // �����v���g�^�C�v����
131 void SSH2_send_kexinit(PTInstVar pvar);
132 static BOOL handle_SSH2_kexinit(PTInstVar pvar);
133 static void SSH2_dh_kex_init(PTInstVar pvar);
134 static void SSH2_dh_gex_kex_init(PTInstVar pvar);
135 static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
136 static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
137 static BOOL handle_SSH2_newkeys(PTInstVar pvar);
138 static BOOL handle_SSH2_authrequest(PTInstVar pvar);
139 static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
140 static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
141 static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
142 static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
143 static BOOL handle_SSH2_open_failure(PTInstVar pvar);
144 static BOOL handle_SSH2_request_success(PTInstVar pvar);
145 static BOOL handle_SSH2_request_failure(PTInstVar pvar);
146 static BOOL handle_SSH2_channel_success(PTInstVar pvar);
147 static BOOL handle_SSH2_channel_data(PTInstVar pvar);
148 static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
149 static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
150 static BOOL handle_SSH2_channel_close(PTInstVar pvar);
151 static BOOL handle_SSH2_channel_open(PTInstVar pvar);
152 static BOOL handle_SSH2_window_adjust(PTInstVar pvar);
153 static BOOL handle_SSH2_channel_request(PTInstVar pvar);
154 void SSH2_dispatch_init(int stage);
155 int SSH2_dispatch_enabled_check(unsigned char message);
156 void SSH2_dispatch_add_message(unsigned char message);
157 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);
158 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
159 static void start_ssh_heartbeat_thread(PTInstVar pvar);
160 static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen);
161
162 //
163 // channel function
164 //
165 static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack,
166 enum confirm_type type, int local_num)
167 {
168 int i, found;
169 Channel_t *c;
170
171 found = -1;
172 for (i = 0 ; i < CHANNEL_MAX ; i++) {
173 if (channels[i].used == 0) { // free channel
174 found = i;
175 break;
176 }
177 }
178 if (found == -1) { // not free channel
179 return (NULL);
180 }
181
182 // setup
183 c = &channels[found];
184 memset(c, 0, sizeof(Channel_t));
185 c->used = 1;
186 c->self_id = i;
187 c->remote_id = -1;
188 c->local_window = window;
189 c->local_window_max = window;
190 c->local_consumed = 0;
191 c->local_maxpacket = maxpack;
192 c->remote_window = 0;
193 c->remote_maxpacket = 0;
194 c->type = type;
195 c->local_num = local_num; // alloc_channel()�����l��������������
196 c->bufchain = NULL;
197 if (type == TYPE_SCP) {
198 c->scp.state = SCP_INIT;
199 c->scp.progress_window = NULL;
200 c->scp.thread = (HANDLE)-1;
201 c->scp.localfp = NULL;
202 }
203
204 return (c);
205 }
206
207 // remote_window�������������������A�������������o�b�t�@�����X�g�i�������j���������������B
208 static void ssh2_channel_add_bufchain(Channel_t *c, unsigned char *buf, unsigned int buflen)
209 {
210 bufchain_t *p, *old;
211
212 // allocate new buffer
213 p = malloc(sizeof(bufchain_t));
214 if (p == NULL)
215 return;
216 p->msg = buffer_init();
217 if (p == NULL) {
218 free(p);
219 return;
220 }
221 buffer_put_raw(p->msg, buf, buflen);
222 p->next = NULL;
223
224 if (c->bufchain == NULL) {
225 c->bufchain = p;
226 } else {
227 old = c->bufchain;
228 while (old->next)
229 old = old->next;
230 old->next = p;
231 }
232 }
233
234
235 static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c)
236 {
237 bufchain_t *ch;
238 unsigned int size;
239
240 while (c->bufchain) {
241 // ����������������
242 ch = c->bufchain;
243 size = buffer_len(ch->msg);
244 if (size >= c->remote_window)
245 break;
246
247 if (c->local_num == -1) { // shell or SCP
248 SSH2_send_channel_data(pvar, c, buffer_ptr(ch->msg), size);
249 } else { // port-forwarding
250 SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size);
251 }
252
253 c->bufchain = ch->next;
254
255 buffer_free(ch->msg);
256 free(ch);
257 }
258 }
259
260
261
262 // channel close�����`���l���\���������X�g�����p����
263 // (2007.4.26 yutaka)
264 static void ssh2_channel_delete(Channel_t *c)
265 {
266 bufchain_t *ch, *ptr;
267
268 ch = c->bufchain;
269 while (ch) {
270 if (ch->msg)
271 buffer_free(ch->msg);
272 ptr = ch;
273 ch = ch->next;
274 free(ptr);
275 }
276
277 if (c->type == TYPE_SCP) {
278 c->scp.state = SCP_CLOSING;
279 if (c->scp.localfp != NULL)
280 fclose(c->scp.localfp);
281 if (c->scp.progress_window != NULL) {
282 DestroyWindow(c->scp.progress_window);
283 c->scp.progress_window = NULL;
284 }
285 if (c->scp.thread != (HANDLE)-1L) {
286 WaitForSingleObject(c->scp.thread, INFINITE);
287 CloseHandle(c->scp.thread);
288 c->scp.thread = (HANDLE)-1L;
289 }
290 }
291
292 memset(c, 0, sizeof(Channel_t));
293 c->used = 0;
294 }
295
296
297 // connection close������������
298 void ssh2_channel_free(void)
299 {
300 int i;
301 Channel_t *c;
302
303 for (i = 0 ; i < CHANNEL_MAX ; i++) {
304 c = &channels[i];
305 ssh2_channel_delete(c);
306 }
307
308 }
309
310 static Channel_t *ssh2_channel_lookup(int id)
311 {
312 Channel_t *c;
313
314 if (id < 0 || id >= CHANNEL_MAX) {
315 return (NULL);
316 }
317 c = &channels[id];
318 if (c->used == 0) { // already freed
319 return (NULL);
320 }
321 return (c);
322 }
323
324 // SSH1��������������channel�\���������ASSH2������Channel_t�����������B
325 // TODO: �����I�����`���l���\������1�������������B
326 // (2005.6.12 yutaka)
327 static Channel_t *ssh2_local_channel_lookup(int local_num)
328 {
329 int i;
330 Channel_t *c;
331
332 for (i = 0 ; i < CHANNEL_MAX ; i++) {
333 c = &channels[i];
334 if (c->local_num == local_num)
335 return (c);
336 }
337 return (NULL);
338 }
339
340
341 //
342 // SSH heartbeat mutex
343 //
344 // TTSSH�� thread-safe �������������A�}���`�X���b�h�������p�P�b�g���M�����������B
345 // �V���O���X���b�h�����R���e�L�X�g�X�C�b�`�������������������������A
346 // ���b�N�������K�v�����������A���������B(2007.12.26 yutaka)
347 //
348 static CRITICAL_SECTION g_ssh_heartbeat_lock; /* �����M�p���b�N */
349
350 void ssh_heartbeat_lock_initialize(void)
351 {
352 //InitializeCriticalSection(&g_ssh_heartbeat_lock);
353 }
354
355 void ssh_heartbeat_lock_finalize(void)
356 {
357 //DeleteCriticalSection(&g_ssh_heartbeat_lock);
358 }
359
360 void ssh_heartbeat_lock(void)
361 {
362 //EnterCriticalSection(&g_ssh_heartbeat_lock);
363 }
364
365 void ssh_heartbeat_unlock(void)
366 {
367 //LeaveCriticalSection(&g_ssh_heartbeat_lock);
368 }
369
370
371 //
372 // SSH memory dump (for debug)
373 //
374 // (2005.3.7 yutaka)
375 //
376 #define MEMTAG_MAX 300
377 #define LOGDUMP "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_authrequest);
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
1920 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1921 // TODO: error check
1922 return;
1923 }
1924
1925 handle_messages[handle_message_count++] = message;
1926 }
1927
1928 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1929 {
1930 unsigned char c;
1931
1932 for (c = begin ; c <= end ; c++) {
1933 SSH2_dispatch_add_message(c);
1934 }
1935 }
1936
1937
1938 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1939 int padding)
1940 {
1941 unsigned char message = prep_packet(pvar, data, len, padding);
1942
1943
1944 #ifdef SSH2_DEBUG
1945 // for SSH2(yutaka)
1946 if (SSHv2(pvar)) {
1947 if (pvar->key_done) {
1948 message = message;
1949 }
1950
1951 if (pvar->userauth_success) {
1952 message = message;
1953 }
1954
1955 if (pvar->rekeying) {
1956 message = message;
1957 }
1958 }
1959 #endif
1960
1961 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1962 if (message != SSH_MSG_NONE) {
1963 // ���b�Z�[�W�^�C�v���������n���h�����N��
1964 SSHPacketHandler handler = get_handler(pvar, message);
1965
1966 // for SSH2(yutaka)
1967 if (SSHv2(pvar)) {
1968 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1969 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1970 char buf[1024];
1971
1972 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
1973 "Unexpected SSH2 message(%d) on current stage(%d)");
1974 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1975 pvar->ts->UIMsg, message, handle_message_stage);
1976 notify_fatal_error(pvar, buf);
1977 // abort
1978 }
1979 }
1980
1981 if (handler == NULL) {
1982 if (SSHv1(pvar)) {
1983 char buf[1024];
1984
1985 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
1986 "Unexpected packet type received: %d");
1987 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1988 pvar->ts->UIMsg, message, handle_message_stage);
1989 notify_fatal_error(pvar, buf);
1990 } else {
1991 unsigned char FAR *outmsg =
1992 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
1993
1994 set_uint32(outmsg,
1995 pvar->ssh_state.receiver_sequence_number - 1);
1996 finish_send_packet(pvar);
1997 /* XXX need to decompress incoming packet, but how? */
1998 }
1999 } else {
2000 if (!handler(pvar)) {
2001 deque_handlers(pvar, message);
2002 }
2003 }
2004 }
2005 }
2006
2007 static BOOL handle_pty_success(PTInstVar pvar)
2008 {
2009 FWD_enter_interactive_mode(pvar);
2010 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2011 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2012 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2013 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2014 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2015 handle_channel_input_eof);
2016 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2017 handle_channel_output_eof);
2018 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2019 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2020 return FALSE;
2021 }
2022
2023 static BOOL handle_pty_failure(PTInstVar pvar)
2024 {
2025 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2026 "The server cannot allocate a pseudo-terminal. "
2027 "You may encounter some problems with the terminal.");
2028 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2029 return handle_pty_success(pvar);
2030 }
2031
2032 static void prep_pty(PTInstVar pvar)
2033 {
2034 int len = strlen(pvar->ts->TermType);
2035 unsigned char FAR *outmsg =
2036 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2037 4 + len + 16 + sizeof(ssh_ttymodes));
2038 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2039 static const SSHPacketHandler handlers[]
2040 = { handle_pty_success, handle_pty_failure };
2041
2042 set_uint32(outmsg, len);
2043 memcpy(outmsg + 4, pvar->ts->TermType, len);
2044 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2045 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2046 set_uint32(outmsg + 4 + len + 8, 0);
2047 set_uint32(outmsg + 4 + len + 12, 0);
2048 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2049 finish_send_packet(pvar);
2050
2051 enque_handlers(pvar, 2, msgs, handlers);
2052
2053 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2054 finish_send_packet(pvar);
2055 }
2056
2057 static void prep_forwarding(PTInstVar pvar)
2058 {
2059 FWD_prep_forwarding(pvar);
2060 prep_pty(pvar);
2061 }
2062
2063
2064 //
2065 //
2066 // (2005.7.10 yutaka)
2067 static void enable_send_compression(PTInstVar pvar)
2068 {
2069 static int initialize = 0;
2070
2071 if (initialize) {
2072 deflateEnd(&pvar->ssh_state.compress_stream);
2073 }
2074 initialize = 1;
2075
2076 pvar->ssh_state.compress_stream.zalloc = NULL;
2077 pvar->ssh_state.compress_stream.zfree = NULL;
2078 pvar->ssh_state.compress_stream.opaque = NULL;
2079 if (deflateInit
2080 (&pvar->ssh_state.compress_stream,
2081 pvar->ssh_state.compression_level) != Z_OK) {
2082 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2083 "An error occurred while setting up compression.\n"
2084 "The connection will close.");
2085 notify_fatal_error(pvar, pvar->ts->UIMsg);
2086 return;
2087 } else {
2088 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2089 if (SSHv2(pvar)) {
2090 pvar->ssh_state.compressing = FALSE;
2091 } else {
2092 pvar->ssh_state.compressing = TRUE;
2093 }
2094 }
2095 }
2096
2097 static void enable_recv_compression(PTInstVar pvar)
2098 {
2099 static int initialize = 0;
2100
2101 if (initialize) {
2102 deflateEnd(&pvar->ssh_state.decompress_stream);
2103 }
2104 initialize = 1;
2105
2106 pvar->ssh_state.decompress_stream.zalloc = NULL;
2107 pvar->ssh_state.decompress_stream.zfree = NULL;
2108 pvar->ssh_state.decompress_stream.opaque = NULL;
2109 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2110 deflateEnd(&pvar->ssh_state.compress_stream);
2111 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2112 "An error occurred while setting up compression.\n"
2113 "The connection will close.");
2114 notify_fatal_error(pvar, pvar->ts->UIMsg);
2115 return;
2116 } else {
2117 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2118 if (SSHv2(pvar)) {
2119 pvar->ssh_state.decompressing = FALSE;
2120 } else {
2121 pvar->ssh_state.decompressing = TRUE;
2122 }
2123
2124 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2125 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2126 }
2127 }
2128
2129 static void enable_compression(PTInstVar pvar)
2130 {
2131 enable_send_compression(pvar);
2132 enable_recv_compression(pvar);
2133
2134 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2135 if (SSHv2(pvar)) {
2136 pvar->ssh_state.compressing = FALSE;
2137 pvar->ssh_state.decompressing = FALSE;
2138 }
2139
2140 }
2141
2142 static BOOL handle_enable_compression(PTInstVar pvar)
2143 {
2144 enable_compression(pvar);
2145 prep_forwarding(pvar);
2146 return FALSE;
2147 }
2148
2149 static BOOL handle_disable_compression(PTInstVar pvar)
2150 {
2151 prep_forwarding(pvar);
2152 return FALSE;
2153 }
2154
2155 static void prep_compression(PTInstVar pvar)
2156 {
2157 if (pvar->session_settings.CompressionLevel > 0) {
2158 // added if statement (2005.7.10 yutaka)
2159 if (SSHv1(pvar)) {
2160 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2161 static const SSHPacketHandler handlers[]
2162 = { handle_enable_compression, handle_disable_compression };
2163
2164 unsigned char FAR *outmsg =
2165 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2166
2167 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2168 finish_send_packet(pvar);
2169
2170 enque_handlers(pvar, 2, msgs, handlers);
2171 }
2172
2173 pvar->ssh_state.compression_level =
2174 pvar->session_settings.CompressionLevel;
2175
2176 } else {
2177 // added if statement (2005.7.10 yutaka)
2178 if (SSHv1(pvar)) {
2179 prep_forwarding(pvar);
2180 }
2181 }
2182 }
2183
2184 static void enque_simple_auth_handlers(PTInstVar pvar)
2185 {
2186 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2187 static const SSHPacketHandler handlers[]
2188 = { handle_auth_success, handle_auth_failure };
2189
2190 enque_handlers(pvar, 2, msgs, handlers);
2191 }
2192
2193 static BOOL handle_rsa_challenge(PTInstVar pvar)
2194 {
2195 int challenge_bytes;
2196
2197 if (!grab_payload(pvar, 2)) {
2198 return FALSE;
2199 }
2200
2201 challenge_bytes = get_mpint_len(pvar, 0);
2202
2203 if (grab_payload(pvar, challenge_bytes)) {
2204 unsigned char FAR *outmsg =
2205 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2206
2207 if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2208 if (CRYPT_generate_RSA_challenge_response
2209 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2210
2211 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2212 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2213 #if 0
2214 //AUTH_destroy_cur_cred(pvar);
2215 #endif
2216
2217 finish_send_packet(pvar);
2218
2219 enque_simple_auth_handlers(pvar);
2220 } else {
2221 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2222 "An error occurred while decrypting the RSA challenge.\n"
2223 "Perhaps the key file is corrupted.");
2224 notify_fatal_error(pvar, pvar->ts->UIMsg);
2225 }
2226 }
2227 else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2228 int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2229 int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2230 int server_key_bytes = (server_key_bits + 7) / 8;
2231 int host_key_bytes = (host_key_bits + 7) / 8;
2232 int session_buf_len = server_key_bytes + host_key_bytes + 8;
2233 char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2234 unsigned char session_id[16];
2235
2236 unsigned char *hash;
2237 int pubkeylen, hashlen;
2238
2239 /* Pageant ���n�b�V�����v�Z���������� */
2240 // ���J��������
2241 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2242 pvar->pageant_keylistlen);
2243 // �Z�b�V����ID������
2244 BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2245 BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2246 session_buf + host_key_bytes);
2247 memcpy(session_buf + server_key_bytes + host_key_bytes,
2248 pvar->crypt_state.server_cookie, 8);
2249 MD5(session_buf, session_buf_len, session_id);
2250 // �n�b�V������������
2251 hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2252 pubkeylen,
2253 pvar->ssh_state.payload,
2254 challenge_bytes + 2,
2255 session_id,
2256 &hashlen);
2257
2258 // �n�b�V�������M
2259 memcpy(outmsg, hash, 16);
2260 free(hash);
2261
2262 finish_send_packet(pvar);
2263
2264 enque_simple_auth_handlers(pvar);
2265 }
2266 }
2267
2268 return FALSE;
2269 }
2270
2271 #define OBFUSCATING_ROUND_TO 32
2272
2273 static int obfuscating_round_up(PTInstVar pvar, int size)
2274 {
2275 return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2276 }
2277
2278 static void try_send_credentials(PTInstVar pvar)
2279 {
2280 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2281 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2282 static const int RSA_msgs[] =
2283 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2284 static const SSHPacketHandler RSA_handlers[]
2285 = { handle_rsa_challenge, handle_rsa_auth_refused };
2286 static const int TIS_msgs[] =
2287 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2288 static const SSHPacketHandler TIS_handlers[]
2289 = { handle_TIS_challenge, handle_auth_failure };
2290
2291 // SSH2���������������������X�L�b�v
2292 if (SSHv2(pvar))
2293 goto skip_ssh2;
2294
2295 switch (cred->method) {
2296 case SSH_AUTH_NONE:
2297 return;
2298 case SSH_AUTH_PASSWORD:{
2299 int len = strlen(cred->password);
2300 // Round up password length to discourage traffic analysis
2301 int obfuscated_len = obfuscating_round_up(pvar, len);
2302 unsigned char FAR *outmsg =
2303 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2304 4 + obfuscated_len);
2305
2306 notify_verbose_message(pvar,
2307 "Trying PASSWORD authentication...",
2308 LOG_LEVEL_VERBOSE);
2309
2310 set_uint32(outmsg, obfuscated_len);
2311 memcpy(outmsg + 4, cred->password, len);
2312 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2313
2314 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2315 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2316 #if 0
2317 //AUTH_destroy_cur_cred(pvar);
2318 #endif
2319
2320 enque_simple_auth_handlers(pvar);
2321 break;
2322 }
2323 case SSH_AUTH_RHOSTS:{
2324 int len = strlen(cred->rhosts_client_user);
2325 unsigned char FAR *outmsg =
2326 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2327
2328 notify_verbose_message(pvar,
2329 "Trying RHOSTS authentication...",
2330 LOG_LEVEL_VERBOSE);
2331
2332 set_uint32(outmsg, len);
2333 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2334 AUTH_destroy_cur_cred(pvar);
2335 enque_simple_auth_handlers(pvar);
2336 break;
2337 }
2338 case SSH_AUTH_RSA:{
2339 int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2340 unsigned char FAR *outmsg =
2341 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2342
2343 notify_verbose_message(pvar,
2344 "Trying RSA authentication...",
2345 LOG_LEVEL_VERBOSE);
2346
2347 set_ushort16_MSBfirst(outmsg, len * 8);
2348 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2349 /* don't destroy the current credentials yet */
2350 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2351 break;
2352 }
2353 case SSH_AUTH_RHOSTS_RSA:{
2354 int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2355 int name_len = strlen(cred->rhosts_client_user);
2356 int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2357 int index;
2358 unsigned char FAR *outmsg =
2359 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2360 12 + mod_len + name_len + exp_len);
2361
2362 notify_verbose_message(pvar,
2363 "Trying RHOSTS+RSA authentication...",
2364 LOG_LEVEL_VERBOSE);
2365
2366 set_uint32(outmsg, name_len);
2367 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2368 index = 4 + name_len;
2369
2370 set_uint32(outmsg + index, 8 * mod_len);
2371 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2372 BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2373 index += 6 + exp_len;
2374
2375 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2376 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2377 /* don't destroy the current credentials yet */
2378 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2379 break;
2380 }
2381 case SSH_AUTH_PAGEANT:{
2382 unsigned char FAR *outmsg;
2383 unsigned char *pubkey;
2384 int len, bn_bytes;
2385
2386 if (pvar->pageant_keycurrent != 0) {
2387 // ���O�������X�L�b�v
2388 pvar->pageant_curkey += 4;
2389 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2390 bn_bytes = (len + 7) / 8;
2391 pvar->pageant_curkey += 2 + bn_bytes;
2392 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2393 bn_bytes = (len + 7) / 8;
2394 pvar->pageant_curkey += 2 + bn_bytes;
2395 // ���O�������R�����g���X�L�b�v
2396 len = get_uint32_MSBfirst(pvar->pageant_curkey);
2397 pvar->pageant_curkey += 4 + len;
2398 // �����������u������
2399 }
2400 pubkey = pvar->pageant_curkey + 4;
2401 len = get_ushort16_MSBfirst(pubkey);
2402 bn_bytes = (len + 7) / 8;
2403 pubkey += 2 + bn_bytes;
2404 len = get_ushort16_MSBfirst(pubkey);
2405 bn_bytes = (len + 7) / 8;
2406 pubkey += 2;
2407 outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2408
2409 notify_verbose_message(pvar,
2410 "Trying RSA authentication...",
2411 LOG_LEVEL_VERBOSE);
2412
2413 set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2414 memcpy(outmsg + 2, pubkey, bn_bytes);
2415 /* don't destroy the current credentials yet */
2416
2417 pvar->pageant_keycurrent++;
2418
2419 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2420 break;
2421 }
2422 case SSH_AUTH_TIS:{
2423 if (cred->password == NULL) {
2424 unsigned char FAR *outmsg =
2425 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2426
2427 notify_verbose_message(pvar,
2428 "Trying TIS authentication...",
2429 LOG_LEVEL_VERBOSE);
2430 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2431 } else {
2432 int len = strlen(cred->password);
2433 int obfuscated_len = obfuscating_round_up(pvar, len);
2434 unsigned char FAR *outmsg =
2435 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2436 4 + obfuscated_len);
2437
2438 notify_verbose_message(pvar, "Sending TIS response",
2439 LOG_LEVEL_VERBOSE);
2440
2441 set_uint32(outmsg, obfuscated_len);
2442 memcpy(outmsg + 4, cred->password, len);
2443 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2444 enque_simple_auth_handlers(pvar);
2445 }
2446
2447 AUTH_destroy_cur_cred(pvar);
2448 break;
2449 }
2450 default:
2451 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2452 "Internal error: unsupported authentication method");
2453 notify_fatal_error(pvar, pvar->ts->UIMsg);
2454 return;
2455 }
2456
2457 finish_send_packet(pvar);
2458
2459 skip_ssh2:;
2460 destroy_packet_buf(pvar);
2461
2462 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2463 }
2464 }
2465
2466 static void try_send_user_name(PTInstVar pvar)
2467 {
2468 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2469 char FAR *username = AUTH_get_user_name(pvar);
2470
2471 if (username != NULL) {
2472 int len = strlen(username);
2473 int obfuscated_len = obfuscating_round_up(pvar, len);
2474 unsigned char FAR *outmsg =
2475 begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
2476 char buf[1024] = "Sending user name: ";
2477 static const int msgs[] =
2478 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2479 static const SSHPacketHandler handlers[]
2480 = { handle_noauth_success, handle_auth_required };
2481
2482 set_uint32(outmsg, obfuscated_len);
2483 memcpy(outmsg + 4, username, len);
2484 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2485 finish_send_packet(pvar);
2486
2487 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2488
2489 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2490 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2491
2492 enque_handlers(pvar, 2, msgs, handlers);
2493 }
2494 }
2495 }
2496
2497 static void send_session_key(PTInstVar pvar)
2498 {
2499 int encrypted_session_key_len;
2500 unsigned char FAR *outmsg;
2501
2502 if (SSHv1(pvar)) {
2503 encrypted_session_key_len =
2504 CRYPT_get_encrypted_session_key_len(pvar);
2505 }
2506
2507 if (!CRYPT_choose_ciphers(pvar))
2508 return;
2509
2510 if (SSHv1(pvar)) {
2511 outmsg =
2512 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2513 15 + encrypted_session_key_len);
2514 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2515 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2516 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2517 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2518 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2519 return;
2520 set_uint32(outmsg + 11 + encrypted_session_key_len,
2521 SSH_PROTOFLAG_SCREEN_NUMBER |
2522 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2523 finish_send_packet(pvar);
2524 }
2525
2526 if (!CRYPT_start_encryption(pvar, 1, 1))
2527 return;
2528 notify_established_secure_connection(pvar);
2529
2530 if (SSHv1(pvar)) {
2531 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2532 }
2533
2534 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2535
2536 if (SSHv1(pvar)) {
2537 try_send_user_name(pvar);
2538 }
2539 }
2540
2541 /*************************
2542 END of message handlers
2543 ************************/
2544
2545 void SSH_init(PTInstVar pvar)
2546 {
2547 int i;
2548
2549 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2550 buf_create(&pvar->ssh_state.precompress_outbuf,
2551 &pvar->ssh_state.precompress_outbuflen);
2552 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2553 &pvar->ssh_state.postdecompress_inbuflen);
2554 pvar->ssh_state.payload = NULL;
2555 pvar->ssh_state.compressing = FALSE;
2556 pvar->ssh_state.decompressing = FALSE;
2557 pvar->ssh_state.status_flags =
2558 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2559 pvar->ssh_state.payload_datalen = 0;
2560 pvar->ssh_state.hostname = NULL;
2561 pvar->ssh_state.server_ID = NULL;
2562 pvar->ssh_state.receiver_sequence_number = 0;
2563 pvar->ssh_state.sender_sequence_number = 0;
2564 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2565 pvar->ssh_state.packet_handlers[i] = NULL;
2566 }
2567
2568 // for SSH2(yutaka)
2569 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2570 pvar->userauth_success = 0;
2571 pvar->session_nego_status = 0;
2572 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2573 pvar->rekeying = 0;
2574 pvar->key_done = 0;
2575 pvar->ssh2_autologin = 0; // autologin disabled(default)
2576 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2577 pvar->userauth_retry_count = 0;
2578 pvar->decomp_buffer = NULL;
2579 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2580 pvar->tryed_ssh2_authlist = FALSE;
2581
2582 }
2583
2584 void SSH_open(PTInstVar pvar)
2585 {
2586 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2587 pvar->ssh_state.tcpport = pvar->ts->TCPPort;
2588 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2589 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2590 }
2591
2592 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2593 {
2594 if (SSHv1(pvar)) {
2595 int len = reason == NULL ? 0 : strlen(reason);
2596 unsigned char FAR *outmsg =
2597 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2598
2599 set_uint32(outmsg, len);
2600 if (reason != NULL) {
2601 memcpy(outmsg + 4, reason, len);
2602 }
2603 finish_send_packet(pvar);
2604
2605 } else { // for SSH2(yutaka)
2606 buffer_t *msg;
2607 unsigned char *outmsg;
2608 int len;
2609 Channel_t *c;
2610
2611 c = ssh2_channel_lookup(pvar->shell_id);
2612 if (c == NULL)
2613 return;
2614
2615 // SSH2 server��channel close���`����
2616 msg = buffer_init();
2617 if (msg == NULL) {
2618 // TODO: error check
2619 return;
2620 }
2621 buffer_put_int(msg, c->remote_id);
2622
2623 len = buffer_len(msg);
2624 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2625 memcpy(outmsg, buffer_ptr(msg), len);
2626 finish_send_packet(pvar);
2627 buffer_free(msg);
2628
2629 }
2630
2631 }
2632
2633 void SSH_notify_host_OK(PTInstVar pvar)
2634 {
2635 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2636 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2637 send_session_key(pvar);
2638 }
2639 }
2640
2641 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2642 {
2643 pvar->ssh_state.win_cols = cols;
2644 pvar->ssh_state.win_rows = rows;
2645
2646 if (SSHv1(pvar)) {
2647 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2648 unsigned char FAR *outmsg =
2649 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2650
2651 set_uint32(outmsg, rows);
2652 set_uint32(outmsg + 4, cols);
2653 set_uint32(outmsg + 8, 0);
2654 set_uint32(outmsg + 12, 0);
2655 finish_send_packet(pvar);
2656 }
2657
2658 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2659 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2660 buffer_t *msg;
2661 char *s;
2662 unsigned char *outmsg;
2663 int len;
2664 Channel_t *c;
2665
2666 c = ssh2_channel_lookup(pvar->shell_id);
2667 if (c == NULL)
2668 return;
2669
2670 msg = buffer_init();
2671 if (msg == NULL) {
2672 // TODO: error check
2673 return;
2674 }
2675 buffer_put_int(msg, c->remote_id);
2676 s = "window-change";
2677 buffer_put_string(msg, s, strlen(s));
2678 buffer_put_char(msg, 0); // wantconfirm
2679 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2680 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2681 buffer_put_int(msg, 480); // XXX:
2682 buffer_put_int(msg, 640); // XXX:
2683 len = buffer_len(msg);
2684 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2685 memcpy(outmsg, buffer_ptr(msg), len);
2686 finish_send_packet(pvar);
2687 buffer_free(msg);
2688
2689 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2690
2691 } else {
2692 // SSH�����������������������B
2693
2694 }
2695
2696 }
2697
2698 int SSH_get_min_packet_size(PTInstVar pvar)
2699 {
2700 if (SSHv1(pvar)) {
2701 return 12;
2702 } else {
2703 int block_size = CRYPT_get_decryption_block_size(pvar);
2704
2705 return max(16, block_size);
2706 }
2707 }
2708
2709 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2710 at least 5 bytes must be decrypted */
2711 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2712 {
2713 if (SSHv2(pvar)) {
2714 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2715 }
2716 }
2717
2718 int SSH_get_clear_MAC_size(PTInstVar pvar)
2719 {
2720 if (SSHv1(pvar)) {
2721 return 0;
2722 } else {
2723 return CRYPT_get_receiver_MAC_size(pvar);
2724 }
2725 }
2726
2727 void SSH_notify_user_name(PTInstVar pvar)
2728 {
2729 try_send_user_name(pvar);
2730 }
2731
2732 void SSH_notify_cred(PTInstVar pvar)
2733 {
2734 try_send_credentials(pvar);
2735 }
2736
2737 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, unsigned int buflen)
2738 {
2739 // RAW�p�P�b�g�_���v������ (2008.8.15 yutaka)
2740 if (LOG_LEVEL_SSHDUMP <= pvar->session_settings.LogLevel) {
2741 init_memdump();
2742 push_memdump("SSH sending packet", "SSH_send", (char *)buf, buflen);
2743 }
2744
2745 if (SSHv1(pvar)) {
2746 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2747 return;
2748 }
2749
2750 while (buflen > 0) {
2751 int len =
2752 buflen >
2753 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2754 unsigned char FAR *outmsg =
2755 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2756
2757 set_uint32(outmsg, len);
2758
2759 if (pvar->ssh_state.compressing) {
2760 buf_ensure_size(&pvar->ssh_state.outbuf,
2761 &pvar->ssh_state.outbuflen,
2762 len + (len >> 6) + 50);
2763 pvar->ssh_state.compress_stream.next_in =
2764 pvar->ssh_state.precompress_outbuf;
2765 pvar->ssh_state.compress_stream.avail_in = 5;
2766 pvar->ssh_state.compress_stream.next_out =
2767 pvar->ssh_state.outbuf + 12;
2768 pvar->ssh_state.compress_stream.avail_out =
2769 pvar->ssh_state.outbuflen - 12;
2770
2771 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2772 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2773 "Error compressing packet data");
2774 notify_fatal_error(pvar, pvar->ts->UIMsg);
2775 return;
2776 }
2777
2778 pvar->ssh_state.compress_stream.next_in =
2779 (unsigned char FAR *) buf;
2780 pvar->ssh_state.compress_stream.avail_in = len;
2781
2782 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
2783 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2784 "Error compressing packet data");
2785 notify_fatal_error(pvar, pvar->ts->UIMsg);
2786 return;
2787 }
2788 } else {
2789 memcpy(outmsg + 4, buf, len);
2790 }
2791
2792 finish_send_packet_special(pvar, 1);
2793
2794 buflen -= len;
2795 buf += len;
2796 }
2797
2798 } else { // for SSH2(yutaka)
2799 Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
2800 SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen);
2801 }
2802
2803 }
2804
2805 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
2806 {
2807 int num_bytes = pvar->ssh_state.payload_datalen;
2808
2809 if (num_bytes > len) {
2810 num_bytes = len;
2811 }
2812
2813 if (!pvar->ssh_state.decompressing) {
2814 memcpy(dest,
2815 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
2816 num_bytes);
2817 pvar->ssh_state.payload_datastart += num_bytes;
2818 } else if (num_bytes > 0) {
2819 pvar->ssh_state.decompress_stream.next_out = dest;
2820 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
2821
2822 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
2823 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
2824 "Invalid compressed data in received packet");
2825 notify_fatal_error(pvar, pvar->ts->UIMsg);
2826 return 0;
2827 }
2828 }
2829
2830 pvar->ssh_state.payload_datalen -= num_bytes;
2831
2832 return num_bytes;
2833 }
2834
2835 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
2836 {
2837 char buf[1024];
2838 char buf2[1024];
2839
2840 // added support of SSH2 packet compression (2005.7.10 yutaka)
2841 // support of "Compression delayed" (2006.6.23 maya)
2842 if (pvar->ssh_state.compressing ||
2843 pvar->ctos_compression == COMP_ZLIB ||
2844 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2845 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2846 unsigned long total_out =
2847 pvar->ssh_state.compress_stream.total_out;
2848
2849 if (total_out > 0) {
2850 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2851 "level %d; ratio %.1f (%ld:%ld)");
2852 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2853 pvar->ssh_state.compression_level,
2854 ((double) total_in) / total_out, total_in,
2855 total_out);
2856 } else {
2857 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2858 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2859 pvar->ssh_state.compression_level);
2860 }
2861 } else {
2862 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2863 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2864 }
2865
2866 // support of "Compression delayed" (2006.6.23 maya)
2867 if (pvar->ssh_state.decompressing ||
2868 pvar->stoc_compression == COMP_ZLIB ||
2869 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2870 unsigned long total_in =
2871 pvar->ssh_state.decompress_stream.total_in;
2872 unsigned long total_out =
2873 pvar->ssh_state.decompress_stream.total_out;
2874
2875 if (total_in > 0) {
2876 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2877 "level %d; ratio %.1f (%ld:%ld)");
2878 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2879 pvar->ssh_state.compression_level,
2880 ((double) total_out) / total_in, total_out,
2881 total_in);
2882 } else {
2883 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2884 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2885 pvar->ssh_state.compression_level);
2886 }
2887 } else {
2888 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2889 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2890 }
2891
2892 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
2893 "Upstream %s; Downstream %s");
2894 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
2895 }
2896
2897 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2898 {
2899 strncpy_s(dest, len,
2900 pvar->ssh_state.server_ID == NULL ? "Unknown"
2901 : pvar->ssh_state.server_ID,
2902 _TRUNCATE);
2903 }
2904
2905 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2906 int len)
2907 {
2908 if (pvar->protocol_major == 0) {
2909 strncpy_s(dest, len, "Unknown", _TRUNCATE);
2910 } else {
2911 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
2912 pvar->protocol_minor);
2913 }
2914 }
2915
2916 void SSH_end(PTInstVar pvar)
2917 {
2918 int i;
2919 int mode;
2920
2921 for (i = 0; i < 256; i++) {
2922 SSHPacketHandlerItem FAR *first_item =
2923 pvar->ssh_state.packet_handlers[i];
2924
2925 if (first_item != NULL) {
2926 SSHPacketHandlerItem FAR *item = first_item;
2927
2928 do {
2929 SSHPacketHandlerItem FAR *cur_item = item;
2930
2931 item = item->next_for_message;
2932 free(cur_item);
2933 } while (item != first_item);
2934 }
2935 pvar->ssh_state.packet_handlers[i] = NULL;
2936 }
2937
2938 free(pvar->ssh_state.hostname);
2939 pvar->ssh_state.hostname = NULL;
2940 free(pvar->ssh_state.server_ID);
2941 pvar->ssh_state.server_ID = NULL;
2942 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2943 buf_destroy(&pvar->ssh_state.precompress_outbuf,
2944 &pvar->ssh_state.precompress_outbuflen);
2945 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2946 &pvar->ssh_state.postdecompress_inbuflen);
2947
2948 // support of "Compression delayed" (2006.6.23 maya)
2949 if (pvar->ssh_state.compressing ||
2950 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2951 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2952 deflateEnd(&pvar->ssh_state.compress_stream);
2953 pvar->ssh_state.compressing = FALSE;
2954 }
2955 // support of "Compression delayed" (2006.6.23 maya)
2956 if (pvar->ssh_state.decompressing ||
2957 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2958 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2959 inflateEnd(&pvar->ssh_state.decompress_stream);
2960 pvar->ssh_state.decompressing = FALSE;
2961 }
2962
2963 #if 1
2964 // SSH2���f�[�^���������� (2004.12.27 yutaka)
2965 if (SSHv2(pvar)) {
2966 if (pvar->kexdh) {
2967 DH_free(pvar->kexdh);
2968 pvar->kexdh = NULL;
2969 }
2970 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
2971 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
2972
2973 if (pvar->my_kex != NULL) {
2974 buffer_free(pvar->my_kex);
2975 pvar->my_kex = NULL;
2976 }
2977 if (pvar->peer_kex != NULL) {
2978 buffer_free(pvar->peer_kex);
2979 pvar->peer_kex = NULL;
2980 }
2981
2982 pvar->we_need = 0;
2983 pvar->key_done = 0;
2984 pvar->rekeying = 0;
2985
2986 if (pvar->session_id != NULL) {
2987 free(pvar->session_id);
2988 pvar->session_id = NULL;
2989 }
2990 pvar->session_id_len = 0;
2991
2992 pvar->userauth_success = 0;
2993 //pvar->remote_id = 0;
2994 pvar->shell_id = 0;
2995 pvar->session_nego_status = 0;
2996
2997 pvar->ssh_heartbeat_tick = 0;
2998
2999 if (pvar->decomp_buffer != NULL) {
3000 buffer_free(pvar->decomp_buffer);
3001 pvar->decomp_buffer = NULL;
3002 }
3003
3004 if (pvar->ssh2_authlist != NULL) { // (2007.4.27 yutaka)
3005 free(pvar->ssh2_authlist);
3006 pvar->ssh2_authlist = NULL;
3007 }
3008
3009 pvar->tryed_ssh2_authlist = FALSE;
3010
3011 // add (2008.3.2 yutaka)
3012 for (mode = 0 ; mode < MODE_MAX ; mode++) {
3013 if (pvar->ssh2_keys[mode].enc.iv != NULL) {
3014 free(pvar->ssh2_keys[mode].enc.iv);
3015 pvar->ssh2_keys[mode].enc.iv = NULL;
3016 }
3017 if (pvar->ssh2_keys[mode].enc.key != NULL) {
3018 free(pvar->ssh2_keys[mode].enc.key);
3019 pvar->ssh2_keys[mode].enc.key = NULL;
3020 }
3021 if (pvar->ssh2_keys[mode].mac.key != NULL) {
3022 free(pvar->ssh2_keys[mode].mac.key);
3023 pvar->ssh2_keys[mode].mac.key = NULL;
3024 }
3025 }
3026 }
3027 #endif
3028
3029 }
3030
3031 static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen)
3032 {
3033 buffer_t *msg;
3034 unsigned char *outmsg;
3035 unsigned int len;
3036
3037 // SSH2���������������A�p�P�b�g���������B(2005.6.19 yutaka)
3038 if (pvar->rekeying) {
3039 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
3040 // �������������������B
3041 c = NULL;
3042
3043 return;
3044 }
3045
3046 if (c == NULL)
3047 return;
3048
3049 if ((unsigned int)buflen > c->remote_window) {
3050 unsigned int offset = c->remote_window;
3051 // ���������f�[�^����������������������
3052 ssh2_channel_add_bufchain(c, buf + offset, buflen - offset);
3053 buflen = offset;
3054 }
3055 if (buflen > 0) {
3056 msg = buffer_init();
3057 if (msg == NULL) {
3058 // TODO: error check
3059 return;
3060 }
3061 buffer_put_int(msg, c->remote_id);
3062 buffer_put_string(msg, (char *)buf, buflen);
3063
3064 len = buffer_len(msg);
3065 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
3066 //if (len + 12 >= pvar->ssh_state.outbuflen) *(int *)0 = 0;
3067 memcpy(outmsg, buffer_ptr(msg), len);
3068 finish_send_packet(pvar);
3069 buffer_free(msg);
3070 //debug_print(1, pvar->ssh_state.outbuf, 7 + 4 + 1 + 1 + len);
3071
3072 // remote window size������
3073 if (buflen <= c->remote_window) {
3074 c->remote_window -= buflen;
3075 }
3076 else {
3077 c->remote_window = 0;
3078 }
3079 }
3080 }
3081
3082 /* support for port forwarding */
3083 void SSH_channel_send(PTInstVar pvar, int channel_num,
3084 uint32 remote_channel_num,
3085 unsigned char FAR * buf, int len)
3086 {
3087 if (SSHv1(pvar)) {
3088 unsigned char FAR *outmsg =
3089 begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
3090
3091 set_uint32(outmsg, remote_channel_num);
3092 set_uint32(outmsg + 4, len);
3093
3094 if (pvar->ssh_state.compressing) {
3095 buf_ensure_size(&pvar->ssh_state.outbuf,
3096 &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
3097 pvar->ssh_state.compress_stream.next_in =
3098 pvar->ssh_state.precompress_outbuf;
3099 pvar->ssh_state.compress_stream.avail_in = 9;
3100 pvar->ssh_state.compress_stream.next_out =
3101 pvar->ssh_state.outbuf + 12;
3102 pvar->ssh_state.compress_stream.avail_out =
3103 pvar->ssh_state.outbuflen - 12;
3104
3105 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
3106 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
3107 "Error compressing packet data");
3108 notify_fatal_error(pvar, pvar->ts->UIMsg);
3109 return;
3110 }
3111
3112 pvar->ssh_state.compress_stream.next_in =
3113 (unsigned char FAR *) buf;
3114 pvar->ssh_state.compress_stream.avail_in = len;
3115
3116 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
3117 Z_OK) {
3118 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
3119 "Error compressing packet data");
3120 notify_fatal_error(pvar, pvar->ts->UIMsg);
3121 return;
3122 }
3123 } else {
3124 memcpy(outmsg + 8, buf, len);
3125 }
3126
3127 finish_send_packet_special(pvar, 1);
3128
3129 } else {
3130 // �|�[�g�t�H���[�f�B���O���������N���C�A���g���������M�v�����ASSH���M���������T�[�o���������������B
3131 Channel_t *c = ssh2_local_channel_lookup(channel_num);
3132 SSH2_send_channel_data(pvar, c, buf, len);
3133 }
3134
3135 }
3136
3137 void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
3138 {
3139 if (SSHv1(pvar)) {
3140 unsigned char FAR *outmsg =
3141 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
3142
3143 set_uint32(outmsg, remote_channel_num);
3144 finish_send_packet(pvar);
3145
3146 } else { // SSH2 (2005.6.26 yutaka)
3147 int len;
3148 Channel_t *c = NULL;
3149 buffer_t *msg;
3150 unsigned char *outmsg;
3151
3152 msg = buffer_init();
3153 if (msg == NULL) {
3154 // TODO: error check
3155 return;
3156 }
3157 buffer_put_int(msg, remote_channel_num);
3158 buffer_put_int(msg, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
3159 buffer_put_string(msg, "", 0); // description
3160 buffer_put_string(msg, "", 0); // language tag
3161
3162 len = buffer_len(msg);
3163 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, len);
3164 memcpy(outmsg, buffer_ptr(msg), len);
3165 finish_send_packet(pvar);
3166 buffer_free(msg);
3167
3168 }
3169 }
3170
3171 void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num,
3172 uint32 local_channel_num)
3173 {
3174 if (SSHv1(pvar)) {
3175 unsigned char FAR *outmsg =
3176 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, 8);
3177
3178 set_uint32(outmsg, remote_channel_num);
3179 set_uint32(outmsg + 4, local_channel_num);
3180 finish_send_packet(pvar);
3181
3182 } else {
3183 buffer_t *msg;
3184 unsigned char *outmsg;
3185 int len;
3186 Channel_t *c;
3187
3188 // port-forwarding(remote to local)�����[�J�����������������T�[�o�������B(2005.7.2 yutaka)
3189 c = ssh2_local_channel_lookup(local_channel_num);
3190 if (c == NULL) {
3191 // It is sure to be successful as long as it's not a program bug either.
3192 return;
3193 }
3194
3195 msg = buffer_init();
3196 if (msg == NULL) {
3197 // TODO: error check
3198 return;
3199 }
3200 buffer_put_int(msg, c->remote_id);
3201 buffer_put_int(msg, c->self_id);
3202 buffer_put_int(msg, c->local_window);
3203 buffer_put_int(msg, c->local_maxpacket);
3204
3205