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 2809 - (show annotations) (download) (as text)
Sun Apr 3 14:39:48 2005 UTC (19 years ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 147296 byte(s)
SSH2 channel lookup機構の追加(ポートフォワーディングのため)。
TTSSH 2.10で追加したlog dump機構において、DH鍵再作成時にbuffer freeで
アプリケーションが落ちてしまうバグを修正。

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