Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2739 - (hide annotations) (download) (as text)
Wed Dec 1 15:37:49 2004 UTC (19 years, 4 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 53457 byte(s)
SSH2自動ログイン機能を追加。
現状、パスワード認証のみに対応。
・コマンドライン
  /ssh /auth=認証メソッド /user=ユーザ名 /passwd=パスワード

1 yutakakn 2728 /*
2     Copyright (c) 1998-2001, Robert O'Callahan
3     All rights reserved.
4    
5     Redistribution and use in source and binary forms, with or without modification,
6     are permitted provided that the following conditions are met:
7    
8     Redistributions of source code must retain the above copyright notice, this list of
9     conditions and the following disclaimer.
10    
11     Redistributions in binary form must reproduce the above copyright notice, this list
12     of conditions and the following disclaimer in the documentation and/or other materials
13     provided with the distribution.
14    
15     The name of Robert O'Callahan may not be used to endorse or promote products derived from
16     this software without specific prior written permission.
17    
18     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21     THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27     */
28    
29     /* Teraterm extension mechanism
30     Robert O'Callahan (roc+tt@cs.cmu.edu)
31    
32     Teraterm by Takashi Teranishi (teranishi@rikaxp.riken.go.jp)
33     */
34    
35     #include "ttxssh.h"
36     #include "fwdui.h"
37     #include "util.h"
38    
39     #include <stdlib.h>
40     #include <stdio.h>
41     #include <string.h>
42     #include <io.h>
43     #include <fcntl.h>
44     #include <sys/stat.h>
45     #include <time.h>
46    
47     #include "resource.h"
48     #include <commctrl.h>
49     #include <commdlg.h>
50     #ifdef INET6
51     #include <winsock2.h>
52     static char FAR *ProtocolFamilyList[] = { "UNSPEC", "IPv6", "IPv4", NULL };
53     #else
54     #include <winsock.h>
55     #endif /* INET6 */
56    
57     #define MATCH_STR(s, o) _strnicmp((s), (o), NUM_ELEM(o) - 1)
58    
59     /* This extension implements SSH, so we choose a load order in the
60     "protocols" range. */
61     #define ORDER 2500
62    
63     #ifdef TERATERM32
64     static HICON SecureIcon = NULL;
65     #endif
66    
67     static TInstVar FAR *pvar;
68    
69     #ifdef TERATERM32
70     /* WIN32 allows multiple instances of a DLL */
71     static TInstVar InstVar;
72     #define GET_VAR()
73     #else
74     /* WIN16 does not allow multiple instances of a DLL */
75    
76     /* maximum number of Tera Term instances */
77     #define MAXNUMINST 32
78     /* list of task handles for Tera Term instances */
79     static HANDLE FAR TaskList[MAXNUMINST];
80     /* variable sets for instances */
81     static TInstVar FAR *FAR InstVar[MAXNUMINST];
82    
83     /* Here's how the TS settings work.
84     Whenever the TS settings are read or written to the INI file, then
85     the shared memory containing those settings is updated.
86     When Teraterm starts, the shared memory is read to initialize the TS
87     settings. */
88    
89     /* TS settings shared across instances */
90     static TS_SSH ts_SSH_settings;
91    
92    
93     extern void SSH2_update_cipher_myproposal(PTInstVar pvar);
94    
95    
96     static BOOL NewVar()
97     {
98     int i = 0;
99     HANDLE Task = GetCurrentTask();
100    
101     if (TaskList[0] == NULL)
102    
103     if (Task == NULL)
104     return FALSE;
105     while ((i < MAXNUMINST) && (TaskList[i] != NULL))
106     i++;
107     if (i >= MAXNUMINST)
108     return FALSE;
109     pvar = (TInstVar FAR *) malloc(sizeof(TInstVar));
110     InstVar[i] = pvar;
111     TaskList[i] = Task;
112     return TRUE;
113     }
114    
115     void DelVar()
116     {
117     int i = 0;
118     HANDLE Task = GetCurrentTask();
119    
120     if (Task == NULL)
121     return;
122     while ((i < MAXNUMINST) && (TaskList[i] != Task))
123     i++;
124     if (i >= MAXNUMINST)
125     return;
126     free(TaskList[i]);
127     TaskList[i] = NULL;
128     }
129    
130     BOOL GetVar()
131     {
132     int i = 0;
133     HANDLE Task = GetCurrentTask();
134    
135     if (Task == NULL)
136     return FALSE;
137     while ((i < MAXNUMINST) && (TaskList[i] != Task))
138     i++;
139     if (i >= MAXNUMINST)
140     return FALSE;
141     pvar = InstVar[i];
142     return TRUE;
143     }
144    
145     #define GET_VAR() if (!GetVar()) return
146     #endif
147    
148     /*
149     This code makes lots of assumptions about the order in which Teraterm
150     does things, and how. A key assumption is that the Notification window
151     passed into WSAAsyncSelect is the main terminal window. We also assume
152     that the socket used in the first WSAconnect is the main session socket.
153     */
154    
155     static void init_TTSSH(PTInstVar pvar)
156     {
157     pvar->socket = INVALID_SOCKET;
158     pvar->OldLargeIcon = NULL;
159     pvar->OldSmallIcon = NULL;
160     pvar->NotificationWindow = NULL;
161     pvar->hostdlg_activated = FALSE;
162     pvar->socket = INVALID_SOCKET;
163     pvar->NotificationWindow = NULL;
164     pvar->protocol_major = 0;
165     pvar->protocol_minor = 0;
166    
167     PKT_init(pvar);
168     SSH_init(pvar);
169     CRYPT_init(pvar);
170     AUTH_init(pvar);
171     HOSTS_init(pvar);
172     FWD_init(pvar);
173     FWDUI_init(pvar);
174     }
175    
176     static void uninit_TTSSH(PTInstVar pvar)
177     {
178     SSH_end(pvar);
179     PKT_end(pvar);
180     AUTH_end(pvar);
181     CRYPT_end(pvar);
182     HOSTS_end(pvar);
183     FWD_end(pvar);
184     FWDUI_end(pvar);
185    
186     if (pvar->OldLargeIcon != NULL) {
187     PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_BIG,
188     (LPARAM) pvar->OldLargeIcon);
189     pvar->OldLargeIcon = NULL;
190     }
191     if (pvar->OldSmallIcon != NULL) {
192     PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_SMALL,
193     (LPARAM) pvar->OldSmallIcon);
194     pvar->OldSmallIcon = NULL;
195     }
196     }
197    
198     static void PASCAL FAR TTXInit(PTTSet ts, PComVar cv)
199     {
200     #ifndef TERATERM32
201     if (!NewVar())
202     return; /* should be called first */
203     pvar->ts_SSH = &ts_SSH_settings;
204     #endif
205     pvar->settings = *pvar->ts_SSH;
206     pvar->ts = ts;
207     pvar->cv = cv;
208     pvar->fatal_error = FALSE;
209     pvar->showing_err = FALSE;
210     pvar->err_msg = NULL;
211    
212     init_TTSSH(pvar);
213     }
214    
215     static void normalize_cipher_order(char FAR * buf)
216     {
217     char ciphers_listed[SSH_CIPHER_MAX + 1];
218     char ciphers_allowed[SSH_CIPHER_MAX + 1];
219     int i, j;
220    
221     /* SSH_CIPHER_NONE means that all ciphers below that one are disabled.
222     We *never* allow no encryption. */
223     #if 0
224     static char default_ciphers[] = {
225     SSH_CIPHER_3DES,
226     SSH_CIPHER_NONE,
227     SSH_CIPHER_DES, SSH_CIPHER_BLOWFISH
228     };
229     #else
230     // for SSH2(yutaka)
231     static char default_ciphers[] = {
232     SSH_CIPHER_AES128,
233     SSH_CIPHER_3DES_CBC,
234     SSH_CIPHER_3DES,
235     SSH_CIPHER_NONE,
236     SSH_CIPHER_DES, SSH_CIPHER_BLOWFISH
237     };
238     #endif
239    
240     memset(ciphers_listed, 0, sizeof(ciphers_listed));
241    
242     memset(ciphers_allowed, 0, sizeof(ciphers_allowed));
243     for (i = 0; i < NUM_ELEM(default_ciphers); i++) {
244     ciphers_allowed[default_ciphers[i]] = 1;
245     }
246    
247     for (i = 0; buf[i] != 0; i++) {
248     int cipher_num = buf[i] - '0';
249    
250     if (cipher_num < 0 || cipher_num > SSH_CIPHER_MAX
251     || !ciphers_allowed[cipher_num]
252     || ciphers_listed[cipher_num]) {
253     memmove(buf + i, buf + i + 1, strlen(buf + i + 1) + 1);
254     i--;
255     } else {
256     ciphers_listed[cipher_num] = 1;
257     }
258     }
259    
260     for (j = 0; j < NUM_ELEM(default_ciphers); j++) {
261     int cipher_num = default_ciphers[j];
262    
263     if (!ciphers_listed[cipher_num]) {
264     buf[i] = cipher_num + '0';
265     i++;
266     }
267     }
268    
269     buf[i] = 0;
270     }
271    
272     /* Remove local settings from the shared memory block. */
273     static void clear_local_settings(PTInstVar pvar)
274     {
275     pvar->ts_SSH->TryDefaultAuth = FALSE;
276     }
277    
278     static BOOL read_BOOL_option(PCHAR fileName, char FAR * keyName, BOOL def)
279     {
280     char buf[1024];
281    
282     buf[0] = 0;
283     GetPrivateProfileString("TTSSH", keyName, "", buf, sizeof(buf),
284     fileName);
285     if (buf[0] == 0) {
286     return def;
287     } else {
288     return atoi(buf) != 0 ||
289     stricmp(buf, "yes") == 0 || stricmp(buf, "y") == 0;
290     }
291     }
292    
293     static void read_string_option(PCHAR fileName, char FAR * keyName,
294     char FAR * def, char FAR * buf, int bufSize)
295     {
296    
297     buf[0] = 0;
298     GetPrivateProfileString("TTSSH", keyName, def, buf, bufSize, fileName);
299     }
300    
301     static void read_ssh_options(PTInstVar pvar, PCHAR fileName)
302     {
303     extern void SSH2_update_cipher_myproposal(PTInstVar pvar);
304     char buf[1024];
305     TS_SSH FAR *settings = pvar->ts_SSH;
306    
307     #define READ_STD_STRING_OPTION(name) \
308     read_string_option(fileName, #name, "", settings->name, sizeof(settings->name))
309    
310     settings->Enabled = read_BOOL_option(fileName, "Enabled", FALSE);
311    
312     buf[0] = 0;
313     GetPrivateProfileString("TTSSH", "Compression", "", buf, sizeof(buf),
314     fileName);
315     settings->CompressionLevel = atoi(buf);
316     if (settings->CompressionLevel < 0 || settings->CompressionLevel > 9) {
317     settings->CompressionLevel = 0;
318     }
319    
320     READ_STD_STRING_OPTION(DefaultUserName);
321     READ_STD_STRING_OPTION(DefaultForwarding);
322     READ_STD_STRING_OPTION(DefaultRhostsLocalUserName);
323     READ_STD_STRING_OPTION(DefaultRhostsHostPrivateKeyFile);
324     READ_STD_STRING_OPTION(DefaultRSAPrivateKeyFile);
325    
326     READ_STD_STRING_OPTION(CipherOrder);
327     normalize_cipher_order(settings->CipherOrder);
328     SSH2_update_cipher_myproposal(pvar); // yutaka
329    
330     read_string_option(fileName, "KnownHostsFiles", "ssh_known_hosts",
331     settings->KnownHostsFiles,
332     sizeof(settings->KnownHostsFiles));
333    
334     buf[0] = 0;
335     GetPrivateProfileString("TTSSH", "DefaultAuthMethod", "", buf,
336     sizeof(buf), fileName);
337     settings->DefaultAuthMethod = atoi(buf);
338     if (settings->DefaultAuthMethod != SSH_AUTH_PASSWORD
339     && settings->DefaultAuthMethod != SSH_AUTH_RSA
340     && settings->DefaultAuthMethod != SSH_AUTH_RHOSTS) {
341     /* this default can never be SSH_AUTH_RHOSTS_RSA because that is not a
342     selection in the dialog box; SSH_AUTH_RHOSTS_RSA is automatically chosen
343     when the dialog box has rhosts selected and an host private key file
344     is supplied. */
345     settings->DefaultAuthMethod = SSH_AUTH_PASSWORD;
346     }
347    
348     buf[0] = 0;
349     GetPrivateProfileString("TTSSH", "LogLevel", "", buf, sizeof(buf),
350     fileName);
351     settings->LogLevel = atoi(buf);
352    
353     buf[0] = 0;
354     GetPrivateProfileString("TTSSH", "WriteBufferSize", "", buf,
355     sizeof(buf), fileName);
356     settings->WriteBufferSize = atoi(buf);
357     if (settings->WriteBufferSize <= 0) {
358     settings->WriteBufferSize = 2 * 1024 * 1024;
359     }
360    
361     settings->LocalForwardingIdentityCheck =
362     read_BOOL_option(fileName, "LocalForwardingIdentityCheck", TRUE);
363    
364     // SSH protocol version (2004.10.11 yutaka)
365 yutakakn 2738 // default is SSH2 (2004.11.30 yutaka)
366     settings->ssh_protocol_version = GetPrivateProfileInt("TTSSH", "ProtocolVersion", 2, fileName);
367 yutakakn 2728
368     clear_local_settings(pvar);
369     }
370    
371     static void write_ssh_options(PTInstVar pvar, PCHAR fileName,
372     TS_SSH FAR * settings)
373     {
374     char buf[1024];
375    
376     WritePrivateProfileString("TTSSH", "Enabled",
377     settings->Enabled ? "1" : "0", fileName);
378    
379     _itoa(settings->CompressionLevel, buf, 10);
380     WritePrivateProfileString("TTSSH", "Compression", buf, fileName);
381    
382     WritePrivateProfileString("TTSSH", "DefaultUserName",
383     settings->DefaultUserName, fileName);
384    
385     WritePrivateProfileString("TTSSH", "DefaultForwarding",
386     settings->DefaultForwarding, fileName);
387    
388     WritePrivateProfileString("TTSSH", "CipherOrder",
389     settings->CipherOrder, fileName);
390    
391     WritePrivateProfileString("TTSSH", "KnownHostsFiles",
392     settings->KnownHostsFiles, fileName);
393    
394     WritePrivateProfileString("TTSSH", "DefaultRhostsLocalUserName",
395     settings->DefaultRhostsLocalUserName,
396     fileName);
397    
398     WritePrivateProfileString("TTSSH", "DefaultRhostsHostPrivateKeyFile",
399     settings->DefaultRhostsHostPrivateKeyFile,
400     fileName);
401    
402     WritePrivateProfileString("TTSSH", "DefaultRSAPrivateKeyFile",
403     settings->DefaultRSAPrivateKeyFile,
404     fileName);
405    
406     _itoa(settings->DefaultAuthMethod, buf, 10);
407     WritePrivateProfileString("TTSSH", "DefaultAuthMethod", buf, fileName);
408    
409     _itoa(settings->LogLevel, buf, 10);
410     WritePrivateProfileString("TTSSH", "LogLevel", buf, fileName);
411    
412     _itoa(settings->WriteBufferSize, buf, 10);
413     WritePrivateProfileString("TTSSH", "WriteBufferSize", buf, fileName);
414    
415     WritePrivateProfileString("TTSSH", "LocalForwardingIdentityCheck",
416     settings->
417     LocalForwardingIdentityCheck ? "1" : "0",
418     fileName);
419    
420     // SSH protocol version (2004.10.11 yutaka)
421     WritePrivateProfileString("TTSSH", "ProtocolVersion",
422     settings->ssh_protocol_version==2 ? "2" : "1",
423     fileName);
424    
425     }
426    
427     /* find free port in all protocol family */
428     static unsigned short find_local_port(PTInstVar pvar)
429     {
430     int tries;
431     #ifdef INET6
432     SOCKET connecter;
433     struct addrinfo hints;
434     struct addrinfo FAR *res;
435     struct addrinfo FAR *res0;
436     unsigned short port;
437     char pname[NI_MAXHOST];
438     #endif /* INET6 */
439    
440     if (pvar->session_settings.DefaultAuthMethod != SSH_AUTH_RHOSTS) {
441     return 0;
442     }
443    
444     /* The random numbers here are only used to try to get fresh
445     ports across runs (dangling ports can cause bind errors
446     if we're unlucky). They do not need to be (and are not)
447     cryptographically strong.
448     */
449     srand((unsigned) GetTickCount());
450    
451     #ifdef INET6
452     for (tries = 20; tries > 0; tries--) {
453     memset(&hints, 0, sizeof(hints));
454     hints.ai_family = pvar->ts->ProtocolFamily;
455     hints.ai_flags = AI_PASSIVE;
456     hints.ai_socktype = SOCK_STREAM;
457     port = (unsigned) rand() % 512 + 512;
458     _snprintf(pname, sizeof(pname), "%d", (int) port);
459     if (getaddrinfo(NULL, pname, &hints, &res0)) {
460     return 0;
461     /* NOT REACHED */
462     }
463    
464     for (res = res0; res; res = res->ai_next) {
465     if (res->ai_family == AF_INET || res->ai_family == AF_INET6)
466     continue;
467    
468     connecter =
469     socket(res->ai_family, res->ai_socktype, res->ai_protocol);
470     if (connecter == INVALID_SOCKET) {
471     freeaddrinfo(res0);
472     return 0;
473     }
474    
475     if (bind(connecter, res->ai_addr, res->ai_addrlen) !=
476     SOCKET_ERROR) {
477     return port;
478     freeaddrinfo(res0);
479     closesocket(connecter);
480     } else if (WSAGetLastError() != WSAEADDRINUSE) {
481     closesocket(connecter);
482     freeaddrinfo(res0);
483     return 0;
484     }
485    
486     closesocket(connecter);
487     }
488     freeaddrinfo(res0);
489     }
490    
491     return 0;
492     #else
493     for (tries = 20; tries > 0; tries--) {
494     SOCKET connecter = socket(AF_INET, SOCK_STREAM, 0);
495     struct sockaddr_in connecter_addr;
496    
497     connecter_addr.sin_family = AF_INET;
498     connecter_addr.sin_port = (unsigned) rand() % 512 + 512;
499     connecter_addr.sin_addr.s_addr = htonl(INADDR_ANY);
500    
501     if (connecter == INVALID_SOCKET) {
502     return 0;
503     }
504    
505     if (bind
506     (connecter, (struct sockaddr FAR *) &connecter_addr,
507     sizeof(connecter_addr)) != SOCKET_ERROR) {
508     closesocket(connecter);
509     return connecter_addr.sin_port;
510     } else if (WSAGetLastError() != WSAEADDRINUSE) {
511     closesocket(connecter);
512     return 0;
513     }
514    
515     closesocket(connecter);
516     }
517    
518     return 0;
519     #endif /* INET6 */
520     }
521    
522     static int PASCAL FAR TTXconnect(SOCKET s,
523     const struct sockaddr FAR * name,
524     int namelen)
525     {
526     GET_VAR();
527    
528     #ifdef INET6
529     if (pvar->socket == INVALID_SOCKET) {
530     struct sockaddr_storage ss;
531     int len;
532    
533     pvar->socket = s;
534    
535     memset(&ss, 0, sizeof(ss));
536     switch (pvar->ts->ProtocolFamily) {
537     case AF_INET:
538     len = sizeof(struct sockaddr_in);
539     ((struct sockaddr_in FAR *) &ss)->sin_family = AF_INET;
540     ((struct sockaddr_in FAR *) &ss)->sin_addr.s_addr = INADDR_ANY;
541     ((struct sockaddr_in FAR *) &ss)->sin_port =
542     htons(find_local_port(pvar));
543     break;
544     case AF_INET6:
545     len = sizeof(struct sockaddr_in6);
546     ((struct sockaddr_in6 FAR *) &ss)->sin6_family = AF_INET6;
547     #if 0 /* symbol "in6addr_any" is not included in wsock32.lib */
548     /* if wsock32.lib will be linked, we can't refer "in6addr_any" */
549     ((struct sockaddr_in6 FAR *) &ss)->sin6_addr = in6addr_any;
550     #eles
551     memset(&((struct sockaddr_in6 FAR *) &ss)->sin6_addr, 0,
552     sizeof(struct in_addr6));
553     #endif /* 0 */
554     ((struct sockaddr_in6 FAR *) &ss)->sin6_port =
555     htons(find_local_port(pvar));
556     break;
557     default:
558     /* NOT REACHED */
559     break;
560     }
561    
562     bind(s, (struct sockaddr FAR *) &ss, len);
563     }
564     #else
565     if (pvar->socket == INVALID_SOCKET) {
566     struct sockaddr_in addr;
567    
568     pvar->socket = s;
569    
570     addr.sin_family = AF_INET;
571     addr.sin_port = htons(find_local_port(pvar));
572     addr.sin_addr.s_addr = INADDR_ANY;
573     memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
574    
575     bind(s, (struct sockaddr FAR *) &addr, sizeof(addr));
576     }
577     #endif /* INET6 */
578    
579     return (pvar->Pconnect) (s, name, namelen);
580     }
581    
582     static int PASCAL FAR TTXWSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
583     long lEvent)
584     {
585     GET_VAR();
586    
587     if (s == pvar->socket) {
588     pvar->notification_events = lEvent;
589     pvar->notification_msg = wMsg;
590    
591     if (pvar->NotificationWindow == NULL) {
592     pvar->NotificationWindow = hWnd;
593     AUTH_advance_to_next_cred(pvar);
594     }
595     }
596    
597     return (pvar->PWSAAsyncSelect) (s, hWnd, wMsg, lEvent);
598     }
599    
600     static int PASCAL FAR TTXrecv(SOCKET s, char FAR * buf, int len, int flags)
601     {
602     GET_VAR();
603    
604     if (s == pvar->socket) {
605     return PKT_recv(pvar, buf, len);
606     } else {
607     return (pvar->Precv) (s, buf, len, flags);
608     }
609     }
610    
611     static int PASCAL FAR TTXsend(SOCKET s, char const FAR * buf, int len,
612     int flags)
613     {
614     GET_VAR();
615    
616     if (s == pvar->socket) {
617     SSH_send(pvar, buf, len);
618     return len;
619     } else {
620     return (pvar->Psend) (s, buf, len, flags);
621     }
622     }
623    
624     void notify_established_secure_connection(PTInstVar pvar)
625     {
626     #ifdef TERATERM32
627     if (SecureIcon == NULL) {
628     SecureIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SECURETT));
629     }
630    
631     if (SecureIcon != NULL) {
632     pvar->OldSmallIcon =
633     (HICON) SendMessage(pvar->NotificationWindow, WM_GETICON,
634     ICON_SMALL, 0);
635     pvar->OldLargeIcon =
636     (HICON) SendMessage(pvar->NotificationWindow, WM_GETICON,
637     ICON_BIG, 0);
638     PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_BIG,
639     (LPARAM) SecureIcon);
640     PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_SMALL,
641     (LPARAM) SecureIcon);
642     }
643     #endif
644    
645     notify_verbose_message(pvar, "Entering secure mode",
646     LOG_LEVEL_VERBOSE);
647     }
648    
649     void notify_closed_connection(PTInstVar pvar)
650     {
651     PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
652     pvar->socket, MAKELPARAM(FD_CLOSE, 0));
653    
654     SSH_notify_disconnecting(pvar, NULL);
655     AUTH_notify_disconnecting(pvar);
656     HOSTS_notify_disconnecting(pvar);
657     }
658    
659     static void add_err_msg(PTInstVar pvar, char FAR * msg)
660     {
661     if (pvar->err_msg != NULL) {
662     char FAR *buf =
663     (char FAR *) malloc(strlen(pvar->err_msg) + 3 + strlen(msg));
664    
665     strcpy(buf, pvar->err_msg);
666     strcat(buf, "\n\n");
667     strcat(buf, msg);
668     free(pvar->err_msg);
669     pvar->err_msg = buf;
670     } else {
671     pvar->err_msg = _strdup(msg);
672     }
673     }
674    
675     void notify_nonfatal_error(PTInstVar pvar, char FAR * msg)
676     {
677     if (!pvar->showing_err) {
678     PostMessage(pvar->NotificationWindow, WM_COMMAND,
679     ID_SSHASYNCMESSAGEBOX, 0);
680     }
681     if (msg[0] != 0) {
682     notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
683     add_err_msg(pvar, msg);
684     }
685     }
686    
687     void notify_fatal_error(PTInstVar pvar, char FAR * msg)
688     {
689     if (msg[0] != 0) {
690     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
691     add_err_msg(pvar, msg);
692     }
693    
694     if (!pvar->fatal_error) {
695     pvar->fatal_error = TRUE;
696    
697     SSH_notify_disconnecting(pvar, msg);
698     AUTH_notify_disconnecting(pvar);
699     HOSTS_notify_disconnecting(pvar);
700    
701     PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
702     pvar->socket, MAKELPARAM(FD_CLOSE,
703     (pvar->PWSAGetLastError) ()));
704     }
705     }
706    
707     void notify_verbose_message(PTInstVar pvar, char FAR * msg, int level)
708     {
709     if (level <= pvar->session_settings.LogLevel) {
710     char buf[1024];
711     int file;
712    
713     get_teraterm_dir_relative_name(buf, NUM_ELEM(buf), "TTSSH.LOG");
714     file = _open(buf, _O_RDWR | _O_APPEND | _O_CREAT | _O_TEXT,
715     _S_IREAD | _S_IWRITE);
716    
717     if (file >= 0) {
718     _write(file, msg, strlen(msg));
719     _write(file, "\n", 1);
720     _close(file);
721     }
722     }
723     }
724    
725     static void PASCAL FAR TTXOpenTCP(TTXSockHooks FAR * hooks)
726     {
727     GET_VAR();
728    
729     if (pvar->settings.Enabled) {
730     char buf[1024] = "\nInitiating SSH session at ";
731     struct tm FAR *newtime;
732     time_t long_time;
733    
734     pvar->session_settings = pvar->settings;
735    
736     time(&long_time);
737     newtime = localtime(&long_time);
738     strcat(buf, asctime(newtime));
739     buf[strlen(buf) - 1] = 0;
740     notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
741    
742     FWDUI_load_settings(pvar);
743    
744     pvar->cv->TelAutoDetect = FALSE;
745     /* This next line should not be needed because Teraterm's
746     CommLib should find ts->Telnet == 0 ... but we'll do this
747     just to be on the safe side. */
748     pvar->cv->TelFlag = FALSE;
749    
750     pvar->Precv = *hooks->Precv;
751     pvar->Psend = *hooks->Psend;
752     pvar->PWSAAsyncSelect = *hooks->PWSAAsyncSelect;
753     pvar->Pconnect = *hooks->Pconnect;
754     pvar->PWSAGetLastError = *hooks->PWSAGetLastError;
755    
756     *hooks->Precv = TTXrecv;
757     *hooks->Psend = TTXsend;
758     *hooks->PWSAAsyncSelect = TTXWSAAsyncSelect;
759     *hooks->Pconnect = TTXconnect;
760    
761     SSH_open(pvar);
762     HOSTS_open(pvar);
763     FWDUI_open(pvar);
764     }
765     }
766    
767     static void PASCAL FAR TTXCloseTCP(TTXSockHooks FAR * hooks)
768     {
769     GET_VAR();
770    
771     if (pvar->session_settings.Enabled) {
772     pvar->socket = INVALID_SOCKET;
773    
774     notify_verbose_message(pvar, "Terminating SSH session...",
775     LOG_LEVEL_VERBOSE);
776    
777     *hooks->Precv = pvar->Precv;
778     *hooks->Psend = pvar->Psend;
779     *hooks->PWSAAsyncSelect = pvar->PWSAAsyncSelect;
780     *hooks->Pconnect = pvar->Pconnect;
781     }
782    
783     uninit_TTSSH(pvar);
784     init_TTSSH(pvar);
785     }
786    
787     static void enable_dlg_items(HWND dlg, int from, int to, BOOL enabled)
788     {
789     for (; from <= to; from++) {
790     EnableWindow(GetDlgItem(dlg, from), enabled);
791     }
792     }
793    
794     static BOOL CALLBACK TTXHostDlg(HWND dlg, UINT msg, WPARAM wParam,
795     LPARAM lParam)
796     {
797     static char *ssh_version[] = {"SSH1", "SSH2", NULL};
798     PGetHNRec GetHNRec;
799     char EntName[7];
800     char TempHost[HostNameMaxLength + 1];
801     WORD i, j, w;
802     BOOL Ok;
803    
804     GET_VAR();
805    
806     switch (msg) {
807     case WM_INITDIALOG:
808     GetHNRec = (PGetHNRec) lParam;
809     SetWindowLong(dlg, DWL_USER, lParam);
810    
811     if (GetHNRec->PortType == IdFile)
812     GetHNRec->PortType = IdTCPIP;
813     CheckRadioButton(dlg, IDC_HOSTTCPIP, IDC_HOSTSERIAL,
814     IDC_HOSTTCPIP + GetHNRec->PortType - 1);
815    
816     strcpy(EntName, "Host");
817    
818     i = 1;
819     do {
820     sprintf(&EntName[4], "%d", i);
821     GetPrivateProfileString("Hosts", EntName, "",
822     TempHost, sizeof(TempHost),
823     GetHNRec->SetupFN);
824     if (strlen(TempHost) > 0)
825     SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_ADDSTRING,
826     0, (LPARAM) TempHost);
827     i++;
828     } while ((i <= 99) && (strlen(TempHost) > 0));
829    
830     SendDlgItemMessage(dlg, IDC_HOSTNAME, EM_LIMITTEXT,
831     HostNameMaxLength - 1, 0);
832    
833     SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_SETCURSEL, 0, 0);
834    
835     CheckRadioButton(dlg, IDC_HOSTTELNET, IDC_HOSTOTHER,
836     pvar->settings.Enabled ? IDC_HOSTSSH : GetHNRec->
837     Telnet ? IDC_HOSTTELNET : IDC_HOSTOTHER);
838     SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, EM_LIMITTEXT, 5, 0);
839     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TCPPort, FALSE);
840     #ifdef INET6
841     for (i = 0; ProtocolFamilyList[i]; ++i) {
842     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_ADDSTRING,
843     0, (LPARAM) ProtocolFamilyList[i]);
844     }
845     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, EM_LIMITTEXT,
846     ProtocolFamilyMaxLength - 1, 0);
847     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_SETCURSEL, 0, 0);
848     #endif /* INET6 */
849    
850     /////// SSH version
851     for (i = 0; ssh_version[i]; ++i) {
852     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_ADDSTRING,
853     0, (LPARAM) ssh_version[i]);
854     }
855     SendDlgItemMessage(dlg, IDC_SSH_VERSION, EM_LIMITTEXT,
856     NUM_ELEM(ssh_version) - 1, 0);
857    
858 yutakakn 2734 if (pvar->settings.ssh_protocol_version == 1) {
859     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 0, 0); // SSH1
860     } else {
861 yutakakn 2728 SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 1, 0); // SSH2
862     }
863    
864     if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
865     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE); // enabled
866     } else {
867     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
868     }
869     /////// SSH version
870    
871    
872     j = 0;
873     w = 1;
874     strcpy(EntName, "COM");
875     for (i = 1; i <= GetHNRec->MaxComPort; i++) {
876     sprintf(&EntName[3], "%d", i);
877     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
878     0, (LPARAM) EntName);
879     j++;
880     if (GetHNRec->ComPort == i)
881     w = j;
882     }
883     if (j > 0)
884     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_SETCURSEL, w - 1, 0);
885     else /* All com ports are already used */
886     GetHNRec->PortType = IdTCPIP;
887    
888     if (GetHNRec->PortType == IdTCPIP)
889     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
890     #ifdef INET6
891     else {
892     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
893     FALSE);
894     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
895     IDC_HOSTTCPPROTOCOL, FALSE);
896     }
897     #else
898     else
899     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
900     FALSE);
901     #endif /* INET6 */
902    
903     // Host dialog���t�H�[�J�X�������� (2004.10.2 yutaka)
904     {
905     HWND hwnd = GetDlgItem(dlg, IDC_HOSTNAME);
906 yutakakn 2734
907 yutakakn 2728 SetFocus(hwnd);
908 yutakakn 2734 //SendMessage(hwnd, BM_SETCHECK, BST_CHECKED, 0);
909     //style = GetClassLongPtr(hwnd, GCL_STYLE);
910     //SetClassLongPtr(hwnd, GCL_STYLE, style | WS_TABSTOP);
911 yutakakn 2728 }
912    
913 yutakakn 2734 // SetFocus()���t�H�[�J�X���������������AFALSE�������K�v�������B
914     // TRUE���������ATABSTOP�������������������R���g���[�����I�������B
915     // (2004.11.23 yutaka)
916     return FALSE;
917     //return TRUE;
918 yutakakn 2728
919     case WM_COMMAND:
920     switch (LOWORD(wParam)) {
921     case IDOK:
922     GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
923     if (GetHNRec != NULL) {
924     if (IsDlgButtonChecked(dlg, IDC_HOSTTCPIP)) {
925     #ifdef INET6
926     char afstr[BUFSIZ];
927     #endif /* INET6 */
928     i = GetDlgItemInt(dlg, IDC_HOSTTCPPORT, &Ok, FALSE);
929     if (Ok) {
930     GetHNRec->TCPPort = i;
931     } else {
932     MessageBox(dlg, "Teraterm",
933     "The TCP port must be a number.",
934     MB_OK | MB_ICONEXCLAMATION);
935     return TRUE;
936     }
937     #ifdef INET6
938     #define getaf(str) \
939     ((strcmp((str), "IPv6") == 0) ? AF_INET6 : \
940     ((strcmp((str), "IPv4") == 0) ? AF_INET : AF_UNSPEC))
941     memset(afstr, 0, sizeof(afstr));
942     GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOL, afstr,
943     sizeof(afstr));
944     GetHNRec->ProtocolFamily = getaf(afstr);
945     #endif /* INET6 */
946     GetHNRec->PortType = IdTCPIP;
947     GetDlgItemText(dlg, IDC_HOSTNAME, GetHNRec->HostName,
948     HostNameMaxLength);
949     GetHNRec->Telnet = FALSE;
950     pvar->hostdlg_activated = TRUE;
951     pvar->hostdlg_Enabled = FALSE;
952     if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
953     GetHNRec->Telnet = TRUE;
954     } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
955     pvar->hostdlg_Enabled = TRUE;
956    
957     // check SSH protocol version
958     memset(afstr, 0, sizeof(afstr));
959     GetDlgItemText(dlg, IDC_SSH_VERSION, afstr, sizeof(afstr));
960     if (stricmp(afstr, "SSH1") == 0) {
961     pvar->settings.ssh_protocol_version = 1;
962     } else {
963     pvar->settings.ssh_protocol_version = 2;
964     }
965     }
966     } else {
967     GetHNRec->PortType = IdSerial;
968     GetHNRec->HostName[0] = 0;
969     memset(EntName, 0, sizeof(EntName));
970     GetDlgItemText(dlg, IDC_HOSTCOM, EntName,
971     sizeof(EntName) - 1);
972     GetHNRec->ComPort = (BYTE) (EntName[3]) - 0x30;
973     if (strlen(EntName) > 4)
974     GetHNRec->ComPort =
975     GetHNRec->ComPort * 10 + (BYTE) (EntName[4]) -
976     0x30;
977     }
978     }
979     EndDialog(dlg, 1);
980     return TRUE;
981    
982     case IDCANCEL:
983     EndDialog(dlg, 0);
984     return TRUE;
985    
986     case IDC_HOSTTCPIP:
987     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
988     TRUE);
989     #ifdef INET6
990     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
991     IDC_HOSTTCPPROTOCOL, TRUE);
992     #endif /* INET6 */
993     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
994    
995 yutakakn 2734 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE); // disabled (2004.11.23 yutaka)
996 yutakakn 2728 if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
997     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
998     } else {
999     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1000     }
1001    
1002     return TRUE;
1003    
1004     case IDC_HOSTSERIAL:
1005     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, TRUE);
1006     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1007     FALSE);
1008     #ifdef INET6
1009     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1010     IDC_HOSTTCPPROTOCOL, FALSE);
1011     #endif /* INET6 */
1012     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1013 yutakakn 2734 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1014 yutakakn 2728
1015     return TRUE;
1016    
1017     case IDC_HOSTSSH:
1018     enable_dlg_items(dlg, IDC_SSH_VERSION,
1019     IDC_SSH_VERSION, TRUE);
1020     goto hostssh_enabled;
1021    
1022     case IDC_HOSTTELNET:
1023     case IDC_HOSTOTHER:
1024     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1025     hostssh_enabled:
1026    
1027     GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1028    
1029     if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1030     if (GetHNRec != NULL)
1031     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TelPort,
1032     FALSE);
1033     } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1034     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, 22, FALSE);
1035     }
1036     return TRUE;
1037    
1038     case IDC_HOSTHELP:
1039     PostMessage(GetParent(dlg), WM_USER_DLGHELP2, 0, 0);
1040     }
1041     }
1042     return FALSE;
1043     }
1044    
1045     static BOOL FAR PASCAL TTXGetHostName(HWND parent, PGetHNRec rec)
1046     {
1047     return (BOOL) DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HOSTDLG),
1048     parent, TTXHostDlg, (LONG) rec);
1049     }
1050    
1051     static void PASCAL FAR TTXGetUIHooks(TTXUIHooks FAR * hooks)
1052     {
1053     GET_VAR();
1054    
1055     *hooks->GetHostName = TTXGetHostName;
1056     }
1057    
1058     static void FAR PASCAL TTXReadINIFile(PCHAR fileName, PTTSet ts)
1059     {
1060     GET_VAR();
1061    
1062     (pvar->ReadIniFile) (fileName, ts);
1063     read_ssh_options(pvar, fileName);
1064     pvar->settings = *pvar->ts_SSH;
1065     notify_verbose_message(pvar, "Reading INI file", LOG_LEVEL_VERBOSE);
1066     FWDUI_load_settings(pvar);
1067     }
1068    
1069     static void FAR PASCAL TTXWriteINIFile(PCHAR fileName, PTTSet ts)
1070     {
1071     GET_VAR();
1072    
1073     (pvar->WriteIniFile) (fileName, ts);
1074     *pvar->ts_SSH = pvar->settings;
1075     clear_local_settings(pvar);
1076     notify_verbose_message(pvar, "Writing INI file", LOG_LEVEL_VERBOSE);
1077     write_ssh_options(pvar, fileName, pvar->ts_SSH);
1078     }
1079    
1080     static void read_ssh_options_from_user_file(PTInstVar pvar,
1081     char FAR * user_file_name)
1082     {
1083     if (user_file_name[0] == '.') {
1084     read_ssh_options(pvar, user_file_name);
1085     } else {
1086     char buf[1024];
1087    
1088     get_teraterm_dir_relative_name(buf, sizeof(buf), user_file_name);
1089     read_ssh_options(pvar, buf);
1090     }
1091    
1092     pvar->settings = *pvar->ts_SSH;
1093     FWDUI_load_settings(pvar);
1094     }
1095    
1096     /* returns 1 if the option text must be deleted */
1097     static int parse_option(PTInstVar pvar, char FAR * option)
1098     {
1099     if ((option[0] == '-' || option[0] == '/')) {
1100     if (MATCH_STR(option + 1, "ssh") == 0) {
1101     if (option[4] == 0) {
1102     pvar->settings.Enabled = 1;
1103     } else if (MATCH_STR(option + 4, "-L") == 0
1104     || MATCH_STR(option + 4, "-R") == 0
1105     || stricmp(option + 4, "-X") == 0) {
1106     if (pvar->settings.DefaultForwarding[0] == 0) {
1107     strcpy(pvar->settings.DefaultForwarding, option + 5);
1108     } else {
1109     strcat(pvar->settings.DefaultForwarding, ";");
1110     strcat(pvar->settings.DefaultForwarding, option + 5);
1111     }
1112     } else if (MATCH_STR(option + 4, "-f=") == 0) {
1113     read_ssh_options_from_user_file(pvar, option + 7);
1114     } else if (MATCH_STR(option + 4, "-v") == 0) {
1115     pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
1116     } else if (stricmp(option + 4, "-autologin") == 0
1117     || stricmp(option + 4, "-autologon") == 0) {
1118     pvar->settings.TryDefaultAuth = TRUE;
1119 yutakakn 2739
1120 yutakakn 2728 } else if (MATCH_STR(option + 4, "-consume=") == 0) {
1121     read_ssh_options_from_user_file(pvar, option + 13);
1122     DeleteFile(option + 13);
1123     } else {
1124     char buf[1024];
1125    
1126     _snprintf(buf, sizeof(buf),
1127     "Unrecognized command-line option: %s", option);
1128     buf[sizeof(buf) - 1] = 0;
1129    
1130     MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1131     }
1132    
1133     return 1;
1134     } else if (MATCH_STR(option + 1, "t=") == 0) {
1135     if (strcmp(option + 3, "2") == 0) {
1136     pvar->settings.Enabled = 1;
1137     return 1;
1138     } else {
1139     pvar->settings.Enabled = 0;
1140     }
1141     } else if (MATCH_STR(option + 1, "f=") == 0) {
1142     read_ssh_options_from_user_file(pvar, option + 3);
1143    
1144     // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1145     } else if (MATCH_STR(option + 1, "1") == 0) {
1146     // command line: /ssh /1 is SSH1 only
1147     pvar->settings.ssh_protocol_version = 1;
1148    
1149     } else if (MATCH_STR(option + 1, "2") == 0) {
1150     // command line: /ssh /2 is SSH2 & SSH1
1151     pvar->settings.ssh_protocol_version = 2;
1152    
1153     } else if (MATCH_STR(option + 1, "nossh") == 0) {
1154     // '/nossh' �I�v�V�����������B
1155     // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1156     // �����������������B(2004.10.11 yutaka)
1157     pvar->settings.Enabled = 0;
1158    
1159 yutakakn 2739 } else if (MATCH_STR(option + 1, "auth") == 0) {
1160     // SSH2�������O�C���I�v�V���������� (2004.11.30 yutaka)
1161     //
1162     // SYNOPSIS: /ssh /auth=�F�����\�b�h /user=���[�U�� /passwd=�p�X���[�h
1163     // EXAMPLE: /ssh /auth=password /user=nike "/passwd=a b c"
1164     // NOTICE: �p�X���[�h�����������������������A�I�v�V�����S�������p�������������B
1165     //
1166     pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1167    
1168     if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h�F��
1169     pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1170    
1171     } else {
1172     // TODO:
1173    
1174     }
1175    
1176     } else if (MATCH_STR(option + 1, "user=") == 0) {
1177     _snprintf(pvar->ssh2_username, sizeof(pvar->ssh2_username), "%s", option + 6);
1178    
1179     } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1180     _snprintf(pvar->ssh2_password, sizeof(pvar->ssh2_password), "%s", option + 8);
1181    
1182 yutakakn 2728 }
1183    
1184     }
1185    
1186     return 0;
1187     }
1188    
1189     static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts,
1190     PCHAR DDETopic)
1191     {
1192     int i;
1193     BOOL inParam = FALSE;
1194     BOOL inQuotes = FALSE;
1195     PCHAR option = NULL;
1196     GET_VAR();
1197    
1198     if (pvar->hostdlg_activated) {
1199     pvar->settings.Enabled = pvar->hostdlg_Enabled;
1200     }
1201    
1202     for (i = 0; param[i] != 0; i++) {
1203     if (inQuotes ? param[i] ==
1204     '"' : (param[i] == ' ' || param[i] == '\t')) {
1205     if (option != NULL) {
1206     char ch = param[i];
1207    
1208     param[i] = 0;
1209     if (parse_option
1210     (pvar, *option == '"' ? option + 1 : option)) {
1211     memset(option, ' ', i + 1 - (option - param));
1212     } else {
1213     param[i] = ch;
1214     }
1215     option = NULL;
1216     }
1217     inParam = FALSE;
1218     inQuotes = FALSE;
1219     } else if (!inParam) {
1220     if (param[i] == '"') {
1221     inQuotes = TRUE;
1222     inParam = TRUE;
1223     option = param + i;
1224     } else if (param[i] != ' ' && param[i] != '\t') {
1225     inParam = TRUE;
1226     option = param + i;
1227     }
1228     }
1229     }
1230    
1231     if (option != NULL) {
1232     if (parse_option(pvar, option)) {
1233     memset(option, ' ', i - (option - param));
1234     }
1235     }
1236    
1237     FWDUI_load_settings(pvar);
1238    
1239     (pvar->ParseParam) (param, ts, DDETopic);
1240    
1241     }
1242    
1243     static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks)
1244     {
1245     GET_VAR();
1246    
1247     pvar->ReadIniFile = *hooks->ReadIniFile;
1248     pvar->WriteIniFile = *hooks->WriteIniFile;
1249     pvar->ParseParam = *hooks->ParseParam;
1250    
1251     *hooks->ReadIniFile = TTXReadINIFile;
1252     *hooks->WriteIniFile = TTXWriteINIFile;
1253     *hooks->ParseParam = TTXParseParam;
1254     }
1255    
1256     static void PASCAL FAR TTXSetWinSize(int rows, int cols)
1257     {
1258     GET_VAR();
1259    
1260     SSH_notify_win_size(pvar, cols, rows);
1261     }
1262    
1263     static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
1264     WORD newItemID, char FAR * text)
1265     {
1266     int i, j;
1267    
1268     for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
1269     HMENU submenu = GetSubMenu(menu, i);
1270    
1271     for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
1272     if (GetMenuItemID(submenu, j) == beforeItemID) {
1273     InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID,
1274     text);
1275     return;
1276     }
1277     }
1278     }
1279     }
1280    
1281     static void PASCAL FAR TTXModifyMenu(HMENU menu)
1282     {
1283     GET_VAR();
1284    
1285     /* inserts before ID_HELP_ABOUT */
1286     insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU,
1287     "About &TTSSH...");
1288    
1289     /* inserts before ID_SETUP_TCPIP */
1290     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU,
1291     "SS&H...");
1292     /* inserts before ID_SETUP_TCPIP */
1293     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU,
1294     "SSH &Authentication...");
1295     /* inserts before ID_SETUP_TCPIP */
1296     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU,
1297     "SSH F&orwarding...");
1298     }
1299    
1300     static void append_about_text(HWND dlg, char FAR * prefix, char FAR * msg)
1301     {
1302     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
1303     (LPARAM) prefix);
1304     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0, (LPARAM) msg);
1305     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
1306     (LPARAM) (char FAR *) "\r\n");
1307     }
1308    
1309     static void init_about_dlg(PTInstVar pvar, HWND dlg)
1310     {
1311     char buf[1024];
1312    
1313     // TTSSH�_�C�A���O���\������SSH������������ (2004.10.30 yutaka)
1314    
1315     if (pvar->socket != INVALID_SOCKET) {
1316     if (SSHv1(pvar)) {
1317     SSH_get_server_ID_info(pvar, buf, sizeof(buf));
1318     append_about_text(dlg, "Server ID: ", buf);
1319     SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
1320     append_about_text(dlg, "Using protocol: ", buf);
1321     CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
1322     append_about_text(dlg, "Encryption: ", buf);
1323     CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
1324     append_about_text(dlg, "Server keys: ", buf);
1325     AUTH_get_auth_info(pvar, buf, sizeof(buf));
1326     append_about_text(dlg, "Authentication: ", buf);
1327     SSH_get_compression_info(pvar, buf, sizeof(buf));
1328     append_about_text(dlg, "Compression: ", buf);
1329    
1330     } else { // SSH2
1331     SSH_get_server_ID_info(pvar, buf, sizeof(buf));
1332     append_about_text(dlg, "Server ID: ", buf);
1333    
1334     append_about_text(dlg, "Client ID: ", pvar->client_version_string);
1335    
1336     SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
1337     append_about_text(dlg, "Using protocol: ", buf);
1338    
1339     if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
1340     strcpy(buf, KEX_DH1);
1341     } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
1342     strcpy(buf, KEX_DH14);
1343     } else {
1344     strcpy(buf, KEX_DHGEX);
1345     }
1346     append_about_text(dlg, "KEX: ", buf);
1347    
1348     if (pvar->hostkey_type == KEY_DSA) {
1349     strcpy(buf, "ssh-dss");
1350     } else {
1351     strcpy(buf, "ssh-rsa");
1352     }
1353     append_about_text(dlg, "Host Key: ", buf);
1354    
1355     CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
1356     append_about_text(dlg, "Encryption: ", buf);
1357     CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
1358     append_about_text(dlg, "Server keys: ", buf);
1359     AUTH_get_auth_info(pvar, buf, sizeof(buf));
1360     append_about_text(dlg, "Authentication: ", buf);
1361     SSH_get_compression_info(pvar, buf, sizeof(buf));
1362     append_about_text(dlg, "Compression: ", buf);
1363    
1364     }
1365     }
1366     }
1367    
1368     static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
1369     LPARAM lParam)
1370     {
1371     switch (msg) {
1372     case WM_INITDIALOG:
1373     init_about_dlg((PTInstVar) lParam, dlg);
1374     return TRUE;
1375     case WM_COMMAND:
1376     switch (LOWORD(wParam)) {
1377     case IDOK:
1378     EndDialog(dlg, 1);
1379     return TRUE;
1380     case IDCANCEL: /* there isn't a cancel button, but other Windows
1381     UI things can send this message */
1382     EndDialog(dlg, 0);
1383     return TRUE;
1384     }
1385     break;
1386     }
1387    
1388     return FALSE;
1389     }
1390    
1391     static char FAR *get_cipher_name(int cipher)
1392     {
1393     switch (cipher) {
1394     case SSH_CIPHER_NONE:
1395     return "<ciphers below this line are disabled>";
1396     case SSH_CIPHER_RC4:
1397     return "RC4";
1398     case SSH_CIPHER_3DES:
1399     return "3DES";
1400     case SSH_CIPHER_DES:
1401     return "DES";
1402     case SSH_CIPHER_IDEA:
1403     return "IDEA";
1404     case SSH_CIPHER_TSS:
1405     return "TSS";
1406     case SSH_CIPHER_BLOWFISH:
1407     return "Blowfish";
1408    
1409     // for SSH2(yutaka)
1410     case SSH_CIPHER_AES128:
1411     return "AES128(SSH2)";
1412     case SSH_CIPHER_3DES_CBC:
1413     return "3DES-CBC(SSH2)";
1414    
1415     default:
1416     return NULL;
1417     }
1418     }
1419    
1420     static void set_move_button_status(HWND dlg)
1421     {
1422     HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1423     int curPos = (int) SendMessage(cipherControl, LB_GETCURSEL, 0, 0);
1424     int maxPos = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0) - 1;
1425    
1426     EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERUP), curPos > 0
1427     && curPos <= maxPos);
1428     EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERDOWN), curPos >= 0
1429     && curPos < maxPos);
1430     }
1431    
1432     static void init_setup_dlg(PTInstVar pvar, HWND dlg)
1433     {
1434     HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
1435     HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1436     int i;
1437     int ch;
1438    
1439     SendMessage(compressionControl, TBM_SETRANGE, TRUE, MAKELONG(0, 9));
1440     SendMessage(compressionControl, TBM_SETPOS, TRUE,
1441     pvar->settings.CompressionLevel);
1442    
1443     normalize_cipher_order(pvar->settings.CipherOrder);
1444     SSH2_update_cipher_myproposal(pvar); // yutaka
1445    
1446     for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) {
1447     int cipher = pvar->settings.CipherOrder[i] - '0';
1448     char FAR *name = get_cipher_name(cipher);
1449    
1450     if (name != NULL) {
1451     SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name);
1452     }
1453     }
1454    
1455     SendMessage(cipherControl, LB_SETCURSEL, 0, 0);
1456     set_move_button_status(dlg);
1457    
1458     for (i = 0; (ch = pvar->settings.KnownHostsFiles[i]) != 0 && ch != ';';
1459     i++) {
1460     }
1461     if (ch != 0) {
1462     pvar->settings.KnownHostsFiles[i] = 0;
1463     SetDlgItemText(dlg, IDC_READWRITEFILENAME,
1464     pvar->settings.KnownHostsFiles);
1465     pvar->settings.KnownHostsFiles[i] = ch;
1466     SetDlgItemText(dlg, IDC_READONLYFILENAME,
1467     pvar->settings.KnownHostsFiles + i + 1);
1468     } else {
1469     SetDlgItemText(dlg, IDC_READWRITEFILENAME,
1470     pvar->settings.KnownHostsFiles);
1471     }
1472     }
1473    
1474     void get_teraterm_dir_relative_name(char FAR * buf, int bufsize,
1475     char FAR * basename)
1476     {
1477     int filename_start = 0;
1478     int i;
1479     int ch;
1480    
1481     if (basename[0] == '\\' || basename[0] == '/'
1482     || (basename[0] != 0 && basename[1] == ':')) {
1483     strncpy(buf, basename, bufsize);
1484     buf[bufsize - 1] = 0;
1485     return;
1486     }
1487    
1488     GetModuleFileName(NULL, buf, bufsize);
1489     for (i = 0; (ch = buf[i]) != 0; i++) {
1490     if (ch == '\\' || ch == '/' || ch == ':') {
1491     filename_start = i + 1;
1492     }
1493     }
1494    
1495     if (bufsize > filename_start) {
1496     strncpy(buf + filename_start, basename, bufsize - filename_start);
1497     }
1498     buf[bufsize - 1] = 0;
1499     }
1500    
1501     int copy_teraterm_dir_relative_path(char FAR * dest, int destsize,
1502     char FAR * basename)
1503     {
1504     char buf[1024];
1505     int filename_start = 0;
1506     int i;
1507     int ch, ch2;
1508    
1509     if (basename[0] != '\\' && basename[0] != '/'
1510     && (basename[0] == 0 || basename[1] != ':')) {
1511     strncpy(dest, basename, destsize);
1512     dest[destsize - 1] = 0;
1513     return strlen(dest);
1514     }
1515    
1516     GetModuleFileName(NULL, buf, sizeof(buf));
1517     for (i = 0; (ch = buf[i]) != 0; i++) {
1518     if (ch == '\\' || ch == '/' || ch == ':') {
1519     filename_start = i + 1;
1520     }
1521     }
1522    
1523     for (i = 0; i < filename_start; i++) {
1524     ch = toupper(buf[i]);
1525     ch2 = toupper(basename[i]);
1526    
1527     if (ch == ch2
1528     || ((ch == '\\' || ch == '/')
1529     && (ch2 == '\\' || ch2 == '/'))) {
1530     } else {
1531     break;
1532     }
1533     }
1534    
1535     if (i == filename_start) {
1536     strncpy(dest, basename + i, destsize);
1537     } else {
1538     strncpy(dest, basename, destsize);
1539     }
1540     dest[destsize - 1] = 0;
1541     return strlen(dest);
1542     }
1543    
1544     static void complete_setup_dlg(PTInstVar pvar, HWND dlg)
1545     {
1546     char buf[4096];
1547     char buf2[1024];
1548     HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
1549     HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1550     int i, j, buf2index, bufindex;
1551     int count = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0);
1552    
1553     pvar->settings.CompressionLevel =
1554     (int) SendMessage(compressionControl, TBM_GETPOS, 0, 0);
1555    
1556     buf2index = 0;
1557     for (i = 0; i < count; i++) {
1558     int len = SendMessage(cipherControl, LB_GETTEXTLEN, i, 0);
1559    
1560     if (len > 0 && len < sizeof(buf)) { /* should always be true */
1561     buf[0] = 0;
1562     SendMessage(cipherControl, LB_GETTEXT, i, (LPARAM) buf);
1563     for (j = 0;
1564     j <= SSH_CIPHER_MAX
1565     && strcmp(buf, get_cipher_name(j)) != 0; j++) {
1566     }
1567     if (j <= SSH_CIPHER_MAX) {
1568     buf2[buf2index] = '0' + j;
1569     buf2index++;
1570     }
1571     }
1572     }
1573     buf2[buf2index] = 0;
1574     normalize_cipher_order(buf2);
1575     strcpy(pvar->settings.CipherOrder, buf2);
1576     SSH2_update_cipher_myproposal(pvar); // yutaka
1577    
1578     buf[0] = 0;
1579     GetDlgItemText(dlg, IDC_READWRITEFILENAME, buf, sizeof(buf));
1580     j = copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles,
1581     sizeof(pvar->settings.
1582     KnownHostsFiles), buf);
1583     buf[0] = 0;
1584     bufindex = 0;
1585     GetDlgItemText(dlg, IDC_READONLYFILENAME, buf, sizeof(buf));
1586     for (i = 0; buf[i] != 0; i++) {
1587     if (buf[i] == ';') {
1588     buf[i] = 0;
1589     if (j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
1590     pvar->settings.KnownHostsFiles[j] = ';';
1591     j++;
1592     j += copy_teraterm_dir_relative_path(pvar->settings.
1593     KnownHostsFiles + j,
1594     sizeof(pvar->settings.
1595     KnownHostsFiles)
1596     - j, buf + bufindex);
1597     }
1598     bufindex = i + 1;
1599     }
1600     }
1601     if (bufindex < i && j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
1602     pvar->settings.KnownHostsFiles[j] = ';';
1603     j++;
1604     copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles + j,
1605     sizeof(pvar->settings.
1606     KnownHostsFiles) - j,
1607     buf + bufindex);
1608     }
1609     }
1610    
1611     static void move_cur_sel_delta(HWND listbox, int delta)
1612     {
1613     int curPos = (int) SendMessage(listbox, LB_GETCURSEL, 0, 0);
1614     int maxPos = (int) SendMessage(listbox, LB_GETCOUNT, 0, 0) - 1;
1615     int newPos = curPos + delta;
1616     char buf[1024];
1617    
1618     if (curPos >= 0 && newPos >= 0 && newPos <= maxPos) {
1619     int len = SendMessage(listbox, LB_GETTEXTLEN, curPos, 0);
1620    
1621     if (len > 0 && len < sizeof(buf)) { /* should always be true */
1622     buf[0] = 0;
1623     SendMessage(listbox, LB_GETTEXT, curPos, (LPARAM) buf);
1624     SendMessage(listbox, LB_DELETESTRING, curPos, 0);
1625     SendMessage(listbox, LB_INSERTSTRING, newPos,
1626     (LPARAM) (char FAR *) buf);
1627     SendMessage(listbox, LB_SETCURSEL, newPos, 0);
1628     }
1629     }
1630     }
1631    
1632     static int get_keys_file_name(HWND parent, char FAR * buf, int bufsize,
1633     int readonly)
1634     {
1635     #ifdef TERATERM32
1636     OPENFILENAME params;
1637     char fullname_buf[2048] = "ssh_known_hosts";
1638    
1639     params.lStructSize = sizeof(OPENFILENAME);
1640     params.hwndOwner = parent;
1641     params.lpstrFilter = NULL;
1642     params.lpstrCustomFilter = NULL;
1643     params.nFilterIndex = 0;
1644     buf[0] = 0;
1645     params.lpstrFile = fullname_buf;
1646     params.nMaxFile = sizeof(fullname_buf);
1647     params.lpstrFileTitle = NULL;
1648     params.lpstrInitialDir = NULL;
1649     params.lpstrTitle =
1650     readonly ? "Choose a read-only known-hosts file to add" :
1651     "Choose a read/write known-hosts file";
1652     params.Flags = (readonly ? OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST : 0)
1653     | OFN_HIDEREADONLY | (!readonly ? OFN_NOREADONLYRETURN : 0);
1654     params.lpstrDefExt = NULL;
1655    
1656     if (GetOpenFileName(&params) != 0) {
1657     copy_teraterm_dir_relative_path(buf, bufsize, fullname_buf);
1658     return 1;
1659     } else {
1660     int err = CommDlgExtendedError();
1661    
1662     if (err != 0) {
1663     char buf[1024];
1664    
1665     _snprintf(buf, sizeof(buf),
1666     "Cannot show file dialog box: error %d", err);
1667     buf[sizeof(buf) - 1] = 0;
1668     MessageBox(parent, buf, "TTSSH Error",
1669     MB_OK | MB_ICONEXCLAMATION);
1670     }
1671    
1672     return 0;
1673     }
1674     #else
1675     return 0;
1676     #endif
1677     }
1678    
1679     static void choose_read_write_file(HWND dlg)
1680     {
1681     char buf[1024];
1682    
1683     if (get_keys_file_name(dlg, buf, sizeof(buf), 0)) {
1684     SetDlgItemText(dlg, IDC_READWRITEFILENAME, buf);
1685     }
1686     }
1687    
1688     static void choose_read_only_file(HWND dlg)
1689     {
1690     char buf[1024];
1691     char buf2[4096];
1692    
1693     if (get_keys_file_name(dlg, buf, sizeof(buf), 1)) {
1694     buf2[0] = 0;
1695     GetDlgItemText(dlg, IDC_READONLYFILENAME, buf2, sizeof(buf2));
1696     if (buf2[0] != 0 && buf2[strlen(buf2) - 1] != ';') {
1697     strncat(buf2, ";", sizeof(buf2));
1698     }
1699     strncat(buf2, buf, sizeof(buf2));
1700     SetDlgItemText(dlg, IDC_READONLYFILENAME, buf2);
1701     }
1702     }
1703    
1704     static BOOL CALLBACK TTXSetupDlg(HWND dlg, UINT msg, WPARAM wParam,
1705     LPARAM lParam)
1706     {
1707     switch (msg) {
1708     case WM_INITDIALOG:
1709     SetWindowLong(dlg, DWL_USER, lParam);
1710     init_setup_dlg((PTInstVar) lParam, dlg);
1711     return TRUE;
1712     case WM_COMMAND:
1713     switch (LOWORD(wParam)) {
1714     case IDOK:
1715     complete_setup_dlg((PTInstVar) GetWindowLong(dlg, DWL_USER),
1716     dlg);
1717     EndDialog(dlg, 1);
1718     return TRUE;
1719     case IDCANCEL: /* there isn't a cancel button, but other Windows
1720     UI things can send this message */
1721     EndDialog(dlg, 0);
1722     return TRUE;
1723     case IDC_SSHMOVECIPHERUP:
1724     move_cur_sel_delta(GetDlgItem(dlg, IDC_SSHCIPHERPREFS), -1);
1725     set_move_button_status(dlg);
1726     SetFocus(GetDlgItem(dlg, IDC_SSHCIPHERPREFS));
1727     return TRUE;
1728     case IDC_SSHMOVECIPHERDOWN:
1729     move_cur_sel_delta(GetDlgItem(dlg, IDC_SSHCIPHERPREFS), 1);
1730     set_move_button_status(dlg);
1731     SetFocus(GetDlgItem(dlg, IDC_SSHCIPHERPREFS));
1732     return TRUE;
1733     case IDC_SSHCIPHERPREFS:
1734     set_move_button_status(dlg);
1735     return TRUE;
1736     case IDC_CHOOSEREADWRITEFILE:
1737     choose_read_write_file(dlg);
1738     return TRUE;
1739     case IDC_CHOOSEREADONLYFILE:
1740     choose_read_only_file(dlg);
1741     return TRUE;
1742     }
1743     break;
1744     }
1745    
1746     return FALSE;
1747     }
1748    
1749     static int PASCAL FAR TTXProcessCommand(HWND hWin, WORD cmd)
1750     {
1751     GET_VAR();
1752    
1753     if (pvar->fatal_error) {
1754     return 0;
1755     }
1756    
1757     switch (cmd) {
1758     case ID_ABOUTMENU:
1759     if (DialogBoxParam
1760     (hInst, MAKEINTRESOURCE(IDD_ABOUTDIALOG), hWin, TTXAboutDlg,
1761     (LPARAM) pvar)
1762     == -1) {
1763     MessageBox(hWin, "Cannot create About box window.",
1764     "TTSSH Error", MB_OK | MB_ICONEXCLAMATION);
1765     }
1766     return 1;
1767     case ID_SSHAUTH:
1768     AUTH_do_cred_dialog(pvar);
1769     return 1;
1770     case ID_SSHSETUPMENU:
1771     if (DialogBoxParam
1772     (hInst, MAKEINTRESOURCE(IDD_SSHSETUP), hWin, TTXSetupDlg,
1773     (LPARAM) pvar)
1774     == -1) {
1775     MessageBox(hWin, "Cannot create TTSSH Setup window.",
1776     "TTSSH Error", MB_OK | MB_ICONEXCLAMATION);
1777     }
1778     return 1;
1779     case ID_SSHAUTHSETUPMENU:
1780     AUTH_do_default_cred_dialog(pvar);
1781     return 1;
1782     case ID_SSHFWDSETUPMENU:
1783     FWDUI_do_forwarding_dialog(pvar);
1784     return 1;
1785     case ID_SSHUNKNOWNHOST:
1786     HOSTS_do_unknown_host_dialog(hWin, pvar);
1787     return 1;
1788     case ID_SSHDIFFERENTHOST:
1789     HOSTS_do_different_host_dialog(hWin, pvar);
1790     return 1;
1791     case ID_SSHASYNCMESSAGEBOX:
1792     if (pvar->err_msg != NULL) {
1793     char FAR *msg = pvar->err_msg;
1794    
1795     /* Could there be a buffer overrun bug anywhere in Win32
1796     MessageBox? Who knows? I'm paranoid. */
1797     if (strlen(msg) > 2048) {
1798     msg[2048] = 0;
1799     }
1800    
1801     pvar->showing_err = TRUE;
1802     pvar->err_msg = NULL;
1803     MessageBox(NULL, msg, "TTSSH",
1804     MB_TASKMODAL | MB_ICONEXCLAMATION);
1805     free(msg);
1806     pvar->showing_err = FALSE;
1807     if (pvar->err_msg != NULL) {
1808     PostMessage(hWin, WM_COMMAND, ID_SSHASYNCMESSAGEBOX, 0);
1809     } else {
1810     AUTH_notify_end_error(pvar);
1811     }
1812     }
1813     return 1;
1814     default:
1815     return 0;
1816     }
1817     }
1818    
1819     static void PASCAL FAR TTXSetCommandLine(PCHAR cmd, int cmdlen,
1820     PGetHNRec rec)
1821     {
1822     char tmpFile[MAX_PATH];
1823     char tmpPath[1024];
1824     char buf[1024];
1825     int i;
1826     GET_VAR();
1827    
1828     GetTempPath(sizeof(tmpPath), tmpPath);
1829     GetTempFileName(tmpPath, "TTX", 0, tmpFile);
1830    
1831     for (i = 0; cmd[i] != ' ' && cmd[i] != 0; i++) {
1832     }
1833    
1834     if (i < cmdlen) {
1835     strncpy(buf, cmd + i, sizeof(buf));
1836     cmd[i] = 0;
1837    
1838     write_ssh_options(pvar, tmpFile, &pvar->settings);
1839    
1840     strncat(cmd, " /ssh-consume=", cmdlen);
1841     strncat(cmd, tmpFile, cmdlen);
1842    
1843     strncat(cmd, buf, cmdlen);
1844    
1845     if (pvar->hostdlg_Enabled) {
1846     strncat(cmd, " /ssh", cmdlen);
1847    
1848     // add option of SSH protcol version (2004.10.11 yutaka)
1849     if (pvar->settings.ssh_protocol_version == 2) {
1850     strncat(cmd, " /2", cmdlen);
1851     } else {
1852     strncat(cmd, " /1", cmdlen);
1853     }
1854    
1855     }
1856     }
1857     }
1858    
1859     /* This function is called when Teraterm is quitting. You can use it to clean
1860     up.
1861    
1862     This function is called for each extension, in reverse load order (see
1863     below).
1864     */
1865     static void PASCAL FAR TTXEnd(void)
1866     {
1867     GET_VAR();
1868    
1869     uninit_TTSSH(pvar);
1870    
1871     if (pvar->err_msg != NULL) {
1872     /* Could there be a buffer overrun bug anywhere in Win32
1873     MessageBox? Who knows? I'm paranoid. */
1874     if (strlen(pvar->err_msg) > 2048) {
1875     pvar->err_msg[2048] = 0;
1876     }
1877    
1878     MessageBox(NULL, pvar->err_msg, "TTSSH",
1879     MB_TASKMODAL | MB_ICONEXCLAMATION);
1880    
1881     free(pvar->err_msg);
1882     pvar->err_msg = NULL;
1883     }
1884     #ifndef TERATERM32
1885     DelVar();
1886     #endif
1887     }
1888    
1889     /* This record contains all the information that the extension forwards to the
1890     main Teraterm code. It mostly consists of pointers to the above functions.
1891     Any of the function pointers can be replaced with NULL, in which case
1892     Teraterm will just ignore that function and assume default behaviour, which
1893     means "do nothing".
1894     */
1895     static TTXExports Exports = {
1896     /* This must contain the size of the structure. See below for its usage. */
1897     sizeof(TTXExports),
1898     ORDER,
1899    
1900     /* Now we just list the functions that we've implemented. */
1901     TTXInit,
1902     TTXGetUIHooks,
1903     TTXGetSetupHooks,
1904     TTXOpenTCP,
1905     TTXCloseTCP,
1906     TTXSetWinSize,
1907     TTXModifyMenu,
1908     NULL,
1909     TTXProcessCommand,
1910     TTXEnd,
1911     TTXSetCommandLine
1912     };
1913    
1914     #ifdef TERATERM32
1915     BOOL __declspec(dllexport)
1916     PASCAL FAR TTXBind(WORD Version, TTXExports FAR * exports)
1917     {
1918     #else
1919     BOOL __export PASCAL FAR TTXBind(WORD Version, TTXExports FAR * exports)
1920     {
1921     #endif
1922     int size = sizeof(Exports) - sizeof(exports->size);
1923     /* do version checking if necessary */
1924     /* if (Version!=TTVERSION) return FALSE; */
1925    
1926     if (size > exports->size) {
1927     size = exports->size;
1928     }
1929     memcpy((char FAR *) exports + sizeof(exports->size),
1930     (char FAR *) &Exports + sizeof(exports->size), size);
1931     return TRUE;
1932     }
1933    
1934     #ifdef TERATERM32
1935     static HANDLE __mem_mapping = NULL;
1936    
1937     BOOL WINAPI DllMain(HANDLE hInstance,
1938     ULONG ul_reason_for_call, LPVOID lpReserved)
1939     {
1940     switch (ul_reason_for_call) {
1941     case DLL_THREAD_ATTACH:
1942     /* do thread initialization */
1943     break;
1944     case DLL_THREAD_DETACH:
1945     /* do thread cleanup */
1946     break;
1947     case DLL_PROCESS_ATTACH:
1948     /* do process initialization */
1949     DisableThreadLibraryCalls(hInstance);
1950     hInst = hInstance;
1951     pvar = &InstVar;
1952     __mem_mapping =
1953     CreateFileMapping((HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0,
1954     sizeof(TS_SSH), "TTSSH_1-4_TS_data");
1955     if (__mem_mapping == NULL) {
1956     /* fake it. The settings won't be shared, but what the heck. */
1957     pvar->ts_SSH = NULL;
1958     } else {
1959     pvar->ts_SSH =
1960     (TS_SSH *) MapViewOfFile(__mem_mapping, FILE_MAP_WRITE, 0,
1961     0, 0);
1962     }
1963     if (pvar->ts_SSH == NULL) {
1964     /* fake it. The settings won't be shared, but what the heck. */
1965     pvar->ts_SSH = (TS_SSH *) malloc(sizeof(TS_SSH));
1966     if (__mem_mapping != NULL) {
1967     CloseHandle(__mem_mapping);
1968     }
1969     }
1970     break;
1971     case DLL_PROCESS_DETACH:
1972     /* do process cleanup */
1973     if (__mem_mapping == NULL) {
1974     free(pvar->ts_SSH);
1975     } else {
1976     CloseHandle(__mem_mapping);
1977     UnmapViewOfFile(pvar->ts_SSH);
1978     }
1979     break;
1980     }
1981     return TRUE;
1982     }
1983     #else
1984     #ifdef WATCOM
1985     #pragma off (unreferenced);
1986     #endif
1987     int CALLBACK LibMain(HANDLE hInstance, WORD wDataSegment,
1988     WORD wHeapSize, LPSTR lpszCmdLine)
1989     #ifdef WATCOM
1990     #pragma on (unreferenced);
1991     #endif
1992     {
1993     int i;
1994     for (i = 0; i < MAXNUMINST; i++)
1995     TaskList[i] = NULL;
1996     hInst = hInstance;
1997     return (1);
1998     }
1999     #endif
2000 yutakakn 2734
2001    
2002     /*
2003     * $Log: not supported by cvs2svn $
2004 yutakakn 2739 * Revision 1.3 2004/11/29 15:52:37 yutakakn
2005     * SSH��default protocol��SSH2�������B
2006     *
2007 yutakakn 2738 * Revision 1.2 2004/11/23 14:32:26 yutakakn
2008     * �����_�C�A���O���N�������ATCP/IP���u�z�X�g���v���t�H�[�J�X�������������������B
2009 yutakakn 2734 *
2010 yutakakn 2738 *
2011 yutakakn 2734 */

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26