Develop and Download Open Source Software

Browse Subversion Repository

Diff of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3221 by maya, Tue Mar 24 09:37:20 2009 UTC revision 3227 by maya, Tue Mar 24 15:10:33 2009 UTC
# Line 1  Line 1 
1  /*  /*
2  Copyright (c) 1998-2001, Robert O'Callahan  Copyright (c) 1998-2001, Robert O'Callahan
3  Copyright (c) 2004-2005, Yutaka Hirata  Copyright (c) 2004-2005, Yutaka Hirata
4  All rights reserved.  All rights reserved.
5    
6  Redistribution and use in source and binary forms, with or without modification,  Redistribution and use in source and binary forms, with or without modification,
7  are permitted provided that the following conditions are met:  are permitted provided that the following conditions are met:
8    
9  Redistributions of source code must retain the above copyright notice, this list of  Redistributions of source code must retain the above copyright notice, this list of
10  conditions and the following disclaimer.  conditions and the following disclaimer.
11    
12  Redistributions in binary form must reproduce the above copyright notice, this list  Redistributions in binary form must reproduce the above copyright notice, this list
13  of conditions and the following disclaimer in the documentation and/or other materials  of conditions and the following disclaimer in the documentation and/or other materials
14  provided with the distribution.  provided with the distribution.
15    
16  The name of Robert O'Callahan may not be used to endorse or promote products derived from  The name of Robert O'Callahan may not be used to endorse or promote products derived from
17  this software without specific prior written permission.  this software without specific prior written permission.
18    
19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
20  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22  THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */  */
29    
30  #include "ttxssh.h"  #include "ttxssh.h"
31  #include "util.h"  #include "util.h"
32  #include "resource.h"  #include "resource.h"
33  #include "libputty.h"  #include "libputty.h"
34    
35  #include <openssl/bn.h>  #include <openssl/bn.h>
36  #include <openssl/evp.h>  #include <openssl/evp.h>
37  #include <openssl/dh.h>  #include <openssl/dh.h>
38  #include <openssl/engine.h>  #include <openssl/engine.h>
39  #include <openssl/rsa.h>  #include <openssl/rsa.h>
40  #include <openssl/dsa.h>  #include <openssl/dsa.h>
41  #include <openssl/md5.h>  #include <openssl/md5.h>
42  #include <limits.h>  #include <limits.h>
43  #include <malloc.h>  #include <malloc.h>
44  #include <string.h>  #include <string.h>
45  #include <stdlib.h>  #include <stdlib.h>
46  #include <process.h>  #include <process.h>
47  #include <time.h>  #include <time.h>
48  #include "buffer.h"  #include "buffer.h"
49  #include "ssh.h"  #include "ssh.h"
50  #include "crypt.h"  #include "crypt.h"
51  #include "fwd.h"  #include "fwd.h"
52  #include "sftp.h"  #include "sftp.h"
53    
54  #include <sys/types.h>  #include <sys/types.h>
55  #include <sys/stat.h>  #include <sys/stat.h>
56  #include <assert.h>  #include <assert.h>
57    
58  #include <direct.h>  #include <direct.h>
59  #include <io.h>  #include <io.h>
60    
61  // SSH2 macro  // SSH2 macro
62  #ifdef _DEBUG  #ifdef _DEBUG
63  #define SSH2_DEBUG  #define SSH2_DEBUG
64  #endif  #endif
65    
66  //#define DONT_WANTCONFIRM 1  // (2005.3.28 yutaka)  //#define DONT_WANTCONFIRM 1  // (2005.3.28 yutaka)
67  #undef DONT_WANTCONFIRM // (2008.11.25 maya)  #undef DONT_WANTCONFIRM // (2008.11.25 maya)
68  #define INTBLOB_LEN 20  #define INTBLOB_LEN 20
69  #define SIGBLOB_LEN (2*INTBLOB_LEN)  #define SIGBLOB_LEN (2*INTBLOB_LEN)
70    
71  //  //
72  // SSH2 data structure  // SSH2 data structure
73  //  //
74    
75  // channel data structure  // channel data structure
76  #define CHANNEL_MAX 100  #define CHANNEL_MAX 100
77    
78  enum scp_state {  enum scp_state {
79          SCP_INIT, SCP_TIMESTAMP, SCP_FILEINFO, SCP_DATA, SCP_CLOSING,          SCP_INIT, SCP_TIMESTAMP, SCP_FILEINFO, SCP_DATA, SCP_CLOSING,
80  };  };
81    
82  typedef struct bufchain {  typedef struct bufchain {
83          buffer_t *msg;          buffer_t *msg;
84          struct bufchain *next;          struct bufchain *next;
85  } bufchain_t;  } bufchain_t;
86    
87  typedef struct scp {  typedef struct scp {
88          enum scp_dir dir;              // transfer direction          enum scp_dir dir;              // transfer direction
89          enum scp_state state;          // SCP state          enum scp_state state;          // SCP state
90          char localfile[MAX_PATH];      // local filename          char localfile[MAX_PATH];      // local filename
91          char localfilefull[MAX_PATH];  // local filename fullpath          char localfilefull[MAX_PATH];  // local filename fullpath
92          char remotefile[MAX_PATH];     // remote filename          char remotefile[MAX_PATH];     // remote filename
93          FILE *localfp;                 // file pointer for local file          FILE *localfp;                 // file pointer for local file
94          struct _stat filestat;         // file status information          struct _stat filestat;         // file status information
95          HWND progress_window;          HWND progress_window;
96          HANDLE thread;          HANDLE thread;
97          unsigned int thread_id;          unsigned int thread_id;
98          PTInstVar pvar;          PTInstVar pvar;
99          // for receiving file          // for receiving file
100          long long filetotalsize;          long long filetotalsize;
101          long long filercvsize;          long long filercvsize;
102  } scp_t;  } scp_t;
103    
104  typedef struct channel {  typedef struct channel {
105          int used;          int used;
106          int self_id;          int self_id;
107          int remote_id;          int remote_id;
108          unsigned int local_window;          unsigned int local_window;
109          unsigned int local_window_max;          unsigned int local_window_max;
110          unsigned int local_consumed;          unsigned int local_consumed;
111          unsigned int local_maxpacket;          unsigned int local_maxpacket;
112          unsigned int remote_window;          unsigned int remote_window;
113          unsigned int remote_maxpacket;          unsigned int remote_maxpacket;
114          enum channel_type type;          enum channel_type type;
115          int local_num;          int local_num;
116          bufchain_t *bufchain;          bufchain_t *bufchain;
117          scp_t scp;          scp_t scp;
118          buffer_t *agent_msg;          buffer_t *agent_msg;
119          int agent_request_len;          int agent_request_len;
120  } Channel_t;  } Channel_t;
121    
122  static Channel_t channels[CHANNEL_MAX];  static Channel_t channels[CHANNEL_MAX];
123    
124  static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";  static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04";
125    
126  static void try_send_credentials(PTInstVar pvar);  static void try_send_credentials(PTInstVar pvar);
127  static void prep_compression(PTInstVar pvar);  static void prep_compression(PTInstVar pvar);
128    
129  // 関数プロトタイプ宣言  // 関数プロトタイプ宣言
130  void SSH2_send_kexinit(PTInstVar pvar);  void SSH2_send_kexinit(PTInstVar pvar);
131  static BOOL handle_SSH2_kexinit(PTInstVar pvar);  static BOOL handle_SSH2_kexinit(PTInstVar pvar);
132  static void SSH2_dh_kex_init(PTInstVar pvar);  static void SSH2_dh_kex_init(PTInstVar pvar);
133  static void SSH2_dh_gex_kex_init(PTInstVar pvar);  static void SSH2_dh_gex_kex_init(PTInstVar pvar);
134  static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);  static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar);
135  static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);  static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar);
136  static BOOL handle_SSH2_newkeys(PTInstVar pvar);  static BOOL handle_SSH2_newkeys(PTInstVar pvar);
137  static BOOL handle_SSH2_service_accept(PTInstVar pvar);  static BOOL handle_SSH2_service_accept(PTInstVar pvar);
138  static BOOL handle_SSH2_userauth_success(PTInstVar pvar);  static BOOL handle_SSH2_userauth_success(PTInstVar pvar);
139  static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);  static BOOL handle_SSH2_userauth_failure(PTInstVar pvar);
140  static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);  static BOOL handle_SSH2_userauth_banner(PTInstVar pvar);
141  static BOOL handle_SSH2_open_confirm(PTInstVar pvar);  static BOOL handle_SSH2_open_confirm(PTInstVar pvar);
142  static BOOL handle_SSH2_open_failure(PTInstVar pvar);  static BOOL handle_SSH2_open_failure(PTInstVar pvar);
143  static BOOL handle_SSH2_request_success(PTInstVar pvar);  static BOOL handle_SSH2_request_success(PTInstVar pvar);
144  static BOOL handle_SSH2_request_failure(PTInstVar pvar);  static BOOL handle_SSH2_request_failure(PTInstVar pvar);
145  static BOOL handle_SSH2_channel_success(PTInstVar pvar);  static BOOL handle_SSH2_channel_success(PTInstVar pvar);
146  static BOOL handle_SSH2_channel_failure(PTInstVar pvar);  static BOOL handle_SSH2_channel_failure(PTInstVar pvar);
147  static BOOL handle_SSH2_channel_data(PTInstVar pvar);  static BOOL handle_SSH2_channel_data(PTInstVar pvar);
148  static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);  static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
149  static BOOL handle_SSH2_channel_eof(PTInstVar pvar);  static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
150  static BOOL handle_SSH2_channel_close(PTInstVar pvar);  static BOOL handle_SSH2_channel_close(PTInstVar pvar);
151  static BOOL handle_SSH2_channel_open(PTInstVar pvar);  static BOOL handle_SSH2_channel_open(PTInstVar pvar);
152  static BOOL handle_SSH2_window_adjust(PTInstVar pvar);  static BOOL handle_SSH2_window_adjust(PTInstVar pvar);
153  static BOOL handle_SSH2_channel_request(PTInstVar pvar);  static BOOL handle_SSH2_channel_request(PTInstVar pvar);
154  void SSH2_dispatch_init(int stage);  void SSH2_dispatch_init(int stage);
155  int SSH2_dispatch_enabled_check(unsigned char message);  int SSH2_dispatch_enabled_check(unsigned char message);
156  void SSH2_dispatch_add_message(unsigned char message);  void SSH2_dispatch_add_message(unsigned char message);
157  void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);  void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end);
158  int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);  int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
159  static void start_ssh_heartbeat_thread(PTInstVar pvar);  static void start_ssh_heartbeat_thread(PTInstVar pvar);
160  static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen);  static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen);
161  void ssh2_channel_send_close(PTInstVar pvar, Channel_t *c);  void ssh2_channel_send_close(PTInstVar pvar, Channel_t *c);
162  static BOOL SSH_agent_response(PTInstVar pvar, Channel_t *c, int local_channel_num, unsigned char *data, unsigned int buflen);  static BOOL SSH_agent_response(PTInstVar pvar, Channel_t *c, int local_channel_num, unsigned char *data, unsigned int buflen);
163    
164  //  //
165  // channel function  // channel function
166  //  //
167  static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack,  static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack,
168                                     enum confirm_type type, int local_num)                                     enum confirm_type type, int local_num)
169  {  {
170          int i, found;          int i, found;
171          Channel_t *c;          Channel_t *c;
172    
173          found = -1;          found = -1;
174          for (i = 0 ; i < CHANNEL_MAX ; i++) {          for (i = 0 ; i < CHANNEL_MAX ; i++) {
175                  if (channels[i].used == 0) { // free channel                  if (channels[i].used == 0) { // free channel
176                          found = i;                          found = i;
177                          break;                          break;
178                  }                  }
179          }          }
180          if (found == -1) { // not free channel          if (found == -1) { // not free channel
181                  return (NULL);                  return (NULL);
182          }          }
183    
184          // setup          // setup
185          c = &channels[found];          c = &channels[found];
186          memset(c, 0, sizeof(Channel_t));          memset(c, 0, sizeof(Channel_t));
187          c->used = 1;          c->used = 1;
188          c->self_id = i;          c->self_id = i;
189          c->remote_id = -1;          c->remote_id = -1;
190          c->local_window = window;          c->local_window = window;
191          c->local_window_max = window;          c->local_window_max = window;
192          c->local_consumed = 0;          c->local_consumed = 0;
193          c->local_maxpacket = maxpack;          c->local_maxpacket = maxpack;
194          c->remote_window = 0;          c->remote_window = 0;
195          c->remote_maxpacket = 0;          c->remote_maxpacket = 0;
196          c->type = type;          c->type = type;
197          c->local_num = local_num;  // alloc_channel()の返値を保存しておく          c->local_num = local_num;  // alloc_channel()の返値を保存しておく
198          c->bufchain = NULL;          c->bufchain = NULL;
199          if (type == TYPE_SCP) {          if (type == TYPE_SCP) {
200                  c->scp.state = SCP_INIT;                  c->scp.state = SCP_INIT;
201                  c->scp.progress_window = NULL;                  c->scp.progress_window = NULL;
202                  c->scp.thread = (HANDLE)-1;                  c->scp.thread = (HANDLE)-1;
203                  c->scp.localfp = NULL;                  c->scp.localfp = NULL;
204          }          }
205          if (type == TYPE_AGENT) {          if (type == TYPE_AGENT) {
206                  c->agent_msg = buffer_init();                  c->agent_msg = buffer_init();
207                  c->agent_request_len = 0;                  c->agent_request_len = 0;
208          }          }
209    
210          return (c);          return (c);
211  }  }
212    
213  // remote_windowの空きがない場合に、送れなかったバッファをリスト(入力順)へつないでおく。  // remote_windowの空きがない場合に、送れなかったバッファをリスト(入力順)へつないでおく。
214  static void ssh2_channel_add_bufchain(Channel_t *c, unsigned char *buf, unsigned int buflen)  static void ssh2_channel_add_bufchain(Channel_t *c, unsigned char *buf, unsigned int buflen)
215  {  {
216          bufchain_t *p, *old;          bufchain_t *p, *old;
217    
218          // allocate new buffer          // allocate new buffer
219          p = malloc(sizeof(bufchain_t));          p = malloc(sizeof(bufchain_t));
220          if (p == NULL)          if (p == NULL)
221                  return;                  return;
222          p->msg = buffer_init();          p->msg = buffer_init();
223          if (p == NULL) {          if (p == NULL) {
224                  free(p);                  free(p);
225                  return;                  return;
226          }          }
227          buffer_put_raw(p->msg, buf, buflen);          buffer_put_raw(p->msg, buf, buflen);
228          p->next = NULL;          p->next = NULL;
229    
230          if (c->bufchain == NULL) {          if (c->bufchain == NULL) {
231                  c->bufchain = p;                  c->bufchain = p;
232          } else {          } else {
233                  old = c->bufchain;                  old = c->bufchain;
234                  while (old->next)                  while (old->next)
235                          old = old->next;                          old = old->next;
236                  old->next = p;                  old->next = p;
237          }          }
238  }  }
239    
240    
241  static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c)  static void ssh2_channel_retry_send_bufchain(PTInstVar pvar, Channel_t *c)
242  {  {
243          bufchain_t *ch;          bufchain_t *ch;
244          unsigned int size;          unsigned int size;
245    
246          while (c->bufchain) {          while (c->bufchain) {
247                  // 先頭から先に送る                  // 先頭から先に送る
248                  ch = c->bufchain;                  ch = c->bufchain;
249                  size = buffer_len(ch->msg);                  size = buffer_len(ch->msg);
250                  if (size >= c->remote_window)                  if (size >= c->remote_window)
251                          break;                          break;
252    
253                  if (c->local_num == -1) { // shell or SCP                  if (c->local_num == -1) { // shell or SCP
254                          SSH2_send_channel_data(pvar, c, buffer_ptr(ch->msg), size);                          SSH2_send_channel_data(pvar, c, buffer_ptr(ch->msg), size);
255                  } else { // port-forwarding                  } else { // port-forwarding
256                          SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size);                          SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size);
257                  }                  }
258    
259                  c->bufchain = ch->next;                  c->bufchain = ch->next;
260    
261                  buffer_free(ch->msg);                  buffer_free(ch->msg);
262                  free(ch);                  free(ch);
263          }          }
264  }  }
265    
266    
267    
268  // channel close時にチャネル構造体をリストへ返却する  // channel close時にチャネル構造体をリストへ返却する
269  // (2007.4.26 yutaka)  // (2007.4.26 yutaka)
270  static void ssh2_channel_delete(Channel_t *c)  static void ssh2_channel_delete(Channel_t *c)
271  {  {
272          bufchain_t *ch, *ptr;          bufchain_t *ch, *ptr;
273    
274          ch = c->bufchain;          ch = c->bufchain;
275          while (ch) {          while (ch) {
276                  if (ch->msg)                  if (ch->msg)
277                          buffer_free(ch->msg);                          buffer_free(ch->msg);
278                  ptr = ch;                  ptr = ch;
279                  ch = ch->next;                  ch = ch->next;
280                  free(ptr);                  free(ptr);
281          }          }
282    
283          if (c->type == TYPE_SCP) {          if (c->type == TYPE_SCP) {
284                  c->scp.state = SCP_CLOSING;                  c->scp.state = SCP_CLOSING;
285                  if (c->scp.localfp != NULL)                  if (c->scp.localfp != NULL)
286                          fclose(c->scp.localfp);                          fclose(c->scp.localfp);
287                  if (c->scp.progress_window != NULL) {                  if (c->scp.progress_window != NULL) {
288                          DestroyWindow(c->scp.progress_window);                          DestroyWindow(c->scp.progress_window);
289                          c->scp.progress_window = NULL;                          c->scp.progress_window = NULL;
290                  }                  }
291                  if (c->scp.thread != (HANDLE)-1L) {                  if (c->scp.thread != (HANDLE)-1L) {
292                          WaitForSingleObject(c->scp.thread, INFINITE);                          WaitForSingleObject(c->scp.thread, INFINITE);
293                          CloseHandle(c->scp.thread);                          CloseHandle(c->scp.thread);
294                          c->scp.thread = (HANDLE)-1L;                          c->scp.thread = (HANDLE)-1L;
295                  }                  }
296          }          }
297          if (c->type == TYPE_AGENT) {          if (c->type == TYPE_AGENT) {
298                  buffer_free(c->agent_msg);                  buffer_free(c->agent_msg);
299          }          }
300    
301          memset(c, 0, sizeof(Channel_t));          memset(c, 0, sizeof(Channel_t));
302          c->used = 0;          c->used = 0;
303  }  }
304    
305    
306  // connection close時に呼ばれる  // connection close時に呼ばれる
307  void ssh2_channel_free(void)  void ssh2_channel_free(void)
308  {  {
309          int i;          int i;
310          Channel_t *c;          Channel_t *c;
311    
312          for (i = 0 ; i < CHANNEL_MAX ; i++) {          for (i = 0 ; i < CHANNEL_MAX ; i++) {
313                  c = &channels[i];                  c = &channels[i];
314                  ssh2_channel_delete(c);                  ssh2_channel_delete(c);
315          }          }
316    
317  }  }
318    
319  static Channel_t *ssh2_channel_lookup(int id)  static Channel_t *ssh2_channel_lookup(int id)
320  {  {
321          Channel_t *c;          Channel_t *c;
322    
323          if (id < 0 || id >= CHANNEL_MAX) {          if (id < 0 || id >= CHANNEL_MAX) {
324                  return (NULL);                  return (NULL);
325          }          }
326          c = &channels[id];          c = &channels[id];
327          if (c->used == 0) { // already freed          if (c->used == 0) { // already freed
328                  return (NULL);                  return (NULL);
329          }          }
330          return (c);          return (c);
331  }  }
332    
333  // SSH1で管理しているchannel構造体から、SSH2向けのChannel_tへ変換する。  // SSH1で管理しているchannel構造体から、SSH2向けのChannel_tへ変換する。
334  // TODO: 将来的にはチャネル構造体は1つに統合する。  // TODO: 将来的にはチャネル構造体は1つに統合する。
335  // (2005.6.12 yutaka)  // (2005.6.12 yutaka)
336  static Channel_t *ssh2_local_channel_lookup(int local_num)  static Channel_t *ssh2_local_channel_lookup(int local_num)
337  {  {
338          int i;          int i;
339          Channel_t *c;          Channel_t *c;
340    
341          for (i = 0 ; i < CHANNEL_MAX ; i++) {          for (i = 0 ; i < CHANNEL_MAX ; i++) {
342                  c = &channels[i];                  c = &channels[i];
343                  if (c->local_num == local_num)                  if (c->local_num == local_num)
344                          return (c);                          return (c);
345          }          }
346          return (NULL);          return (NULL);
347  }  }
348    
349    
350  //  //
351  // SSH heartbeat mutex  // SSH heartbeat mutex
352  //  //
353  // TTSSHは thread-safe ではないため、マルチスレッドからのパケット送信はできない。  // TTSSHは thread-safe ではないため、マルチスレッドからのパケット送信はできない。
354  // シングルスレッドではコンテキストスイッチが発生することはないため、  // シングルスレッドではコンテキストスイッチが発生することはないため、
355  // ロックを取る必要もないため、削除する。(2007.12.26 yutaka)  // ロックを取る必要もないため、削除する。(2007.12.26 yutaka)
356  //  //
357  static CRITICAL_SECTION g_ssh_heartbeat_lock;   /* 送受信用ロック */  static CRITICAL_SECTION g_ssh_heartbeat_lock;   /* 送受信用ロック */
358    
359  void ssh_heartbeat_lock_initialize(void)  void ssh_heartbeat_lock_initialize(void)
360  {  {
361          //InitializeCriticalSection(&g_ssh_heartbeat_lock);          //InitializeCriticalSection(&g_ssh_heartbeat_lock);
362  }  }
363    
364  void ssh_heartbeat_lock_finalize(void)  void ssh_heartbeat_lock_finalize(void)
365  {  {
366          //DeleteCriticalSection(&g_ssh_heartbeat_lock);          //DeleteCriticalSection(&g_ssh_heartbeat_lock);
367  }  }
368    
369  void ssh_heartbeat_lock(void)  void ssh_heartbeat_lock(void)
370  {  {
371          //EnterCriticalSection(&g_ssh_heartbeat_lock);          //EnterCriticalSection(&g_ssh_heartbeat_lock);
372  }  }
373    
374  void ssh_heartbeat_unlock(void)  void ssh_heartbeat_unlock(void)
375  {  {
376          //LeaveCriticalSection(&g_ssh_heartbeat_lock);          //LeaveCriticalSection(&g_ssh_heartbeat_lock);
377  }  }
378    
379    
380  //  //
381  // SSH memory dump (for debug)  // SSH memory dump (for debug)
382  //  //
383  // (2005.3.7 yutaka)  // (2005.3.7 yutaka)
384  //  //
385  #define MEMTAG_MAX 300  #define MEMTAG_MAX 300
386  #define LOGDUMP "ssh2connect.log"  #define LOGDUMP "ssh2connect.log"
387  #define LOG_PACKET_DUMP "ssh2packet.log"  #define LOG_PACKET_DUMP "ssh2packet.log"
388  #define SENDTOME "Please send '"LOGDUMP"' file to Tera Term developer team."  #define SENDTOME "Please send '"LOGDUMP"' file to Tera Term developer team."
389    
390  typedef struct memtag {  typedef struct memtag {
391          char *name;          char *name;
392          char *desc;          char *desc;
393          time_t time;          time_t time;
394          int len;          int len;
395          char *data;          char *data;
396  } memtag_t;  } memtag_t;
397    
398  static memtag_t memtags[MEMTAG_MAX];  static memtag_t memtags[MEMTAG_MAX];
399  static int memtag_count = 0;  static int memtag_count = 0;
400  static int memtag_use = 0;  static int memtag_use = 0;
401    
402  /* ダンプラインをフォーマット表示する */  /* ダンプラインをフォーマット表示する */
403  static void displine_memdump(FILE *fp, int addr, int *bytes, int byte_cnt)  static void displine_memdump(FILE *fp, int addr, int *bytes, int byte_cnt)
404  {  {
405          int i, c;          int i, c;
406    
407          /* 先頭のアドレス表示 */          /* 先頭のアドレス表示 */
408          fprintf(fp, "%08X : ", addr);          fprintf(fp, "%08X : ", addr);
409    
410          /* バイナリ表示(4バイトごとに空白を挿入)*/          /* バイナリ表示(4バイトごとに空白を挿入)*/
411          for (i = 0 ; i < byte_cnt ; i++) {          for (i = 0 ; i < byte_cnt ; i++) {
412                  if (i > 0 && i % 4 == 0)                  if (i > 0 && i % 4 == 0)
413                          fprintf(fp, " ");                          fprintf(fp, " ");
414    
415                  fprintf(fp, "%02X", bytes[i]);                  fprintf(fp, "%02X", bytes[i]);
416          }          }
417    
418          /* ASCII表示部分までの空白を補う */          /* ASCII表示部分までの空白を補う */
419          fprintf(fp, "   %*s%*s", (16-byte_cnt)*2+1, " ", (16-byte_cnt+3)/4, " ");          fprintf(fp, "   %*s%*s", (16-byte_cnt)*2+1, " ", (16-byte_cnt+3)/4, " ");
420    
421          /* ASCII表示 */          /* ASCII表示 */
422          for (i = 0 ; i < byte_cnt ; i++) {          for (i = 0 ; i < byte_cnt ; i++) {
423                  c = bytes[i];                  c = bytes[i];
424                  if (isprint(c)) {                  if (isprint(c)) {
425                          fprintf(fp, "%c", c);                          fprintf(fp, "%c", c);
426                  } else {                  } else {
427                          fprintf(fp, ".");                          fprintf(fp, ".");
428                  }                  }
429          }          }
430    
431          fprintf(fp, "\n");          fprintf(fp, "\n");
432  }  }
433    
434    
435  /* ダンプルーチン */  /* ダンプルーチン */
436  static void dump_memdump(FILE *fp, char *data, int len)  static void dump_memdump(FILE *fp, char *data, int len)
437  {  {
438          int c, addr;          int c, addr;
439          int bytes[16], *ptr;          int bytes[16], *ptr;
440          int byte_cnt;          int byte_cnt;
441          int i;          int i;
442    
443          addr = 0;          addr = 0;
444          byte_cnt = 0;          byte_cnt = 0;
445          ptr = bytes;          ptr = bytes;
446          for (i = 0 ; i < len ; i++) {          for (i = 0 ; i < len ; i++) {
447                  c = data[i];                  c = data[i];
448                  *ptr++ = c & 0xff;                  *ptr++ = c & 0xff;
449                  byte_cnt++;                  byte_cnt++;
450    
451                  if (byte_cnt == 16) {                  if (byte_cnt == 16) {
452                          displine_memdump(fp, addr, bytes, byte_cnt);                          displine_memdump(fp, addr, bytes, byte_cnt);
453    
454                          addr += 16;                          addr += 16;
455                          byte_cnt = 0;                          byte_cnt = 0;
456                          ptr = bytes;                          ptr = bytes;
457                  }                  }
458          }          }
459    
460          if (byte_cnt > 0) {          if (byte_cnt > 0) {
461                  displine_memdump(fp, addr, bytes, byte_cnt);                  displine_memdump(fp, addr, bytes, byte_cnt);
462          }          }
463  }  }
464    
465  void init_memdump(void)  void init_memdump(void)
466  {  {
467          int i;          int i;
468    
469          if (memtag_use > 0)          if (memtag_use > 0)
470                  return;                  return;
471    
472          for (i = 0 ; i < MEMTAG_MAX ; i++) {          for (i = 0 ; i < MEMTAG_MAX ; i++) {
473                  memtags[i].name = NULL;                  memtags[i].name = NULL;
474                  memtags[i].desc = NULL;                  memtags[i].desc = NULL;
475                  memtags[i].data = NULL;                  memtags[i].data = NULL;
476                  memtags[i].len = 0;                  memtags[i].len = 0;
477          }          }
478          memtag_use++;          memtag_use++;
479  }  }
480    
481  void finish_memdump(void)  void finish_memdump(void)
482  {  {
483          int i;          int i;
484    
485          // initializeされてないときは何もせずに戻る。(2005.4.3 yutaka)          // initializeされてないときは何もせずに戻る。(2005.4.3 yutaka)
486          if (memtag_use <= 0)          if (memtag_use <= 0)
487                  return;                  return;
488          memtag_use--;          memtag_use--;
489    
490          for (i = 0 ; i < MEMTAG_MAX ; i++) {          for (i = 0 ; i < MEMTAG_MAX ; i++) {
491                  free(memtags[i].name);                  free(memtags[i].name);
492                  free(memtags[i].desc);                  free(memtags[i].desc);
493                  free(memtags[i].data);                  free(memtags[i].data);
494                  memtags[i].len = 0;                  memtags[i].len = 0;
495          }          }
496          memtag_count = 0;          memtag_count = 0;
497  }  }
498    
499  void save_memdump(char *filename)  void save_memdump(char *filename)
500  {  {
501          FILE *fp;          FILE *fp;
502          int i;          int i;
503          time_t t;          time_t t;
504          struct tm *tm;          struct tm *tm;
505    
506          fp = fopen(filename, "w");          fp = fopen(filename, "w");
507          if (fp == NULL)          if (fp == NULL)
508                  return;                  return;
509    
510          t = time(NULL);          t = time(NULL);
511          tm = localtime(&t);          tm = localtime(&t);
512    
513          fprintf(fp, "<<< Tera Term SSH2 log dump >>>\n");          fprintf(fp, "<<< Tera Term SSH2 log dump >>>\n");
514          fprintf(fp, "saved time: %04d/%02d/%02d %02d:%02d:%02d\n",          fprintf(fp, "saved time: %04d/%02d/%02d %02d:%02d:%02d\n",
515                  tm->tm_year + 1900,                  tm->tm_year + 1900,
516                  tm->tm_mon + 1,                  tm->tm_mon + 1,
517                  tm->tm_mday,                  tm->tm_mday,
518                  tm->tm_hour,                  tm->tm_hour,
519                  tm->tm_min,                  tm->tm_min,
520                  tm->tm_sec);                  tm->tm_sec);
521          fprintf(fp, "\n");          fprintf(fp, "\n");
522    
523          for (i = 0 ; i < memtag_count ; i++) {          for (i = 0 ; i < memtag_count ; i++) {
524                  fprintf(fp, "============================================\n");                  fprintf(fp, "============================================\n");
525                  fprintf(fp, "name: %s\n", memtags[i].name);                  fprintf(fp, "name: %s\n", memtags[i].name);
526                  fprintf(fp, "--------------------------------------------\n");                  fprintf(fp, "--------------------------------------------\n");
527                  fprintf(fp, "description: %s\n", memtags[i].desc);                  fprintf(fp, "description: %s\n", memtags[i].desc);
528                  fprintf(fp, "--------------------------------------------\n");                  fprintf(fp, "--------------------------------------------\n");
529                  fprintf(fp, "time: %s", ctime(&memtags[i].time));                  fprintf(fp, "time: %s", ctime(&memtags[i].time));
530                  fprintf(fp, "============================================\n");                  fprintf(fp, "============================================\n");
531                  dump_memdump(fp, memtags[i].data, memtags[i].len);                  dump_memdump(fp, memtags[i].data, memtags[i].len);
532                  fprintf(fp, "\n\n\n");                  fprintf(fp, "\n\n\n");
533          }          }
534    
535          fprintf(fp, "[EOF]\n");          fprintf(fp, "[EOF]\n");
536    
537          fclose(fp);          fclose(fp);
538  }  }
539    
540  void push_memdump(char *name, char *desc, char *data, int len)  void push_memdump(char *name, char *desc, char *data, int len)
541  {  {
542          memtag_t *ptr;          memtag_t *ptr;
543          char *dp;          char *dp;
544    
545          dp = malloc(len);          dp = malloc(len);
546          if (dp == NULL)          if (dp == NULL)
547                  return;                  return;
548          memcpy(dp, data, len);          memcpy(dp, data, len);
549    
550          if (memtag_count >= MEMTAG_MAX)          if (memtag_count >= MEMTAG_MAX)
551                  return;                  return;
552    
553          ptr = &memtags[memtag_count];          ptr = &memtags[memtag_count];
554          memtag_count++;          memtag_count++;
555          ptr->name = _strdup(name);          ptr->name = _strdup(name);
556          ptr->desc = _strdup(desc);          ptr->desc = _strdup(desc);
557          ptr->time = time(NULL);          ptr->time = time(NULL);
558          ptr->data = dp;          ptr->data = dp;
559          ptr->len = len;          ptr->len = len;
560  }  }
561    
562  void push_bignum_memdump(char *name, char *desc, BIGNUM *bignum)  void push_bignum_memdump(char *name, char *desc, BIGNUM *bignum)
563  {  {
564          int len;          int len;
565          char *buf;          char *buf;
566    
567          len = BN_num_bytes(bignum);          len = BN_num_bytes(bignum);
568          buf = malloc(len); // allocate          buf = malloc(len); // allocate
569          if (buf == NULL)          if (buf == NULL)
570                  return;                  return;
571          BN_bn2bin(bignum, buf);          BN_bn2bin(bignum, buf);
572          push_memdump(name, desc, buf, len); // at push_bignum_memdump()          push_memdump(name, desc, buf, len); // at push_bignum_memdump()
573          free(buf); // free          free(buf); // free
574  }  }
575    
576    
577  //  //
578  //  //
579  //  //
580    
581    
582  static int get_predecryption_amount(PTInstVar pvar)  static int get_predecryption_amount(PTInstVar pvar)
583  {  {
584          static int small_block_decryption_sizes[] = { 5, 5, 6, 6, 8 };          static int small_block_decryption_sizes[] = { 5, 5, 6, 6, 8 };
585    
586          if (SSHv1(pvar)) {          if (SSHv1(pvar)) {
587                  return 0;                  return 0;
588          } else {          } else {
589                  int block_size = CRYPT_get_decryption_block_size(pvar);                  int block_size = CRYPT_get_decryption_block_size(pvar);
590    
591                  if (block_size < 5) {                  if (block_size < 5) {
592                          return small_block_decryption_sizes[block_size];                          return small_block_decryption_sizes[block_size];
593                  } else {                  } else {
594                          return block_size;                          return block_size;
595                  }                  }
596          }          }
597  }  }
598    
599  /* Get up to 'limit' bytes into the payload buffer.  /* Get up to 'limit' bytes into the payload buffer.
600     'limit' is counted from the start of the payload data.     'limit' is counted from the start of the payload data.
601     Returns the amount of data in the payload buffer, or     Returns the amount of data in the payload buffer, or
602     -1 if there is an error.     -1 if there is an error.
603     We can return more than limit in some cases. */     We can return more than limit in some cases. */
604  static int buffer_packet_data(PTInstVar pvar, int limit)  static int buffer_packet_data(PTInstVar pvar, int limit)
605  {  {
606          if (pvar->ssh_state.payloadlen >= 0) {          if (pvar->ssh_state.payloadlen >= 0) {
607                  return pvar->ssh_state.payloadlen;                  return pvar->ssh_state.payloadlen;
608          } else {          } else {
609                  int cur_decompressed_bytes =                  int cur_decompressed_bytes =
610                          pvar->ssh_state.decompress_stream.next_out -                          pvar->ssh_state.decompress_stream.next_out -
611                          pvar->ssh_state.postdecompress_inbuf;                          pvar->ssh_state.postdecompress_inbuf;
612    
613                  while (limit > cur_decompressed_bytes) {                  while (limit > cur_decompressed_bytes) {
614                          int result;                          int result;
615    
616                          pvar->ssh_state.payload =                          pvar->ssh_state.payload =
617                                  pvar->ssh_state.postdecompress_inbuf + 1;                                  pvar->ssh_state.postdecompress_inbuf + 1;
618                          if (pvar->ssh_state.postdecompress_inbuflen == cur_decompressed_bytes) {                          if (pvar->ssh_state.postdecompress_inbuflen == cur_decompressed_bytes) {
619                                  buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,                                  buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
620                                                  &pvar->ssh_state.postdecompress_inbuflen,                                                  &pvar->ssh_state.postdecompress_inbuflen,
621                                                  min(limit, cur_decompressed_bytes * 2));                                                  min(limit, cur_decompressed_bytes * 2));
622                          }                          }
623    
624                          pvar->ssh_state.decompress_stream.next_out =                          pvar->ssh_state.decompress_stream.next_out =
625                                  pvar->ssh_state.postdecompress_inbuf +                                  pvar->ssh_state.postdecompress_inbuf +
626                                  cur_decompressed_bytes;                                  cur_decompressed_bytes;
627                          pvar->ssh_state.decompress_stream.avail_out =                          pvar->ssh_state.decompress_stream.avail_out =
628                                  min(limit, pvar->ssh_state.postdecompress_inbuflen)                                  min(limit, pvar->ssh_state.postdecompress_inbuflen)
629                                  - cur_decompressed_bytes;                                  - cur_decompressed_bytes;
630    
631                          result =                          result =
632                                  inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH);                                  inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH);
633                          cur_decompressed_bytes =                          cur_decompressed_bytes =
634                                  pvar->ssh_state.decompress_stream.next_out -                                  pvar->ssh_state.decompress_stream.next_out -
635                                  pvar->ssh_state.postdecompress_inbuf;                                  pvar->ssh_state.postdecompress_inbuf;
636    
637                          switch (result) {                          switch (result) {
638                          case Z_OK:                          case Z_OK:
639                                  break;                                  break;
640                          case Z_BUF_ERROR:                          case Z_BUF_ERROR:
641                                  pvar->ssh_state.payloadlen = cur_decompressed_bytes;                                  pvar->ssh_state.payloadlen = cur_decompressed_bytes;
642                                  return cur_decompressed_bytes;                                  return cur_decompressed_bytes;
643                          default:                          default:
644                                  UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,                                  UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar,
645                                                    "Invalid compressed data in received packet");                                                    "Invalid compressed data in received packet");
646                                  notify_fatal_error(pvar, pvar->ts->UIMsg);                                  notify_fatal_error(pvar, pvar->ts->UIMsg);
647                                  return -1;                                  return -1;
648                          }                          }
649                  }                  }
650    
651                  return cur_decompressed_bytes;                  return cur_decompressed_bytes;
652          }          }
653  }  }
654    
655  /* For use by the protocol processing code.  /* For use by the protocol processing code.
656     Gets N bytes of uncompressed payload. Returns FALSE if data not available     Gets N bytes of uncompressed payload. Returns FALSE if data not available
657     and a fatal error has been signaled.     and a fatal error has been signaled.
658     The data is available in the payload buffer. This buffer address     The data is available in the payload buffer. This buffer address
659     can change during a call to grab_payload, so take care!     can change during a call to grab_payload, so take care!
660     The payload pointer is set to point to the first byte of the actual data     The payload pointer is set to point to the first byte of the actual data
661     (after the packet type byte).     (after the packet type byte).
662  */  */
663  static BOOL grab_payload(PTInstVar pvar, int num_bytes)  static BOOL grab_payload(PTInstVar pvar, int num_bytes)
664  {  {
665          /* Accept maximum of 4MB of payload data */          /* Accept maximum of 4MB of payload data */
666          int in_buffer = buffer_packet_data(pvar, PACKET_MAX_SIZE);          int in_buffer = buffer_packet_data(pvar, PACKET_MAX_SIZE);
667    
668          if (in_buffer < 0) {          if (in_buffer < 0) {
669                  return FALSE;                  return FALSE;
670          } else {          } else {
671                  pvar->ssh_state.payload_grabbed += num_bytes;                  pvar->ssh_state.payload_grabbed += num_bytes;
672                  if (pvar->ssh_state.payload_grabbed > in_buffer) {                  if (pvar->ssh_state.payload_grabbed > in_buffer) {
673                          char buf[128];                          char buf[128];
674                          UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_ERROR", pvar,                          UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_ERROR", pvar,
675                                            "Received truncated packet (%ld > %d) @ grab_payload()");                                            "Received truncated packet (%ld > %d) @ grab_payload()");
676                          _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,                          _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
677                                      pvar->ssh_state.payload_grabbed, in_buffer);                                      pvar->ssh_state.payload_grabbed, in_buffer);
678                          notify_fatal_error(pvar, buf);                          notify_fatal_error(pvar, buf);
679                          return FALSE;                          return FALSE;
680                  } else {                  } else {
681                          return TRUE;                          return TRUE;
682                  }                  }
683          }          }
684  }  }
685    
686  static BOOL grab_payload_limited(PTInstVar pvar, int num_bytes)  static BOOL grab_payload_limited(PTInstVar pvar, int num_bytes)
687  {  {
688          int in_buffer;          int in_buffer;
689    
690          pvar->ssh_state.payload_grabbed += num_bytes;          pvar->ssh_state.payload_grabbed += num_bytes;
691          in_buffer = buffer_packet_data(pvar, pvar->ssh_state.payload_grabbed);          in_buffer = buffer_packet_data(pvar, pvar->ssh_state.payload_grabbed);
692    
693          if (in_buffer < 0) {          if (in_buffer < 0) {
694                  return FALSE;                  return FALSE;
695          } else {          } else {
696                  if (pvar->ssh_state.payload_grabbed > in_buffer) {                  if (pvar->ssh_state.payload_grabbed > in_buffer) {
697                          char buf[128];                          char buf[128];
698                          UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_LIM_ERROR", pvar,                          UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_LIM_ERROR", pvar,
699                                            "Received truncated packet (%ld > %d) @ grab_payload_limited()");                                            "Received truncated packet (%ld > %d) @ grab_payload_limited()");
700                          _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,                          _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
701                                      pvar->ssh_state.payload_grabbed, in_buffer);                                      pvar->ssh_state.payload_grabbed, in_buffer);
702                          notify_fatal_error(pvar, buf);                          notify_fatal_error(pvar, buf);
703                          return FALSE;                          return FALSE;
704                  } else {                  } else {
705                          return TRUE;                          return TRUE;
706                  }                  }
707          }          }
708  }  }
709    
710  #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))  #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))
711  #define get_uint32(buf) get_uint32_MSBfirst((buf))  #define get_uint32(buf) get_uint32_MSBfirst((buf))
712  #define set_uint32(buf, v) set_uint32_MSBfirst((buf), (v))  #define set_uint32(buf, v) set_uint32_MSBfirst((buf), (v))
713  #define get_mpint_len(pvar, offset) ((get_ushort16_MSBfirst((pvar)->ssh_state.payload + (offset)) + 7) >> 3)  #define get_mpint_len(pvar, offset) ((get_ushort16_MSBfirst((pvar)->ssh_state.payload + (offset)) + 7) >> 3)
714  #define get_ushort16(buf) get_ushort16_MSBfirst((buf))  #define get_ushort16(buf) get_ushort16_MSBfirst((buf))
715    
716  #define do_crc(buf, len) (~(uint32)crc32(0xFFFFFFFF, (buf), (len)))  #define do_crc(buf, len) (~(uint32)crc32(0xFFFFFFFF, (buf), (len)))
717    
718  /* Decrypt the payload, checksum it, eat the padding, get the packet type  /* Decrypt the payload, checksum it, eat the padding, get the packet type
719     and return it.     and return it.
720     'data' points to the start of the packet --- its length field.     'data' points to the start of the packet --- its length field.
721     'len' is the length of the     'len' is the length of the
722     payload + padding (+ length of CRC for SSHv1). 'padding' is the length     payload + padding (+ length of CRC for SSHv1). 'padding' is the length
723     of the padding alone. */     of the padding alone. */
724  static int prep_packet(PTInstVar pvar, char FAR * data, int len,  static int prep_packet(PTInstVar pvar, char FAR * data, int len,
725                                             int padding)                                             int padding)
726  {  {
727          pvar->ssh_state.payload = data + 4;          pvar->ssh_state.payload = data + 4;
728          pvar->ssh_state.payloadlen = len;          pvar->ssh_state.payloadlen = len;
729    
730          if (SSHv1(pvar)) {          if (SSHv1(pvar)) {
731                  if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {                  if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
732                          UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar,                          UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar,
733                                            "'CORE insertion attack' detected.  Aborting connection.");                                            "'CORE insertion attack' detected.  Aborting connection.");
734                          notify_fatal_error(pvar, pvar->ts->UIMsg);                          notify_fatal_error(pvar, pvar->ts->UIMsg);
735                  }                  }
736    
737                  CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);                  CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
738                  /* PKT guarantees that the data is always 4-byte aligned */                  /* PKT guarantees that the data is always 4-byte aligned */
739                  if (do_crc(pvar->ssh_state.payload, len - 4) !=                  if (do_crc(pvar->ssh_state.payload, len - 4) !=
740                          get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {                          get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
741                          UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,                          UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
742                                            "Detected corrupted data; connection terminating.");                                            "Detected corrupted data; connection terminating.");
743                          notify_fatal_error(pvar, pvar->ts->UIMsg);                          notify_fatal_error(pvar, pvar->ts->UIMsg);
744                          return SSH_MSG_NONE;                          return SSH_MSG_NONE;
745                  }                  }
746    
747                  pvar->ssh_state.payload += padding;                  pvar->ssh_state.payload += padding;
748                  pvar->ssh_state.payloadlen -= padding + 4;                  pvar->ssh_state.payloadlen -= padding + 4;
749          } else {          } else {
750                  int already_decrypted = get_predecryption_amount(pvar);                  int already_decrypted = get_predecryption_amount(pvar);
751    
752  #if 0  #if 0
753                  CRYPT_decrypt(pvar, data + already_decrypted,                  CRYPT_decrypt(pvar, data + already_decrypted,
754                                len - already_decrypted);                                len - already_decrypted);
755  #else  #else
756                  CRYPT_decrypt(pvar, data + already_decrypted,                  CRYPT_decrypt(pvar, data + already_decrypted,
757                                (4 + len) - already_decrypted);                                (4 + len) - already_decrypted);
758  #endif  #endif
759    
760                  if (!CRYPT_verify_receiver_MAC                  if (!CRYPT_verify_receiver_MAC
761                          (pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4,                          (pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4,
762                           data + len + 4)) {                           data + len + 4)) {
763                          UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,                          UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,
764                                            "Detected corrupted data; connection terminating.");                                            "Detected corrupted data; connection terminating.");
765                          notify_fatal_error(pvar, pvar->ts->UIMsg);                          notify_fatal_error(pvar, pvar->ts->UIMsg);
766                          return SSH_MSG_NONE;                          return SSH_MSG_NONE;
767                  }                  }
768    
769                  pvar->ssh_state.payload++;                  pvar->ssh_state.payload++;
770                  pvar->ssh_state.payloadlen -= padding + 1;                  pvar->ssh_state.payloadlen -= padding + 1;
771          }          }
772    
773          pvar->ssh_state.payload_grabbed = 0;          pvar->ssh_state.payload_grabbed = 0;
774    
775          if (SSHv1(pvar)) {          if (SSHv1(pvar)) {
776                  if (pvar->ssh_state.decompressing) {                  if (pvar->ssh_state.decompressing) {
777                          if (pvar->ssh_state.decompress_stream.avail_in != 0) {                          if (pvar->ssh_state.decompress_stream.avail_in != 0) {
778                                  UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,                                  UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
779                                                    "Internal error: a packet was not fully decompressed.\n"                                                    "Internal error: a packet was not fully decompressed.\n"
780                                                    "This is a bug, please report it.");                                                    "This is a bug, please report it.");
781                                  notify_nonfatal_error(pvar, pvar->ts->UIMsg);                                  notify_nonfatal_error(pvar, pvar->ts->UIMsg);
782                          }                          }
783    
784                          pvar->ssh_state.decompress_stream.next_in =                          pvar->ssh_state.decompress_stream.next_in =
785                                  pvar->ssh_state.payload;                                  pvar->ssh_state.payload;
786                          pvar->ssh_state.decompress_stream.avail_in =                          pvar->ssh_state.decompress_stream.avail_in =
787                                  pvar->ssh_state.payloadlen;                                  pvar->ssh_state.payloadlen;
788                          pvar->ssh_state.decompress_stream.next_out =                          pvar->ssh_state.decompress_stream.next_out =
789                                  pvar->ssh_state.postdecompress_inbuf;                                  pvar->ssh_state.postdecompress_inbuf;
790                          pvar->ssh_state.payloadlen = -1;                          pvar->ssh_state.payloadlen = -1;
791                  } else {                  } else {
792                          pvar->ssh_state.payload++;                          pvar->ssh_state.payload++;
793                  }                  }
794    
795                  if (!grab_payload_limited(pvar, 1)) {                  if (!grab_payload_limited(pvar, 1)) {
796                          return SSH_MSG_NONE;                          return SSH_MSG_NONE;
797                  }                  }
798    
799          } else {          } else {
800                  // support of SSH2 packet compression (2005.7.9 yutaka)                  // support of SSH2 packet compression (2005.7.9 yutaka)
801                  // support of "Compression delayed" (2006.6.23 maya)                  // support of "Compression delayed" (2006.6.23 maya)
802                  if ((pvar->stoc_compression == COMP_ZLIB ||                  if ((pvar->stoc_compression == COMP_ZLIB ||
803                       pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&                       pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&
804                      pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled                      pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
805                          int ret;                          int ret;
806    
807                          if (pvar->decomp_buffer == NULL) {                          if (pvar->decomp_buffer == NULL) {
808                                  pvar->decomp_buffer = buffer_init();                                  pvar->decomp_buffer = buffer_init();
809                                  if (pvar->decomp_buffer == NULL)                                  if (pvar->decomp_buffer == NULL)
810                                          return SSH_MSG_NONE;                                          return SSH_MSG_NONE;
811                          }                          }
812                          // 一度確保したバッファは使い回すので初期化を忘れずに。                          // 一度確保したバッファは使い回すので初期化を忘れずに。
813                          buffer_clear(pvar->decomp_buffer);                          buffer_clear(pvar->decomp_buffer);
814    
815                          // packet sizeとpaddingを取り除いたペイロード部分のみを展開する。                          // packet sizeとpaddingを取り除いたペイロード部分のみを展開する。
816                          ret = buffer_decompress(&pvar->ssh_state.decompress_stream,                          ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
817                                                  pvar->ssh_state.payload,                                                  pvar->ssh_state.payload,
818                                                  pvar->ssh_state.payloadlen,                                                  pvar->ssh_state.payloadlen,
819                                                  pvar->decomp_buffer);                                                  pvar->decomp_buffer);
820    
821                          // ポインタの更新。                          // ポインタの更新。
822                          pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);                          pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
823                          pvar->ssh_state.payload++;                          pvar->ssh_state.payload++;
824                          pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);                          pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
825    
826                  } else {                  } else {
827                          pvar->ssh_state.payload++;                          pvar->ssh_state.payload++;
828                  }                  }
829    
830                  if (!grab_payload_limited(pvar, 1)) {                  if (!grab_payload_limited(pvar, 1)) {
831                          return SSH_MSG_NONE;                          return SSH_MSG_NONE;
832                  }                  }
833    
834          }          }
835    
836          pvar->ssh_state.receiver_sequence_number++;          pvar->ssh_state.receiver_sequence_number++;
837    
838          return pvar->ssh_state.payload[-1];          return pvar->ssh_state.payload[-1];
839  }  }
840    
841  /* Create a packet to be sent. The SSH protocol packet type is in 'type';  /* Create a packet to be sent. The SSH protocol packet type is in 'type';
842     'len' contains the length of the packet payload, in bytes (this     'len' contains the length of the packet payload, in bytes (this
843     does not include the space for any of the packet headers or padding,     does not include the space for any of the packet headers or padding,
844     or for the packet type byte).     or for the packet type byte).
845     Returns a pointer to the payload data area, a region of length 'len',     Returns a pointer to the payload data area, a region of length 'len',
846     to be filled by the caller. */     to be filled by the caller. */
847  static unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len)  static unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len)
848  {  {
849          unsigned char FAR *buf;          unsigned char FAR *buf;
850    
851          pvar->ssh_state.outgoing_packet_len = len + 1;          pvar->ssh_state.outgoing_packet_len = len + 1;
852    
853          if (pvar->ssh_state.compressing) {          if (pvar->ssh_state.compressing) {
854                  buf_ensure_size(&pvar->ssh_state.precompress_outbuf,                  buf_ensure_size(&pvar->ssh_state.precompress_outbuf,
855                                  &pvar->ssh_state.precompress_outbuflen, 1 + len);                                  &pvar->ssh_state.precompress_outbuflen, 1 + len);
856                  buf = pvar->ssh_state.precompress_outbuf;                  buf = pvar->ssh_state.precompress_outbuf;
857          } else {          } else {
858                  /* For SSHv2,                  /* For SSHv2,
859                     Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)                     Encrypted_length is 4(packetlength) + 1(paddinglength) + 1(packettype)
860                     + len(payload) + 4(minpadding), rounded up to nearest block_size                     + len(payload) + 4(minpadding), rounded up to nearest block_size
861                     We only need a reasonable upper bound for the buffer size */                     We only need a reasonable upper bound for the buffer size */
862                  buf_ensure_size(&pvar->ssh_state.outbuf,                  buf_ensure_size(&pvar->ssh_state.outbuf,
863                                  &pvar->ssh_state.outbuflen,                                  &pvar->ssh_state.outbuflen,
864                                  len + 30 + CRYPT_get_sender_MAC_size(pvar) +                                  len + 30 + CRYPT_get_sender_MAC_size(pvar) +
865                                  CRYPT_get_encryption_block_size(pvar));                                  CRYPT_get_encryption_block_size(pvar));
866                  buf = pvar->ssh_state.outbuf + 12;                  buf = pvar->ssh_state.outbuf + 12;
867          }          }
868    
869          buf[0] = (unsigned char) type;          buf[0] = (unsigned char) type;
870          return buf + 1;          return buf + 1;
871  }  }
872    
873  #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0)  #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0)
874    
875  // 送信リトライ関数の追加  // 送信リトライ関数の追加
876  //  //
877  // WinSockの send() はバッファサイズ(len)よりも少ない値を正常時に返してくる  // WinSockの send() はバッファサイズ(len)よりも少ない値を正常時に返してくる
878  // ことがあるので、その場合はエラーとしない。  // ことがあるので、その場合はエラーとしない。
879  // これにより、TCPコネクション切断の誤検出を防ぐ。  // これにより、TCPコネクション切断の誤検出を防ぐ。
880  // (2006.12.9 yutaka)  // (2006.12.9 yutaka)
881  static int retry_send_packet(PTInstVar pvar, char FAR * data, int len)  static int retry_send_packet(PTInstVar pvar, char FAR * data, int len)
882  {  {
883          int n;          int n;
884          int err;          int err;
885    
886          while (len > 0) {          while (len > 0) {
887                  n = (pvar->Psend)(pvar->socket, data, len, 0);                  n = (pvar->Psend)(pvar->socket, data, len, 0);
888    
889                  if (n < 0) {                  if (n < 0) {
890                          err = WSAGetLastError();                          err = WSAGetLastError();
891                          if (err < WSABASEERR || err == WSAEWOULDBLOCK) {                          if (err < WSABASEERR || err == WSAEWOULDBLOCK) {
892                                  // send()の返値が0未満で、かつエラー番号が 10000 未満の場合は、                                  // send()の返値が0未満で、かつエラー番号が 10000 未満の場合は、
893                                  // 成功したものと見なす。                                  // 成功したものと見なす。
894                                  // PuTTY 0.58の実装を参考。                                  // PuTTY 0.58の実装を参考。
895                                  // (2007.2.4 yutak)                                  // (2007.2.4 yutak)
896                                  return 0; // success                                  return 0; // success
897                          }                          }
898                          return 1; // error                          return 1; // error
899                  }                  }
900    
901                  len -= n;                  len -= n;
902                  data += n;                  data += n;
903          }          }
904    
905          return 0; // success          return 0; // success
906  }  }
907    
908  static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)  static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len)
909  {  {
910          // パケット送信後にバッファを使いまわすため、ブロッキングで送信してしまう必要がある。          // パケット送信後にバッファを使いまわすため、ブロッキングで送信してしまう必要がある。
911          // ノンブロッキングで送信してWSAEWOULDBLOCKが返ってきた場合、そのバッファは送信完了する          // ノンブロッキングで送信してWSAEWOULDBLOCKが返ってきた場合、そのバッファは送信完了する
912          // まで保持しておかなくてはならない。(2007.10.30 yutaka)          // まで保持しておかなくてはならない。(2007.10.30 yutaka)
913          u_long do_block = 0;          u_long do_block = 0;
914          int code = 0;          int code = 0;
915          char *kind = NULL, buf[256];          char *kind = NULL, buf[256];
916    
917  #if 0  #if 0
918          if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,          if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
919                                       0, 0) == SOCKET_ERROR                                       0, 0) == SOCKET_ERROR
920           || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR           || ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR
921           || retry_send_packet(pvar, data, len)           || retry_send_packet(pvar, data, len)
922           || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,           || (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
923                                       pvar->notification_msg,                                       pvar->notification_msg,
924                                       pvar->notification_events) ==                                       pvar->notification_events) ==
925                  SOCKET_ERROR) {                  SOCKET_ERROR) {
926                  UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,                  UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
927                                    "A communications error occurred while sending an SSH packet.\n"                                    "A communications error occurred while sending an SSH packet.\n"
928                                    "The connection will close.");                                    "The connection will close.");
929                  notify_fatal_error(pvar, pvar->ts->UIMsg);                  notify_fatal_error(pvar, pvar->ts->UIMsg);
930                  return FALSE;                  return FALSE;
931          } else {          } else {
932                  return TRUE;                  return TRUE;
933          }          }
934  #else  #else
935          if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,          if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
936                                       0, 0) == SOCKET_ERROR) {                                       0, 0) == SOCKET_ERROR) {
937                          code = WSAGetLastError();                          code = WSAGetLastError();
938                          kind = "WSAAsyncSelect1";                          kind = "WSAAsyncSelect1";
939                          goto error;                          goto error;
940          }          }
941          if (ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR) {          if (ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR) {
942                          code = WSAGetLastError();                          code = WSAGetLastError();
943                          kind = "ioctlsocket";                          kind = "ioctlsocket";
944                          goto error;                          goto error;
945          }          }
946          if (retry_send_packet(pvar, data, len) != 0) {          if (retry_send_packet(pvar, data, len) != 0) {
947                          code = WSAGetLastError();                          code = WSAGetLastError();
948                          kind = "retry_send_packet";                          kind = "retry_send_packet";
949                          goto error;                          goto error;
950          }          }
951          if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,          if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow,
952                                       pvar->notification_msg,                                       pvar->notification_msg,
953                                       pvar->notification_events) ==                                       pvar->notification_events) ==
954                  SOCKET_ERROR) {                  SOCKET_ERROR) {
955                          code = WSAGetLastError();                          code = WSAGetLastError();
956                          kind = "WSAAsyncSelect2";                          kind = "WSAAsyncSelect2";
957                          goto error;                          goto error;
958          }          }
959          return TRUE;          return TRUE;
960    
961  error:  error:
962          UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,          UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar,
963                            "A communications error occurred while sending an SSH packet.\n"                            "A communications error occurred while sending an SSH packet.\n"
964                            "The connection will close. (%s:%d)");                            "The connection will close. (%s:%d)");
965          _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,          _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
966                      kind, code);                      kind, code);
967          notify_fatal_error(pvar, buf);          notify_fatal_error(pvar, buf);
968          return FALSE;          return FALSE;
969  #endif  #endif
970  }  }
971    
972  /* if skip_compress is true, then the data has already been compressed  /* if skip_compress is true, then the data has already been compressed
973     into outbuf + 12 */     into outbuf + 12 */
974  static void finish_send_packet_special(PTInstVar pvar, int skip_compress)  static void finish_send_packet_special(PTInstVar pvar, int skip_compress)
975  {  {
976          unsigned int len = pvar->ssh_state.outgoing_packet_len;          unsigned int len = pvar->ssh_state.outgoing_packet_len;
977          unsigned char FAR *data;          unsigned char FAR *data;
978          unsigned int data_length;          unsigned int data_length;
979          buffer_t *msg = NULL; // for SSH2 packet compression          buffer_t *msg = NULL; // for SSH2 packet compression
980    
981          if (pvar->ssh_state.compressing) {          if (pvar->ssh_state.compressing) {
982                  if (!skip_compress) {                  if (!skip_compress) {
983                          buf_ensure_size(&pvar->ssh_state.outbuf,                          buf_ensure_size(&pvar->ssh_state.outbuf,
984                                          &pvar->ssh_state.outbuflen,                                          &pvar->ssh_state.outbuflen,
985                                          (int)(len + (len >> 6) + 50 +                                          (int)(len + (len >> 6) + 50 +
986                                                CRYPT_get_sender_MAC_size(pvar)));                                                CRYPT_get_sender_MAC_size(pvar)));
987                          pvar->ssh_state.compress_stream.next_in =                          pvar->ssh_state.compress_stream.next_in =
988                                  pvar->ssh_state.precompress_outbuf;                                  pvar->ssh_state.precompress_outbuf;
989                          pvar->ssh_state.compress_stream.avail_in = len;                          pvar->ssh_state.compress_stream.avail_in = len;
990                          pvar->ssh_state.compress_stream.next_out =                          pvar->ssh_state.compress_stream.next_out =
991                                  pvar->ssh_state.outbuf + 12;                                  pvar->ssh_state.outbuf + 12;
992                          pvar->ssh_state.compress_stream.avail_out =                          pvar->ssh_state.compress_stream.avail_out =
993                                  pvar->ssh_state.outbuflen - 12;                                  pvar->ssh_state.outbuflen - 12;
994    
995                          if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {                          if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) {
996                                  UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,                                  UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
997                                                    "An error occurred while compressing packet data.\n"                                                    "An error occurred while compressing packet data.\n"
998                                                    "The connection will close.");                                                    "The connection will close.");
999                                  notify_fatal_error(pvar, pvar->ts->UIMsg);                                  notify_fatal_error(pvar, pvar->ts->UIMsg);
1000                                  return;                                  return;
1001                          }                          }
1002                  }                  }
1003    
1004                  len =                  len =
1005                          pvar->ssh_state.outbuflen - 12 -                          pvar->ssh_state.outbuflen - 12 -
1006                          pvar->ssh_state.compress_stream.avail_out;                          pvar->ssh_state.compress_stream.avail_out;
1007          }          }
1008    
1009          if (SSHv1(pvar)) {          if (SSHv1(pvar)) {
1010                  int padding = 8 - ((len + 4) % 8);                  int padding = 8 - ((len + 4) % 8);
1011    
1012                  data = pvar->ssh_state.outbuf + 8 - padding;                  data = pvar->ssh_state.outbuf + 8 - padding;
1013                  data_length = padding + len + 8;                  data_length = padding + len + 8;
1014    
1015                  set_uint32(data, len + 4);                  set_uint32(data, len + 4);
1016                  if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {                  if (CRYPT_get_receiver_cipher(pvar) != SSH_CIPHER_NONE) {
1017                          CRYPT_set_random_data(pvar, data + 4, padding);                          CRYPT_set_random_data(pvar, data + 4, padding);
1018                  } else {                  } else {
1019                          memset(data + 4, 0, padding);                          memset(data + 4, 0, padding);
1020                  }                  }
1021                  set_uint32(data + data_length - 4,                  set_uint32(data + data_length - 4,
1022                             do_crc(data + 4, data_length - 8));                             do_crc(data + 4, data_length - 8));
1023                  CRYPT_encrypt(pvar, data + 4, data_length - 4);                  CRYPT_encrypt(pvar, data + 4, data_length - 4);
1024          } else { //for SSH2(yutaka)          } else { //for SSH2(yutaka)
1025                  int block_size = CRYPT_get_encryption_block_size(pvar);                  int block_size = CRYPT_get_encryption_block_size(pvar);
1026                  unsigned int encryption_size;                  unsigned int encryption_size;
1027                  unsigned int padding;                  unsigned int padding;
1028                  BOOL ret;                  BOOL ret;
1029    
1030                  /*                  /*
1031                   データ構造                   データ構造
1032                   pvar->ssh_state.outbuf:                   pvar->ssh_state.outbuf:
1033                   offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ...         EOD                   offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ...         EOD
1034                           <--ignore---> ^^^^^^^^    <---- payload --->                           <--ignore---> ^^^^^^^^    <---- payload --->
1035                                                 packet length                                                 packet length
1036    
1037                                                                      ^^padding                                                                      ^^padding
1038    
1039                                                             <---------------------------->                                                             <---------------------------->
1040                                                                SSH2 sending data on TCP                                                                SSH2 sending data on TCP
1041                                    
1042                   NOTE:                   NOTE:
1043                     payload = type(1) + raw-data                     payload = type(1) + raw-data
1044                     len = ssh_state.outgoing_packet_len = payload size                     len = ssh_state.outgoing_packet_len = payload size
1045                   */                   */
1046                  // パケット圧縮が有効の場合、パケットを圧縮してから送信パケットを構築する。(2005.7.9 yutaka)                  // パケット圧縮が有効の場合、パケットを圧縮してから送信パケットを構築する。(2005.7.9 yutaka)
1047                  // support of "Compression delayed" (2006.6.23 maya)                  // support of "Compression delayed" (2006.6.23 maya)
1048                  if ((pvar->ctos_compression == COMP_ZLIB ||                  if ((pvar->ctos_compression == COMP_ZLIB ||
1049                       pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&                       pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) &&
1050                      pvar->ssh2_keys[MODE_OUT].comp.enabled) {                      pvar->ssh2_keys[MODE_OUT].comp.enabled) {
1051                          // このバッファは packet-length(4) + padding(1) + payload(any) を示す。                          // このバッファは packet-length(4) + padding(1) + payload(any) を示す。
1052                          msg = buffer_init();                          msg = buffer_init();
1053                          if (msg == NULL) {                          if (msg == NULL) {
1054                                  // TODO: error check                                  // TODO: error check
1055                                  return;                                  return;
1056                          }                          }
1057    
1058                          // 圧縮対象はヘッダを除くペイロードのみ。                          // 圧縮対象はヘッダを除くペイロードのみ。
1059                          buffer_append(msg, "\0\0\0\0\0", 5);  // 5 = packet-length(4) + padding(1)                          buffer_append(msg, "\0\0\0\0\0", 5);  // 5 = packet-length(4) + padding(1)
1060                          if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {                          if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
1061                                  UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,                                  UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar,
1062                                                    "An error occurred while compressing packet data.\n"                                                    "An error occurred while compressing packet data.\n"
1063                                                    "The connection will close.");                                                    "The connection will close.");
1064                                  notify_fatal_error(pvar, pvar->ts->UIMsg);                                  notify_fatal_error(pvar, pvar->ts->UIMsg);
1065                                  return;                                  return;
1066                          }                          }
1067                          data = buffer_ptr(msg);                          data = buffer_ptr(msg);
1068                          len = buffer_len(msg) - 5;  // 'len' is overwritten.                          len = buffer_len(msg) - 5;  // 'len' is overwritten.
1069    
1070                  } else {                  } else {
1071                          // 無圧縮                          // 無圧縮
1072                          data = pvar->ssh_state.outbuf + 7;                          data = pvar->ssh_state.outbuf + 7;
1073    
1074                  }                  }
1075    
1076                  // 送信パケット構築(input parameter: data, len)                  // 送信パケット構築(input parameter: data, len)
1077                  if (block_size < 8) {                  if (block_size < 8) {
1078                          block_size = 8;                          block_size = 8;
1079                  }                  }
1080  #if 0  #if 0
1081                  encryption_size = ((len + 8) / block_size + 1) * block_size;                  encryption_size = ((len + 8) / block_size + 1) * block_size;
1082                  data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);                  data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1083    
1084                  set_uint32(data, encryption_size - 4);                  set_uint32(data, encryption_size - 4);
1085                  padding = encryption_size - len - 5;                  padding = encryption_size - len - 5;
1086                  data[4] = (unsigned char) padding;                  data[4] = (unsigned char) padding;
1087  #else  #else
1088                  // でかいパケットを送ろうとすると、サーバ側で"Bad packet length"になってしまう問題への対処。                  // でかいパケットを送ろうとすると、サーバ側で"Bad packet length"になってしまう問題への対処。
1089                  // (2007.10.29 yutaka)                  // (2007.10.29 yutaka)
1090                  encryption_size = 4 + 1 + len;                  encryption_size = 4 + 1 + len;
1091                  padding = block_size - (encryption_size % block_size);                  padding = block_size - (encryption_size % block_size);
1092                  if (padding < 4)                  if (padding < 4)
1093                          padding += block_size;                          padding += block_size;
1094                  encryption_size += padding;                  encryption_size += padding;
1095                  set_uint32(data, encryption_size - 4);                  set_uint32(data, encryption_size - 4);
1096                  data[4] = (unsigned char) padding;                  data[4] = (unsigned char) padding;
1097                  data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);                  data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
1098  #endif  #endif
1099                  //if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;                  //if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;
1100                  CRYPT_set_random_data(pvar, data + 5 + len, padding);                  CRYPT_set_random_data(pvar, data + 5 + len, padding);
1101                  ret = CRYPT_build_sender_MAC(pvar,                  ret = CRYPT_build_sender_MAC(pvar,
1102                                               pvar->ssh_state.sender_sequence_number,                                               pvar->ssh_state.sender_sequence_number,
1103                                               data, encryption_size,                                               data, encryption_size,
1104                                               data + encryption_size);                                               data + encryption_size);
1105                  if (ret == FALSE) { // HMACがまだ設定されていない場合                  if (ret == FALSE) { // HMACがまだ設定されていない場合
1106                          data_length = encryption_size;                          data_length = encryption_size;
1107                  }                  }
1108    
1109                  // パケットを暗号化する。HMAC以降は暗号化対象外。                  // パケットを暗号化する。HMAC以降は暗号化対象外。
1110                  CRYPT_encrypt(pvar, data, encryption_size);                  CRYPT_encrypt(pvar, data, encryption_size);
1111          }          }
1112    
1113          send_packet_blocking(pvar, data, data_length);          send_packet_blocking(pvar, data, data_length);
1114    
1115          buffer_free(msg);          buffer_free(msg);
1116    
1117          pvar->ssh_state.sender_sequence_number++;          pvar->ssh_state.sender_sequence_number++;
1118    
1119          // 送信時刻を記録          // 送信時刻を記録
1120          pvar->ssh_heartbeat_tick = time(NULL);          pvar->ssh_heartbeat_tick = time(NULL);
1121  }  }
1122    
1123  static void destroy_packet_buf(PTInstVar pvar)  static void destroy_packet_buf(PTInstVar pvar)
1124  {  {
1125          memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);          memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen);
1126          if (pvar->ssh_state.compressing) {          if (pvar->ssh_state.compressing) {
1127                  memset(pvar->ssh_state.precompress_outbuf, 0,                  memset(pvar->ssh_state.precompress_outbuf, 0,
1128                         pvar->ssh_state.precompress_outbuflen);                         pvar->ssh_state.precompress_outbuflen);
1129          }          }
1130  }  }
1131    
1132  /* The handlers are added to the queue for each message. When one of the  /* The handlers are added to the queue for each message. When one of the
1133     handlers fires, if it returns FALSE, then all handlers in the set are     handlers fires, if it returns FALSE, then all handlers in the set are
1134     removed from their queues. */     removed from their queues. */
1135  static void enque_handlers(PTInstVar pvar, int num_msgs,  static void enque_handlers(PTInstVar pvar, int num_msgs,
1136                             const int FAR * messages,                             const int FAR * messages,
1137                             const SSHPacketHandler FAR * handlers)                             const SSHPacketHandler FAR * handlers)
1138  {  {
1139          SSHPacketHandlerItem FAR *first_item;          SSHPacketHandlerItem FAR *first_item;
1140          SSHPacketHandlerItem FAR *last_item = NULL;          SSHPacketHandlerItem FAR *last_item = NULL;
1141          int i;          int i;
1142    
1143          for (i = 0; i < num_msgs; i++) {          for (i = 0; i < num_msgs; i++) {
1144                  SSHPacketHandlerItem FAR *item =                  SSHPacketHandlerItem FAR *item =
1145                          (SSHPacketHandlerItem FAR *)                          (SSHPacketHandlerItem FAR *)
1146                          malloc(sizeof(SSHPacketHandlerItem));                          malloc(sizeof(SSHPacketHandlerItem));
1147                  SSHPacketHandlerItem FAR *cur_item =                  SSHPacketHandlerItem FAR *cur_item =
1148                          pvar->ssh_state.packet_handlers[messages[i]];                          pvar->ssh_state.packet_handlers[messages[i]];
1149    
1150                  item->handler = handlers[i];                  item->handler = handlers[i];
1151    
1152                  if (cur_item == NULL) {                  if (cur_item == NULL) {
1153                          pvar->ssh_state.packet_handlers[messages[i]] = item;                          pvar->ssh_state.packet_handlers[messages[i]] = item;
1154                          item->next_for_message = item;                          item->next_for_message = item;
1155                          item->last_for_message = item;                          item->last_for_message = item;
1156                          item->active_for_message = messages[i];                          item->active_for_message = messages[i];
1157                  } else {                  } else {
1158                          item->next_for_message = cur_item;                          item->next_for_message = cur_item;
1159                          item->last_for_message = cur_item->last_for_message;                          item->last_for_message = cur_item->last_for_message;
1160                          cur_item->last_for_message->next_for_message = item;                          cur_item->last_for_message->next_for_message = item;
1161                          cur_item->last_for_message = item;                          cur_item->last_for_message = item;
1162                          item->active_for_message = -1;                          item->active_for_message = -1;
1163                  }                  }
1164    
1165                  if (last_item != NULL) {                  if (last_item != NULL) {
1166                          last_item->next_in_set = item;                          last_item->next_in_set = item;
1167                  } else {                  } else {
1168                          first_item = item;                          first_item = item;
1169                  }                  }
1170                  last_item = item;                  last_item = item;
1171          }          }
1172    
1173          if (last_item != NULL) {          if (last_item != NULL) {
1174                  last_item->next_in_set = first_item;                  last_item->next_in_set = first_item;
1175          }          }
1176  }  }
1177    
1178  static SSHPacketHandler get_handler(PTInstVar pvar, int message)  static SSHPacketHandler get_handler(PTInstVar pvar, int message)
1179  {  {
1180          SSHPacketHandlerItem FAR *cur_item =          SSHPacketHandlerItem FAR *cur_item =
1181                  pvar->ssh_state.packet_handlers[message];                  pvar->ssh_state.packet_handlers[message];
1182    
1183          if (cur_item == NULL) {          if (cur_item == NULL) {
1184                  return NULL;                  return NULL;
1185          } else {          } else {
1186                  return cur_item->handler;                  return cur_item->handler;
1187          }          }
1188  }  }
1189    
1190  /* Called only by SSH_handle_packet */  /* Called only by SSH_handle_packet */
1191  static void deque_handlers(PTInstVar pvar, int message)  static void deque_handlers(PTInstVar pvar, int message)
1192  {  {
1193          SSHPacketHandlerItem FAR *cur_item =          SSHPacketHandlerItem FAR *cur_item =
1194                  pvar->ssh_state.packet_handlers[message];                  pvar->ssh_state.packet_handlers[message];
1195          SSHPacketHandlerItem FAR *first_item_in_set = cur_item;          SSHPacketHandlerItem FAR *first_item_in_set = cur_item;
1196    
1197          if (cur_item == NULL)          if (cur_item == NULL)
1198                  return;                  return;
1199    
1200          do {          do {
1201                  SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;                  SSHPacketHandlerItem FAR *next_in_set = cur_item->next_in_set;
1202    
1203                  if (cur_item->active_for_message >= 0) {                  if (cur_item->active_for_message >= 0) {
1204                          SSHPacketHandlerItem FAR *replacement =                          SSHPacketHandlerItem FAR *replacement =
1205                                  cur_item->next_for_message;                                  cur_item->next_for_message;
1206    
1207                          if (replacement == cur_item) {                          if (replacement == cur_item) {
1208                                  replacement = NULL;                                  replacement = NULL;
1209                          } else {                          } else {
1210                                  replacement->active_for_message =                                  replacement->active_for_message =
1211                                          cur_item->active_for_message;                                          cur_item->active_for_message;
1212                          }                          }
1213                          pvar->ssh_state.packet_handlers[cur_item->active_for_message] =                          pvar->ssh_state.packet_handlers[cur_item->active_for_message] =
1214                                  replacement;                                  replacement;
1215                  }                  }
1216                  cur_item->next_for_message->last_for_message =                  cur_item->next_for_message->last_for_message =
1217                          cur_item->last_for_message;                          cur_item->last_for_message;
1218                  cur_item->last_for_message->next_for_message =                  cur_item->last_for_message->next_for_message =
1219                          cur_item->next_for_message;                          cur_item->next_for_message;
1220    
1221                  free(cur_item);                  free(cur_item);
1222                  cur_item = next_in_set;                  cur_item = next_in_set;
1223          } while (cur_item != first_item_in_set);          } while (cur_item != first_item_in_set);
1224  }  }
1225    
1226  static void enque_handler(PTInstVar pvar, int message,  static void enque_handler(PTInstVar pvar, int message,
1227                            SSHPacketHandler handler)                            SSHPacketHandler handler)
1228  {  {
1229          enque_handlers(pvar, 1, &message, &handler);          enque_handlers(pvar, 1, &message, &handler);
1230  }  }
1231    
1232  static void chop_newlines(char FAR * buf)  static void chop_newlines(char FAR * buf)
1233  {  {
1234          int len = strlen(buf);          int len = strlen(buf);
1235    
1236          while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {          while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1237                  buf[len - 1] = 0;                  buf[len - 1] = 0;
1238                  len--;                  len--;
1239          }          }
1240  }  }
1241    
1242  /********************/  /********************/
1243  /* Message handlers */  /* Message handlers */
1244  /********************/  /********************/
1245    
1246  static BOOL handle_forwarding_success(PTInstVar pvar)  static BOOL handle_forwarding_success(PTInstVar pvar)
1247  {  {
1248          return FALSE;          return FALSE;
1249  }  }
1250    
1251  static BOOL handle_forwarding_failure(PTInstVar pvar)  static BOOL handle_forwarding_failure(PTInstVar pvar)
1252  {  {
1253          return FALSE;          return FALSE;
1254  }  }
1255    
1256  static void enque_forwarding_request_handlers(PTInstVar pvar)  static void enque_forwarding_request_handlers(PTInstVar pvar)
1257  {  {
1258          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1259          static const SSHPacketHandler handlers[]          static const SSHPacketHandler handlers[]
1260          = { handle_forwarding_success, handle_forwarding_failure };          = { handle_forwarding_success, handle_forwarding_failure };
1261    
1262          enque_handlers(pvar, 2, msgs, handlers);          enque_handlers(pvar, 2, msgs, handlers);
1263  }  }
1264    
1265  static BOOL handle_auth_failure(PTInstVar pvar)  static BOOL handle_auth_failure(PTInstVar pvar)
1266  {  {
1267          notify_verbose_message(pvar, "Authentication failed",          notify_verbose_message(pvar, "Authentication failed",
1268                                 LOG_LEVEL_VERBOSE);                                 LOG_LEVEL_VERBOSE);
1269    
1270          // retry countの追加 (2005.7.15 yutaka)          // retry countの追加 (2005.7.15 yutaka)
1271          pvar->userauth_retry_count++;          pvar->userauth_retry_count++;
1272    
1273          AUTH_set_generic_mode(pvar);          AUTH_set_generic_mode(pvar);
1274          AUTH_advance_to_next_cred(pvar);          AUTH_advance_to_next_cred(pvar);
1275          pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;          pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1276          try_send_credentials(pvar);          try_send_credentials(pvar);
1277          return FALSE;          return FALSE;
1278  }  }
1279    
1280  static BOOL handle_rsa_auth_refused(PTInstVar pvar)  static BOOL handle_rsa_auth_refused(PTInstVar pvar)
1281  {  {
1282          if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {          if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
1283                  if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {                  if (pvar->pageant_keycount <= pvar->pageant_keycurrent) {
1284                          // 全ての鍵を試し終わった                          // 全ての鍵を試し終わった
1285                          safefree(pvar->pageant_key);                          safefree(pvar->pageant_key);
1286                  }                  }
1287                  else {                  else {
1288                          // まだ鍵がある                          // まだ鍵がある
1289                          pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;                          pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1290                          try_send_credentials(pvar);                          try_send_credentials(pvar);
1291                          return TRUE;                          return TRUE;
1292                  }                  }
1293          }          }
1294          AUTH_destroy_cur_cred(pvar);          AUTH_destroy_cur_cred(pvar);
1295          return handle_auth_failure(pvar);          return handle_auth_failure(pvar);
1296  }  }
1297    
1298  static BOOL handle_TIS_challenge(PTInstVar pvar)  static BOOL handle_TIS_challenge(PTInstVar pvar)
1299  {  {
1300          if (grab_payload(pvar, 4)) {          if (grab_payload(pvar, 4)) {
1301                  int len = get_payload_uint32(pvar, 0);                  int len = get_payload_uint32(pvar, 0);
1302    
1303                  if (grab_payload(pvar, len)) {                  if (grab_payload(pvar, len)) {
1304                          notify_verbose_message(pvar, "Received TIS challenge",                          notify_verbose_message(pvar, "Received TIS challenge",
1305                                                 LOG_LEVEL_VERBOSE);                                                 LOG_LEVEL_VERBOSE);
1306    
1307                          AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);                          AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len);
1308                          AUTH_advance_to_next_cred(pvar);                          AUTH_advance_to_next_cred(pvar);
1309                          pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;                          pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1310                          try_send_credentials(pvar);                          try_send_credentials(pvar);
1311                  }                  }
1312          }          }
1313          return FALSE;          return FALSE;
1314  }  }
1315    
1316  static BOOL handle_auth_required(PTInstVar pvar)  static BOOL handle_auth_required(PTInstVar pvar)
1317  {  {
1318          notify_verbose_message(pvar, "Server requires authentication",          notify_verbose_message(pvar, "Server requires authentication",
1319                                 LOG_LEVEL_VERBOSE);                                 LOG_LEVEL_VERBOSE);
1320    
1321          pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;          pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS;
1322          try_send_credentials(pvar);          try_send_credentials(pvar);
1323          /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */          /* the first AUTH_advance_to_next_cred is issued early by ttxssh.c */
1324    
1325          return FALSE;          return FALSE;
1326  }  }
1327    
1328  static BOOL handle_ignore(PTInstVar pvar)  static BOOL handle_ignore(PTInstVar pvar)
1329  {  {
1330          if (SSHv1(pvar)) {          if (SSHv1(pvar)) {
1331                  notify_verbose_message(pvar, "SSH_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);                  notify_verbose_message(pvar, "SSH_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1332    
1333                  if (grab_payload(pvar, 4)                  if (grab_payload(pvar, 4)
1334                   && grab_payload(pvar, get_payload_uint32(pvar, 0))) {                   && grab_payload(pvar, get_payload_uint32(pvar, 0))) {
1335                          /* ignore it! but it must be decompressed */                          /* ignore it! but it must be decompressed */
1336                  }                  }
1337          }          }
1338          else {          else {
1339                  notify_verbose_message(pvar, "SSH2_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);                  notify_verbose_message(pvar, "SSH2_MSG_IGNORE was received.", LOG_LEVEL_VERBOSE);
1340    
1341                  // メッセージが SSH2_MSG_IGNORE の時は何もしない                  // メッセージが SSH2_MSG_IGNORE の時は何もしない
1342                  // Cisco ルータ対策 (2006.11.28 maya)                  // Cisco ルータ対策 (2006.11.28 maya)
1343          }          }
1344          return TRUE;          return TRUE;
1345  }  }
1346    
1347  static BOOL handle_debug(PTInstVar pvar)  static BOOL handle_debug(PTInstVar pvar)
1348  {  {
1349          BOOL always_display;          BOOL always_display;
1350          char FAR *description;          char FAR *description;
1351          int description_len;          int description_len;
1352          char buf[2048];          char buf[2048];
1353    
1354          if (SSHv1(pvar)) {          if (SSHv1(pvar)) {
1355                  notify_verbose_message(pvar, "SSH_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);                  notify_verbose_message(pvar, "SSH_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1356    
1357                  if (grab_payload(pvar, 4)                  if (grab_payload(pvar, 4)
1358                   && grab_payload(pvar, description_len =                   && grab_payload(pvar, description_len =
1359                                   get_payload_uint32(pvar, 0))) {                                   get_payload_uint32(pvar, 0))) {
1360                          always_display = FALSE;                          always_display = FALSE;
1361                          description = pvar->ssh_state.payload + 4;                          description = pvar->ssh_state.payload + 4;
1362                          description[description_len] = 0;                          description[description_len] = 0;
1363                  } else {                  } else {
1364                          return TRUE;                          return TRUE;
1365                  }                  }
1366          } else {          } else {
1367                  notify_verbose_message(pvar, "SSH2_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);                  notify_verbose_message(pvar, "SSH2_MSG_DEBUG was received.", LOG_LEVEL_VERBOSE);
1368    
1369                  if (grab_payload(pvar, 5)                  if (grab_payload(pvar, 5)
1370                   && grab_payload(pvar,                   && grab_payload(pvar,
1371                                   (description_len = get_payload_uint32(pvar, 1)) + 4)                                   (description_len = get_payload_uint32(pvar, 1)) + 4)
1372                   && grab_payload(pvar,                   && grab_payload(pvar,
1373                                   get_payload_uint32(pvar, 5 + description_len))) {                                   get_payload_uint32(pvar, 5 + description_len))) {
1374                          always_display = pvar->ssh_state.payload[0] != 0;                          always_display = pvar->ssh_state.payload[0] != 0;
1375                          description = pvar->ssh_state.payload + 5;                          description = pvar->ssh_state.payload + 5;
1376                          description[description_len] = 0;                          description[description_len] = 0;
1377                  } else {                  } else {
1378                          return TRUE;                          return TRUE;
1379                  }                  }
1380          }          }
1381    
1382          chop_newlines(description);          chop_newlines(description);
1383          _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",          _snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s",
1384                      description);                      description);
1385          if (always_display) {          if (always_display) {
1386                  notify_nonfatal_error(pvar, buf);                  notify_nonfatal_error(pvar, buf);
1387          } else {          } else {
1388                  notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);                  notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1389          }          }
1390          return TRUE;          return TRUE;
1391  }  }
1392    
1393  static BOOL handle_disconnect(PTInstVar pvar)  static BOOL handle_disconnect(PTInstVar pvar)
1394  {  {
1395          int reason_code;          int reason_code;
1396          char FAR *description;          char FAR *description;
1397          int description_len;          int description_len;
1398          char buf[2048];          char buf[2048];
1399          char FAR *explanation = "";          char FAR *explanation = "";
1400          char uimsg[MAX_UIMSG];          char uimsg[MAX_UIMSG];
1401    
1402          if (SSHv1(pvar)) {          if (SSHv1(pvar)) {
1403                  notify_verbose_message(pvar, "SSH_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);                  notify_verbose_message(pvar, "SSH_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1404    
1405                  if (grab_payload(pvar, 4)                  if (grab_payload(pvar, 4)
1406                   && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {                   && grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) {
1407                          reason_code = -1;                          reason_code = -1;
1408                          description = pvar->ssh_state.payload + 4;                          description = pvar->ssh_state.payload + 4;
1409                          description[description_len] = 0;                          description[description_len] = 0;
1410                  } else {                  } else {
1411                          return TRUE;                          return TRUE;
1412                  }                  }
1413          } else {          } else {
1414                  notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);                  notify_verbose_message(pvar, "SSH2_MSG_DISCONNECT was received.", LOG_LEVEL_VERBOSE);
1415    
1416                  if (grab_payload(pvar, 8)                  if (grab_payload(pvar, 8)
1417                   && grab_payload(pvar,                   && grab_payload(pvar,
1418                                   (description_len = get_payload_uint32(pvar, 4)) + 4)                                   (description_len = get_payload_uint32(pvar, 4)) + 4)
1419                   && grab_payload(pvar,                   && grab_payload(pvar,
1420                                   get_payload_uint32(pvar, 8 + description_len))) {                                   get_payload_uint32(pvar, 8 + description_len))) {
1421                          reason_code = get_payload_uint32(pvar, 0);                          reason_code = get_payload_uint32(pvar, 0);
1422                          description = pvar->ssh_state.payload + 8;                          description = pvar->ssh_state.payload + 8;
1423                          description[description_len] = 0;                          description[description_len] = 0;
1424                  } else {                  } else {
1425                          return TRUE;                          return TRUE;
1426                  }                  }
1427          }          }
1428    
1429          chop_newlines(description);          chop_newlines(description);
1430          if (description[0] == 0) {          if (description[0] == 0) {
1431                  description = NULL;                  description = NULL;
1432          }          }
1433    
1434          if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {          if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) {
1435                  UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,                  UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar,
1436                                    "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"                                    "\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n"
1437                                    "This often happens when someone is already forwarding that port from the server.");                                    "This often happens when someone is already forwarding that port from the server.");
1438                  strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);                  strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE);
1439                  explanation = uimsg;                  explanation = uimsg;
1440          }          }
1441    
1442          if (description != NULL) {          if (description != NULL) {
1443                  UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,                  UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar,
1444                                    "Server disconnected with message '%s'%s");                                    "Server disconnected with message '%s'%s");
1445                  _snprintf_s(buf, sizeof(buf), _TRUNCATE,                  _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1446                              pvar->ts->UIMsg, description,                              pvar->ts->UIMsg, description,
1447                              explanation);                              explanation);
1448          } else {          } else {
1449                  UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,                  UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar,
1450                                    "Server disconnected (no reason given).%s");                                    "Server disconnected (no reason given).%s");
1451                  _snprintf_s(buf, sizeof(buf), _TRUNCATE,                  _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1452                              pvar->ts->UIMsg, explanation);                              pvar->ts->UIMsg, explanation);
1453          }          }
1454          notify_fatal_error(pvar, buf);          notify_fatal_error(pvar, buf);
1455    
1456          return TRUE;          return TRUE;
1457  }  }
1458    
1459  static BOOL handle_unimplemented(PTInstVar pvar)  static BOOL handle_unimplemented(PTInstVar pvar)
1460  {  {
1461          /* Should never receive this since we only send base 2.0 protocol messages */          /* Should never receive this since we only send base 2.0 protocol messages */
1462          grab_payload(pvar, 4);          grab_payload(pvar, 4);
1463          return TRUE;          return TRUE;
1464  }  }
1465    
1466  static BOOL handle_crypt_success(PTInstVar pvar)  static BOOL handle_crypt_success(PTInstVar pvar)
1467  {  {
1468          notify_verbose_message(pvar, "Secure mode successfully achieved",          notify_verbose_message(pvar, "Secure mode successfully achieved",
1469                                 LOG_LEVEL_VERBOSE);                                 LOG_LEVEL_VERBOSE);
1470          return FALSE;          return FALSE;
1471  }  }
1472    
1473  static BOOL handle_noauth_success(PTInstVar pvar)  static BOOL handle_noauth_success(PTInstVar pvar)
1474  {  {
1475          notify_verbose_message(pvar, "Server does not require authentication",          notify_verbose_message(pvar, "Server does not require authentication",
1476                                 LOG_LEVEL_VERBOSE);                                 LOG_LEVEL_VERBOSE);
1477          prep_compression(pvar);          prep_compression(pvar);
1478          return FALSE;          return FALSE;
1479  }  }
1480    
1481  static BOOL handle_auth_success(PTInstVar pvar)  static BOOL handle_auth_success(PTInstVar pvar)
1482  {  {
1483          notify_verbose_message(pvar, "Authentication accepted",          notify_verbose_message(pvar, "Authentication accepted",
1484                                 LOG_LEVEL_VERBOSE);                                 LOG_LEVEL_VERBOSE);
1485          prep_compression(pvar);          prep_compression(pvar);
1486    
1487          // ハートビート・スレッドの開始 (2004.12.11 yutaka)          // ハートビート・スレッドの開始 (2004.12.11 yutaka)
1488          start_ssh_heartbeat_thread(pvar);          start_ssh_heartbeat_thread(pvar);
1489    
1490          return FALSE;          return FALSE;
1491  }  }
1492    
1493  static BOOL handle_server_public_key(PTInstVar pvar)  static BOOL handle_server_public_key(PTInstVar pvar)
1494  {  {
1495          int server_key_public_exponent_len;          int server_key_public_exponent_len;
1496          int server_key_public_modulus_pos;          int server_key_public_modulus_pos;
1497          int server_key_public_modulus_len;          int server_key_public_modulus_len;
1498          int host_key_bits_pos;          int host_key_bits_pos;
1499          int host_key_public_exponent_len;          int host_key_public_exponent_len;
1500          int host_key_public_modulus_pos;          int host_key_public_modulus_pos;
1501          int host_key_public_modulus_len;          int host_key_public_modulus_len;
1502          int protocol_flags_pos;          int protocol_flags_pos;
1503          int supported_ciphers;          int supported_ciphers;
1504          char FAR *inmsg;          char FAR *inmsg;
1505          Key hostkey;          Key hostkey;
1506          int supported_types;          int supported_types;
1507    
1508          notify_verbose_message(pvar, "SSH_SMSG_PUBLIC_KEY was received.", LOG_LEVEL_VERBOSE);          notify_verbose_message(pvar, "SSH_SMSG_PUBLIC_KEY was received.", LOG_LEVEL_VERBOSE);
1509    
1510          if (!grab_payload(pvar, 14))          if (!grab_payload(pvar, 14))
1511                  return FALSE;                  return FALSE;
1512          server_key_public_exponent_len = get_mpint_len(pvar, 12);          server_key_public_exponent_len = get_mpint_len(pvar, 12);
1513    
1514          if (!grab_payload(pvar, server_key_public_exponent_len + 2))          if (!grab_payload(pvar, server_key_public_exponent_len + 2))
1515                  return FALSE;                  return FALSE;
1516          server_key_public_modulus_pos = 14 + server_key_public_exponent_len;          server_key_public_modulus_pos = 14 + server_key_public_exponent_len;
1517          server_key_public_modulus_len =          server_key_public_modulus_len =
1518                  get_mpint_len(pvar, server_key_public_modulus_pos);                  get_mpint_len(pvar, server_key_public_modulus_pos);
1519    
1520          if (!grab_payload(pvar, server_key_public_modulus_len + 6))          if (!grab_payload(pvar, server_key_public_modulus_len + 6))
1521                  return FALSE;                  return FALSE;
1522          host_key_bits_pos =          host_key_bits_pos =
1523                  server_key_public_modulus_pos + 2 + server_key_public_modulus_len;                  server_key_public_modulus_pos + 2 + server_key_public_modulus_len;
1524          host_key_public_exponent_len =          host_key_public_exponent_len =
1525                  get_mpint_len(pvar, host_key_bits_pos + 4);                  get_mpint_len(pvar, host_key_bits_pos + 4);
1526    
1527          if (!grab_payload(pvar, host_key_public_exponent_len + 2))          if (!grab_payload(pvar, host_key_public_exponent_len + 2))
1528                  return FALSE;                  return FALSE;
1529          host_key_public_modulus_pos =          host_key_public_modulus_pos =
1530                  host_key_bits_pos + 6 + host_key_public_exponent_len;                  host_key_bits_pos + 6 + host_key_public_exponent_len;
1531          host_key_public_modulus_len =          host_key_public_modulus_len =
1532                  get_mpint_len(pvar, host_key_public_modulus_pos);                  get_mpint_len(pvar, host_key_public_modulus_pos);
1533    
1534          if (!grab_payload(pvar, host_key_public_modulus_len + 12))          if (!grab_payload(pvar, host_key_public_modulus_len + 12))
1535                  return FALSE;                  return FALSE;
1536          protocol_flags_pos =          protocol_flags_pos =
1537                  host_key_public_modulus_pos + 2 + host_key_public_modulus_len;                  host_key_public_modulus_pos + 2 + host_key_public_modulus_len;
1538    
1539          inmsg = pvar->ssh_state.payload;          inmsg = pvar->ssh_state.payload;
1540    
1541          CRYPT_set_server_cookie(pvar, inmsg);          CRYPT_set_server_cookie(pvar, inmsg);
1542          if (!CRYPT_set_server_RSA_key(pvar,          if (!CRYPT_set_server_RSA_key(pvar,
1543                                        get_uint32(inmsg + 8),                                        get_uint32(inmsg + 8),
1544                                        pvar->ssh_state.payload + 12,                                        pvar->ssh_state.payload + 12,
1545                                        inmsg + server_key_public_modulus_pos))                                        inmsg + server_key_public_modulus_pos))
1546                  return FALSE;                  return FALSE;
1547          if (!CRYPT_set_host_RSA_key(pvar,          if (!CRYPT_set_host_RSA_key(pvar,
1548                                      get_uint32(inmsg + host_key_bits_pos),                                      get_uint32(inmsg + host_key_bits_pos),
1549                                      inmsg + host_key_bits_pos + 4,                                      inmsg + host_key_bits_pos + 4,
1550                                      inmsg + host_key_public_modulus_pos))                                      inmsg + host_key_public_modulus_pos))
1551                  return FALSE;                  return FALSE;
1552          pvar->ssh_state.server_protocol_flags =          pvar->ssh_state.server_protocol_flags =
1553                  get_uint32(inmsg + protocol_flags_pos);                  get_uint32(inmsg + protocol_flags_pos);
1554    
1555          supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);          supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4);
1556          if (!CRYPT_set_supported_ciphers(pvar,          if (!CRYPT_set_supported_ciphers(pvar,
1557                                           supported_ciphers,                                           supported_ciphers,
1558                                           supported_ciphers))                                           supported_ciphers))
1559                  return FALSE;                  return FALSE;
1560    
1561          // SSH1 サーバは、サポートされている認証方式を送ってくる          // SSH1 サーバは、サポートされている認証方式を送ってくる
1562          // RSA が有効なら PAGEANT を有効にする          // RSA が有効なら PAGEANT を有効にする
1563          supported_types = get_uint32(inmsg + protocol_flags_pos + 8);          supported_types = get_uint32(inmsg + protocol_flags_pos + 8);
1564          if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {          if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) {
1565                  supported_types |= (1 << SSH_AUTH_PAGEANT);                  supported_types |= (1 << SSH_AUTH_PAGEANT);
1566          }          }
1567          if (!AUTH_set_supported_auth_types(pvar,          if (!AUTH_set_supported_auth_types(pvar,
1568                                             supported_types))                                             supported_types))
1569                  return FALSE;                  return FALSE;
1570    
1571          /* this must be the LAST THING in this function, since it can cause          /* this must be the LAST THING in this function, since it can cause
1572             host_is_OK to be called. */             host_is_OK to be called. */
1573          hostkey.type = KEY_RSA1;          hostkey.type = KEY_RSA1;
1574          hostkey.bits = get_uint32(inmsg + host_key_bits_pos);          hostkey.bits = get_uint32(inmsg + host_key_bits_pos);
1575          hostkey.exp = inmsg + host_key_bits_pos + 4;          hostkey.exp = inmsg + host_key_bits_pos + 4;
1576          hostkey.mod = inmsg + host_key_public_modulus_pos;          hostkey.mod = inmsg + host_key_public_modulus_pos;
1577          HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);          HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, &hostkey);
1578    
1579          return FALSE;          return FALSE;
1580  }  }
1581    
1582  /*  /*
1583  The ID must have already been found to start with "SSH-". It must  The ID must have already been found to start with "SSH-". It must
1584  be null-terminated.  be null-terminated.
1585  */  */
1586  static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)  static BOOL parse_protocol_ID(PTInstVar pvar, char FAR * ID)
1587  {  {
1588          char FAR *str;          char FAR *str;
1589    
1590          for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {          for (str = ID + 4; *str >= '0' && *str <= '9'; str++) {
1591          }          }
1592    
1593          if (*str != '.') {          if (*str != '.') {
1594                  return FALSE;                  return FALSE;
1595          }          }
1596    
1597          pvar->protocol_major = atoi(ID + 4);          pvar->protocol_major = atoi(ID + 4);
1598          pvar->protocol_minor = atoi(str + 1);          pvar->protocol_minor = atoi(str + 1);
1599    
1600          // for SSH2(yutaka)          // for SSH2(yutaka)
1601          // 1.99ならSSH2での接続を行う          // 1.99ならSSH2での接続を行う
1602          if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {          if (pvar->protocol_major == 1 && pvar->protocol_minor == 99) {
1603                  // ユーザが SSH2 を選択しているのならば                  // ユーザが SSH2 を選択しているのならば
1604                  if (pvar->settings.ssh_protocol_version == 2) {                  if (pvar->settings.ssh_protocol_version == 2) {
1605                          pvar->protocol_major = 2;                          pvar->protocol_major = 2;
1606                          pvar->protocol_minor = 0;                          pvar->protocol_minor = 0;
1607                  }                  }
1608    
1609          }          }
1610    
1611          // SSH バージョンを teraterm 側にセットする          // SSH バージョンを teraterm 側にセットする
1612          // SCP コマンドのため (2008.2.3 maya)          // SCP コマンドのため (2008.2.3 maya)
1613          pvar->cv->isSSH = pvar->protocol_major;          pvar->cv->isSSH = pvar->protocol_major;
1614    
1615          for (str = str + 1; *str >= '0' && *str <= '9'; str++) {          for (str = str + 1; *str >= '0' && *str <= '9'; str++) {
1616          }          }
1617    
1618          return *str == '-';          return *str == '-';
1619  }  }
1620    
1621  /*  /*
1622  On entry, the pvar->protocol_xxx fields hold the server's advertised  On entry, the pvar->protocol_xxx fields hold the server's advertised
1623  protocol number. We replace the fields with the protocol number we will  protocol number. We replace the fields with the protocol number we will
1624  actually use, or return FALSE if there is no usable protocol version.  actually use, or return FALSE if there is no usable protocol version.
1625  */  */
1626  static BOOL negotiate_protocol(PTInstVar pvar)  static BOOL negotiate_protocol(PTInstVar pvar)
1627  {  {
1628          switch (pvar->protocol_major) {          switch (pvar->protocol_major) {
1629          case 1:          case 1:
1630                  if (pvar->protocol_minor > 5) {                  if (pvar->protocol_minor > 5) {
1631                          pvar->protocol_minor = 5;                          pvar->protocol_minor = 5;
1632                  }                  }
1633    
1634                  return TRUE;                  return TRUE;
1635    
1636          // for SSH2(yutaka)          // for SSH2(yutaka)
1637          case 2:          case 2:
1638                  return TRUE;                    // SSH2 support                  return TRUE;                    // SSH2 support
1639    
1640          default:          default:
1641                  return FALSE;                  return FALSE;
1642          }          }
1643  }  }
1644    
1645  static void init_protocol(PTInstVar pvar)  static void init_protocol(PTInstVar pvar)
1646  {  {
1647          CRYPT_initialize_random_numbers(pvar);          CRYPT_initialize_random_numbers(pvar);
1648    
1649          // known_hostsファイルからホスト公開鍵を先読みしておく          // known_hostsファイルからホスト公開鍵を先読みしておく
1650          HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);          HOSTS_prefetch_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport);
1651    
1652          /* while we wait for a response from the server... */          /* while we wait for a response from the server... */
1653    
1654          if (SSHv1(pvar)) {          if (SSHv1(pvar)) {
1655                  enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);                  enque_handler(pvar, SSH_MSG_DISCONNECT, handle_disconnect);
1656                  enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);                  enque_handler(pvar, SSH_MSG_IGNORE, handle_ignore);
1657                  enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);                  enque_handler(pvar, SSH_MSG_DEBUG, handle_debug);
1658                  enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);                  enque_handler(pvar, SSH_SMSG_PUBLIC_KEY, handle_server_public_key);
1659    
1660          } else {  // for SSH2(yutaka)          } else {  // for SSH2(yutaka)
1661                  enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);                  enque_handler(pvar, SSH2_MSG_DISCONNECT, handle_disconnect);
1662                  enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);                  enque_handler(pvar, SSH2_MSG_IGNORE, handle_ignore);
1663                  enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);                  enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug);
1664                  enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);                  enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit);
1665                  enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);                  enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented);
1666                  enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);                  enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply);
1667                  enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);                  enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply);
1668                  enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);                  enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys);
1669                  enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);                  enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_service_accept);
1670                  enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);                  enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success);
1671                  enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);                  enque_handler(pvar, SSH2_MSG_USERAUTH_FAILURE, handle_SSH2_userauth_failure);
1672                  enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);                  enque_handler(pvar, SSH2_MSG_USERAUTH_BANNER, handle_SSH2_userauth_banner);
1673                  enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);                  enque_handler(pvar, SSH2_MSG_USERAUTH_INFO_REQUEST, handle_SSH2_userauth_inforeq);
1674    
1675                  enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);                  enque_handler(pvar, SSH2_MSG_UNIMPLEMENTED, handle_unimplemented);
1676    
1677                  // ユーザ認証後のディスパッチルーチン                  // ユーザ認証後のディスパッチルーチン
1678                  enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);                  enque_handler(pvar, SSH2_MSG_CHANNEL_CLOSE, handle_SSH2_channel_close);
1679                  enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);                  enque_handler(pvar, SSH2_MSG_CHANNEL_DATA, handle_SSH2_channel_data);
1680                  enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);                  enque_handler(pvar, SSH2_MSG_CHANNEL_EOF, handle_SSH2_channel_eof);
1681                  enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);                  enque_handler(pvar, SSH2_MSG_CHANNEL_EXTENDED_DATA, handle_SSH2_channel_extended_data);
1682                  enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);                  enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN, handle_SSH2_channel_open);
1683                  enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);                  enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, handle_SSH2_open_confirm);
1684                  enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);                  enque_handler(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, handle_SSH2_open_failure);
1685                  enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);                  enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1686                  enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);                  enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1687                  enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);                  enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1688                  enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);                  enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1689  //              enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);  //              enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1690                  enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);                  enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1691                  enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);                  enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
1692    
1693          }          }
1694  }  }
1695    
1696  BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)  BOOL SSH_handle_server_ID(PTInstVar pvar, char FAR * ID, int ID_len)
1697  {  {
1698          static const char prefix[] = "Received server prologue string: ";          static const char prefix[] = "Received server prologue string: ";
1699    
1700          // initialize SSH2 memory dump (2005.3.7 yutaka)          // initialize SSH2 memory dump (2005.3.7 yutaka)
1701          init_memdump();          init_memdump();
1702          push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);          push_memdump("pure server ID", "start protocol version exchange", ID, ID_len);
1703    
1704          if (ID_len <= 0) {          if (ID_len <= 0) {
1705                  return FALSE;                  return FALSE;
1706          } else {          } else {
1707                  int buf_len = ID_len + NUM_ELEM(prefix);                  int buf_len = ID_len + NUM_ELEM(prefix);
1708                  char FAR *buf = (char FAR *) malloc(buf_len);                  char FAR *buf = (char FAR *) malloc(buf_len);
1709    
1710                  strncpy_s(buf, buf_len, prefix, _TRUNCATE);                  strncpy_s(buf, buf_len, prefix, _TRUNCATE);
1711                  strncat_s(buf, buf_len, ID, _TRUNCATE);                  strncat_s(buf, buf_len, ID, _TRUNCATE);
1712                  chop_newlines(buf);                  chop_newlines(buf);
1713    
1714                  notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);                  notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
1715    
1716                  free(buf);                  free(buf);
1717    
1718    
1719                  // ここでのコピーは削除 (2005.3.9 yutaka)                  // ここでのコピーは削除 (2005.3.9 yutaka)
1720  #if 0  #if 0
1721                  // for calculate SSH2 hash                  // for calculate SSH2 hash
1722                  // サーババージョンの保存(改行は取り除くこと)                  // サーババージョンの保存(改行は取り除くこと)
1723                  if (ID_len >= sizeof(pvar->server_version_string))                  if (ID_len >= sizeof(pvar->server_version_string))
1724                          return FALSE;                          return FALSE;
1725                  strncpy(pvar->server_version_string, ID, ID_len);                  strncpy(pvar->server_version_string, ID, ID_len);
1726  #endif  #endif
1727    
1728    
1729                  if (ID[ID_len - 1] != '\n') {                  if (ID[ID_len - 1] != '\n') {
1730                          pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;                          pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING;
1731                          return FALSE;                          return FALSE;
1732                  } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {                  } else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) {
1733                          pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;                          pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING;
1734                          return FALSE;                          return FALSE;
1735                  } else if (strncmp(ID, "SSH-", 4) != 0) {                  } else if (strncmp(ID, "SSH-", 4) != 0) {
1736                          return FALSE;                          return FALSE;
1737                  } else {                  } else {
1738                          ID[ID_len - 1] = 0;                          ID[ID_len - 1] = 0;
1739    
1740                          if (ID_len > 1 && ID[ID_len - 2] == '\r') {                          if (ID_len > 1 && ID[ID_len - 2] == '\r') {
1741                                  ID[ID_len - 2] = 0;                                  ID[ID_len - 2] = 0;
1742                          }                          }
1743    
1744                          pvar->ssh_state.server_ID = _strdup(ID);                          pvar->ssh_state.server_ID = _strdup(ID);
1745    
1746                          if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {                          if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) {
1747                                  UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,                                  UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar,
1748                                                    "This program does not understand the server's version of the protocol.");                                                    "This program does not understand the server's version of the protocol.");
1749                                  notify_fatal_error(pvar, pvar->ts->UIMsg);                                  notify_fatal_error(pvar, pvar->ts->UIMsg);
1750                          } else {                          } else {
1751                                  char TTSSH_ID[1024];                                  char TTSSH_ID[1024];
1752                                  int TTSSH_ID_len;                                  int TTSSH_ID_len;
1753                                  int a, b, c, d;                                  int a, b, c, d;
1754    
1755                                  // 自分自身のバージョンを取得する (2005.3.3 yutaka)                                  // 自分自身のバージョンを取得する (2005.3.3 yutaka)
1756                                  get_file_version("ttxssh.dll", &a, &b, &c, &d);                                  get_file_version("ttxssh.dll", &a, &b, &c, &d);
1757    
1758                                  _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,                                  _snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE,
1759                                              "SSH-%d.%d-TTSSH/%d.%d Win32\n",                                              "SSH-%d.%d-TTSSH/%d.%d Win32\n",
1760                                              pvar->protocol_major, pvar->protocol_minor, a, b);                                              pvar->protocol_major, pvar->protocol_minor, a, b);
1761                                  TTSSH_ID_len = strlen(TTSSH_ID);                                  TTSSH_ID_len = strlen(TTSSH_ID);
1762    
1763                                  // for SSH2(yutaka)                                  // for SSH2(yutaka)
1764                                  // クライアントバージョンの保存(改行は取り除くこと)                                  // クライアントバージョンの保存(改行は取り除くこと)
1765                                  strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),                                  strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string),
1766                                            TTSSH_ID, _TRUNCATE);                                            TTSSH_ID, _TRUNCATE);
1767    
1768                                  // サーババージョンの保存(改行は取り除くこと)(2005.3.9 yutaka)                                  // サーババージョンの保存(改行は取り除くこと)(2005.3.9 yutaka)
1769                                  _snprintf_s(pvar->server_version_string,                                  _snprintf_s(pvar->server_version_string,
1770                                              sizeof(pvar->server_version_string), _TRUNCATE,                                              sizeof(pvar->server_version_string), _TRUNCATE,
1771                                              "%s", pvar->ssh_state.server_ID);                                              "%s", pvar->ssh_state.server_ID);
1772    
1773                                  if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,                                  if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len,
1774                                                     0) != TTSSH_ID_len) {                                                     0) != TTSSH_ID_len) {
1775                                          UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,                                          UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar,
1776                                                            "An error occurred while sending the SSH ID string.\n"                                                            "An error occurred while sending the SSH ID string.\n"
1777                                                            "The connection will close.");                                                            "The connection will close.");
1778                                          notify_fatal_error(pvar, pvar->ts->UIMsg);                                          notify_fatal_error(pvar, pvar->ts->UIMsg);
1779                                  } else {                                  } else {
1780                                          // 改行コードの除去 (2004.8.4 yutaka)                                          // 改行コードの除去 (2004.8.4 yutaka)
1781                                          pvar->client_version_string[--TTSSH_ID_len] = 0;                                          pvar->client_version_string[--TTSSH_ID_len] = 0;
1782    
1783                                          push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));                                          push_memdump("server ID", NULL, pvar->server_version_string, strlen(pvar->server_version_string));
1784                                          push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));                                          push_memdump("client ID", NULL, pvar->client_version_string, strlen(pvar->client_version_string));
1785    
1786                                          // SSHハンドラの登録を行う                                          // SSHハンドラの登録を行う
1787                                          init_protocol(pvar);                                          init_protocol(pvar);
1788    
1789                                          SSH2_dispatch_init(1);                                          SSH2_dispatch_init(1);
1790                                          SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);                                          SSH2_dispatch_add_message(SSH2_MSG_KEXINIT);
1791                                          SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround   (2005.3.3 yutaka)                                          SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround   (2005.3.3 yutaka)
1792                                  }                                  }
1793                          }                          }
1794    
1795                          return TRUE;                          return TRUE;
1796                  }                  }
1797          }          }
1798  }  }
1799    
1800  static BOOL handle_exit(PTInstVar pvar)  static BOOL handle_exit(PTInstVar pvar)
1801  {  {
1802          if (grab_payload(pvar, 4)) {          if (grab_payload(pvar, 4)) {
1803                  begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);                  begin_send_packet(pvar, SSH_CMSG_EXIT_CONFIRMATION, 0);
1804                  finish_send_packet(pvar);                  finish_send_packet(pvar);
1805                  notify_closed_connection(pvar);                  notify_closed_connection(pvar);
1806          }          }
1807          return TRUE;          return TRUE;
1808  }  }
1809    
1810  static BOOL handle_data(PTInstVar pvar)  static BOOL handle_data(PTInstVar pvar)
1811  {  {
1812          if (grab_payload_limited(pvar, 4)) {          if (grab_payload_limited(pvar, 4)) {
1813                  pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);                  pvar->ssh_state.payload_datalen = get_payload_uint32(pvar, 0);
1814                  pvar->ssh_state.payload_datastart = 4;                  pvar->ssh_state.payload_datastart = 4;
1815          }          }
1816          return TRUE;          return TRUE;
1817  }  }
1818    
1819  static BOOL handle_channel_open(PTInstVar pvar)  static BOOL handle_channel_open(PTInstVar pvar)
1820  {  {
1821          int host_len;          int host_len;
1822          int originator_len;          int originator_len;
1823    
1824          if ((pvar->ssh_state.          if ((pvar->ssh_state.
1825                   server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {                   server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1826                  if (grab_payload(pvar, 8)                  if (grab_payload(pvar, 8)
1827                   && grab_payload(pvar,                   && grab_payload(pvar,
1828                                   8 + (host_len = get_payload_uint32(pvar, 4)))                                   8 + (host_len = get_payload_uint32(pvar, 4)))
1829                   && grab_payload(pvar, originator_len =                   && grab_payload(pvar, originator_len =
1830                                   get_payload_uint32(pvar, host_len + 12))) {                                   get_payload_uint32(pvar, host_len + 12))) {
1831                          int local_port = get_payload_uint32(pvar, 8 + host_len);                          int local_port = get_payload_uint32(pvar, 8 + host_len);
1832    
1833                          pvar->ssh_state.payload[8 + host_len] = 0;                          pvar->ssh_state.payload[8 + host_len] = 0;
1834                          FWD_open(pvar, get_payload_uint32(pvar, 0),                          FWD_open(pvar, get_payload_uint32(pvar, 0),
1835                                   pvar->ssh_state.payload + 8, local_port,                                   pvar->ssh_state.payload + 8, local_port,
1836                                   pvar->ssh_state.payload + 16 + host_len,                                   pvar->ssh_state.payload + 16 + host_len,
1837                                   originator_len,                                   originator_len,
1838                                   NULL);                                   NULL);
1839                  }                  }
1840          } else {          } else {
1841                  if (grab_payload(pvar, 8)                  if (grab_payload(pvar, 8)
1842                   && grab_payload(pvar,                   && grab_payload(pvar,
1843                                   4 + (host_len = get_payload_uint32(pvar, 4)))) {                                   4 + (host_len = get_payload_uint32(pvar, 4)))) {
1844                          int local_port = get_payload_uint32(pvar, 8 + host_len);                          int local_port = get_payload_uint32(pvar, 8 + host_len);
1845    
1846                          pvar->ssh_state.payload[8 + host_len] = 0;                          pvar->ssh_state.payload[8 + host_len] = 0;
1847                          FWD_open(pvar, get_payload_uint32(pvar, 0),                          FWD_open(pvar, get_payload_uint32(pvar, 0),
1848                                   pvar->ssh_state.payload + 8, local_port, NULL, 0,                                   pvar->ssh_state.payload + 8, local_port, NULL, 0,
1849                                   NULL);                                   NULL);
1850                  }                  }
1851          }          }
1852    
1853          return TRUE;          return TRUE;
1854  }  }
1855    
1856  static BOOL handle_X11_channel_open(PTInstVar pvar)  static BOOL handle_X11_channel_open(PTInstVar pvar)
1857  {  {
1858          int originator_len;          int originator_len;
1859    
1860          if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {          if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) {
1861                  if (grab_payload(pvar, 8)                  if (grab_payload(pvar, 8)
1862                   && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {                   && grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) {
1863                          FWD_X11_open(pvar, get_payload_uint32(pvar, 0),                          FWD_X11_open(pvar, get_payload_uint32(pvar, 0),
1864                                       pvar->ssh_state.payload + 8, originator_len, NULL);                                       pvar->ssh_state.payload + 8, originator_len, NULL);
1865                  }                  }
1866          } else {          } else {
1867                  if (grab_payload(pvar, 4)) {                  if (grab_payload(pvar, 4)) {
1868                          FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);                          FWD_X11_open(pvar, get_payload_uint32(pvar, 0), NULL, 0, NULL);
1869                  }                  }
1870          }          }
1871    
1872          return TRUE;          return TRUE;
1873  }  }
1874    
1875  static BOOL handle_channel_open_confirmation(PTInstVar pvar)  static BOOL handle_channel_open_confirmation(PTInstVar pvar)
1876  {  {
1877          if (grab_payload(pvar, 8)) {          if (grab_payload(pvar, 8)) {
1878                  FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),                  FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0),
1879                                     get_payload_uint32(pvar, 4));                                     get_payload_uint32(pvar, 4));
1880          }          }
1881          return FALSE;          return FALSE;
1882  }  }
1883    
1884  static BOOL handle_channel_open_failure(PTInstVar pvar)  static BOOL handle_channel_open_failure(PTInstVar pvar)
1885  {  {
1886          if (grab_payload(pvar, 4)) {          if (grab_payload(pvar, 4)) {
1887                  FWD_failed_open(pvar, get_payload_uint32(pvar, 0));                  FWD_failed_open(pvar, get_payload_uint32(pvar, 0));
1888          }          }
1889          return FALSE;          return FALSE;
1890  }  }
1891    
1892  static BOOL handle_channel_data(PTInstVar pvar)  static BOOL handle_channel_data(PTInstVar pvar)
1893  {  {
1894          int len;          int len;
1895    
1896          if (grab_payload(pvar, 8)          if (grab_payload(pvar, 8)
1897           && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {           && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1898                  FWDChannel *channel;                  FWDChannel *channel;
1899                  int local_channel_num = get_payload_uint32(pvar, 0);                  int local_channel_num = get_payload_uint32(pvar, 0);
1900                  if (!FWD_check_local_channel_num(pvar, local_channel_num)) {                  if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1901                          return FALSE;                          return FALSE;
1902                  }                  }
1903                  channel = pvar->fwd_state.channels + local_channel_num;                  channel = pvar->fwd_state.channels + local_channel_num;
1904                  if (channel->type == TYPE_AGENT) {                  if (channel->type == TYPE_AGENT) {
1905                          SSH_agent_response(pvar, NULL, local_channel_num,                          SSH_agent_response(pvar, NULL, local_channel_num,
1906                                             pvar->ssh_state.payload + 8, len);                                             pvar->ssh_state.payload + 8, len);
1907                  }                  }
1908                  else {                  else {
1909                          FWD_received_data(pvar, local_channel_num,                          FWD_received_data(pvar, local_channel_num,
1910                                            pvar->ssh_state.payload + 8, len);                                            pvar->ssh_state.payload + 8, len);
1911                  }                  }
1912          }          }
1913          return TRUE;          return TRUE;
1914  }  }
1915    
1916  static BOOL handle_channel_input_eof(PTInstVar pvar)  static BOOL handle_channel_input_eof(PTInstVar pvar)
1917  {  {
1918          if (grab_payload(pvar, 4)) {          if (grab_payload(pvar, 4)) {
1919                  int local_channel_num = get_payload_uint32(pvar, 0);                  int local_channel_num = get_payload_uint32(pvar, 0);
1920                  FWDChannel *channel;                  FWDChannel *channel;
1921                  if (!FWD_check_local_channel_num(pvar, local_channel_num)) {                  if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1922                          return FALSE;                          return FALSE;
1923                  }                  }
1924                  channel = pvar->fwd_state.channels + local_channel_num;                  channel = pvar->fwd_state.channels + local_channel_num;
1925                  if (channel->type == TYPE_AGENT) {                  if (channel->type == TYPE_AGENT) {
1926                          channel->status |= FWD_CLOSED_REMOTE_IN;                          channel->status |= FWD_CLOSED_REMOTE_IN;
1927                          SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);                          SSH_channel_input_eof(pvar, channel->remote_num, local_channel_num);
1928                  }                  }
1929                  else {                  else {
1930                          FWD_channel_input_eof(pvar, local_channel_num);                          FWD_channel_input_eof(pvar, local_channel_num);
1931                  }                  }
1932          }          }
1933          return TRUE;          return TRUE;
1934  }  }
1935    
1936  static BOOL handle_channel_output_eof(PTInstVar pvar)  static BOOL handle_channel_output_eof(PTInstVar pvar)
1937  {  {
1938          if (grab_payload(pvar, 4)) {          if (grab_payload(pvar, 4)) {
1939                  int local_channel_num = get_payload_uint32(pvar, 0);                  int local_channel_num = get_payload_uint32(pvar, 0);
1940                  FWDChannel *channel;                  FWDChannel *channel;
1941                  if (!FWD_check_local_channel_num(pvar, local_channel_num)) {                  if (!FWD_check_local_channel_num(pvar, local_channel_num)) {
1942                          return FALSE;                          return FALSE;
1943                  }                  }
1944                  channel = pvar->fwd_state.channels + local_channel_num;                  channel = pvar->fwd_state.channels + local_channel_num;
1945                  if (channel->type == TYPE_AGENT) {                  if (channel->type == TYPE_AGENT) {
1946                          channel->status |= FWD_CLOSED_REMOTE_OUT;                          channel->status |= FWD_CLOSED_REMOTE_OUT;
1947                          SSH_channel_output_eof(pvar, channel->remote_num);                          SSH_channel_output_eof(pvar, channel->remote_num);
1948                          FWD_free_channel(pvar, local_channel_num);                          FWD_free_channel(pvar, local_channel_num);
1949                  }                  }
1950                  else {                  else {
1951                          FWD_channel_output_eof(pvar, local_channel_num);                          FWD_channel_output_eof(pvar, local_channel_num);
1952                  }                  }
1953          }          }
1954          return TRUE;          return TRUE;
1955  }  }
1956    
1957  static BOOL handle_agent_open(PTInstVar pvar)  static BOOL handle_agent_open(PTInstVar pvar)
1958  {  {
1959          if (grab_payload(pvar, 4)) {          if (grab_payload(pvar, 4)) {
1960                  int remote_id = get_payload_uint32(pvar, 0);                  int remote_id = get_payload_uint32(pvar, 0);
1961                  int local_id;                  int local_id;
1962    
1963                  if (pvar->agentfwd_enable) {                  if (pvar->agentfwd_enable) {
1964                          local_id = FWD_agent_open(pvar, remote_id);                          local_id = FWD_agent_open(pvar, remote_id);
1965                          if (local_id == -1) {                          if (local_id == -1) {
1966                                  SSH_fail_channel_open(pvar, remote_id);                                  SSH_fail_channel_open(pvar, remote_id);
1967                          }                          }
1968                          else {                          else {
1969                                  SSH_confirm_channel_open(pvar, remote_id, local_id);                                  SSH_confirm_channel_open(pvar, remote_id, local_id);
1970                          }                          }
1971                  }                  }
1972                  else {                  else {
1973                          SSH_fail_channel_open(pvar, remote_id);                          SSH_fail_channel_open(pvar, remote_id);
1974                  }                  }
1975          }          }
1976          /*          /*
1977          else {          else {
1978                  // 通知する相手channelが分からないので何もできない                  // 通知する相手channelが分からないので何もできない
1979          }          }
1980          */          */
1981    
1982          return TRUE;          return TRUE;
1983  }  }
1984    
1985    
1986    
1987  // ハンドリングするメッセージを決定する  // ハンドリングするメッセージを決定する
1988    
1989  #define HANDLE_MESSAGE_MAX 30  #define HANDLE_MESSAGE_MAX 30
1990  static unsigned char handle_messages[HANDLE_MESSAGE_MAX];  static unsigned char handle_messages[HANDLE_MESSAGE_MAX];
1991  static int handle_message_count = 0;  static int handle_message_count = 0;
1992  static int handle_message_stage = 0;  static int handle_message_stage = 0;
1993    
1994  void SSH2_dispatch_init(int stage)  void SSH2_dispatch_init(int stage)
1995  {  {
1996          handle_message_count = 0;          handle_message_count = 0;
1997          handle_message_stage = stage;          handle_message_stage = stage;
1998  }  }
1999    
2000  int SSH2_dispatch_enabled_check(unsigned char message)  int SSH2_dispatch_enabled_check(unsigned char message)
2001  {  {
2002          int i;          int i;
2003    
2004          for (i = 0 ; i < handle_message_count ; i++) {          for (i = 0 ; i < handle_message_count ; i++) {
2005                  if (handle_messages[i] == message)                  if (handle_messages[i] == message)
2006                          return 1;                          return 1;
2007          }          }
2008          return 0;          return 0;
2009  }  }
2010    
2011  void SSH2_dispatch_add_message(unsigned char message)  void SSH2_dispatch_add_message(unsigned char message)
2012  {  {
2013          int i;          int i;
2014    
2015          if (handle_message_count >= HANDLE_MESSAGE_MAX) {          if (handle_message_count >= HANDLE_MESSAGE_MAX) {
2016                  // TODO: error check                  // TODO: error check
2017                  return;                  return;
2018          }          }
2019    
2020          // すでに登録されているメッセージは追加しない          // すでに登録されているメッセージは追加しない
2021          for (i=0; i<handle_message_count; i++) {          for (i=0; i<handle_message_count; i++) {
2022                  if (handle_messages[i] == message) {                  if (handle_messages[i] == message) {
2023                          return;                          return;
2024                  }                  }
2025          }          }
2026    
2027          handle_messages[handle_message_count++] = message;          handle_messages[handle_message_count++] = message;
2028  }  }
2029    
2030  void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)  void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end)
2031  {  {
2032          unsigned char c;          unsigned char c;
2033    
2034          for (c = begin ; c <= end ; c++) {          for (c = begin ; c <= end ; c++) {
2035                  SSH2_dispatch_add_message(c);                  SSH2_dispatch_add_message(c);
2036          }          }
2037  }  }
2038    
2039    
2040  void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,  void SSH_handle_packet(PTInstVar pvar, char FAR * data, int len,
2041                                             int padding)                                             int padding)
2042  {  {
2043          unsigned char message = prep_packet(pvar, data, len, padding);          unsigned char message = prep_packet(pvar, data, len, padding);
2044    
2045                    
2046  #ifdef SSH2_DEBUG  #ifdef SSH2_DEBUG
2047          // for SSH2(yutaka)          // for SSH2(yutaka)
2048          if (SSHv2(pvar)) {          if (SSHv2(pvar)) {
2049                  if (pvar->key_done) {                  if (pvar->key_done) {
2050                          message = message;                          message = message;
2051                  }                  }
2052    
2053                  if (pvar->userauth_success) {                  if (pvar->userauth_success) {
2054                          message = message;                          message = message;
2055                  }                  }
2056    
2057                  if (pvar->rekeying) {                  if (pvar->rekeying) {
2058                          message = message;                          message = message;
2059                  }                  }
2060          }          }
2061  #endif  #endif
2062    
2063          // SSHのメッセージタイプをチェック          // SSHのメッセージタイプをチェック
2064          if (message != SSH_MSG_NONE) {          if (message != SSH_MSG_NONE) {
2065                  // メッセージタイプに応じたハンドラを起動                  // メッセージタイプに応じたハンドラを起動
2066                  SSHPacketHandler handler = get_handler(pvar, message);                  SSHPacketHandler handler = get_handler(pvar, message);
2067    
2068                  // for SSH2(yutaka)                  // for SSH2(yutaka)
2069                  if (SSHv2(pvar)) {                  if (SSHv2(pvar)) {
2070                          // 想定外のメッセージタイプが到着したらアボートさせる。                          // 想定外のメッセージタイプが到着したらアボートさせる。
2071                          if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {                          if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2072                                  char buf[1024];                                  char buf[1024];
2073    
2074                                  UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,                                  UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar,
2075                                                                    "Unexpected SSH2 message(%d) on current stage(%d)");                                                                    "Unexpected SSH2 message(%d) on current stage(%d)");
2076                                  _snprintf_s(buf, sizeof(buf), _TRUNCATE,                                  _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2077                                          pvar->ts->UIMsg, message, handle_message_stage);                                          pvar->ts->UIMsg, message, handle_message_stage);
2078                                  notify_fatal_error(pvar, buf);                                  notify_fatal_error(pvar, buf);
2079                                  // abort                                  // abort
2080                          }                          }
2081                  }                  }
2082    
2083                  if (handler == NULL) {                  if (handler == NULL) {
2084                          if (SSHv1(pvar)) {                          if (SSHv1(pvar)) {
2085                                  char buf[1024];                                  char buf[1024];
2086    
2087                                  UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,                                  UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar,
2088                                                    "Unexpected packet type received: %d");                                                    "Unexpected packet type received: %d");
2089                                  _snprintf_s(buf, sizeof(buf), _TRUNCATE,                                  _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2090                                          pvar->ts->UIMsg, message, handle_message_stage);                                          pvar->ts->UIMsg, message, handle_message_stage);
2091                                  notify_fatal_error(pvar, buf);                                  notify_fatal_error(pvar, buf);
2092                          } else {                          } else {
2093                                  unsigned char FAR *outmsg =                                  unsigned char FAR *outmsg =
2094                                          begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);                                          begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
2095    
2096                                  set_uint32(outmsg,                                  set_uint32(outmsg,
2097                                             pvar->ssh_state.receiver_sequence_number - 1);                                             pvar->ssh_state.receiver_sequence_number - 1);
2098                                  finish_send_packet(pvar);                                  finish_send_packet(pvar);
2099    
2100                                  notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);                                  notify_verbose_message(pvar, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().", LOG_LEVEL_VERBOSE);
2101                                  /* XXX need to decompress incoming packet, but how? */                                  /* XXX need to decompress incoming packet, but how? */
2102                          }                          }
2103                  } else {                  } else {
2104                          if (!handler(pvar)) {                          if (!handler(pvar)) {
2105                                  deque_handlers(pvar, message);                                  deque_handlers(pvar, message);
2106                          }                          }
2107                  }                  }
2108          }          }
2109  }  }
2110    
2111  static BOOL handle_pty_success(PTInstVar pvar)  static BOOL handle_pty_success(PTInstVar pvar)
2112  {  {
2113          FWD_enter_interactive_mode(pvar);          FWD_enter_interactive_mode(pvar);
2114          enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);          enque_handler(pvar, SSH_SMSG_EXITSTATUS, handle_exit);
2115          enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);          enque_handler(pvar, SSH_SMSG_STDOUT_DATA, handle_data);
2116          enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);          enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data);
2117          enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);          enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data);
2118          enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,          enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF,
2119                        handle_channel_input_eof);                        handle_channel_input_eof);
2120          enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,          enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED,
2121                        handle_channel_output_eof);                        handle_channel_output_eof);
2122          enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);          enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2123          enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);          enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2124          enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);          enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2125          return FALSE;          return FALSE;
2126  }  }
2127    
2128  static BOOL handle_pty_failure(PTInstVar pvar)  static BOOL handle_pty_failure(PTInstVar pvar)
2129  {  {
2130          UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,          UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar,
2131                            "The server cannot allocate a pseudo-terminal. "                            "The server cannot allocate a pseudo-terminal. "
2132                            "You may encounter some problems with the terminal.");                            "You may encounter some problems with the terminal.");
2133          notify_nonfatal_error(pvar, pvar->ts->UIMsg);          notify_nonfatal_error(pvar, pvar->ts->UIMsg);
2134          return handle_pty_success(pvar);          return handle_pty_success(pvar);
2135  }  }
2136    
2137  static void prep_pty(PTInstVar pvar)  static void prep_pty(PTInstVar pvar)
2138  {  {
2139          int len = strlen(pvar->ts->TermType);          int len = strlen(pvar->ts->TermType);
2140          unsigned char FAR *outmsg =          unsigned char FAR *outmsg =
2141                  begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,                  begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY,
2142                                    4 + len + 16 + sizeof(ssh_ttymodes));                                    4 + len + 16 + sizeof(ssh_ttymodes));
2143          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2144          static const SSHPacketHandler handlers[]          static const SSHPacketHandler handlers[]
2145          = { handle_pty_success, handle_pty_failure };          = { handle_pty_success, handle_pty_failure };
2146    
2147          set_uint32(outmsg, len);          set_uint32(outmsg, len);
2148          memcpy(outmsg + 4, pvar->ts->TermType, len);          memcpy(outmsg + 4, pvar->ts->TermType, len);
2149          set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);          set_uint32(outmsg + 4 + len, pvar->ssh_state.win_rows);
2150          set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);          set_uint32(outmsg + 4 + len + 4, pvar->ssh_state.win_cols);
2151          set_uint32(outmsg + 4 + len + 8, 0);          set_uint32(outmsg + 4 + len + 8, 0);
2152          set_uint32(outmsg + 4 + len + 12, 0);          set_uint32(outmsg + 4 + len + 12, 0);
2153          memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));          memcpy(outmsg + 4 + len + 16, ssh_ttymodes, sizeof(ssh_ttymodes));
2154          finish_send_packet(pvar);          finish_send_packet(pvar);
2155    
2156          enque_handlers(pvar, 2, msgs, handlers);          enque_handlers(pvar, 2, msgs, handlers);
2157    
2158          begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);          begin_send_packet(pvar, SSH_CMSG_EXEC_SHELL, 0);
2159          finish_send_packet(pvar);          finish_send_packet(pvar);
2160  }  }
2161    
2162  static BOOL handle_agent_request_success(PTInstVar pvar)  static BOOL handle_agent_request_success(PTInstVar pvar)
2163  {  {
2164          pvar->agentfwd_enable = TRUE;          pvar->agentfwd_enable = TRUE;
2165          prep_pty(pvar);          prep_pty(pvar);
2166          return FALSE;          return FALSE;
2167  }  }
2168    
2169  static BOOL handle_agent_request_failure(PTInstVar pvar)  static BOOL handle_agent_request_failure(PTInstVar pvar)
2170  {  {
2171          prep_pty(pvar);          prep_pty(pvar);
2172          return FALSE;          return FALSE;
2173  }  }
2174    
2175  static void prep_agent_request(PTInstVar pvar)  static void prep_agent_request(PTInstVar pvar)
2176  {  {
2177          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2178          static const SSHPacketHandler handlers[]          static const SSHPacketHandler handlers[]
2179          = { handle_agent_request_success, handle_agent_request_failure };          = { handle_agent_request_success, handle_agent_request_failure };
2180    
2181          enque_handlers(pvar, 2, msgs, handlers);          enque_handlers(pvar, 2, msgs, handlers);
2182    
2183          begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);          begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2184          finish_send_packet(pvar);          finish_send_packet(pvar);
2185  }  }
2186    
2187  static void prep_forwarding(PTInstVar pvar)  static void prep_forwarding(PTInstVar pvar)
2188  {  {
2189          FWD_prep_forwarding(pvar);          FWD_prep_forwarding(pvar);
2190    
2191          if (pvar->session_settings.ForwardAgent) {          if (pvar->session_settings.ForwardAgent) {
2192                  prep_agent_request(pvar);                  prep_agent_request(pvar);
2193          }          }
2194          else {          else {
2195                  prep_pty(pvar);                  prep_pty(pvar);
2196          }          }
2197  }  }
2198    
2199    
2200  //  //
2201  //  //
2202  // (2005.7.10 yutaka)  // (2005.7.10 yutaka)
2203  static void enable_send_compression(PTInstVar pvar)  static void enable_send_compression(PTInstVar pvar)
2204  {  {
2205          static int initialize = 0;          static int initialize = 0;
2206    
2207          if (initialize) {          if (initialize) {
2208                  deflateEnd(&pvar->ssh_state.compress_stream);                  deflateEnd(&pvar->ssh_state.compress_stream);
2209          }          }
2210          initialize = 1;          initialize = 1;
2211    
2212          pvar->ssh_state.compress_stream.zalloc = NULL;          pvar->ssh_state.compress_stream.zalloc = NULL;
2213          pvar->ssh_state.compress_stream.zfree = NULL;          pvar->ssh_state.compress_stream.zfree = NULL;
2214          pvar->ssh_state.compress_stream.opaque = NULL;          pvar->ssh_state.compress_stream.opaque = NULL;
2215          if (deflateInit          if (deflateInit
2216              (&pvar->ssh_state.compress_stream,              (&pvar->ssh_state.compress_stream,
2217               pvar->ssh_state.compression_level) != Z_OK) {               pvar->ssh_state.compression_level) != Z_OK) {
2218                  UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,                  UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2219                                    "An error occurred while setting up compression.\n"                                    "An error occurred while setting up compression.\n"
2220                                    "The connection will close.");                                    "The connection will close.");
2221                  notify_fatal_error(pvar, pvar->ts->UIMsg);                  notify_fatal_error(pvar, pvar->ts->UIMsg);
2222                  return;                  return;
2223          } else {          } else {
2224                  // SSH2では圧縮・展開処理をSSH1とは別に行うので、下記フラグは落としておく。(2005.7.9 yutaka)                  // SSH2では圧縮・展開処理をSSH1とは別に行うので、下記フラグは落としておく。(2005.7.9 yutaka)
2225                  if (SSHv2(pvar)) {                  if (SSHv2(pvar)) {
2226                          pvar->ssh_state.compressing = FALSE;                          pvar->ssh_state.compressing = FALSE;
2227                  } else {                  } else {
2228                          pvar->ssh_state.compressing = TRUE;                          pvar->ssh_state.compressing = TRUE;
2229                  }                  }
2230          }          }
2231  }  }
2232    
2233  static void enable_recv_compression(PTInstVar pvar)  static void enable_recv_compression(PTInstVar pvar)
2234  {  {
2235          static int initialize = 0;          static int initialize = 0;
2236    
2237          if (initialize) {          if (initialize) {
2238                  deflateEnd(&pvar->ssh_state.decompress_stream);                  deflateEnd(&pvar->ssh_state.decompress_stream);
2239          }          }
2240          initialize = 1;          initialize = 1;
2241    
2242          pvar->ssh_state.decompress_stream.zalloc = NULL;          pvar->ssh_state.decompress_stream.zalloc = NULL;
2243          pvar->ssh_state.decompress_stream.zfree = NULL;          pvar->ssh_state.decompress_stream.zfree = NULL;
2244          pvar->ssh_state.decompress_stream.opaque = NULL;          pvar->ssh_state.decompress_stream.opaque = NULL;
2245          if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {          if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) {
2246                  deflateEnd(&pvar->ssh_state.compress_stream);                  deflateEnd(&pvar->ssh_state.compress_stream);
2247                  UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,                  UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar,
2248                                    "An error occurred while setting up compression.\n"                                    "An error occurred while setting up compression.\n"
2249                                    "The connection will close.");                                    "The connection will close.");
2250                  notify_fatal_error(pvar, pvar->ts->UIMsg);                  notify_fatal_error(pvar, pvar->ts->UIMsg);
2251                  return;                  return;
2252          } else {          } else {
2253                  // SSH2では圧縮・展開処理をSSH1とは別に行うので、下記フラグは落としておく。(2005.7.9 yutaka)                  // SSH2では圧縮・展開処理をSSH1とは別に行うので、下記フラグは落としておく。(2005.7.9 yutaka)
2254                  if (SSHv2(pvar)) {                  if (SSHv2(pvar)) {
2255                          pvar->ssh_state.decompressing = FALSE;                          pvar->ssh_state.decompressing = FALSE;
2256                  } else {                  } else {
2257                          pvar->ssh_state.decompressing = TRUE;                          pvar->ssh_state.decompressing = TRUE;
2258                  }                  }
2259    
2260                  buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,                  buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
2261                                  &pvar->ssh_state.postdecompress_inbuflen, 1000);                                  &pvar->ssh_state.postdecompress_inbuflen, 1000);
2262          }          }
2263  }  }
2264    
2265  static void enable_compression(PTInstVar pvar)  static void enable_compression(PTInstVar pvar)
2266  {  {
2267          enable_send_compression(pvar);          enable_send_compression(pvar);
2268          enable_recv_compression(pvar);          enable_recv_compression(pvar);
2269    
2270          // SSH2では圧縮・展開処理をSSH1とは別に行うので、下記フラグは落としておく。(2005.7.9 yutaka)          // SSH2では圧縮・展開処理をSSH1とは別に行うので、下記フラグは落としておく。(2005.7.9 yutaka)
2271          if (SSHv2(pvar)) {          if (SSHv2(pvar)) {
2272                  pvar->ssh_state.compressing = FALSE;                  pvar->ssh_state.compressing = FALSE;
2273                  pvar->ssh_state.decompressing = FALSE;                  pvar->ssh_state.decompressing = FALSE;
2274          }          }
2275    
2276  }  }
2277    
2278  static BOOL handle_enable_compression(PTInstVar pvar)  static BOOL handle_enable_compression(PTInstVar pvar)
2279  {  {
2280          enable_compression(pvar);          enable_compression(pvar);
2281          prep_forwarding(pvar);          prep_forwarding(pvar);
2282          return FALSE;          return FALSE;
2283  }  }
2284    
2285  static BOOL handle_disable_compression(PTInstVar pvar)  static BOOL handle_disable_compression(PTInstVar pvar)
2286  {  {
2287          prep_forwarding(pvar);          prep_forwarding(pvar);
2288          return FALSE;          return FALSE;
2289  }  }
2290    
2291  static void prep_compression(PTInstVar pvar)  static void prep_compression(PTInstVar pvar)
2292  {  {
2293          if (pvar->session_settings.CompressionLevel > 0) {          if (pvar->session_settings.CompressionLevel > 0) {
2294                  // added if statement (2005.7.10 yutaka)                  // added if statement (2005.7.10 yutaka)
2295                  if (SSHv1(pvar)) {                  if (SSHv1(pvar)) {
2296                          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };                          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2297                          static const SSHPacketHandler handlers[]                          static const SSHPacketHandler handlers[]
2298                          = { handle_enable_compression, handle_disable_compression };                          = { handle_enable_compression, handle_disable_compression };
2299    
2300                          unsigned char FAR *outmsg =                          unsigned char FAR *outmsg =
2301                                  begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);                                  begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
2302    
2303                          set_uint32(outmsg, pvar->session_settings.CompressionLevel);                          set_uint32(outmsg, pvar->session_settings.CompressionLevel);
2304                          finish_send_packet(pvar);                          finish_send_packet(pvar);
2305    
2306                          enque_handlers(pvar, 2, msgs, handlers);                          enque_handlers(pvar, 2, msgs, handlers);
2307                  }                  }
2308    
2309                  pvar->ssh_state.compression_level =                  pvar->ssh_state.compression_level =
2310                          pvar->session_settings.CompressionLevel;                          pvar->session_settings.CompressionLevel;
2311    
2312          } else {          } else {
2313                  // added if statement (2005.7.10 yutaka)                  // added if statement (2005.7.10 yutaka)
2314                  if (SSHv1(pvar)) {                  if (SSHv1(pvar)) {
2315                          prep_forwarding(pvar);                          prep_forwarding(pvar);
2316                  }                  }
2317          }          }
2318  }  }
2319    
2320  static void enque_simple_auth_handlers(PTInstVar pvar)  static void enque_simple_auth_handlers(PTInstVar pvar)
2321  {  {
2322          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2323          static const SSHPacketHandler handlers[]          static const SSHPacketHandler handlers[]
2324          = { handle_auth_success, handle_auth_failure };          = { handle_auth_success, handle_auth_failure };
2325    
2326          enque_handlers(pvar, 2, msgs, handlers);          enque_handlers(pvar, 2, msgs, handlers);
2327  }  }
2328    
2329  static BOOL handle_rsa_challenge(PTInstVar pvar)  static BOOL handle_rsa_challenge(PTInstVar pvar)
2330  {  {
2331          int challenge_bytes;          int challenge_bytes;
2332    
2333          if (!grab_payload(pvar, 2)) {          if (!grab_payload(pvar, 2)) {
2334                  return FALSE;                  return FALSE;
2335          }          }
2336    
2337          challenge_bytes = get_mpint_len(pvar, 0);          challenge_bytes = get_mpint_len(pvar, 0);
2338    
2339          if (grab_payload(pvar, challenge_bytes)) {          if (grab_payload(pvar, challenge_bytes)) {
2340                  unsigned char FAR *outmsg =                  unsigned char FAR *outmsg =
2341                          begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);                          begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16);
2342    
2343                  if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {                  if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) {
2344                          if (CRYPT_generate_RSA_challenge_response                          if (CRYPT_generate_RSA_challenge_response
2345                                  (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {                                  (pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) {
2346    
2347                                  // セッション複製時にパスワードを使い回したいので、ここでのリソース解放はやめる。                                  // セッション複製時にパスワードを使い回したいので、ここでのリソース解放はやめる。
2348                                  // socket close時にもこの関数は呼ばれているので、たぶん問題ない。(2005.4.8 yutaka)                                  // socket close時にもこの関数は呼ばれているので、たぶん問題ない。(2005.4.8 yutaka)
2349  #if 0  #if 0
2350                                  //AUTH_destroy_cur_cred(pvar);                                  //AUTH_destroy_cur_cred(pvar);
2351  #endif  #endif
2352    
2353                                  finish_send_packet(pvar);                                  finish_send_packet(pvar);
2354    
2355                                  enque_simple_auth_handlers(pvar);                                  enque_simple_auth_handlers(pvar);
2356                          } else {                          } else {
2357                                  UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,                                  UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar,
2358                                                                    "An error occurred while decrypting the RSA challenge.\n"                                                                    "An error occurred while decrypting the RSA challenge.\n"
2359                                                                    "Perhaps the key file is corrupted.");                                                                    "Perhaps the key file is corrupted.");
2360                                  notify_fatal_error(pvar, pvar->ts->UIMsg);                                  notify_fatal_error(pvar, pvar->ts->UIMsg);
2361                          }                          }
2362                  }                  }
2363                  else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {                  else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) {
2364                          int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);                          int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n);
2365                          int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);                          int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n);
2366                          int server_key_bytes = (server_key_bits + 7) / 8;                          int server_key_bytes = (server_key_bits + 7) / 8;
2367                          int host_key_bytes = (host_key_bits + 7) / 8;                          int host_key_bytes = (host_key_bits + 7) / 8;
2368                          int session_buf_len = server_key_bytes + host_key_bytes + 8;                          int session_buf_len = server_key_bytes + host_key_bytes + 8;
2369                          char FAR *session_buf = (char FAR *) malloc(session_buf_len);                          char FAR *session_buf = (char FAR *) malloc(session_buf_len);
2370                          unsigned char session_id[16];                          unsigned char session_id[16];
2371    
2372                          unsigned char *hash;                          unsigned char *hash;
2373                          int pubkeylen, hashlen;                          int pubkeylen, hashlen;
2374    
2375                          /* Pageant にハッシュを計算してもらう */                          /* Pageant にハッシュを計算してもらう */
2376                          // 公開鍵の長さ                          // 公開鍵の長さ
2377                          pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,                          pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey,
2378                                                            pvar->pageant_keylistlen);                                                            pvar->pageant_keylistlen);
2379                          // セッションIDを作成                          // セッションIDを作成
2380                          BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);                          BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf);
2381                          BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,                          BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n,
2382                                    session_buf + host_key_bytes);                                    session_buf + host_key_bytes);
2383                          memcpy(session_buf + server_key_bytes + host_key_bytes,                          memcpy(session_buf + server_key_bytes + host_key_bytes,
2384                                 pvar->crypt_state.server_cookie, 8);                                 pvar->crypt_state.server_cookie, 8);
2385                          MD5(session_buf, session_buf_len, session_id);                          MD5(session_buf, session_buf_len, session_id);
2386                          // ハッシュを受け取る                          // ハッシュを受け取る
2387                          hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,                          hash = putty_hash_ssh1_challenge(pvar->pageant_curkey,
2388                                                           pubkeylen,                                                           pubkeylen,
2389                                                           pvar->ssh_state.payload,                                                           pvar->ssh_state.payload,
2390                                                           challenge_bytes + 2,                                                           challenge_bytes + 2,
2391                                                           session_id,                                                           session_id,
2392                                                           &hashlen);                                                           &hashlen);
2393    
2394                          // ハッシュを送信                          // ハッシュを送信
2395                          memcpy(outmsg, hash, 16);                          memcpy(outmsg, hash, 16);
2396                          free(hash);                          free(hash);
2397    
2398                          finish_send_packet(pvar);                          finish_send_packet(pvar);
2399    
2400                          enque_simple_auth_handlers(pvar);                          enque_simple_auth_handlers(pvar);
2401                  }                  }
2402          }          }
2403    
2404          return FALSE;          return FALSE;
2405  }  }
2406    
2407  #define OBFUSCATING_ROUND_TO 32  #define OBFUSCATING_ROUND_TO 32
2408    
2409  static int obfuscating_round_up(PTInstVar pvar, int size)  static int obfuscating_round_up(PTInstVar pvar, int size)
2410  {  {
2411          return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);          return (size + OBFUSCATING_ROUND_TO - 1) & ~(OBFUSCATING_ROUND_TO - 1);
2412  }  }
2413    
2414  static void try_send_credentials(PTInstVar pvar)  static void try_send_credentials(PTInstVar pvar)
2415  {  {
2416          if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {          if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) {
2417                  AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);                  AUTHCred FAR *cred = AUTH_get_cur_cred(pvar);
2418                  static const int RSA_msgs[] =                  static const int RSA_msgs[] =
2419                          { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };                          { SSH_SMSG_AUTH_RSA_CHALLENGE, SSH_SMSG_FAILURE };
2420                  static const SSHPacketHandler RSA_handlers[]                  static const SSHPacketHandler RSA_handlers[]
2421                  = { handle_rsa_challenge, handle_rsa_auth_refused };                  = { handle_rsa_challenge, handle_rsa_auth_refused };
2422                  static const int TIS_msgs[] =                  static const int TIS_msgs[] =
2423                          { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };                          { SSH_SMSG_AUTH_TIS_CHALLENGE, SSH_SMSG_FAILURE };
2424                  static const SSHPacketHandler TIS_handlers[]                  static const SSHPacketHandler TIS_handlers[]
2425                  = { handle_TIS_challenge, handle_auth_failure };                  = { handle_TIS_challenge, handle_auth_failure };
2426    
2427                  // SSH2の場合は以下の処理をスキップ                  // SSH2の場合は以下の処理をスキップ
2428                  if (SSHv2(pvar))                  if (SSHv2(pvar))
2429                          goto skip_ssh2;                          goto skip_ssh2;
2430    
2431                  switch (cred->method) {                  switch (cred->method) {
2432                  case SSH_AUTH_NONE:                  case SSH_AUTH_NONE:
2433                          return;                          return;
2434                  case SSH_AUTH_PASSWORD:{                  case SSH_AUTH_PASSWORD:{
2435                                  int len = strlen(cred->password);                                  int len = strlen(cred->password);
2436                                  // Round up password length to discourage traffic analysis                                  // Round up password length to discourage traffic analysis
2437                                  int obfuscated_len = obfuscating_round_up(pvar, len);                                  int obfuscated_len = obfuscating_round_up(pvar, len);
2438                                  unsigned char FAR *outmsg =                                  unsigned char FAR *outmsg =
2439                                          begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,                                          begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD,
2440                                                            4 + obfuscated_len);                                                            4 + obfuscated_len);
2441    
2442                                  notify_verbose_message(pvar,                                  notify_verbose_message(pvar,
2443                                                         "Trying PASSWORD authentication...",                                                         "Trying PASSWORD authentication...",
2444                                                         LOG_LEVEL_VERBOSE);                                                         LOG_LEVEL_VERBOSE);
2445    
2446                                  set_uint32(outmsg, obfuscated_len);                                  set_uint32(outmsg, obfuscated_len);
2447                                  memcpy(outmsg + 4, cred->password, len);                                  memcpy(outmsg + 4, cred->password, len);
2448                                  memset(outmsg + 4 + len, 0, obfuscated_len - len);                                  memset(outmsg + 4 + len, 0, obfuscated_len - len);
2449                                                                    
2450                                  // セッション複製時にパスワードを使い回したいので、ここでのリソース解放はやめる。                                  // セッション複製時にパスワードを使い回したいので、ここでのリソース解放はやめる。
2451                                  // socket close時にもこの関数は呼ばれているので、たぶん問題ない。(2005.4.8 yutaka)                                  // socket close時にもこの関数は呼ばれているので、たぶん問題ない。(2005.4.8 yutaka)
2452  #if 0  #if 0
2453                                  //AUTH_destroy_cur_cred(pvar);                                  //AUTH_destroy_cur_cred(pvar);
2454  #endif  #endif
2455                                                                    
2456                                  enque_simple_auth_handlers(pvar);                                  enque_simple_auth_handlers(pvar);
2457                                  break;                                  break;
2458                          }                          }
2459                  case SSH_AUTH_RHOSTS:{                  case SSH_AUTH_RHOSTS:{
2460                                  int len = strlen(cred->rhosts_client_user);                                  int len = strlen(cred->rhosts_client_user);
2461                                  unsigned char FAR *outmsg =                                  unsigned char FAR *outmsg =
2462                                          begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);                                          begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len);
2463    
2464                                  notify_verbose_message(pvar,                                  notify_verbose_message(pvar,
2465                                                         "Trying RHOSTS authentication...",                                                         "Trying RHOSTS authentication...",
2466                                                         LOG_LEVEL_VERBOSE);                                                         LOG_LEVEL_VERBOSE);
2467    
2468                                  set_uint32(outmsg, len);                                  set_uint32(outmsg, len);
2469                                  memcpy(outmsg + 4, cred->rhosts_client_user, len);                                  memcpy(outmsg + 4, cred->rhosts_client_user, len);
2470                                  AUTH_destroy_cur_cred(pvar);                                  AUTH_destroy_cur_cred(pvar);
2471                                  enque_simple_auth_handlers(pvar);                                  enque_simple_auth_handlers(pvar);
2472                                  break;                                  break;
2473                          }                          }
2474                  case SSH_AUTH_RSA:{                  case SSH_AUTH_RSA:{
2475                                  int len = BN_num_bytes(cred->key_pair->RSA_key->n);                                  int len = BN_num_bytes(cred->key_pair->RSA_key->n);
2476                                  unsigned char FAR *outmsg =                                  unsigned char FAR *outmsg =
2477                                          begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);                                          begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len);
2478    
2479                                  notify_verbose_message(pvar,                                  notify_verbose_message(pvar,
2480                                                         "Trying RSA authentication...",                                                         "Trying RSA authentication...",
2481                                                         LOG_LEVEL_VERBOSE);                                                         LOG_LEVEL_VERBOSE);
2482    
2483                                  set_ushort16_MSBfirst(outmsg, len * 8);                                  set_ushort16_MSBfirst(outmsg, len * 8);
2484                                  BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);                                  BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2);
2485                                  /* don't destroy the current credentials yet */                                  /* don't destroy the current credentials yet */
2486                                  enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);                                  enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2487                                  break;                                  break;
2488                          }                          }
2489                  case SSH_AUTH_RHOSTS_RSA:{                  case SSH_AUTH_RHOSTS_RSA:{
2490                                  int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);                                  int mod_len = BN_num_bytes(cred->key_pair->RSA_key->n);
2491                                  int name_len = strlen(cred->rhosts_client_user);                                  int name_len = strlen(cred->rhosts_client_user);
2492                                  int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);                                  int exp_len = BN_num_bytes(cred->key_pair->RSA_key->e);
2493                                  int index;                                  int index;
2494                                  unsigned char FAR *outmsg =                                  unsigned char FAR *outmsg =
2495                                          begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,                                          begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA,
2496                                                            12 + mod_len + name_len + exp_len);                                                            12 + mod_len + name_len + exp_len);
2497    
2498                                  notify_verbose_message(pvar,                                  notify_verbose_message(pvar,
2499                                                         "Trying RHOSTS+RSA authentication...",                                                         "Trying RHOSTS+RSA authentication...",
2500                                                         LOG_LEVEL_VERBOSE);                                                         LOG_LEVEL_VERBOSE);
2501    
2502                                  set_uint32(outmsg, name_len);                                  set_uint32(outmsg, name_len);
2503                                  memcpy(outmsg + 4, cred->rhosts_client_user, name_len);                                  memcpy(outmsg + 4, cred->rhosts_client_user, name_len);
2504                                  index = 4 + name_len;                                  index = 4 + name_len;
2505    
2506                                  set_uint32(outmsg + index, 8 * mod_len);                                  set_uint32(outmsg + index, 8 * mod_len);
2507                                  set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);                                  set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len);
2508                                  BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);                                  BN_bn2bin(cred->key_pair->RSA_key->e, outmsg + index + 6);
2509                                  index += 6 + exp_len;                                  index += 6 + exp_len;
2510    
2511                                  set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);                                  set_ushort16_MSBfirst(outmsg + index, 8 * mod_len);
2512                                  BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);                                  BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + index + 2);
2513                                  /* don't destroy the current credentials yet */                                  /* don't destroy the current credentials yet */
2514                                  enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);                                  enque_handlers(pvar, 2, RSA_msgs, RSA_handlers);
2515                                  break;                                  break;
2516                          }                          }
2517                  case SSH_AUTH_PAGEANT:{                  case SSH_AUTH_PAGEANT:{
2518                                  unsigned char FAR *outmsg;                                  unsigned char FAR *outmsg;
2519                                  unsigned char *pubkey;                                  unsigned char *pubkey;
2520                                  int len, bn_bytes;                                  int len, bn_bytes;
2521    
2522                                  if (pvar->pageant_keycurrent != 0) {                                  if (pvar->pageant_keycurrent != 0) {
2523                                          // 直前の鍵をスキップ                                          // 直前の鍵をスキップ
2524                                          pvar->pageant_curkey += 4;                                          pvar->pageant_curkey += 4;
2525                                          len = get_ushort16_MSBfirst(pvar->pageant_curkey);                                          len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2526                                          bn_bytes = (len + 7) / 8;                                          bn_bytes = (len + 7) / 8;
2527                                          pvar->pageant_curkey += 2 + bn_bytes;                                          pvar->pageant_curkey += 2 + bn_bytes;
2528                                          len = get_ushort16_MSBfirst(pvar->pageant_curkey);                                          len = get_ushort16_MSBfirst(pvar->pageant_curkey);
2529                                          bn_bytes = (len + 7) / 8;                                          bn_bytes = (len + 7) / 8;
2530                                          pvar->pageant_curkey += 2 + bn_bytes;                                          pvar->pageant_curkey += 2 + bn_bytes;
2531                                          // 直前の鍵のコメントをスキップ                                          // 直前の鍵のコメントをスキップ
2532                                          len = get_uint32_MSBfirst(pvar->pageant_curkey);                                          len = get_uint32_MSBfirst(pvar->pageant_curkey);
2533                                          pvar->pageant_curkey += 4 + len;                                          pvar->pageant_curkey += 4 + len;
2534                                          // 次の鍵の位置へ来る                                          // 次の鍵の位置へ来る
2535                                  }                                  }
2536                                  pubkey = pvar->pageant_curkey + 4;                                  pubkey = pvar->pageant_curkey + 4;
2537                                  len = get_ushort16_MSBfirst(pubkey);                                  len = get_ushort16_MSBfirst(pubkey);
2538                                  bn_bytes = (len + 7) / 8;                                  bn_bytes = (len + 7) / 8;
2539                                  pubkey += 2 + bn_bytes;                                  pubkey += 2 + bn_bytes;
2540                               &nbs