зеркало из https://github.com/github/putty.git
Pageant now accepts an initial key list on the command line
[originally from svn r592]
This commit is contained in:
Родитель
4bd19700a1
Коммит
c96384efe0
4
Makefile
4
Makefile
|
@ -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
|
||||
|
|
34
pageant.c
34
pageant.c
|
@ -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
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) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче