1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Rationalise ordering of authentication operations. Still some work to do,

but at least pscp no longer hangs when prompting for a passphrase

[originally from svn r621]
This commit is contained in:
Simon Tatham 2000-09-25 10:14:53 +00:00
parent 117fd9affc
commit 673f2e48a7
6 changed files with 159 additions and 104 deletions

View File

@ -127,7 +127,8 @@ void add_keyfile(char *filename) {
int ret;
int attempts;
needs_pass = rsakey_encrypted(filename);
/* FIXME: we can acquire comment here and use it in dialog */
needs_pass = rsakey_encrypted(filename, NULL);
attempts = 0;
key = malloc(sizeof(*key));
do {

130
ssh.c
View File

@ -1273,6 +1273,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
while (pktin.type == SSH1_SMSG_FAILURE) {
static char password[100];
static char prompt[200];
static int pos;
static char c;
static int pwpkt_type;
@ -1385,10 +1386,71 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
if (*cfg.keyfile && !tried_publickey)
pwpkt_type = SSH1_CMSG_AUTH_RSA;
if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD &&
!(flags & FLAG_INTERACTIVE)) {
char prompt[200];
sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost);
if (pktin.type == SSH1_SMSG_FAILURE &&
cfg.try_tis_auth &&
(supported_auths_mask & (1<<SSH1_AUTH_TIS))) {
pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
logevent("Requested TIS authentication");
send_packet(SSH1_CMSG_AUTH_TIS, PKT_END);
crWaitUntil(ispkt);
if (pktin.type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
logevent("TIS authentication declined");
if (flags & FLAG_INTERACTIVE)
c_write("TIS authentication refused.\r\n", 29);
} else {
int challengelen = ((pktin.body[0] << 24) |
(pktin.body[1] << 16) |
(pktin.body[2] << 8) |
(pktin.body[3]));
logevent("Received TIS challenge");
if (challengelen > sizeof(prompt)-1)
challengelen = sizeof(prompt)-1; /* prevent overrun */
memcpy(prompt, pktin.body+4, challengelen);
prompt[challengelen] = '\0';
}
}
if (pktin.type == SSH1_SMSG_FAILURE &&
cfg.try_tis_auth &&
(supported_auths_mask & (1<<SSH1_AUTH_CCARD))) {
pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
logevent("Requested CryptoCard authentication");
send_packet(SSH1_CMSG_AUTH_CCARD, PKT_END);
crWaitUntil(ispkt);
if (pktin.type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
logevent("CryptoCard authentication declined");
c_write("CryptoCard authentication refused.\r\n", 29);
} else {
int challengelen = ((pktin.body[0] << 24) |
(pktin.body[1] << 16) |
(pktin.body[2] << 8) |
(pktin.body[3]));
logevent("Received CryptoCard challenge");
if (challengelen > sizeof(prompt)-1)
challengelen = sizeof(prompt)-1; /* prevent overrun */
memcpy(prompt, pktin.body+4, challengelen);
strncpy(prompt + challengelen, "\r\nResponse : ",
sizeof(prompt)-challengelen);
prompt[sizeof(prompt)-1] = '\0';
}
}
if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
sprintf(prompt, "%.90s@%.90s's password: ",
cfg.username, savedhost);
}
if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
char *comment = NULL;
if (flags & FLAG_VERBOSE)
c_write("Trying public key authentication.\r\n", 35);
if (!rsakey_encrypted(cfg.keyfile, &comment)) {
if (flags & FLAG_VERBOSE)
c_write("No passphrase required.\r\n", 25);
goto tryauth;
}
sprintf(prompt, "Passphrase for key \"%.100s\": ", comment);
free(comment);
}
if (!(flags & FLAG_INTERACTIVE)) {
if (!ssh_get_password(prompt, password, sizeof(password))) {
/*
* get_password failed to get a password (for
@ -1401,59 +1463,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
crReturn(1);
}
} else {
if (pktin.type == SSH1_SMSG_FAILURE &&
cfg.try_tis_auth &&
(supported_auths_mask & (1<<SSH1_AUTH_TIS))) {
pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
logevent("Requested TIS authentication");
send_packet(SSH1_CMSG_AUTH_TIS, PKT_END);
crWaitUntil(ispkt);
if (pktin.type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
logevent("TIS authentication declined");
c_write("TIS authentication refused.\r\n", 29);
} else {
int challengelen = ((pktin.body[0] << 24) |
(pktin.body[1] << 16) |
(pktin.body[2] << 8) |
(pktin.body[3]));
logevent("Received TIS challenge");
c_write(pktin.body+4, challengelen);
}
}
if (pktin.type == SSH1_SMSG_FAILURE &&
cfg.try_tis_auth &&
(supported_auths_mask & (1<<SSH1_AUTH_CCARD))) {
pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
logevent("Requested CryptoCard authentication");
send_packet(SSH1_CMSG_AUTH_CCARD, PKT_END);
crWaitUntil(ispkt);
if (pktin.type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
logevent("CryptoCard authentication declined");
c_write("CryptoCard authentication refused.\r\n", 29);
} else {
int challengelen = ((pktin.body[0] << 24) |
(pktin.body[1] << 16) |
(pktin.body[2] << 8) |
(pktin.body[3]));
logevent("Received CryptoCard challenge");
c_write(pktin.body+4, challengelen);
c_write("\r\nResponse : ", 13);
}
}
if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD)
c_write("password: ", 10);
if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
if (flags & FLAG_VERBOSE)
c_write("Trying public key authentication.\r\n", 35);
if (!rsakey_encrypted(cfg.keyfile)) {
if (flags & FLAG_VERBOSE)
c_write("No passphrase required.\r\n", 25);
goto tryauth;
}
c_write("passphrase: ", 12);
}
c_write(prompt, strlen(prompt));
pos = 0;
ssh_send_ok = 1;
while (pos >= 0) {
@ -1482,8 +1492,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
}
}
c_write("\r\n", 2);
}
}
tryauth:
if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
@ -1518,8 +1527,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
crWaitUntil(ispkt);
if (pktin.type == SSH1_SMSG_FAILURE) {
if (flags & FLAG_VERBOSE)
c_write("Server refused our public key.\r\n", 32);
c_write("Server refused our public key.\r\n", 32);
continue; /* go and try password */
}
if (pktin.type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {

2
ssh.h
View File

@ -156,7 +156,7 @@ Bignum dh_create_e(void);
Bignum dh_find_K(Bignum f);
int loadrsakey(char *filename, struct RSAKey *key, char *passphrase);
int rsakey_encrypted(char *filename);
int rsakey_encrypted(char *filename, char **comment);
void des3_decrypt_pubkey(unsigned char *key,
unsigned char *blk, int len);

View File

@ -324,6 +324,9 @@ int ssh1_read_bignum(unsigned char *data, Bignum *result) {
b = (w+7)/8; /* bits -> bytes */
w = (w+15)/16; /* bits -> words */
if (!result) /* just return length */
return b + 2;
bn = newbn(w);
for (i=1; i<=w; i++)

107
sshpubk.c
View File

@ -1,17 +1,17 @@
/*
* Read SSH public keys from files.
*
* First implementation: only supports unencrypted SSH 1.1 format
* RSA keys. Encryption, and SSH 2 DSS keys, to be supported later.
* Generic SSH public-key handling operations. In particular,
* reading of SSH public-key files, and also the generic `sign'
* operation for ssh2 (which checks the type of the key and
* dispatches to the appropriate key-type specific function).
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h> /* FIXME */
#include <stdarg.h> /* FIXME */
#include <windows.h> /* FIXME */
#include "putty.h" /* FIXME */
#include "putty.h"
#include "ssh.h"
#define GET_32BIT(cp) \
@ -21,33 +21,40 @@
((unsigned long)(unsigned char)(cp)[3]))
#define rsa_signature "SSH PRIVATE KEY FILE FORMAT 1.1\n"
#define dss_signature "-----BEGIN DSA PRIVATE KEY-----\n"
int loadrsakey(char *filename, struct RSAKey *key, char *passphrase) {
FILE *fp;
#define BASE64_TOINT(x) ( (x)-'A'<26 ? (x)-'A'+0 :\
(x)-'a'<26 ? (x)-'a'+26 :\
(x)-'0'<10 ? (x)-'0'+52 :\
(x)=='+' ? 62 : \
(x)=='/' ? 63 : 0 )
static int loadrsakey_main(FILE *fp, struct RSAKey *key,
char **commentptr, char *passphrase) {
unsigned char buf[16384];
unsigned char keybuf[16];
int len;
int i, j, ciphertype;
int ret = 0;
struct MD5Context md5c;
char *comment;
fp = fopen(filename, "rb");
if (!fp)
goto end;
/* Slurp the whole file into a buffer. */
/* Slurp the whole file (minus the header) into a buffer. */
len = fread(buf, 1, sizeof(buf), fp);
fclose(fp);
if (len < 0 || len == sizeof(buf))
goto end; /* file too big or not read */
if (len < sizeof(rsa_signature) ||
memcmp(buf, rsa_signature, sizeof(rsa_signature)) != 0)
goto end; /* failure to have sig at front */
i = 0;
i = sizeof(rsa_signature);
/*
* A zero byte. (The signature includes a terminating NUL.)
*/
if (len-i < 1 || buf[i] != 0)
goto end;
i++;
/* Next, one byte giving encryption type, and one reserved uint32. */
/* One byte giving encryption type, and one reserved uint32. */
if (len-i < 1)
goto end;
ciphertype = buf[i];
@ -69,12 +76,19 @@ int loadrsakey(char *filename, struct RSAKey *key, char *passphrase) {
j = GET_32BIT(buf+i);
i += 4;
if (len-i < j) goto end;
key->comment = malloc(j+1);
if (key->comment) {
memcpy(key->comment, buf+i, j);
key->comment[j] = '\0';
comment = malloc(j+1);
if (comment) {
memcpy(comment, buf+i, j);
comment[j] = '\0';
}
i += j;
if (commentptr)
*commentptr = comment;
if (key)
key->comment = comment;
if (!key) {
return ciphertype != 0;
}
/*
* Decrypt remainder of buffer.
@ -108,24 +122,49 @@ int loadrsakey(char *filename, struct RSAKey *key, char *passphrase) {
return ret;
}
/*
* See whether an RSA key is encrypted.
*/
int rsakey_encrypted(char *filename) {
int loadrsakey(char *filename, struct RSAKey *key, char *passphrase) {
FILE *fp;
unsigned char buf[1+sizeof(rsa_signature)];
int len;
unsigned char buf[64];
fp = fopen(filename, "rb");
if (!fp)
return 0; /* doesn't even exist */
/* Slurp the whole file into a buffer. */
len = fread(buf, 1, sizeof(buf), fp);
/*
* Read the first line of the file and see if it's a v1 private
* key file.
*/
if (fgets(buf, sizeof(buf), fp) &&
!strcmp(buf, rsa_signature)) {
return loadrsakey_main(fp, key, NULL, passphrase);
}
/*
* Otherwise, we have nothing. Return empty-handed.
*/
fclose(fp);
if (len < sizeof(buf))
return 0; /* not even valid */
if (buf[sizeof(buf)-1])
return 1; /* encrypted */
return 0;
}
/*
* See whether an RSA key is encrypted. Return its comment field as
* well.
*/
int rsakey_encrypted(char *filename, char **comment) {
FILE *fp;
unsigned char buf[64];
fp = fopen(filename, "rb");
if (!fp)
return 0; /* doesn't even exist */
/*
* Read the first line of the file and see if it's a v1 private
* key file.
*/
if (fgets(buf, sizeof(buf), fp) &&
!strcmp(buf, rsa_signature)) {
return loadrsakey_main(fp, NULL, comment, NULL);
}
return 0; /* wasn't the right kind of file */
}

View File

@ -43,9 +43,12 @@ int makekey(unsigned char *data, struct RSAKey *result,
unsigned char *p = data;
int i;
result->bits = 0;
for (i=0; i<4; i++)
result->bits = (result->bits << 8) + *p++;
if (result) {
result->bits = 0;
for (i=0; i<4; i++)
result->bits = (result->bits << 8) + *p++;
} else
p += 4;
/*
* order=0 means exponent then modulus (the keys sent by the
@ -54,12 +57,13 @@ int makekey(unsigned char *data, struct RSAKey *result,
*/
if (order == 0)
p += ssh1_read_bignum(p, &result->exponent);
result->bytes = (((p[0] << 8) + p[1]) + 7) / 8;
p += ssh1_read_bignum(p, result ? &result->exponent : NULL);
if (result)
result->bytes = (((p[0] << 8) + p[1]) + 7) / 8;
if (keystr) *keystr = p+2;
p += ssh1_read_bignum(p, &result->modulus);
p += ssh1_read_bignum(p, result ? &result->modulus : NULL);
if (order == 1)
p += ssh1_read_bignum(p, &result->exponent);
p += ssh1_read_bignum(p, result ? &result->exponent : NULL);
return p - data;
}