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 3167 - (show annotations) (download) (as text)
Thu Nov 20 07:49:52 2008 UTC (15 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 231232 byte(s)
ログの採取箇所を増やした

1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 Copyright (c) 2004-2005, Yutaka Hirata
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
8
9 Redistributions of source code must retain the above copyright notice, this list of
10 conditions and the following disclaimer.
11
12 Redistributions in binary form must reproduce the above copyright notice, this list
13 of conditions and the following disclaimer in the documentation and/or other materials
14 provided with the distribution.
15
16 The name of Robert O'Callahan may not be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "ttxssh.h"
31 #include "util.h"
32 #include "resource.h"
33 #include "libputty.h"
34
35 #include <openssl/bn.h>
36 #include <openssl/evp.h>
37 #include <openssl/dh.h>
38 #include <openssl/engine.h>
39 #include <openssl/rsa.h>
40 #include <openssl/dsa.h>
41 #include <openssl/md5.h>
42 #include <limits.h>
43 #include <malloc.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <process.h>
47 #include <time.h>
48 #include "buffer.h"
49 #include "ssh.h"
50 #include "crypt.h"
51 #include "fwd.h"
52 #include "sftp.h"
53
54 #include <sys/types.h>
55 #include <sys/stat.h>
56 #include <assert.h>
57
58 #include <direct.h>
59 #include <io.h>
60
61 // SSH2 macro
62 #ifdef _DEBUG
63 #define SSH2_DEBUG
64 #endif
65
66 #define DONT_WANTCONFIRM 1 // (2005.3.28 yutaka)
67 #define INTBLOB_LEN 20
68 #define SIGBLOB_LEN (2*INTBLOB_LEN)
69
70 //
71 // SSH2 data structure
72 //
73
74 // channel data structure
75 #define CHANNEL_MAX 100
76
77 enum channel_type {
78 TYPE_SHELL, TYPE_PORTFWD, TYPE_SCP, TYPE_SFTP,
79 };
80
81 enum scp_state {
82 SCP_INIT, SCP_TIMESTAMP, SCP_FILEINFO, SCP_DATA, SCP_CLOSING,
83 };
84
85 typedef struct bufchain {
86 buffer_t *msg;
87 struct bufchain *next;
88 } bufchain_t;
89
90 typedef struct scp {
91 enum scp_dir dir; // transfer direction
92 enum scp_state state; // SCP state
93 char localfile[MAX_PATH]; // local filename
94 char localfilefull[MAX_PATH]; // local filename fullpath
95 char remotefile[MAX_PATH]; // remote filename
96 FILE *localfp; // file pointer for local file
97 struct _stat filestat; // file status information
98 HWND progress_window;
99 HANDLE thread;
100 unsigned int thread_id;
101 PTInstVar pvar;
102 // for receiving file
103 long long filetotalsize;
104 long long filercvsize;
105 } scp_t;
106
107 typedef struct channel {
108 int used;
109 int self_id;
110 int remote_id;
111 unsigned int local_window;
112 unsigned int local_window_max;
113 unsigned int local_consumed;
114 unsigned int local_maxpacket;
115 unsigned int remote_window;
116 unsigned int remote_maxpacket;
117 enum channel_type type;
118 int local_num;
119 bufchain_t *bufchain;
120 scp_t scp;
121 } Channel_t;
122
123 static Channel_t channels[CHANNEL_MAX];
124
125 static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
126
127 static void try_send_credentials(PTInstVar pvar);
128 static void prep_compression(PTInstVar pvar);
129
130 // �����v���g�^�C�v����
131 void SSH2_send_kexinit(PTInstVar pvar);
132 static BOOL handle_SSH2_kexinit(PTInstVar pvar);
133 static void SSH2_dh_kex_init(PTInstVar pvar);
134 static void SSH2_dh_gex_kex_init(PTInstVar pvar);
135 static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
136 static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
137 static BOOL handle_SSH2_newkeys(PTInstVar pvar);
138 static BOOL handle_SSH2_service_accept(PTInstVar pvar);
139 static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
140 static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
141 static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
142 static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
143 static BOOL handle_SSH2_open_failure(PTInstVar pvar);
144 static BOOL handle_SSH2_request_success(PTInstVar pvar);
145 static BOOL handle_SSH2_request_failure(PTInstVar pvar);
146 static BOOL handle_SSH2_channel_success(PTInstVar pvar);
147 static BOOL handle_SSH2_channel_data(PTInstVar pvar);
148 static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
149 static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
150 static BOOL handle_SSH2_channel_close(PTInstVar pvar);
151 static BOOL handle_SSH2_channel_open(PTInstVar pvar);
152 static BOOL handle_SSH2_window_adjust(PTInstVar pvar);
153 static BOOL handle_SSH2_channel_request(PTInstVar pvar);
154 void SSH2_dispatch_init(int stage);
155 int SSH2_dispatch_enabled_check(unsigned char message);
156 void SSH2_dispatch_add_message(unsigned char message);
157 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);
158 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
159 static void start_ssh_heartbeat_thread(PTInstVar pvar);
160 static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen);
161
162 //
163 // channel function
164 //
165 static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack,
166 enum confirm_type type, int local_num)
167 {
168 int i, found;
169 Channel_t *c;
170
171 found = -1;
172 for (i = 0 ; i < CHANNEL_MAX ; i++) {
173 if (channels[i].used == 0) { // free channel
174 found = i;
175 break;
176 }
177 }
178 if (found == -1) { // not free channel
179 return (NULL);
180 }
181
182 // setup
183 c = &channels[found];
184 memset(c, 0, sizeof(Channel_t));
185 c->used = 1;
186 c->self_id = i;
187 c->remote_id = -1;
188 c->local_window = window;
189 c->local_window_max = window;
190 c->local_consumed = 0;
191 c->local_maxpacket = maxpack;
192 c->remote_window = 0;
193 c->remote_maxpacket = 0;
194 c->type = type;
195 c->local_num = local_num; // alloc_channel()�����l��������������
196 c->bufchain = NULL;
197 if (type == TYPE_SCP) {
198 c->scp.state = SCP_INIT;
199 c->scp.progress_window = NULL;
200 c->scp.thread = (HANDLE)-1;
201 c->scp.localfp = NULL;
202 }
203
204 return (c);
205 }
206
207 // remote_window�������������������A�������������o�b�t�@�����X�g�i�������j���������������B
208 static void ssh2_channel_add_bufchain(Channel_t *c, unsigned char *buf, unsigned int buflen)
209 {
210 bufchain_t *p, *old;
211
212 // allocate new buffer
213 p = malloc(sizeof(bufchain_t));
214 if (p == NULL)
215 return;
216 p->msg = buffer_init();
217 if (p == NULL) {
218 free(p);
219 return;
220 }
221 buffer_put_raw(p->msg, buf, buflen);
222 p->next = NULL;
223
224 if (c->bufchain == NULL) {
225 c->bufchain = p;
226 } else {
227 old = c->bufchain;
228 while (old->next)
229 old = old->next;
230 old->next = p;
231 }
232 }
233
234
235 static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c)
236 {
237 bufchain_t *ch;
238 unsigned int size;
239
240 while (c->bufchain) {
241 // ����������������
242 ch = c->bufchain;
243 size = buffer_len(ch->msg);
244 if (size >= c->remote_window)
245 break;
246
247 if (c->local_num == -1) { // shell or SCP
248 SSH2_send_channel_data(pvar, c, buffer_ptr(ch->msg), size);
249 } else { // port-forwarding
250 SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size);
251 }
252
253 c->bufchain = ch->next;
254
255 buffer_free(ch->msg);
256 free(ch);
257 }
258 }
259
260
261
262 // channel close�����`���l���\���������X�g�����p����
263 // (2007.4.26 yutaka)
264 static void ssh2_channel_delete(Channel_t *c)
265 {
266 bufchain_t *ch, *ptr;
267
268 ch = c->bufchain;
269 while (ch) {
270 if (ch->msg)
271 buffer_free(ch->msg);
272 ptr = ch;
273 ch = ch->next;
274 free(ptr);
275 }
276
277 if (c->type == TYPE_SCP) {
278 c->scp.state = SCP_CLOSING;
279 if (c->scp.localfp != NULL)
280 fclose(c->scp.localfp);
281 if (c->scp.progress_window != NULL) {
282 DestroyWindow(c->scp.progress_window);
283 c->scp.progress_window = NULL;
284 }
285 if (c->scp.thread != (HANDLE)-1L) {
286 WaitForSingleObject(c->scp.thread, INFINITE);
287 CloseHandle(c->scp.thread);
288 c->scp.thread = (HANDLE)-1L;
289 }
290 }
291
292 memset(c, 0, sizeof(Channel_t));
293 c->used = 0;
294 }
295
296
297 // connection close������������
298 void ssh2_channel_free(void)
299 {
300 int i;
301 Channel_t *c;
302
303 for (i = 0 ; i < CHANNEL_MAX ; i++) {
304 c = &channels[i];
305 ssh2_channel_delete(c);
306 }
307
308 }
309
310 static Channel_t *ssh2_channel_lookup(int id)
311 {
312 Channel_t *c;
313
314 if (id < 0 || id >= CHANNEL_MAX) {
315 return (NULL);
316 }
317 c = &channels[id];
318 if (c->used == 0) { // already freed
319 return (NULL);
320 }
321 return (c);
322 }
323
324 // SSH1��������������channel�\���������ASSH2������Channel_t�����������B
325 // TODO: �����I�����`���l���\������1�������������B
326 // (2005.6.12 yutaka)
327 static Channel_t *ssh2_local_channel_lookup(int local_num)
328 {
329 int i;
330 Channel_t *c;
331
332 for (i = 0 ; i < CHANNEL_MAX ; i++) {
333 c = &channels[i];
334 if (c->local_num == local_num)
335 return (c);
336 }
337 return (NULL);
338 }
339
340
341 //
342 // SSH heartbeat mutex
343 //
344 // TTSSH�� thread-safe �������������A�}���`�X���b�h�������p�P�b�g���M�����������B
345 // �V���O���X���b�h�����R���e�L�X�g�X�C�b�`�������������������������A
346 // ���b�N�������K�v�����������A���������B(2007.12.26 yutaka)
347 //
348 static CRITICAL_SECTION g_ssh_heartbeat_lock; /* �����M�p���b�N */
349
350 void ssh_heartbeat_lock_initialize(void)
351 {
352 //InitializeCriticalSection(&g_ssh_heartbeat_lock);
353 }
354
355 void ssh_heartbeat_lock_finalize(void)
356 {
357 //DeleteCriticalSection(&g_ssh_heartbeat_lock);
358 }
359
360 void ssh_heartbeat_lock(void)
361 {
362 //EnterCriticalSection(&g_ssh_heartbeat_lock);
363 }
364
365 void ssh_heartbeat_unlock(void)
366 {
367 //LeaveCriticalSection(&g_ssh_heartbeat_lock);
368 }
369
370
371 //
372 // SSH memory dump (for debug)
373 //
374 // (2005.3.7 yutaka)
375 //
376 #define MEMTAG_MAX 300
377 #define LOGDUMP "ssh2connect.log"
378 #define LOG_PACKET_DUMP "ssh2packet.log"
379 #define SENDTOME "Please send '"LOGDUMP"' file to Tera Term developer team."
380
381 typedef struct memtag {
382 char *name;
383 char *desc;
384 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 notify_verbose_message(pvar, "SSH_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1320
1321 if (grab_payload(pvar, 4)
1322 && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1323 /* ignore it! but it must be decompressed */
1324 }
1325 }
1326 else {
1327 notify_verbose_message(pvar, "SSH2_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1328
1329 // ���b�Z�[�W�� SSH2_MSG_IGNORE ����������������
1330 // Cisco ���[�^���� (2006.11.28 maya)
1331 }
1332 return TRUE;
1333 }
1334
1335 static BOOL handle_debug(PTInstVar pvar)
1336 {
1337 BOOL always_display;
1338 char FAR *description;
1339 int description_len;
1340 char buf[2048];
1341
1342 if (SSHv1(pvar)) {
1343 notify_verbose_message(pvar, "SSH_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1344
1345 if (grab_payload(pvar, 4)
1346 && grab_payload(pvar, description_len =
1347 get_payload_uint32(pvar, 0))) {
1348 always_display = FALSE;
1349 description = pvar->ssh_state.payload + 4;
1350 description[description_len] = 0;
1351 } else {
1352 return TRUE;
1353 }
1354 } else {
1355 notify_verbose_message(pvar, "SSH2_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1356
1357 if (grab_payload(pvar, 5)
1358 && grab_payload(pvar,
1359 (description_len = get_payload_uint32(pvar, 1)) + 4)
1360 && grab_payload(pvar,
1361 get_payload_uint32(pvar, 5 + description_len))) {
1362 always_display = pvar->ssh_state.payload[0] != 0;
1363 description = pvar->ssh_state.payload + 5;
1364 description[description_len] = 0;
1365 } else {
1366 return TRUE;
1367 }
1368 }
1369
1370 chop_newlines(description);
1371 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1372 description);
1373 if (always_display) {
1374 notify_nonfatal_error(pvar, buf);
1375 } else {
1376 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1377 }
1378 return TRUE;
1379 }
1380
1381 static BOOL handle_disconnect(PTInstVar pvar)
1382 {
1383 int reason_code;
1384 char FAR *description;
1385 int description_len;
1386 char buf[2048];
1387 char FAR *explanation = "";
1388 char uimsg[MAX_UIMSG];
1389
1390 if (SSHv1(pvar)) {
1391 notify_verbose_message(pvar, "SSH_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1392
1393 if (grab_payload(pvar, 4)
1394 && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1395 reason_code = -1;
1396 description = pvar->ssh_state.payload + 4;
1397 description[description_len] = 0;
1398 } else {
1399 return TRUE;
1400 }
1401 } else {
1402 notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1403
1404 if (grab_payload(pvar, 8)
1405 && grab_payload(pvar,
1406 (description_len = get_payload_uint32(pvar, 4)) + 4)
1407 && grab_payload(pvar,
1408 get_payload_uint32(pvar, 8 + description_len))) {
1409 reason_code = get_payload_uint32(pvar, 0);
1410 description = pvar->ssh_state.payload + 8;
1411 description[description_len] = 0;
1412 } else {
1413 return TRUE;
1414 }
1415 }
1416
1417 chop_newlines(description);
1418 if (description[0] == 0) {
1419 description = NULL;
1420 }
1421
1422 if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1423 UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1424 "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1425 "This often happens when someone is already forwarding that port from the server.");
1426 strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1427 explanation = uimsg;
1428 }
1429
1430 if (description != NULL) {
1431 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1432 "Server disconnected with message '%s'%s");
1433 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1434 pvar->ts->UIMsg, description,
1435 explanation);
1436 } else {
1437 UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1438 "Server disconnected (no reason given).%s");
1439 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1440 pvar->ts->UIMsg, explanation);
1441 }
1442 notify_fatal_error(pvar, buf);
1443
1444 return TRUE;
1445 }
1446
1447 static BOOL handle_unimplemented(PTInstVar pvar)
1448 {
1449 /* Should never receive this since we only send base 2.0 protocol messages */
1450 grab_payload(pvar, 4);
1451 return TRUE;
1452 }
1453
1454 static BOOL handle_crypt_success(PTInstVar pvar)
1455 {
1456 notify_verbose_message(pvar, "Secure mode successfully achieved",
1457 LOG_LEVEL_VERBOSE);
1458 return FALSE;
1459 }
1460
1461 static BOOL handle_noauth_success(PTInstVar pvar)
1462 {
1463 notify_verbose_message(pvar, "Server does not require authentication",
1464 LOG_LEVEL_VERBOSE);
1465 prep_compression(pvar);
1466 return FALSE;
1467 }
1468
1469 static BOOL handle_auth_success(PTInstVar pvar)
1470 {
1471 notify_verbose_message(pvar, "Authentication accepted",
1472 LOG_LEVEL_VERBOSE);
1473 prep_compression(pvar);
1474
1475 // �n�[�g�r�[�g�E�X���b�h���J�n (2004.12.11 yutaka)
1476 start_ssh_heartbeat_thread(pvar);
1477
1478 return FALSE;
1479 }
1480
1481 static BOOL handle_server_public_key(PTInstVar pvar)
1482 {
1483 int server_key_public_exponent_len;
1484 int server_key_public_modulus_pos;
1485 int server_key_public_modulus_len;
1486 int host_key_bits_pos;
1487 int host_key_public_exponent_len;
1488 int host_key_public_modulus_pos;
1489 int host_key_public_modulus_len;
1490 int protocol_flags_pos;
1491 int supported_ciphers;
1492 char FAR *inmsg;
1493 Key hostkey;
1494 int supported_types;
1495
1496 notify_verbose_message(pvar, "SSH_SMSG_PUBLIC_KEY was received.", LOG_LEVEL_VERBOSE);
1497
1498 if (!grab_payload(pvar, 14))
1499 return FALSE;
1500 server_key_public_exponent_len = get_mpint_len(pvar, 12);
1501
1502 if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1503 return FALSE;
1504 server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1505 server_key_public_modulus_len =
1506 get_mpint_len(pvar, server_key_public_modulus_pos);
1507
1508 if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1509 return FALSE;
1510 host_key_bits_pos =
1511 server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1512 host_key_public_exponent_len =
1513 get_mpint_len(pvar, host_key_bits_pos + 4);
1514
1515 if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1516 return FALSE;
1517 host_key_public_modulus_pos =
1518 host_key_bits_pos + 6 + host_key_public_exponent_len;
1519 host_key_public_modulus_len =
1520 get_mpint_len(pvar, host_key_public_modulus_pos);
1521
1522 if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1523 return FALSE;
1524 protocol_flags_pos =
1525 host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1526
1527 inmsg = pvar->ssh_state.payload;
1528
1529 CRYPT_set_server_cookie(pvar, inmsg);
1530 if (!CRYPT_set_server_RSA_key(pvar,
1531 get_uint32(inmsg + 8),
1532 pvar->ssh_state.payload + 12,
1533 inmsg + server_key_public_modulus_pos))
1534 return FALSE;
1535 if (!CRYPT_set_host_RSA_key(pvar,
1536 get_uint32(inmsg + host_key_bits_pos),
1537 inmsg + host_key_bits_pos + 4,
1538 inmsg + host_key_public_modulus_pos))
1539 return FALSE;
1540 pvar->ssh_state.server_protocol_flags =
1541 get_uint32(inmsg + protocol_flags_pos);
1542
1543 supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1544 if (!CRYPT_set_supported_ciphers(pvar,
1545 supported_ciphers,
1546 supported_ciphers))
1547 return FALSE;
1548
1549 // SSH1 �T�[�o���A�T�|�[�g�����������F������������������
1550 // RSA ���L������ PAGEANT ���L��������
1551 supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1552 if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1553 supported_types |= (1 << SSH_AUTH_PAGEANT);
1554 }
1555 if (!AUTH_set_supported_auth_types(pvar,
1556 supported_types))
1557 return FALSE;
1558
1559 /* this must be the LAST THING in this function, since it can cause
1560 host_is_OK to be called. */
1561 hostkey.type = KEY_RSA1;
1562 hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1563 hostkey.exp = inmsg + host_key_bits_pos + 4;
1564 hostkey.mod = inmsg + host_key_public_modulus_pos;
1565 HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1566
1567 return FALSE;
1568 }
1569
1570 /*
1571 The ID must have already been found to start with "SSH-". It must
1572 be null-terminated.
1573 */
1574 static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1575 {
1576 char FAR *str;
1577
1578 for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1579 }
1580
1581 if (*str != '.') {
1582 return FALSE;
1583 }
1584
1585 pvar->protocol_major = atoi(ID + 4);
1586 pvar->protocol_minor = atoi(str + 1);
1587
1588 // for SSH2(yutaka)
1589 // 1.99����SSH2�����������s��
1590 if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
1591 // ���[�U�� SSH2 ���I������������������
1592 if (pvar->settings.ssh_protocol_version == 2) {
1593 pvar->protocol_major = 2;
1594 pvar->protocol_minor = 0;
1595 }
1596
1597 }
1598
1599 // SSH �o�[�W������ teraterm �����Z�b�g����
1600 // SCP �R�}���h������ (2008.2.3 maya)
1601 pvar->cv->isSSH = pvar->protocol_major;
1602
1603 for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1604 }
1605
1606 return *str == '-';
1607 }
1608
1609 /*
1610 On entry, the pvar->protocol_xxx fields hold the server's advertised
1611 protocol number. We replace the fields with the protocol number we will
1612 actually use, or return FALSE if there is no usable protocol version.
1613 */
1614 static BOOL negotiate_protocol(PTInstVar pvar)
1615 {
1616 switch (pvar->protocol_major) {
1617 case 1:
1618 if (pvar->protocol_minor > 5) {
1619 pvar->protocol_minor = 5;
1620 }
1621
1622 return TRUE;
1623
1624 // for SSH2(yutaka)
1625 case 2:
1626 return TRUE; // SSH2 support
1627
1628 default:
1629 return FALSE;
1630 }
1631 }
1632
1633 static void init_protocol(PTInstVar pvar)
1634 {
1635 CRYPT_initialize_random_numbers(pvar);
1636
1637 // known_hosts�t�@�C�������z�X�g���J������������������
1638 HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1639
1640 /* while we wait for a response from the server... */
1641
1642 if (SSHv1(pvar)) {
1643 enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1644 enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1645 enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1646 enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1647
1648 } else { // for SSH2(yutaka)
1649 enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1650 enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1651 enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1652 enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1653 enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1654 enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1655 enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1656 enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1657 enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1658 enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1659 enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1660 enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1661 enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1662
1663 enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1664
1665 // ���[�U�F�������f�B�X�p�b�`���[�`��
1666 enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1667 enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1668 enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1669 enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1670 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1671 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1672 enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1673 enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1674 enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1675 enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1676 // enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1677 enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1678 enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1679
1680 }
1681 }
1682
1683 BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1684 {
1685 static const char prefix[] = "Received server prologue string: ";
1686
1687 // initialize SSH2 memory dump (2005.3.7 yutaka)
1688 init_memdump();
1689 push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1690
1691 if (ID_len <= 0) {
1692 return FALSE;
1693 } else {
1694 int buf_len = ID_len + NUM_ELEM(prefix);
1695 char FAR *buf = (char FAR *) malloc(buf_len);
1696
1697 strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1698 strncat_s(buf, buf_len, ID, _TRUNCATE);
1699 chop_newlines(buf);
1700
1701 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1702
1703 free(buf);
1704
1705
1706 // ���������R�s�[������ (2005.3.9 yutaka)
1707 #if 0
1708 // for calculate SSH2 hash
1709 // �T�[�o�o�[�W�����������i���s���������������j
1710 if (ID_len >= sizeof(pvar->server_version_string))
1711 return FALSE;
1712 strncpy(pvar->server_version_string, ID, ID_len);
1713 #endif
1714
1715
1716 if (ID[ID_len - 1] != '\n') {
1717 pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1718 return FALSE;
1719 } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1720 pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1721 return FALSE;
1722 } else if (strncmp(ID, "SSH-", 4) != 0) {
1723 return FALSE;
1724 } else {
1725 ID[ID_len - 1] = 0;
1726
1727 if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1728 ID[ID_len - 2] = 0;
1729 }
1730
1731 pvar->ssh_state.server_ID = _strdup(ID);
1732
1733 if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1734 UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1735 "This program does not understand the server's version of the protocol.");
1736 notify_fatal_error(pvar, pvar->ts->UIMsg);
1737 } else {
1738 char TTSSH_ID[1024];
1739 int TTSSH_ID_len;
1740 int a, b, c, d;
1741
1742 // �������g���o�[�W�������������� (2005.3.3 yutaka)
1743 get_file_version("ttxssh.dll", &a, &b, &c, &d);
1744
1745 _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1746 "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1747 pvar->protocol_major, pvar->protocol_minor, a, b);
1748 TTSSH_ID_len = strlen(TTSSH_ID);
1749
1750 // for SSH2(yutaka)
1751 // �N���C�A���g�o�[�W�����������i���s���������������j
1752 strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1753 TTSSH_ID, _TRUNCATE);
1754
1755 // �T�[�o�o�[�W�����������i���s���������������j(2005.3.9 yutaka)
1756 _snprintf_s(pvar->server_version_string,
1757 sizeof(pvar->server_version_string), _TRUNCATE,
1758 "%s", pvar->ssh_state.server_ID);
1759
1760 if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1761 0) != TTSSH_ID_len) {
1762 UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1763 "An error occurred while sending the SSH ID string.\n"
1764 "The connection will close.");
1765 notify_fatal_error(pvar, pvar->ts->UIMsg);
1766 } else {
1767 // ���s�R�[�h������ (2004.8.4 yutaka)
1768 pvar->client_version_string[--TTSSH_ID_len] = 0;
1769
1770 push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1771 push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1772
1773 // SSH�n���h�����o�^���s��
1774 init_protocol(pvar);
1775
1776 SSH2_dispatch_init(1);
1777 SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1778 SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.3 yutaka)
1779 }
1780 }
1781
1782 return TRUE;
1783 }
1784 }
1785 }
1786
1787 static BOOL handle_exit(PTInstVar pvar)
1788 {
1789 if (grab_payload(pvar, 4)) {
1790 begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1791 finish_send_packet(pvar);
1792 notify_closed_connection(pvar);
1793 }
1794 return TRUE;
1795 }
1796
1797 static BOOL handle_data(PTInstVar pvar)
1798 {
1799 if (grab_payload_limited(pvar, 4)) {
1800 pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1801 pvar->ssh_state.payload_datastart = 4;
1802 }
1803 return TRUE;
1804 }
1805
1806 static BOOL handle_channel_open(PTInstVar pvar)
1807 {
1808 int host_len;
1809 int originator_len;
1810
1811 if ((pvar->ssh_state.
1812 server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1813 if (grab_payload(pvar, 8)
1814 && grab_payload(pvar,
1815 8 + (host_len = get_payload_uint32(pvar, 4)))
1816 && grab_payload(pvar, originator_len =
1817 get_payload_uint32(pvar, host_len + 12))) {
1818 int local_port = get_payload_uint32(pvar, 8 + host_len);
1819
1820 pvar->ssh_state.payload[8 + host_len] = 0;
1821 FWD_open(pvar, get_payload_uint32(pvar, 0),
1822 pvar->ssh_state.payload + 8, local_port,
1823 pvar->ssh_state.payload + 16 + host_len,
1824 originator_len,
1825 NULL);
1826 }
1827 } else {
1828 if (grab_payload(pvar, 8)
1829 && grab_payload(pvar,
1830 4 + (host_len = get_payload_uint32(pvar, 4)))) {
1831 int local_port = get_payload_uint32(pvar, 8 + host_len);
1832
1833 pvar->ssh_state.payload[8 + host_len] = 0;
1834 FWD_open(pvar, get_payload_uint32(pvar, 0),
1835 pvar->ssh_state.payload + 8, local_port, NULL, 0,
1836 NULL);
1837 }
1838 }
1839
1840 return TRUE;
1841 }
1842
1843 static BOOL handle_X11_channel_open(PTInstVar pvar)
1844 {
1845 int originator_len;
1846
1847 if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1848 if (grab_payload(pvar, 8)
1849 && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1850 FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1851 pvar->ssh_state.payload + 8, originator_len, NULL);
1852 }
1853 } else {
1854 if (grab_payload(pvar, 4)) {
1855 FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1856 }
1857 }
1858
1859 return TRUE;
1860 }
1861
1862 static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1863 {
1864 if (grab_payload(pvar, 8)) {
1865 FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1866 get_payload_uint32(pvar, 4));
1867 }
1868 return FALSE;
1869 }
1870
1871 static BOOL handle_channel_open_failure(PTInstVar pvar)
1872 {
1873 if (grab_payload(pvar, 4)) {
1874 FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1875 }
1876 return FALSE;
1877 }
1878
1879 static BOOL handle_channel_data(PTInstVar pvar)
1880 {
1881 int len;
1882
1883 if (grab_payload(pvar, 8)
1884 && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1885 FWD_received_data(pvar, get_payload_uint32(pvar, 0),
1886 pvar->ssh_state.payload + 8, len);
1887 }
1888 return TRUE;
1889 }
1890
1891 static BOOL handle_channel_input_eof(PTInstVar pvar)
1892 {
1893 if (grab_payload(pvar, 4)) {
1894 FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));
1895 }
1896 return TRUE;
1897 }
1898
1899 static BOOL handle_channel_output_eof(PTInstVar pvar)
1900 {
1901 if (grab_payload(pvar, 4)) {
1902 FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1903 }
1904 return TRUE;
1905 }
1906
1907
1908
1909 // �n���h�����O�������b�Z�[�W����������
1910
1911 #define HANDLE_MESSAGE_MAX 30
1912 static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1913 static int handle_message_count = 0;
1914 static int handle_message_stage = 0;
1915
1916 void SSH2_dispatch_init(int stage)
1917 {
1918 handle_message_count = 0;
1919 handle_message_stage = stage;
1920 }
1921
1922 int SSH2_dispatch_enabled_check(unsigned char message)
1923 {
1924 int i;
1925
1926 for (i = 0 ; i < handle_message_count ; i++) {
1927 if (handle_messages[i] == message)
1928 return 1;
1929 }
1930 return 0;
1931 }
1932
1933 void SSH2_dispatch_add_message(unsigned char message)
1934 {
1935 int i;
1936
1937 if (handle_message_count >= HANDLE_MESSAGE_MAX) {
1938 // TODO: error check
1939 return;
1940 }
1941
1942 // �������o�^�������������b�Z�[�W������������
1943 for (i=0; i<handle_message_count; i++) {
1944 if (handle_messages[i] == message) {
1945 return;
1946 }
1947 }
1948
1949 handle_messages[handle_message_count++] = message;
1950 }
1951
1952 void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
1953 {
1954 unsigned char c;
1955
1956 for (c = begin ; c <= end ; c++) {
1957 SSH2_dispatch_add_message(c);
1958 }
1959 }
1960
1961
1962 void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
1963 int padding)
1964 {
1965 unsigned char message = prep_packet(pvar, data, len, padding);
1966
1967
1968 #ifdef SSH2_DEBUG
1969 // for SSH2(yutaka)
1970 if (SSHv2(pvar)) {
1971 if (pvar->key_done) {
1972 message = message;
1973 }
1974
1975 if (pvar->userauth_success) {
1976 message = message;
1977 }
1978
1979 if (pvar->rekeying) {
1980 message = message;
1981 }
1982 }
1983 #endif
1984
1985 // SSH�����b�Z�[�W�^�C�v���`�F�b�N
1986 if (message != SSH_MSG_NONE) {
1987 // ���b�Z�[�W�^�C�v���������n���h�����N��
1988 SSHPacketHandler handler = get_handler(pvar, message);
1989
1990 // for SSH2(yutaka)
1991 if (SSHv2(pvar)) {
1992 // �z���O�����b�Z�[�W�^�C�v�������������A�{�[�g�������B
1993 if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
1994 char buf[1024];
1995
1996 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
1997 "Unexpected SSH2 message(%d) on current stage(%d)");
1998 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1999 pvar->ts->UIMsg, message, handle_message_stage);
2000 notify_fatal_error(pvar, buf);
2001 // abort
2002 }
2003 }
2004
2005 if (handler == NULL) {
2006 if (SSHv1(pvar)) {
2007 char buf[1024];
2008
2009 UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2010 "Unexpected packet type received: %d");
2011 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2012 pvar->ts->UIMsg, message, handle_message_stage);
2013 notify_fatal_error(pvar, buf);
2014 } else {
2015 unsigned char FAR *outmsg =
2016 begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2017
2018 set_uint32(outmsg,
2019 pvar->ssh_state.receiver_sequence_number - 1);
2020 finish_send_packet(pvar);
2021
2022 notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2023 /* XXX need to decompress incoming packet, but how? */
2024 }
2025 } else {
2026 if (!handler(pvar)) {
2027 deque_handlers(pvar, message);
2028 }
2029 }
2030 }
2031 }
2032
2033 static BOOL handle_pty_success(PTInstVar pvar)
2034 {
2035 FWD_enter_interactive_mode(pvar);
2036 enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2037 enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2038 enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2039 enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2040 enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2041 handle_channel_input_eof);
2042 enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2043 handle_channel_output_eof);
2044 enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2045 enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2046 return FALSE;
2047 }
2048
2049 static BOOL handle_pty_failure(PTInstVar pvar)
2050 {
2051 UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2052 "The server cannot allocate a pseudo-terminal. "
2053 "You may encounter some problems with the terminal.");
2054 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2055 return handle_pty_success(pvar);
2056 }
2057
2058 static void prep_pty(PTInstVar pvar)
2059 {
2060 int len = strlen(pvar->ts->TermType);
2061 unsigned char FAR *outmsg =
2062 begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2063 4 + len + 16 + sizeof(ssh_ttymodes));
2064 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2065 static const SSHPacketHandler handlers[]
2066 = { handle_pty_success, handle_pty_failure };
2067
2068 set_uint32(outmsg, len);
2069 memcpy(outmsg + 4, pvar->ts->TermType, len);
2070 set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2071 set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2072 set_uint32(outmsg + 4 + len + 8, 0);
2073 set_uint32(outmsg + 4 + len + 12, 0);
2074 memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2075 finish_send_packet(pvar);
2076
2077 enque_handlers(pvar, 2, msgs, handlers);
2078
2079 begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2080 finish_send_packet(pvar);
2081 }
2082
2083 static void prep_forwarding(PTInstVar pvar)
2084 {
2085 FWD_prep_forwarding(pvar);
2086 prep_pty(pvar);
2087 }
2088
2089
2090 //
2091 //
2092 // (2005.7.10 yutaka)
2093 static void enable_send_compression(PTInstVar pvar)
2094 {
2095 static int initialize = 0;
2096
2097 if (initialize) {
2098 deflateEnd(&pvar->ssh_state.compress_stream);
2099 }
2100 initialize = 1;
2101
2102 pvar->ssh_state.compress_stream.zalloc = NULL;
2103 pvar->ssh_state.compress_stream.zfree = NULL;
2104 pvar->ssh_state.compress_stream.opaque = NULL;
2105 if (deflateInit
2106 (&pvar->ssh_state.compress_stream,
2107 pvar->ssh_state.compression_level) != Z_OK) {
2108 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2109 "An error occurred while setting up compression.\n"
2110 "The connection will close.");
2111 notify_fatal_error(pvar, pvar->ts->UIMsg);
2112 return;
2113 } else {
2114 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2115 if (SSHv2(pvar)) {
2116 pvar->ssh_state.compressing = FALSE;
2117 } else {
2118 pvar->ssh_state.compressing = TRUE;
2119 }
2120 }
2121 }
2122
2123 static void enable_recv_compression(PTInstVar pvar)
2124 {
2125 static int initialize = 0;
2126
2127 if (initialize) {
2128 deflateEnd(&pvar->ssh_state.decompress_stream);
2129 }
2130 initialize = 1;
2131
2132 pvar->ssh_state.decompress_stream.zalloc = NULL;
2133 pvar->ssh_state.decompress_stream.zfree = NULL;
2134 pvar->ssh_state.decompress_stream.opaque = NULL;
2135 if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2136 deflateEnd(&pvar->ssh_state.compress_stream);
2137 UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2138 "An error occurred while setting up compression.\n"
2139 "The connection will close.");
2140 notify_fatal_error(pvar, pvar->ts->UIMsg);
2141 return;
2142 } else {
2143 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2144 if (SSHv2(pvar)) {
2145 pvar->ssh_state.decompressing = FALSE;
2146 } else {
2147 pvar->ssh_state.decompressing = TRUE;
2148 }
2149
2150 buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2151 &pvar->ssh_state.postdecompress_inbuflen, 1000);
2152 }
2153 }
2154
2155 static void enable_compression(PTInstVar pvar)
2156 {
2157 enable_send_compression(pvar);
2158 enable_recv_compression(pvar);
2159
2160 // SSH2�������k�E�W�J������SSH1���������s�������A���L�t���O���������������B(2005.7.9 yutaka)
2161 if (SSHv2(pvar)) {
2162 pvar->ssh_state.compressing = FALSE;
2163 pvar->ssh_state.decompressing = FALSE;
2164 }
2165
2166 }
2167
2168 static BOOL handle_enable_compression(PTInstVar pvar)
2169 {
2170 enable_compression(pvar);
2171 prep_forwarding(pvar);
2172 return FALSE;
2173 }
2174
2175 static BOOL handle_disable_compression(PTInstVar pvar)
2176 {
2177 prep_forwarding(pvar);
2178 return FALSE;
2179 }
2180
2181 static void prep_compression(PTInstVar pvar)
2182 {
2183 if (pvar->session_settings.CompressionLevel > 0) {
2184 // added if statement (2005.7.10 yutaka)
2185 if (SSHv1(pvar)) {
2186 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2187 static const SSHPacketHandler handlers[]
2188 = { handle_enable_compression, handle_disable_compression };
2189
2190 unsigned char FAR *outmsg =
2191 begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2192
2193 set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2194 finish_send_packet(pvar);
2195
2196 enque_handlers(pvar, 2, msgs, handlers);
2197 }
2198
2199 pvar->ssh_state.compression_level =
2200 pvar->session_settings.CompressionLevel;
2201
2202 } else {
2203 // added if statement (2005.7.10 yutaka)
2204 if (SSHv1(pvar)) {
2205 prep_forwarding(pvar);
2206 }
2207 }
2208 }
2209
2210 static void enque_simple_auth_handlers(PTInstVar pvar)
2211 {
2212 static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2213 static const SSHPacketHandler handlers[]
2214 = { handle_auth_success, handle_auth_failure };
2215
2216 enque_handlers(pvar, 2, msgs, handlers);
2217 }
2218
2219 static BOOL handle_rsa_challenge(PTInstVar pvar)
2220 {
2221 int challenge_bytes;
2222
2223 if (!grab_payload(pvar, 2)) {
2224 return FALSE;
2225 }
2226
2227 challenge_bytes = get_mpint_len(pvar, 0);
2228
2229 if (grab_payload(pvar, challenge_bytes)) {
2230 unsigned char FAR *outmsg =
2231 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2232
2233 if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2234 if (CRYPT_generate_RSA_challenge_response
2235 (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2236
2237 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2238 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2239 #if 0
2240 //AUTH_destroy_cur_cred(pvar);
2241 #endif
2242
2243 finish_send_packet(pvar);
2244
2245 enque_simple_auth_handlers(pvar);
2246 } else {
2247 UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2248 "An error occurred while decrypting the RSA challenge.\n"
2249 "Perhaps the key file is corrupted.");
2250 notify_fatal_error(pvar, pvar->ts->UIMsg);
2251 }
2252 }
2253 else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2254 int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2255 int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2256 int server_key_bytes = (server_key_bits + 7) / 8;
2257 int host_key_bytes = (host_key_bits + 7) / 8;
2258 int session_buf_len = server_key_bytes + host_key_bytes + 8;
2259 char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2260 unsigned char session_id[16];
2261
2262 unsigned char *hash;
2263 int pubkeylen, hashlen;
2264
2265 /* Pageant ���n�b�V�����v�Z���������� */
2266 // ���J��������
2267 pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2268 pvar->pageant_keylistlen);
2269 // �Z�b�V����ID������
2270 BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2271 BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2272 session_buf + host_key_bytes);
2273 memcpy(session_buf + server_key_bytes + host_key_bytes,
2274 pvar->crypt_state.server_cookie, 8);
2275 MD5(session_buf, session_buf_len, session_id);
2276 // �n�b�V������������
2277 hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2278 pubkeylen,
2279 pvar->ssh_state.payload,
2280 challenge_bytes + 2,
2281 session_id,
2282 &hashlen);
2283
2284 // �n�b�V�������M
2285 memcpy(outmsg, hash, 16);
2286 free(hash);
2287
2288 finish_send_packet(pvar);
2289
2290 enque_simple_auth_handlers(pvar);
2291 }
2292 }
2293
2294 return FALSE;
2295 }
2296
2297 #define OBFUSCATING_ROUND_TO 32
2298
2299 static int obfuscating_round_up(PTInstVar pvar, int size)
2300 {
2301 return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2302 }
2303
2304 static void try_send_credentials(PTInstVar pvar)
2305 {
2306 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2307 AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2308 static const int RSA_msgs[] =
2309 { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2310 static const SSHPacketHandler RSA_handlers[]
2311 = { handle_rsa_challenge, handle_rsa_auth_refused };
2312 static const int TIS_msgs[] =
2313 { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2314 static const SSHPacketHandler TIS_handlers[]
2315 = { handle_TIS_challenge, handle_auth_failure };
2316
2317 // SSH2���������������������X�L�b�v
2318 if (SSHv2(pvar))
2319 goto skip_ssh2;
2320
2321 switch (cred->method) {
2322 case SSH_AUTH_NONE:
2323 return;
2324 case SSH_AUTH_PASSWORD:{
2325 int len = strlen(cred->password);
2326 // Round up password length to discourage traffic analysis
2327 int obfuscated_len = obfuscating_round_up(pvar, len);
2328 unsigned char FAR *outmsg =
2329 begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2330 4 + obfuscated_len);
2331
2332 notify_verbose_message(pvar,
2333 "Trying PASSWORD authentication...",
2334 LOG_LEVEL_VERBOSE);
2335
2336 set_uint32(outmsg, obfuscated_len);
2337 memcpy(outmsg + 4, cred->password, len);
2338 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2339
2340 // �Z�b�V�������������p�X���[�h���g���������������A�����������\�[�X�������������B
2341 // socket close���������������������������������A���������������B(2005.4.8 yutaka)
2342 #if 0
2343 //AUTH_destroy_cur_cred(pvar);
2344 #endif
2345
2346 enque_simple_auth_handlers(pvar);
2347 break;
2348 }
2349 case SSH_AUTH_RHOSTS:{
2350 int len = strlen(cred->rhosts_client_user);
2351 unsigned char FAR *outmsg =
2352 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2353
2354 notify_verbose_message(pvar,
2355 "Trying RHOSTS authentication...",
2356 LOG_LEVEL_VERBOSE);
2357
2358 set_uint32(outmsg, len);
2359 memcpy(outmsg + 4, cred->rhosts_client_user, len);
2360 AUTH_destroy_cur_cred(pvar);
2361 enque_simple_auth_handlers(pvar);
2362 break;
2363 }
2364 case SSH_AUTH_RSA:{
2365 int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2366 unsigned char FAR *outmsg =
2367 begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2368
2369 notify_verbose_message(pvar,
2370 "Trying RSA authentication...",
2371 LOG_LEVEL_VERBOSE);
2372
2373 set_ushort16_MSBfirst(outmsg, len * 8);
2374 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2375 /* don't destroy the current credentials yet */
2376 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2377 break;
2378 }
2379 case SSH_AUTH_RHOSTS_RSA:{
2380 int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2381 int name_len = strlen(cred->rhosts_client_user);
2382 int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2383 int index;
2384 unsigned char FAR *outmsg =
2385 begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2386 12 + mod_len + name_len + exp_len);
2387
2388 notify_verbose_message(pvar,
2389 "Trying RHOSTS+RSA authentication...",
2390 LOG_LEVEL_VERBOSE);
2391
2392 set_uint32(outmsg, name_len);
2393 memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2394 index = 4 + name_len;
2395
2396 set_uint32(outmsg + index, 8 * mod_len);
2397 set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2398 BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2399 index += 6 + exp_len;
2400
2401 set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2402 BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2403 /* don't destroy the current credentials yet */
2404 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2405 break;
2406 }
2407 case SSH_AUTH_PAGEANT:{
2408 unsigned char FAR *outmsg;
2409 unsigned char *pubkey;
2410 int len, bn_bytes;
2411
2412 if (pvar->pageant_keycurrent != 0) {
2413 // ���O�������X�L�b�v
2414 pvar->pageant_curkey += 4;
2415 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2416 bn_bytes = (len + 7) / 8;
2417 pvar->pageant_curkey += 2 + bn_bytes;
2418 len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2419 bn_bytes = (len + 7) / 8;
2420 pvar->pageant_curkey += 2 + bn_bytes;
2421 // ���O�������R�����g���X�L�b�v
2422 len = get_uint32_MSBfirst(pvar->pageant_curkey);
2423 pvar->pageant_curkey += 4 + len;
2424 // �����������u������
2425 }
2426 pubkey = pvar->pageant_curkey + 4;
2427 len = get_ushort16_MSBfirst(pubkey);
2428 bn_bytes = (len + 7) / 8;
2429 pubkey += 2 + bn_bytes;
2430 len = get_ushort16_MSBfirst(pubkey);
2431 bn_bytes = (len + 7) / 8;
2432 pubkey += 2;
2433 outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes);
2434
2435 notify_verbose_message(pvar,
2436 "Trying RSA authentication...",
2437 LOG_LEVEL_VERBOSE);
2438
2439 set_ushort16_MSBfirst(outmsg, bn_bytes * 8);
2440 memcpy(outmsg + 2, pubkey, bn_bytes);
2441 /* don't destroy the current credentials yet */
2442
2443 pvar->pageant_keycurrent++;
2444
2445 enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2446 break;
2447 }
2448 case SSH_AUTH_TIS:{
2449 if (cred->password == NULL) {
2450 unsigned char FAR *outmsg =
2451 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0);
2452
2453 notify_verbose_message(pvar,
2454 "Trying TIS authentication...",
2455 LOG_LEVEL_VERBOSE);
2456 enque_handlers(pvar, 2, TIS_msgs, TIS_handlers);
2457 } else {
2458 int len = strlen(cred->password);
2459 int obfuscated_len = obfuscating_round_up(pvar, len);
2460 unsigned char FAR *outmsg =
2461 begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE,
2462 4 + obfuscated_len);
2463
2464 notify_verbose_message(pvar, "Sending TIS response",
2465 LOG_LEVEL_VERBOSE);
2466
2467 set_uint32(outmsg, obfuscated_len);
2468 memcpy(outmsg + 4, cred->password, len);
2469 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2470 enque_simple_auth_handlers(pvar);
2471 }
2472
2473 AUTH_destroy_cur_cred(pvar);
2474 break;
2475 }
2476 default:
2477 UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar,
2478 "Internal error: unsupported authentication method");
2479 notify_fatal_error(pvar, pvar->ts->UIMsg);
2480 return;
2481 }
2482
2483 finish_send_packet(pvar);
2484
2485 skip_ssh2:;
2486 destroy_packet_buf(pvar);
2487
2488 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_CREDENTIALS;
2489 }
2490 }
2491
2492 static void try_send_user_name(PTInstVar pvar)
2493 {
2494 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME) == 0) {
2495 char FAR *username = AUTH_get_user_name(pvar);
2496
2497 if (username != NULL) {
2498 int len = strlen(username);
2499 int obfuscated_len = obfuscating_round_up(pvar, len);
2500 unsigned char FAR *outmsg =
2501 begin_send_packet(pvar, SSH_CMSG_USER, 4 + obfuscated_len);
2502 char buf[1024] = "Sending user name: ";
2503 static const int msgs[] =
2504 { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2505 static const SSHPacketHandler handlers[]
2506 = { handle_noauth_success, handle_auth_required };
2507
2508 set_uint32(outmsg, obfuscated_len);
2509 memcpy(outmsg + 4, username, len);
2510 memset(outmsg + 4 + len, 0, obfuscated_len - len);
2511 finish_send_packet(pvar);
2512
2513 pvar->ssh_state.status_flags |= STATUS_DONT_SEND_USER_NAME;
2514
2515 strncat_s(buf, sizeof(buf), username, _TRUNCATE);
2516 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
2517
2518 enque_handlers(pvar, 2, msgs, handlers);
2519 }
2520 }
2521 }
2522
2523 static void send_session_key(PTInstVar pvar)
2524 {
2525 int encrypted_session_key_len;
2526 unsigned char FAR *outmsg;
2527
2528 if (SSHv1(pvar)) {
2529 encrypted_session_key_len =
2530 CRYPT_get_encrypted_session_key_len(pvar);
2531 }
2532
2533 if (!CRYPT_choose_ciphers(pvar))
2534 return;
2535
2536 if (SSHv1(pvar)) {
2537 outmsg =
2538 begin_send_packet(pvar, SSH_CMSG_SESSION_KEY,
2539 15 + encrypted_session_key_len);
2540 outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar);
2541 memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */
2542 outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5);
2543 outmsg[10] = (unsigned char) (encrypted_session_key_len << 3);
2544 if (!CRYPT_choose_session_key(pvar, outmsg + 11))
2545 return;
2546 set_uint32(outmsg + 11 + encrypted_session_key_len,
2547 SSH_PROTOFLAG_SCREEN_NUMBER |
2548 SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
2549 finish_send_packet(pvar);
2550 }
2551
2552 if (!CRYPT_start_encryption(pvar, 1, 1))
2553 return;
2554 notify_established_secure_connection(pvar);
2555
2556 if (SSHv1(pvar)) {
2557 enque_handler(pvar, SSH_SMSG_SUCCESS, handle_crypt_success);
2558 }
2559
2560 pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_USER_NAME;
2561
2562 if (SSHv1(pvar)) {
2563 try_send_user_name(pvar);
2564 }
2565 }
2566
2567 /*************************
2568 END of message handlers
2569 ************************/
2570
2571 void SSH_init(PTInstVar pvar)
2572 {
2573 int i;
2574
2575 buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2576 buf_create(&pvar->ssh_state.precompress_outbuf,
2577 &pvar->ssh_state.precompress_outbuflen);
2578 buf_create(&pvar->ssh_state.postdecompress_inbuf,
2579 &pvar->ssh_state.postdecompress_inbuflen);
2580 pvar->ssh_state.payload = NULL;
2581 pvar->ssh_state.compressing = FALSE;
2582 pvar->ssh_state.decompressing = FALSE;
2583 pvar->ssh_state.status_flags =
2584 STATUS_DONT_SEND_USER_NAME | STATUS_DONT_SEND_CREDENTIALS;
2585 pvar->ssh_state.payload_datalen = 0;
2586 pvar->ssh_state.hostname = NULL;
2587 pvar->ssh_state.server_ID = NULL;
2588 pvar->ssh_state.receiver_sequence_number = 0;
2589 pvar->ssh_state.sender_sequence_number = 0;
2590 for (i = 0; i < NUM_ELEM(pvar->ssh_state.packet_handlers); i++) {
2591 pvar->ssh_state.packet_handlers[i] = NULL;
2592 }
2593
2594 // for SSH2(yutaka)
2595 memset(pvar->ssh2_keys, 0, sizeof(pvar->ssh2_keys));
2596 pvar->userauth_success = 0;
2597 pvar->session_nego_status = 0;
2598 pvar->settings.ssh_protocol_version = 2; // SSH2(default)
2599 pvar->rekeying = 0;
2600 pvar->key_done = 0;
2601 pvar->ssh2_autologin = 0; // autologin disabled(default)
2602 pvar->ask4passwd = 0; // disabled(default) (2006.9.18 maya)
2603 pvar->userauth_retry_count = 0;
2604 pvar->decomp_buffer = NULL;
2605 pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2606 pvar->tryed_ssh2_authlist = FALSE;
2607
2608 }
2609
2610 void SSH_open(PTInstVar pvar)
2611 {
2612 pvar->ssh_state.hostname = _strdup(pvar->ts->HostName);
2613 pvar->ssh_state.tcpport = pvar->ts->TCPPort;
2614 pvar->ssh_state.win_cols = pvar->ts->TerminalWidth;
2615 pvar->ssh_state.win_rows = pvar->ts->TerminalHeight;
2616 }
2617
2618 void SSH_notify_disconnecting(PTInstVar pvar, char FAR * reason)
2619 {
2620 if (SSHv1(pvar)) {
2621 int len = reason == NULL ? 0 : strlen(reason);
2622 unsigned char FAR *outmsg =
2623 begin_send_packet(pvar, SSH_MSG_DISCONNECT, len + 4);
2624
2625 set_uint32(outmsg, len);
2626 if (reason != NULL) {
2627 memcpy(outmsg + 4, reason, len);
2628 }
2629 finish_send_packet(pvar);
2630
2631 } else { // for SSH2(yutaka)
2632 buffer_t *msg;
2633 unsigned char *outmsg;
2634 int len;
2635 Channel_t *c;
2636
2637 c = ssh2_channel_lookup(pvar->shell_id);
2638 if (c == NULL)
2639 return;
2640
2641 // SSH2 server��channel close���`����
2642 msg = buffer_init();
2643 if (msg == NULL) {
2644 // TODO: error check
2645 return;
2646 }
2647 buffer_put_int(msg, c->remote_id);
2648
2649 len = buffer_len(msg);
2650 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len);
2651 memcpy(outmsg, buffer_ptr(msg), len);
2652 finish_send_packet(pvar);
2653 buffer_free(msg);
2654
2655 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_CLOSE was sent at SSH_notify_disconnecting().", LOG_LEVEL_VERBOSE);
2656 }
2657
2658 }
2659
2660 void SSH_notify_host_OK(PTInstVar pvar)
2661 {
2662 if ((pvar->ssh_state.status_flags & STATUS_HOST_OK) == 0) {
2663 pvar->ssh_state.status_flags |= STATUS_HOST_OK;
2664 send_session_key(pvar);
2665 }
2666 }
2667
2668 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows)
2669 {
2670 pvar->ssh_state.win_cols = cols;
2671 pvar->ssh_state.win_rows = rows;
2672
2673 if (SSHv1(pvar)) {
2674 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) == handle_data) {
2675 unsigned char FAR *outmsg =
2676 begin_send_packet(pvar, SSH_CMSG_WINDOW_SIZE, 16);
2677
2678 set_uint32(outmsg, rows);
2679 set_uint32(outmsg + 4, cols);
2680 set_uint32(outmsg + 8, 0);
2681 set_uint32(outmsg + 12, 0);
2682 finish_send_packet(pvar);
2683 }
2684
2685 } else if (SSHv2(pvar)) { // �^�[�~�i���T�C�Y���X���m������ (2005.1.4 yutaka)
2686 // SSH2�����������`�F�b�N���s���B(2005.1.5 yutaka)
2687 buffer_t *msg;
2688 char *s;
2689 unsigned char *outmsg;
2690 int len;
2691 Channel_t *c;
2692
2693 c = ssh2_channel_lookup(pvar->shell_id);
2694 if (c == NULL)
2695 return;
2696
2697 msg = buffer_init();
2698 if (msg == NULL) {
2699 // TODO: error check
2700 return;
2701 }
2702 buffer_put_int(msg, c->remote_id);
2703 s = "window-change";
2704 buffer_put_string(msg, s, strlen(s));
2705 buffer_put_char(msg, 0); // wantconfirm
2706 buffer_put_int(msg, pvar->ssh_state.win_cols); // columns
2707 buffer_put_int(msg, pvar->ssh_state.win_rows); // lines
2708 buffer_put_int(msg, 480); // XXX:
2709 buffer_put_int(msg, 640); // XXX:
2710 len = buffer_len(msg);
2711 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
2712 memcpy(outmsg, buffer_ptr(msg), len);
2713 finish_send_packet(pvar);
2714 buffer_free(msg);
2715
2716 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at SSH_notify_win_size().", LOG_LEVEL_VERBOSE);
2717
2718 } else {
2719 // SSH�����������������������B
2720
2721 }
2722
2723 }
2724
2725 int SSH_get_min_packet_size(PTInstVar pvar)
2726 {
2727 if (SSHv1(pvar)) {
2728 return 12;
2729 } else {
2730 int block_size = CRYPT_get_decryption_block_size(pvar);
2731
2732 return max(16, block_size);
2733 }
2734 }
2735
2736 /* data is guaranteed to be at least SSH_get_min_packet_size bytes long
2737 at least 5 bytes must be decrypted */
2738 void SSH_predecrpyt_packet(PTInstVar pvar, char FAR * data)
2739 {
2740 if (SSHv2(pvar)) {
2741 CRYPT_decrypt(pvar, data, get_predecryption_amount(pvar));
2742 }
2743 }
2744
2745 int SSH_get_clear_MAC_size(PTInstVar pvar)
2746 {
2747 if (SSHv1(pvar)) {
2748 return 0;
2749 } else {
2750 return CRYPT_get_receiver_MAC_size(pvar);
2751 }
2752 }
2753
2754 void SSH_notify_user_name(PTInstVar pvar)
2755 {
2756 try_send_user_name(pvar);
2757 }
2758
2759 void SSH_notify_cred(PTInstVar pvar)
2760 {
2761 try_send_credentials(pvar);
2762 }
2763
2764 void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, unsigned int buflen)
2765 {
2766 // RAW�p�P�b�g�_���v������ (2008.8.15 yutaka)
2767 if (LOG_LEVEL_SSHDUMP <= pvar->session_settings.LogLevel) {
2768 init_memdump();
2769 push_memdump("SSH sending packet", "SSH_send", (char *)buf, buflen);
2770 }
2771
2772 if (SSHv1(pvar)) {
2773 if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) {
2774 return;
2775 }
2776
2777 while (buflen > 0) {
2778 int len =
2779 buflen >
2780 SSH_MAX_SEND_PACKET_SIZE ? SSH_MAX_SEND_PACKET_SIZE : buflen;
2781 unsigned char FAR *outmsg =
2782 begin_send_packet(pvar, SSH_CMSG_STDIN_DATA, 4 + len);
2783
2784 set_uint32(outmsg, len);
2785
2786 if (pvar->ssh_state.compressing) {
2787 buf_ensure_size(&pvar->ssh_state.outbuf,
2788 &pvar->ssh_state.outbuflen,
2789 len + (len >> 6) + 50);
2790 pvar->ssh_state.compress_stream.next_in =
2791 pvar->ssh_state.precompress_outbuf;
2792 pvar->ssh_state.compress_stream.avail_in = 5;
2793 pvar->ssh_state.compress_stream.next_out =
2794 pvar->ssh_state.outbuf + 12;
2795 pvar->ssh_state.compress_stream.avail_out =
2796 pvar->ssh_state.outbuflen - 12;
2797
2798 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2799 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2800 "Error compressing packet data");
2801 notify_fatal_error(pvar, pvar->ts->UIMsg);
2802 return;
2803 }
2804
2805 pvar->ssh_state.compress_stream.next_in =
2806 (unsigned char FAR *) buf;
2807 pvar->ssh_state.compress_stream.avail_in = len;
2808
2809 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
2810 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
2811 "Error compressing packet data");
2812 notify_fatal_error(pvar, pvar->ts->UIMsg);
2813 return;
2814 }
2815 } else {
2816 memcpy(outmsg + 4, buf, len);
2817 }
2818
2819 finish_send_packet_special(pvar, 1);
2820
2821 buflen -= len;
2822 buf += len;
2823 }
2824
2825 } else { // for SSH2(yutaka)
2826 Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
2827 SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen);
2828 }
2829
2830 }
2831
2832 int SSH_extract_payload(PTInstVar pvar, unsigned char FAR * dest, int len)
2833 {
2834 int num_bytes = pvar->ssh_state.payload_datalen;
2835
2836 if (num_bytes > len) {
2837 num_bytes = len;
2838 }
2839
2840 if (!pvar->ssh_state.decompressing) {
2841 memcpy(dest,
2842 pvar->ssh_state.payload + pvar->ssh_state.payload_datastart,
2843 num_bytes);
2844 pvar->ssh_state.payload_datastart += num_bytes;
2845 } else if (num_bytes > 0) {
2846 pvar->ssh_state.decompress_stream.next_out = dest;
2847 pvar->ssh_state.decompress_stream.avail_out = num_bytes;
2848
2849 if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) {
2850 UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
2851 "Invalid compressed data in received packet");
2852 notify_fatal_error(pvar, pvar->ts->UIMsg);
2853 return 0;
2854 }
2855 }
2856
2857 pvar->ssh_state.payload_datalen -= num_bytes;
2858
2859 return num_bytes;
2860 }
2861
2862 void SSH_get_compression_info(PTInstVar pvar, char FAR * dest, int len)
2863 {
2864 char buf[1024];
2865 char buf2[1024];
2866
2867 // added support of SSH2 packet compression (2005.7.10 yutaka)
2868 // support of "Compression delayed" (2006.6.23 maya)
2869 if (pvar->ssh_state.compressing ||
2870 pvar->ctos_compression == COMP_ZLIB ||
2871 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2872 unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2873 unsigned long total_out =
2874 pvar->ssh_state.compress_stream.total_out;
2875
2876 if (total_out > 0) {
2877 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2878 "level %d; ratio %.1f (%ld:%ld)");
2879 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2880 pvar->ssh_state.compression_level,
2881 ((double) total_in) / total_out, total_in,
2882 total_out);
2883 } else {
2884 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2885 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
2886 pvar->ssh_state.compression_level);
2887 }
2888 } else {
2889 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2890 strncpy_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2891 }
2892
2893 // support of "Compression delayed" (2006.6.23 maya)
2894 if (pvar->ssh_state.decompressing ||
2895 pvar->stoc_compression == COMP_ZLIB ||
2896 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2897 unsigned long total_in =
2898 pvar->ssh_state.decompress_stream.total_in;
2899 unsigned long total_out =
2900 pvar->ssh_state.decompress_stream.total_out;
2901
2902 if (total_in > 0) {
2903 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar,
2904 "level %d; ratio %.1f (%ld:%ld)");
2905 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2906 pvar->ssh_state.compression_level,
2907 ((double) total_out) / total_in, total_out,
2908 total_in);
2909 } else {
2910 UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d");
2911 _snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg,
2912 pvar->ssh_state.compression_level);
2913 }
2914 } else {
2915 UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none");
2916 strncpy_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2917 }
2918
2919 UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar,
2920 "Upstream %s; Downstream %s");
2921 _snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2);
2922 }
2923
2924 void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len)
2925 {
2926 strncpy_s(dest, len,
2927 pvar->ssh_state.server_ID == NULL ? "Unknown"
2928 : pvar->ssh_state.server_ID,
2929 _TRUNCATE);
2930 }
2931
2932 void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest,
2933 int len)
2934 {
2935 if (pvar->protocol_major == 0) {
2936 strncpy_s(dest, len, "Unknown", _TRUNCATE);
2937 } else {
2938 _snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major,
2939 pvar->protocol_minor);
2940 }
2941 }
2942
2943 void SSH_end(PTInstVar pvar)
2944 {
2945 int i;
2946 int mode;
2947
2948 for (i = 0; i < 256; i++) {
2949 SSHPacketHandlerItem FAR *first_item =
2950 pvar->ssh_state.packet_handlers[i];
2951
2952 if (first_item != NULL) {
2953 SSHPacketHandlerItem FAR *item = first_item;
2954
2955 do {
2956 SSHPacketHandlerItem FAR *cur_item = item;
2957
2958 item = item->next_for_message;
2959 free(cur_item);
2960 } while (item != first_item);
2961 }
2962 pvar->ssh_state.packet_handlers[i] = NULL;
2963 }
2964
2965 free(pvar->ssh_state.hostname);
2966 pvar->ssh_state.hostname = NULL;
2967 free(pvar->ssh_state.server_ID);
2968 pvar->ssh_state.server_ID = NULL;
2969 buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen);
2970 buf_destroy(&pvar->ssh_state.precompress_outbuf,
2971 &pvar->ssh_state.precompress_outbuflen);
2972 buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
2973 &pvar->ssh_state.postdecompress_inbuflen);
2974
2975 // support of "Compression delayed" (2006.6.23 maya)
2976 if (pvar->ssh_state.compressing ||
2977 pvar->ctos_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2978 pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) {
2979 deflateEnd(&pvar->ssh_state.compress_stream);
2980 pvar->ssh_state.compressing = FALSE;
2981 }
2982 // support of "Compression delayed" (2006.6.23 maya)
2983 if (pvar->ssh_state.decompressing ||
2984 pvar->stoc_compression == COMP_ZLIB || // add SSH2 flag (2005.7.10 yutaka)
2985 pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) {
2986 inflateEnd(&pvar->ssh_state.decompress_stream);
2987 pvar->ssh_state.decompressing = FALSE;
2988 }
2989
2990 #if 1
2991 // SSH2���f�[�^���������� (2004.12.27 yutaka)
2992 if (SSHv2(pvar)) {
2993 if (pvar->kexdh) {
2994 DH_free(pvar->kexdh);
2995 pvar->kexdh = NULL;
2996 }
2997 memset(pvar->server_version_string, 0, sizeof(pvar->server_version_string));
2998 memset(pvar->client_version_string, 0, sizeof(pvar->client_version_string));
2999
3000 if (pvar->my_kex != NULL) {
3001 buffer_free(pvar->my_kex);
3002 pvar->my_kex = NULL;
3003 }
3004 if (pvar->peer_kex != NULL) {
3005 buffer_free(pvar->peer_kex);
3006 pvar->peer_kex = NULL;
3007 }
3008
3009 pvar->we_need = 0;
3010 pvar->key_done = 0;
3011 pvar->rekeying = 0;
3012
3013 if (pvar->session_id != NULL) {
3014 free(pvar->session_id);
3015 pvar->session_id = NULL;
3016 }
3017 pvar->session_id_len = 0;
3018
3019 pvar->userauth_success = 0;
3020 //pvar->remote_id = 0;
3021 pvar->shell_id = 0;
3022 pvar->session_nego_status = 0;
3023
3024 pvar->ssh_heartbeat_tick = 0;
3025
3026 if (pvar->decomp_buffer != NULL) {
3027 buffer_free(pvar->decomp_buffer);
3028 pvar->decomp_buffer = NULL;
3029 }
3030
3031 if (pvar->ssh2_authlist != NULL) { // (2007.4.27 yutaka)
3032 free(pvar->ssh2_authlist);
3033 pvar->ssh2_authlist = NULL;
3034 }
3035
3036 pvar->tryed_ssh2_authlist = FALSE;
3037
3038 // add (2008.3.2 yutaka)
3039 for (mode = 0 ; mode < MODE_MAX ; mode++) {
3040 if (pvar->ssh2_keys[mode].enc.iv != NULL) {
3041 free(pvar->ssh2_keys[mode].enc.iv);
3042 pvar->ssh2_keys[mode].enc.iv = NULL;
3043 }
3044 if (pvar->ssh2_keys[mode].enc.key != NULL) {
3045 free(pvar->ssh2_keys[mode].enc.key);
3046 pvar->ssh2_keys[mode].enc.key = NULL;
3047 }
3048 if (pvar->ssh2_keys[mode].mac.key != NULL) {
3049 free(pvar->ssh2_keys[mode].mac.key);
3050 pvar->ssh2_keys[mode].mac.key = NULL;
3051 }
3052 }
3053 }
3054 #endif
3055
3056 }
3057
3058 static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen)
3059 {
3060 buffer_t *msg;
3061 unsigned char *outmsg;
3062 unsigned int len;
3063
3064 // SSH2���������������A�p�P�b�g���������B(2005.6.19 yutaka)
3065 if (pvar->rekeying) {
3066 // TODO: ���z���������p�P�b�g�j�����������A�p�P�b�g���������x���������������������A
3067 // �������������������B
3068 c = NULL;
3069
3070 return;
3071 }
3072
3073 if (c == NULL)
3074 return;
3075
3076 if ((unsigned int)buflen > c->remote_window) {
3077 unsigned int offset = c->remote_window;
3078 // ���������f�[�^����������������������
3079 ssh2_channel_add_bufchain(c, buf + offset, buflen - offset);
3080 buflen = offset;
3081 }
3082 if (buflen > 0) {
3083 msg = buffer_init();
3084 if (msg == NULL) {
3085 // TODO: error check
3086 return;
3087 }
3088 buffer_put_int(msg, c->remote_id);
3089 buffer_put_string(msg, (char *)buf, buflen);
3090
3091 len = buffer_len(msg);
3092 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
3093 //if (len + 12 >= pvar->ssh_state.outbuflen) *(int *)0 = 0;
3094 memcpy(outmsg, buffer_ptr(msg), len);
3095 finish_send_packet(pvar);
3096 buffer_free(msg);
3097 //debug_print(1, pvar->ssh_state.outbuf, 7 + 4 + 1 + 1 + len);
3098
3099 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_DATA was sent at SSH_handle_packet().", LOG_LEVEL_SSHDUMP);
3100
3101 // remote window size������
3102 if (buflen <= c->remote_window) {
3103 c->remote_window -= buflen;
3104 }
3105 else {
3106 c->remote_window = 0;
3107 }
3108 }
3109 }
3110
3111 /* support for port forwarding */
3112 void SSH_channel_send(PTInstVar pvar, int channel_num,
3113 uint32 remote_channel_num,
3114 unsigned char FAR * buf, int len)
3115 {
3116 if (SSHv1(pvar)) {
3117 unsigned char FAR *outmsg =
3118 begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
3119
3120 set_uint32(outmsg, remote_channel_num);
3121 set_uint32(outmsg + 4, len);
3122
3123 if (pvar->ssh_state.compressing) {
3124 buf_ensure_size(&pvar->ssh_state.outbuf,
3125 &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
3126 pvar->ssh_state.compress_stream.next_in =
3127 pvar->ssh_state.precompress_outbuf;
3128 pvar->ssh_state.compress_stream.avail_in = 9;
3129 pvar->ssh_state.compress_stream.next_out =
3130 pvar->ssh_state.outbuf + 12;
3131 pvar->ssh_state.compress_stream.avail_out =
3132 pvar->ssh_state.outbuflen - 12;
3133
3134 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
3135 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
3136 "Error compressing packet data");
3137 notify_fatal_error(pvar, pvar->ts->UIMsg);
3138 return;
3139 }
3140
3141 pvar->ssh_state.compress_stream.next_in =
3142 (unsigned char FAR *) buf;
3143 pvar->ssh_state.compress_stream.avail_in = len;
3144
3145 if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
3146 Z_OK) {
3147 UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
3148 "Error compressing packet data");
3149 notify_fatal_error(pvar, pvar->ts->UIMsg);
3150 return;
3151 }
3152 } else {
3153 memcpy(outmsg + 8, buf, len);
3154 }
3155
3156 finish_send_packet_special(pvar, 1);
3157
3158 } else {
3159 // �|�[�g�t�H���[�f�B���O���������N���C�A���g���������M�v�����ASSH���M���������T�[�o���������������B
3160 Channel_t *c = ssh2_local_channel_lookup(channel_num);
3161 SSH2_send_channel_data(pvar, c, buf, len);
3162 }
3163
3164 }
3165
3166 void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
3167 {
3168 if (SSHv1(pvar)) {
3169 unsigned char FAR *outmsg =
3170 begin_send_packet(pvar, SSH_MSG_CHANNEL_OPEN_FAILURE, 4);
3171
3172 set_uint32(outmsg, remote_channel_num);
3173 finish_send_packet(pvar);
3174
3175 } else { // SSH2 (2005.6.26 yutaka)
3176 int len;
3177 Channel_t *c = NULL;
3178 buffer_t *msg;
3179 unsigned char *outmsg;
3180
3181 msg = buffer_init();
3182 if (msg == NULL) {
3183 // TODO: error check
3184 return;
3185 }
3186 buffer_put_int(msg, remote_channel_num);
3187 buffer_put_int(msg, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
3188 buffer_put_string(msg, "", 0); // description
3189 buffer_put_string(msg, "", 0); // language tag
3190
3191 len = buffer_len(msg);
3192 outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, len);
3193 memcpy(outmsg, buffer_ptr(msg), len);
3194 finish_send_packet(pvar);
3195 buffer_free(msg);
3196
3197 notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_OPEN_FAILURE was sent at SSH_fail_channel_open().", LOG_LEVEL_VERBOSE);
3198 }
3199