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 6969 - (show annotations) (download) (as text)
Thu Nov 2 11:37:41 2017 UTC (6 years, 5 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ssh.c
File MIME type: text/x-csrc
File size: 266854 byte(s)
OpenSSH の EtM 方式の MAC に対応。#31495

以下の MAC 方式に対応。
  ・hmac-sha2-256-etm@openssh.comhmac-sha2-512-etm@openssh.comhmac-sha1-etm@openssh.comhmac-md5-etm@openssh.com (*1)
  ・hmac-ripemd160-etm@openssh.com (*1, *2)
  ・hmac-sha1-96-etm@openssh.com (*1, *3)
  ・hmac-md5-96-etm@openssh.com (*1, *3)

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