1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Changes from executor:

- NetHack keypad mode (Shift only works with NumLock off)
 - Alt-Space handling (best I could manage; not too bad considering)
 - Event Log rather than Telnet Negotiation Log

[originally from svn r284]
This commit is contained in:
Simon Tatham 1999-11-09 11:10:04 +00:00
parent 59e798fc6d
commit f6c63320ea
10 changed files with 189 additions and 65 deletions

View File

@ -114,6 +114,9 @@ typedef struct {
int linux_funkeys; int linux_funkeys;
int app_cursor; int app_cursor;
int app_keypad; int app_keypad;
int nethack_keypad;
int alt_f4; /* is it special? */
int alt_space; /* is it special? */
/* Terminal options */ /* Terminal options */
int savelines; int savelines;
int dec_om; int dec_om;
@ -186,8 +189,8 @@ void random_save_seed(void);
int do_config (void); int do_config (void);
int do_reconfig (HWND); int do_reconfig (HWND);
void do_defaults (char *); void do_defaults (char *);
void lognegot (char *); void logevent (char *);
void shownegot (HWND); void showeventlog (HWND);
void showabout (HWND); void showabout (HWND);
void verify_ssh_host_key(char *host, struct RSAKey *key); void verify_ssh_host_key(char *host, struct RSAKey *key);
void get_sesslist(int allocate); void get_sesslist(int allocate);

67
ssh.c
View File

@ -251,9 +251,10 @@ static int ssh_versioncmp(char *a, char *b) {
} }
static int do_ssh_init(void) { static int do_ssh_init(void) {
char c; char c, *vsp;
char version[10]; char version[10];
char vstring[40]; char vstring[80];
char vlog[sizeof(vstring)+20];
int i; int i;
#ifdef FWHACK #ifdef FWHACK
@ -269,11 +270,15 @@ static int do_ssh_init(void) {
if (s_read(&c,1) != 1 || c != 'S') return 0; if (s_read(&c,1) != 1 || c != 'S') return 0;
if (s_read(&c,1) != 1 || c != 'H') return 0; if (s_read(&c,1) != 1 || c != 'H') return 0;
#endif #endif
strcpy(vstring, "SSH-");
vsp = vstring+4;
if (s_read(&c,1) != 1 || c != '-') return 0; if (s_read(&c,1) != 1 || c != '-') return 0;
i = 0; i = 0;
while (1) { while (1) {
if (s_read(&c,1) != 1) if (s_read(&c,1) != 1)
return 0; return 0;
if (vsp < vstring+sizeof(vstring)-1)
*vsp++ = c;
if (i >= 0) { if (i >= 0) {
if (c == '-') { if (c == '-') {
version[i] = '\0'; version[i] = '\0';
@ -285,8 +290,16 @@ static int do_ssh_init(void) {
break; break;
} }
*vsp = 0;
sprintf(vlog, "Server version: %s", vstring);
vlog[strcspn(vlog, "\r\n")] = '\0';
logevent(vlog);
sprintf(vstring, "SSH-%s-PuTTY\n", sprintf(vstring, "SSH-%s-PuTTY\n",
(ssh_versioncmp(version, "1.5") <= 0 ? version : "1.5")); (ssh_versioncmp(version, "1.5") <= 0 ? version : "1.5"));
sprintf(vlog, "We claim version: %s", vstring);
vlog[strcspn(vlog, "\r\n")] = '\0';
logevent(vlog);
s_write(vstring, strlen(vstring)); s_write(vstring, strlen(vstring));
return 1; return 1;
} }
@ -315,14 +328,33 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
if (pktin.type != SSH_SMSG_PUBLIC_KEY) if (pktin.type != SSH_SMSG_PUBLIC_KEY)
fatalbox("Public key packet not received"); fatalbox("Public key packet not received");
memcpy(cookie, pktin.body, 8); logevent("Received public keys");
MD5Init(&md5c); memcpy(cookie, pktin.body, 8);
i = makekey(pktin.body+8, &servkey, &keystr1); i = makekey(pktin.body+8, &servkey, &keystr1);
j = makekey(pktin.body+8+i, &hostkey, &keystr2); j = makekey(pktin.body+8+i, &hostkey, &keystr2);
/*
* Hash the host key and print the hash in the log box. Just as
* a last resort in case the registry's host key checking is
* compromised, we'll allow the user some ability to verify
* host keys by eye.
*/
MD5Init(&md5c);
MD5Update(&md5c, keystr2, hostkey.bytes);
MD5Final(session_id, &md5c);
{
char logmsg[80];
int i;
logevent("Host key MD5 is:");
strcpy(logmsg, " ");
for (i = 0; i < 16; i++)
sprintf(logmsg+strlen(logmsg), "%02x", session_id[i]);
logevent(logmsg);
}
supported_ciphers_mask = ((pktin.body[12+i+j] << 24) | supported_ciphers_mask = ((pktin.body[12+i+j] << 24) |
(pktin.body[13+i+j] << 16) | (pktin.body[13+i+j] << 16) |
(pktin.body[14+i+j] << 8) | (pktin.body[14+i+j] << 8) |
@ -333,6 +365,8 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
(pktin.body[18+i+j] << 8) | (pktin.body[18+i+j] << 8) |
(pktin.body[19+i+j])); (pktin.body[19+i+j]));
MD5Init(&md5c);
MD5Update(&md5c, keystr2, hostkey.bytes); MD5Update(&md5c, keystr2, hostkey.bytes);
MD5Update(&md5c, keystr1, servkey.bytes); MD5Update(&md5c, keystr1, servkey.bytes);
MD5Update(&md5c, pktin.body, 8); MD5Update(&md5c, pktin.body, 8);
@ -364,6 +398,8 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
rsaencrypt(rsabuf, hostkey.bytes, &servkey); rsaencrypt(rsabuf, hostkey.bytes, &servkey);
} }
logevent("Encrypted session key");
cipher_type = cfg.cipher == CIPHER_BLOWFISH ? SSH_CIPHER_BLOWFISH : cipher_type = cfg.cipher == CIPHER_BLOWFISH ? SSH_CIPHER_BLOWFISH :
cfg.cipher == CIPHER_DES ? SSH_CIPHER_DES : cfg.cipher == CIPHER_DES ? SSH_CIPHER_DES :
SSH_CIPHER_3DES; SSH_CIPHER_3DES;
@ -371,6 +407,11 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
c_write("Selected cipher not supported, falling back to 3DES\r\n", 53); c_write("Selected cipher not supported, falling back to 3DES\r\n", 53);
cipher_type = SSH_CIPHER_3DES; cipher_type = SSH_CIPHER_3DES;
} }
switch (cipher_type) {
case SSH_CIPHER_3DES: logevent("Using 3DES encryption"); break;
case SSH_CIPHER_DES: logevent("Using single-DES encryption"); break;
case SSH_CIPHER_BLOWFISH: logevent("Using Blowfish encryption"); break;
}
s_wrpkt_start(SSH_CMSG_SESSION_KEY, len+15); s_wrpkt_start(SSH_CMSG_SESSION_KEY, len+15);
pktout.body[0] = cipher_type; pktout.body[0] = cipher_type;
@ -381,6 +422,7 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
pktout.body[len+11] = pktout.body[len+12] = 0; /* protocol flags */ pktout.body[len+11] = pktout.body[len+12] = 0; /* protocol flags */
pktout.body[len+13] = pktout.body[len+14] = 0; pktout.body[len+13] = pktout.body[len+14] = 0;
s_wrpkt(); s_wrpkt();
logevent("Trying to enable encryption...");
free(rsabuf); free(rsabuf);
@ -394,6 +436,8 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
if (pktin.type != SSH_SMSG_SUCCESS) if (pktin.type != SSH_SMSG_SUCCESS)
fatalbox("Encryption not successfully enabled"); fatalbox("Encryption not successfully enabled");
logevent("Successfully started encryption");
fflush(stdout); fflush(stdout);
{ {
static char username[100]; static char username[100];
@ -442,6 +486,11 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
c_write(stuff, strlen(stuff)); c_write(stuff, strlen(stuff));
} }
s_wrpkt_start(SSH_CMSG_USER, 4+strlen(username)); s_wrpkt_start(SSH_CMSG_USER, 4+strlen(username));
{
char userlog[20+sizeof(username)];
sprintf(userlog, "Sent username \"%s\"", username);
logevent(userlog);
}
pktout.body[0] = pktout.body[1] = pktout.body[2] = 0; pktout.body[0] = pktout.body[1] = pktout.body[2] = 0;
pktout.body[3] = strlen(username); pktout.body[3] = strlen(username);
memcpy(pktout.body+4, username, strlen(username)); memcpy(pktout.body+4, username, strlen(username));
@ -465,16 +514,19 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
cfg.try_tis_auth && cfg.try_tis_auth &&
(supported_auths_mask & (1<<SSH_AUTH_TIS))) { (supported_auths_mask & (1<<SSH_AUTH_TIS))) {
pwpkt_type = SSH_CMSG_AUTH_TIS_RESPONSE; pwpkt_type = SSH_CMSG_AUTH_TIS_RESPONSE;
logevent("Requested TIS authentication");
s_wrpkt_start(SSH_CMSG_AUTH_TIS, 0); s_wrpkt_start(SSH_CMSG_AUTH_TIS, 0);
s_wrpkt(); s_wrpkt();
do { crReturnV; } while (!ispkt); do { crReturnV; } while (!ispkt);
if (pktin.type != SSH_SMSG_AUTH_TIS_CHALLENGE) { if (pktin.type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
logevent("TIS authentication declined");
c_write("TIS authentication refused.\r\n", 29); c_write("TIS authentication refused.\r\n", 29);
} else { } else {
int challengelen = ((pktin.body[0] << 24) | int challengelen = ((pktin.body[0] << 24) |
(pktin.body[1] << 16) | (pktin.body[1] << 16) |
(pktin.body[2] << 8) | (pktin.body[2] << 8) |
(pktin.body[3])); (pktin.body[3]));
logevent("Received TIS challenge");
c_write(pktin.body+4, challengelen); c_write(pktin.body+4, challengelen);
} }
} }
@ -512,15 +564,19 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
pktout.body[3] = strlen(password); pktout.body[3] = strlen(password);
memcpy(pktout.body+4, password, strlen(password)); memcpy(pktout.body+4, password, strlen(password));
s_wrpkt(); s_wrpkt();
logevent("Sent password");
memset(password, 0, strlen(password)); memset(password, 0, strlen(password));
do { crReturnV; } while (!ispkt); do { crReturnV; } while (!ispkt);
if (pktin.type == 15) { if (pktin.type == 15) {
c_write("Access denied\r\n", 15); c_write("Access denied\r\n", 15);
logevent("Authentication refused");
} else if (pktin.type != 14) { } else if (pktin.type != 14) {
fatalbox("Strange packet received, type %d", pktin.type); fatalbox("Strange packet received, type %d", pktin.type);
} }
} }
logevent("Authentication successful");
if (!cfg.nopty) { if (!cfg.nopty) {
i = strlen(cfg.termtype); i = strlen(cfg.termtype);
s_wrpkt_start(SSH_CMSG_REQUEST_PTY, i+5*4+1); s_wrpkt_start(SSH_CMSG_REQUEST_PTY, i+5*4+1);
@ -547,10 +603,12 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
} else if (pktin.type == SSH_SMSG_FAILURE) { } else if (pktin.type == SSH_SMSG_FAILURE) {
c_write("Server refused to allocate pty\r\n", 32); c_write("Server refused to allocate pty\r\n", 32);
} }
logevent("Allocated pty");
} }
s_wrpkt_start(SSH_CMSG_EXEC_SHELL, 0); s_wrpkt_start(SSH_CMSG_EXEC_SHELL, 0);
s_wrpkt(); s_wrpkt();
logevent("Started session");
ssh_state = SSH_STATE_SESSION; ssh_state = SSH_STATE_SESSION;
if (size_needed) if (size_needed)
@ -567,6 +625,7 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt) {
c_write(pktin.body+4, len); c_write(pktin.body+4, len);
} else if (pktin.type == SSH_MSG_DISCONNECT) { } else if (pktin.type == SSH_MSG_DISCONNECT) {
ssh_state = SSH_STATE_CLOSED; ssh_state = SSH_STATE_CLOSED;
logevent("Received disconnect request");
} else if (pktin.type == SSH_SMSG_SUCCESS) { } else if (pktin.type == SSH_SMSG_SUCCESS) {
/* may be from EXEC_SHELL on some servers */ /* may be from EXEC_SHELL on some servers */
} else if (pktin.type == SSH_SMSG_FAILURE) { } else if (pktin.type == SSH_SMSG_FAILURE) {

2
ssh.h
View File

@ -44,3 +44,5 @@ void SHATransform(word32 *digest, word32 *data);
int random_byte(void); int random_byte(void);
void random_add_noise(void *noise, int length); void random_add_noise(void *noise, int length);
void logevent (char *);

View File

@ -396,6 +396,7 @@ static void blowfish_sesskey(unsigned char *key)
ectx.iv0 = 0; ectx.iv0 = 0;
ectx.iv1 = 0; ectx.iv1 = 0;
dctx = ectx; dctx = ectx;
logevent("Initialised Blowfish encryption");
} }
static void blowfish_encrypt_blk(unsigned char *blk, int len) static void blowfish_encrypt_blk(unsigned char *blk, int len)

