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