Pageant now accepts an initial key list on the command line

[originally from svn r592]
This commit is contained in:
Simon Tatham 2000-09-15 10:48:42 +00:00
Родитель 4bd19700a1
Коммит c96384efe0
3 изменённых файлов: 163 добавлений и 17 удалений

Просмотреть файл

@ -62,7 +62,7 @@ MOBJS = misc.$(OBJ) version.$(OBJ)
##-- objects putty pscp plink
OBJS1 = sshcrc.$(OBJ) sshdes.$(OBJ) sshmd5.$(OBJ) sshrsa.$(OBJ) sshrand.$(OBJ)
OBJS2 = sshsha.$(OBJ) sshblowf.$(OBJ) noise.$(OBJ) sshdh.$(OBJ) sshdss.$(OBJ)
OBJS3 = sshbn.$(OBJ) sshpubk.$(OBJ) ssh.$(OBJ) pageantc.$(OBJ)
OBJS3 = sshbn.$(OBJ) sshpubk.$(OBJ) ssh.$(OBJ) pageantc.$(OBJ) tree234.$(OBJ)
##-- objects pageant
PAGE1 = pageant.$(OBJ) sshrsa.$(OBJ) sshpubk.$(OBJ) sshdes.$(OBJ) sshbn.$(OBJ)
PAGE2 = sshmd5.$(OBJ) version.$(OBJ) tree234.$(OBJ)
@ -183,7 +183,7 @@ xlat.$(OBJ): xlat.c putty.h
ldisc.$(OBJ): ldisc.c putty.h
misc.$(OBJ): misc.c putty.h
noise.$(OBJ): noise.c putty.h ssh.h
ssh.$(OBJ): ssh.c ssh.h putty.h
ssh.$(OBJ): ssh.c ssh.h putty.h tree234.h
sshcrc.$(OBJ): sshcrc.c ssh.h
sshdes.$(OBJ): sshdes.c ssh.h
sshmd5.$(OBJ): sshmd5.c ssh.h

Просмотреть файл

