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