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 3108 - (show annotations) (download) (as text)
Tue Feb 12 23:11:49 2008 UTC (16 years, 2 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 218474 byte(s)
Pageant 対応処理を追加した。
SSH2 はひととおり対応済み。
SSH1 は実装途中。

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