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