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 3165 - (show annotations) (download) (as text)
Wed Nov 19 15:44:06 2008 UTC (15 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 227800 byte(s)
1.150の修正は意味がなかったので戻す

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