@ -21,8 +21,6 @@
#define APPNAME "Pageant"
#define MAILSLOTNAME "\\\\.\\mailslot\\pageant_listener"
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
#define SSH_AGENTC_RSA_CHALLENGE 3
@ -513,7 +511,6 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
WNDCLASS wndclass;
HANDLE mailslot;
MSG msg;
instance = inst;
@ -572,22 +569,31 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
ShowWindow (hwnd, SW_HIDE);
/*
* Create the mailslot.
*/
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
mailslot = CreateMailslot(MAILSLOTNAME, 0, 0, &sa);
}
/*
* Initialise storage for RSA keys.
*/
rsakeys = newtree234(cmpkeys);
/*
* Process the command line and add RSA keys as listed on it.
* FIXME: we don't support spaces in filenames here. We should.
*/
{
char *p = cmdline;
while (*p) {
while (*p && isspace(*p)) p++;
if (*p && !isspace(*p)) {
char *q = p;
while (*p && !isspace(*p)) p++;
if (*p) *p++ = '\0';
add_keyfile(q);
}
}
}
/*
* Main message loop.
*/
while (GetMessage(&msg, NULL, 0, 0) == 1) {
TranslateMessage(&msg);
DispatchMessage(&msg);

142
ssh.c
Просмотреть файл

@ -5,6 +5,7 @@
#include <winsock.h>
#include "putty.h"
#include "tree234.h"
#include "ssh.h"
#include "scp.h"
@ -38,6 +39,13 @@
#define SSH1_SMSG_STDERR_DATA 18
#define SSH1_CMSG_EOF 19
#define SSH1_SMSG_EXIT_STATUS 20
#define SSH1_MSG_CHANNEL_OPEN_CONFIRMATION 21
#define SSH1_MSG_CHANNEL_OPEN_FAILURE 22
#define SSH1_MSG_CHANNEL_DATA 23
#define SSH1_MSG_CHANNEL_CLOSE 24
#define SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION 25
#define SSH1_CMSG_AGENT_REQUEST_FORWARDING 30
#define SSH1_SMSG_AGENT_OPEN 31
#define SSH1_CMSG_EXIT_CONFIRMATION 33
#define SSH1_MSG_IGNORE 32
#define SSH1_MSG_DEBUG 36
@ -146,7 +154,7 @@ struct ssh_hostkey *hostkey_algs[] = { &ssh_dss };
extern struct ssh_mac ssh_sha1;
SHA_State exhash;
static SHA_State exhash;
static void nullmac_key(unsigned char *key) { }
static void nullmac_generate(unsigned char *blk, int len, unsigned long seq) { }
@ -178,6 +186,37 @@ int (*ssh_get_password)(const char *prompt, char *str, int maxlen) = NULL;
static char *savedhost;
static int ssh_send_ok;
/*
* 2-3-4 tree storing channels.
*/
struct ssh_channel {
int remoteid, localid;
int type;
int closes;
union {
struct ssh_agent_channel {
unsigned char *message;
unsigned char msglen[4];
int lensofar, totallen;
} a;
} u;
};
static tree234 *ssh_channels; /* indexed by local id */
static int ssh_channelcmp(void *av, void *bv) {
struct ssh_channel *a = (struct ssh_channel *)av;
struct ssh_channel *b = (struct ssh_channel *)bv;
if (a->localid < b->localid) return -1;
if (a->localid > b->localid) return +1;
return 0;
}
static int ssh_channelfind(void *av, void *bv) {
int *a = (int *)av;
struct ssh_channel *b = (struct ssh_channel *)bv;
if (*a < b->localid) return -1;
if (*a > b->localid) return +1;
return 0;
}
static enum {
SSH_STATE_BEFORE_SIZE,
SSH_STATE_INTERMED,
@ -1497,6 +1536,18 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) {
if (ssh_state == SSH_STATE_CLOSED)
crReturnV;
if (1 /* FIXME: agent exists && agent forwarding configured */ ) {
logevent("Requesting agent forwarding");
send_packet(SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END);
do { crReturnV; } while (!ispkt);
if (pktin.type != SSH1_SMSG_SUCCESS && pktin.type != SSH1_SMSG_FAILURE) {
fatalbox("Protocol confusion");
} else if (pktin.type == SSH1_SMSG_FAILURE) {
logevent("Agent forwarding refused");
} else
logevent("Agent forwarding enabled");
}
if (!cfg.nopty) {
send_packet(SSH1_CMSG_REQUEST_PTY,
PKT_STR, cfg.termtype,
@ -1525,6 +1576,7 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) {
ssh_size();
ssh_send_ok = 1;
ssh_channels = newtree234(ssh_channelcmp);
while (1) {
crReturnV;
if (ispkt) {
@ -1535,6 +1587,94 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) {
} else if (pktin.type == SSH1_MSG_DISCONNECT) {
ssh_state = SSH_STATE_CLOSED;
logevent("Received disconnect request");
} else if (pktin.type == SSH1_SMSG_AGENT_OPEN) {
/* Remote side is trying to open a channel to talk to our
* agent. Give them back a local channel number. */
int i = 1;
struct ssh_channel *c;
enum234 e;
for (c = first234(ssh_channels, &e); c; c = next234(&e)) {
if (c->localid > i)
break; /* found a free number */
i = c->localid + 1;
}
c = malloc(sizeof(struct ssh_channel));
c->remoteid = GET_32BIT(pktin.body);
c->localid = i;
c->type = SSH1_SMSG_AGENT_OPEN; /* identify channel type */
add234(ssh_channels, c);
send_packet(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
PKT_INT, c->remoteid, PKT_INT, c->localid,
PKT_END);
} else if (pktin.type == SSH1_MSG_CHANNEL_CLOSE ||
pktin.type == SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION) {
/* Remote side closes a channel. */
int i = GET_32BIT(pktin.body);
struct ssh_channel *c;
c = find234(ssh_channels, &i, ssh_channelfind);
if (c) {
int closetype;
closetype = (pktin.type == SSH1_MSG_CHANNEL_CLOSE ? 1 : 2);
send_packet(pktin.type, PKT_INT, c->remoteid, PKT_END);
c->closes |= closetype;
if (c->closes == 3) {
del234(ssh_channels, c);
free(c);
}
}
} else if (pktin.type == SSH1_MSG_CHANNEL_DATA) {
/* Data sent down one of our channels. */
int i = GET_32BIT(pktin.body);
int len = GET_32BIT(pktin.body+4);
unsigned char *p = pktin.body+8;
struct ssh_channel *c;
c = find234(ssh_channels, &i, ssh_channelfind);
if (c) {
switch(c->type) {
case SSH1_SMSG_AGENT_OPEN:
/* Data for an agent message. Buffer it. */
while (len > 0) {
if (c->u.a.lensofar < 4) {
int l = min(4 - c->u.a.lensofar, len);
memcpy(c->u.a.msglen + c->u.a.lensofar, p, l);
p += l; len -= l; c->u.a.lensofar += l;
}
if (c->u.a.lensofar == 4) {
c->u.a.totallen = 4 + GET_32BIT(c->u.a.msglen);
c->u.a.message = malloc(c->u.a.totallen);
memcpy(c->u.a.message, c->u.a.msglen, 4);
}
if (c->u.a.lensofar >= 4 && len > 0) {
int l = min(c->u.a.totallen - c->u.a.lensofar, len);
memcpy(c->u.a.message + c->u.a.lensofar, p, l);
p += l; len -= l; c->u.a.lensofar += l;
}
if (c->u.a.lensofar == c->u.a.totallen) {
void *reply, *sentreply;
int replylen;
agent_query(c->u.a.message, c->u.a.totallen,
&reply, &replylen);
if (reply)
sentreply = reply;
else {
/* Fake SSH_AGENT_FAILURE. */
sentreply = "\0\0\0\1\5";
replylen = 5;
}
send_packet(SSH1_MSG_CHANNEL_DATA,
PKT_INT, c->remoteid,
PKT_INT, replylen,
PKT_DATA, sentreply, replylen,
PKT_END);
if (reply)
free(reply);
free(c->u.a.message);
c->u.a.lensofar = 0;
}
}
break;
}
}
} else if (pktin.type == SSH1_SMSG_SUCCESS) {
/* may be from EXEC_SHELL on some servers */
} else if (pktin.type == SSH1_SMSG_FAILURE) {