View File

@ -657,6 +657,7 @@ static void des3_sesskey(unsigned char *key) {
memset(div1, 0, sizeof(div1)); memset(div1, 0, sizeof(div1));
memset(div2, 0, sizeof(div2)); memset(div2, 0, sizeof(div2));
memset(div3, 0, sizeof(div3)); memset(div3, 0, sizeof(div3));
logevent("Initialised triple-DES encryption");
} }
static void des3_encrypt_blk(unsigned char *blk, int len) { static void des3_encrypt_blk(unsigned char *blk, int len) {
@ -678,6 +679,7 @@ static void des_sesskey(unsigned char *key) {
memset(eiv1, 0, sizeof(eiv1)); memset(eiv1, 0, sizeof(eiv1));
des_set_key(key, &dkey1); des_set_key(key, &dkey1);
memset(div1, 0, sizeof(div1)); memset(div1, 0, sizeof(div1));
logevent("Initialised single-DES encryption");
} }
static void des_encrypt_blk(unsigned char *blk, int len) { static void des_encrypt_blk(unsigned char *blk, int len) {

View File

@ -184,7 +184,7 @@ static void log_option (char *sender, int cmd, int option) {
(cmd == WILL ? "WILL" : cmd == WONT ? "WONT" : (cmd == WILL ? "WILL" : cmd == WONT ? "WONT" :
cmd == DO ? "DO" : cmd == DONT ? "DONT" : "<??>"), cmd == DO ? "DO" : cmd == DONT ? "DONT" : "<??>"),
telopt(option)); telopt(option));
lognegot(buf); logevent(buf);
} }
static void send_opt (int cmd, int option) { static void send_opt (int cmd, int option) {
@ -285,11 +285,11 @@ static void process_subneg (void) {
n = 4 + strlen(cfg.termspeed); n = 4 + strlen(cfg.termspeed);
b[n] = IAC; b[n+1] = SE; b[n] = IAC; b[n+1] = SE;
s_write (b, n+2); s_write (b, n+2);
lognegot("server:\tSB TSPEED SEND"); logevent("server:\tSB TSPEED SEND");
sprintf(logbuf, "client:\tSB TSPEED IS %s", cfg.termspeed); sprintf(logbuf, "client:\tSB TSPEED IS %s", cfg.termspeed);
lognegot (logbuf); logevent (logbuf);
} else } else
lognegot ("server:\tSB TSPEED <something weird>"); logevent ("server:\tSB TSPEED <something weird>");
break; break;
case TELOPT_TTYPE: case TELOPT_TTYPE:
if (sb_len == 1 && sb_buf[0] == TELQUAL_SEND) { if (sb_len == 1 && sb_buf[0] == TELQUAL_SEND) {
@ -302,11 +302,11 @@ static void process_subneg (void) {
b[n+4] = IAC; b[n+5] = SE; b[n+4] = IAC; b[n+5] = SE;
s_write (b, n+6); s_write (b, n+6);
b[n+4] = 0; b[n+4] = 0;
lognegot("server:\tSB TTYPE SEND"); logevent("server:\tSB TTYPE SEND");
sprintf(logbuf, "client:\tSB TTYPE IS %s", b+4); sprintf(logbuf, "client:\tSB TTYPE IS %s", b+4);
lognegot(logbuf); logevent(logbuf);
} else } else
lognegot("server:\tSB TTYPE <something weird>\r\n"); logevent("server:\tSB TTYPE <something weird>\r\n");
break; break;
case TELOPT_OLD_ENVIRON: case TELOPT_OLD_ENVIRON:
case TELOPT_NEW_ENVIRON: case TELOPT_NEW_ENVIRON:
@ -316,7 +316,7 @@ static void process_subneg (void) {
char logbuf[50]; char logbuf[50];
p++; p++;
sprintf (logbuf, "server:\tSB %s SEND", telopt(sb_opt)); sprintf (logbuf, "server:\tSB %s SEND", telopt(sb_opt));
lognegot (logbuf); logevent (logbuf);
if (sb_opt == TELOPT_OLD_ENVIRON) { if (sb_opt == TELOPT_OLD_ENVIRON) {
if (cfg.rfc_environ) { if (cfg.rfc_environ) {
value = RFC_VALUE; value = RFC_VALUE;
@ -368,7 +368,7 @@ static void process_subneg (void) {
s_write (b, n); s_write (b, n);
sprintf(logbuf, "client:\tSB %s IS %s", telopt(sb_opt), sprintf(logbuf, "client:\tSB %s IS %s", telopt(sb_opt),
n==6 ? "<nothing>" : "<stuff>"); n==6 ? "<nothing>" : "<stuff>");
lognegot (logbuf); logevent (logbuf);
} }
break; break;
} }
@ -681,7 +681,7 @@ static void telnet_size(void) {
sprintf(logbuf, "client:\tSB NAWS %d,%d", sprintf(logbuf, "client:\tSB NAWS %d,%d",
((unsigned char)b[3] << 8) + (unsigned char)b[4], ((unsigned char)b[3] << 8) + (unsigned char)b[4],
((unsigned char)b[5] << 8) + (unsigned char)b[6]); ((unsigned char)b[5] << 8) + (unsigned char)b[6]);
lognegot (logbuf); logevent (logbuf);
} }
/* /*

View File

@ -57,9 +57,12 @@
#define IDC1_KPSTATIC 1010 #define IDC1_KPSTATIC 1010
#define IDC1_KPNORMAL 1011 #define IDC1_KPNORMAL 1011
#define IDC1_KPAPPLIC 1012 #define IDC1_KPAPPLIC 1012
#define IDC1_CURSTATIC 1013 #define IDC1_KPNH 1013
#define IDC1_CURNORMAL 1014 #define IDC1_CURSTATIC 1014
#define IDC1_CURAPPLIC 1015 #define IDC1_CURNORMAL 1015
#define IDC1_CURAPPLIC 1016
#define IDC1_ALTF4 1017
#define IDC1_ALTSPACE 1018
#define IDC2_WRAPMODE 1001 #define IDC2_WRAPMODE 1001
#define IDC2_DECOM 1002 #define IDC2_DECOM 1002

View File

@ -77,28 +77,34 @@ STYLE WS_CHILD | WS_VISIBLE | NOT WS_BORDER
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif"
BEGIN BEGIN
LTEXT "Action of Backspace:", IDC1_DELSTATIC, 3, 3, 162, 8 LTEXT "Action of Backspace:", IDC1_DELSTATIC, 3, 3, 162, 8
AUTORADIOBUTTON "Control-&H (ASCII 8)", IDC1_DEL008, 3, 12, 162, 10, WS_GROUP AUTORADIOBUTTON "Control-&H", IDC1_DEL008, 3, 12, 50, 10, WS_GROUP
AUTORADIOBUTTON "Control-&? (ASCII 127)", IDC1_DEL127, 3, 22, 162, 10 AUTORADIOBUTTON "Control-&? (127)", IDC1_DEL127, 62, 12, 100, 10
LTEXT "Action of Home and End:", IDC1_HOMESTATIC, 3, 35, 162, 8 LTEXT "Action of Home and End:", IDC1_HOMESTATIC, 3, 25, 162, 8
AUTORADIOBUTTON "&Standard (ESC [ 1 ~ and ESC [ 4 ~)", AUTORADIOBUTTON "&Standard",
IDC1_HOMETILDE, 3, 44, 162, 10, WS_GROUP IDC1_HOMETILDE, 3, 34, 50, 10, WS_GROUP
AUTORADIOBUTTON "&rxvt (ESC [ H and ESC O w)", AUTORADIOBUTTON "&rxvt",
IDC1_HOMERXVT, 3, 54, 162, 10 IDC1_HOMERXVT, 62, 34, 50, 10
LTEXT "Action of F1 through F5:", IDC1_FUNCSTATIC, 3, 67, 162, 8 LTEXT "Action of F1 through F5:", IDC1_FUNCSTATIC, 3, 47, 162, 8
AUTORADIOBUTTON "S&tandard (ESC [ 11 ~ through ESC [ 15 ~)", AUTORADIOBUTTON "S&tandard",
IDC1_FUNCTILDE, 3, 76, 162, 10, WS_GROUP IDC1_FUNCTILDE, 3, 56, 50, 10, WS_GROUP
AUTORADIOBUTTON "&Linux (ESC [ [ A through ESC [ [ E)", AUTORADIOBUTTON "&Linux console",
IDC1_FUNCLINUX, 3, 86, 162, 10 IDC1_FUNCLINUX, 62, 56, 100, 10
LTEXT "Initial state of numeric keypad:", IDC1_KPSTATIC, 3, 99, 162, 8 LTEXT "Initial state of cursor keys:", IDC1_CURSTATIC, 3, 69, 162, 8
AUTORADIOBUTTON "&Normal (depends on NumLock)", AUTORADIOBUTTON "&Normal",
IDC1_KPNORMAL, 3, 108, 162, 10, WS_GROUP IDC1_CURNORMAL, 3, 78, 50, 10, WS_GROUP
AUTORADIOBUTTON "A&pplication (ESC O P etc)", AUTORADIOBUTTON "A&pplication",
IDC1_KPAPPLIC, 3, 118, 162, 10 IDC1_CURAPPLIC, 62, 78, 50, 10
LTEXT "Initial state of cursor keys:", IDC1_CURSTATIC, 3, 131, 162, 8 LTEXT "Initial state of numeric keypad:", IDC1_KPSTATIC, 3, 91, 162, 8
AUTORADIOBUTTON "Nor&mal (ESC [ A through ESC [ D)", AUTORADIOBUTTON "Nor&mal",
IDC1_CURNORMAL, 3, 140, 162, 10, WS_GROUP IDC1_KPNORMAL, 3, 100, 50, 10, WS_GROUP
AUTORADIOBUTTON "Appl&ication (ESC O A through ESC O D)", AUTORADIOBUTTON "Appl&ication",
IDC1_CURAPPLIC, 3, 150, 162, 10 IDC1_KPAPPLIC, 62, 100, 50, 10
AUTORADIOBUTTON "N&etHack",
IDC1_KPNH, 121, 100, 50, 10
AUTOCHECKBOX "ALT-F&4 is special (closes window)",
IDC1_ALTF4, 3, 113, 162, 10
AUTOCHECKBOX "ALT-Space is special (S&ystem menu)",
IDC1_ALTSPACE, 3, 123, 162, 10
END END
IDD_PANEL2 DIALOG DISCARDABLE 6, 30, 168, 163 IDD_PANEL2 DIALOG DISCARDABLE 6, 30, 168, 163
@ -217,7 +223,7 @@ END
IDD_LOGBOX DIALOG DISCARDABLE 100, 20, 160, 119 IDD_LOGBOX DIALOG DISCARDABLE 100, 20, 160, 119
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "PuTTY Negotiation Log" CAPTION "PuTTY Event Log"
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif"
BEGIN BEGIN
DEFPUSHBUTTON "&Close", IDOK, 58, 102, 44, 14 DEFPUSHBUTTON "&Close", IDOK, 58, 102, 44, 14

View File

@ -15,8 +15,9 @@
static const char *const puttystr = PUTTY_REG_POS "\\Sessions"; static const char *const puttystr = PUTTY_REG_POS "\\Sessions";
static char **negots = NULL; static char **events = NULL;
static int nnegots = 0, negsize = 0; static int nevents = 0, negsize = 0;
static HWND logbox = NULL, abtbox = NULL; static HWND logbox = NULL, abtbox = NULL;
static char hex[16] = "0123456789ABCDEF"; static char hex[16] = "0123456789ABCDEF";
@ -153,6 +154,9 @@ static void save_settings (char *section, int do_host) {
wppi (sesskey, "LinuxFunctionKeys", cfg.linux_funkeys); wppi (sesskey, "LinuxFunctionKeys", cfg.linux_funkeys);
wppi (sesskey, "ApplicationCursorKeys", cfg.app_cursor); wppi (sesskey, "ApplicationCursorKeys", cfg.app_cursor);
wppi (sesskey, "ApplicationKeypad", cfg.app_keypad); wppi (sesskey, "ApplicationKeypad", cfg.app_keypad);
wppi (sesskey, "NetHackKeypad", cfg.nethack_keypad);
wppi (sesskey, "AltF4", cfg.alt_f4);
wppi (sesskey, "AltSpace", cfg.alt_space);
wppi (sesskey, "ScrollbackLines", cfg.savelines); wppi (sesskey, "ScrollbackLines", cfg.savelines);
wppi (sesskey, "DECOriginMode", cfg.dec_om); wppi (sesskey, "DECOriginMode", cfg.dec_om);
wppi (sesskey, "AutoWrapMode", cfg.wrap_mode); wppi (sesskey, "AutoWrapMode", cfg.wrap_mode);
@ -283,6 +287,9 @@ static void load_settings (char *section, int do_host) {
gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.linux_funkeys); gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.linux_funkeys);
gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor); gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor);
gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad); gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad);
gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines); gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om); gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode); gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
@ -355,9 +362,9 @@ static int CALLBACK LogProc (HWND hwnd, UINT msg,
switch (msg) { switch (msg) {
case WM_INITDIALOG: case WM_INITDIALOG:
for (i=0; i<nnegots; i++) for (i=0; i<nevents; i++)
SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING, SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
0, (LPARAM)negots[i]); 0, (LPARAM)events[i]);
return 1; return 1;
/* case WM_CTLCOLORDLG: */ /* case WM_CTLCOLORDLG: */
/* return (int) GetStockObject (LTGRAY_BRUSH); */ /* return (int) GetStockObject (LTGRAY_BRUSH); */
@ -624,8 +631,11 @@ static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
cfg.linux_funkeys ? IDC1_FUNCLINUX : IDC1_FUNCTILDE); cfg.linux_funkeys ? IDC1_FUNCLINUX : IDC1_FUNCTILDE);
CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC, CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL); cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPAPPLIC, CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
cfg.nethack_keypad ? IDC1_KPNH :
cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL); cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
break; break;
case WM_COMMAND: case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED || if (HIWORD(wParam) == BN_CLICKED ||
@ -646,11 +656,26 @@ static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
case IDC1_KPNORMAL: case IDC1_KPNORMAL:
case IDC1_KPAPPLIC: case IDC1_KPAPPLIC:
cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC); cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
cfg.nethack_keypad = FALSE;
break;
case IDC1_KPNH:
cfg.app_keypad = FALSE;
cfg.nethack_keypad = TRUE;
break; break;
case IDC1_CURNORMAL: case IDC1_CURNORMAL:
case IDC1_CURAPPLIC: case IDC1_CURAPPLIC:
cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC); cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
break; break;
case IDC1_ALTF4:
if (HIWORD(wParam) == BN_CLICKED ||
HIWORD(wParam) == BN_DOUBLECLICKED)
cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
break;
case IDC1_ALTSPACE:
if (HIWORD(wParam) == BN_CLICKED ||
HIWORD(wParam) == BN_DOUBLECLICKED)
cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
break;
} }
} }
return GeneralPanelProc (hwnd, msg, wParam, lParam); return GeneralPanelProc (hwnd, msg, wParam, lParam);
@ -1361,20 +1386,20 @@ void do_defaults (char *session) {
load_settings ("Default Settings", FALSE); load_settings ("Default Settings", FALSE);
} }
void lognegot (char *string) { void logevent (char *string) {
if (nnegots >= negsize) { if (nevents >= negsize) {
negsize += 64; negsize += 64;
negots = srealloc (negots, negsize * sizeof(*negots)); events = srealloc (events, negsize * sizeof(*events));
} }
negots[nnegots] = smalloc(1+strlen(string)); events[nevents] = smalloc(1+strlen(string));
strcpy (negots[nnegots], string); strcpy (events[nevents], string);
nnegots++; nevents++;
if (logbox) if (logbox)
SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING, SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
0, (LPARAM)string); 0, (LPARAM)string);
} }
void shownegot (HWND hwnd) { void showeventlog (HWND hwnd) {
if (!logbox) { if (!logbox) {
logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX), logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
hwnd, LogProc); hwnd, LogProc);

View File

@ -341,9 +341,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
AppendMenu (p, MF_ENABLED, IDM_TEL_EOR, "End Of Record"); AppendMenu (p, MF_ENABLED, IDM_TEL_EOR, "End Of Record");
AppendMenu (p, MF_ENABLED, IDM_TEL_EOF, "End Of File"); AppendMenu (p, MF_ENABLED, IDM_TEL_EOF, "End Of File");
AppendMenu (m, MF_POPUP | MF_ENABLED, (UINT) p, "Telnet Command"); AppendMenu (m, MF_POPUP | MF_ENABLED, (UINT) p, "Telnet Command");
AppendMenu (m, MF_ENABLED, IDM_SHOWLOG, "Show Negotiation");
AppendMenu (m, MF_SEPARATOR, 0, 0); AppendMenu (m, MF_SEPARATOR, 0, 0);
} }
AppendMenu (m, MF_ENABLED, IDM_SHOWLOG, "Event Log");
AppendMenu (m, MF_SEPARATOR, 0, 0);
AppendMenu (m, MF_ENABLED, IDM_NEWSESS, "New Session"); AppendMenu (m, MF_ENABLED, IDM_NEWSESS, "New Session");
AppendMenu (m, MF_ENABLED, IDM_DUPSESS, "Duplicate Session"); AppendMenu (m, MF_ENABLED, IDM_DUPSESS, "Duplicate Session");
s = CreateMenu(); s = CreateMenu();
@ -628,7 +629,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message,
case WM_SYSCOMMAND: case WM_SYSCOMMAND:
switch (wParam & ~0xF) { /* low 4 bits reserved to Windows */ switch (wParam & ~0xF) { /* low 4 bits reserved to Windows */
case IDM_SHOWLOG: case IDM_SHOWLOG:
shownegot(hwnd); showeventlog(hwnd);
break; break;
case IDM_NEWSESS: case IDM_NEWSESS:
case IDM_DUPSESS: case IDM_DUPSESS:
@ -1013,6 +1014,8 @@ static int WINAPI WndProc (HWND hwnd, UINT message,
int len; int len;
len = TranslateKey (wParam, lParam, buf); len = TranslateKey (wParam, lParam, buf);
if (len == -1)
return DefWindowProc (hwnd, message, wParam, lParam);
back->send (buf, len); back->send (buf, len);
} }
return 0; return 0;
@ -1253,9 +1256,12 @@ static int TranslateKey(WPARAM wParam, LPARAM lParam, unsigned char *output) {
SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0); SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);
return 0; return 0;
} }
if ((lParam & 0x20000000) && wParam == VK_F4) { if ((lParam & 0x20000000) && wParam == VK_F4 && cfg.alt_f4) {
SendMessage (hwnd, WM_CLOSE, 0, 0); return -1;
return 0; }
if ((lParam & 0x20000000) && wParam == VK_SPACE && cfg.alt_space) {
SendMessage (hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0);
return -1;
} }
/* /*
@ -1281,12 +1287,29 @@ static int TranslateKey(WPARAM wParam, LPARAM lParam, unsigned char *output) {
return p - output; return p - output;
} }
/* if (cfg.nethack_keypad) {
* If we're in applications keypad mode, we have to process it int shift = keystate[VK_SHIFT] & 0x80;
* before char-map translation, because it will pre-empt lots /*
* of stuff, even if NumLock is off. * NB the shifted versions only work with numlock off.
*/ */
if (app_keypad_keys) { switch ( (lParam >> 16) & 0x1FF ) {
case 0x047: *p++ = shift ? 'Y' : 'y'; return p - output;
case 0x048: *p++ = shift ? 'K' : 'k'; return p - output;
case 0x049: *p++ = shift ? 'U' : 'u'; return p - output;
case 0x04B: *p++ = shift ? 'H' : 'h'; return p - output;
case 0x04C: *p++ = '.'; return p - output;
case 0x04D: *p++ = shift ? 'L' : 'l'; return p - output;
case 0x04F: *p++ = shift ? 'B' : 'b'; return p - output;
case 0x050: *p++ = shift ? 'J' : 'j'; return p - output;
case 0x051: *p++ = shift ? 'N' : 'n'; return p - output;
case 0x053: *p++ = '.'; return p - output;
}
} else if (app_keypad_keys) {
/*
* If we're in applications keypad mode, we have to process it
* before char-map translation, because it will pre-empt lots
* of stuff, even if NumLock is off.
*/
if (ret) { if (ret) {
/* /*
* Hack to ensure NumLock doesn't interfere with * Hack to ensure NumLock doesn't interfere with