mirror of
https://github.com/openssh/libopenssh
synced 2026-04-16 09:45:53 +00:00
convert serverloop.c ssh-keygen.c ssh-pkcs11-helper.c to new buffer API
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "sshbuf.h"
|
||||
#include "servconf.h"
|
||||
#include "compat.h"
|
||||
#include "pathnames.h"
|
||||
@@ -52,7 +52,7 @@ static void add_one_listen_addr(ServerOptions *, char *, int);
|
||||
|
||||
/* Use of privilege separation or not */
|
||||
extern int use_privsep;
|
||||
extern Buffer cfg;
|
||||
extern struct sshbuf *cfg;
|
||||
|
||||
/* Initializes the server options to their default values. */
|
||||
|
||||
@@ -1480,7 +1480,7 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
/* Reads the server configuration file. */
|
||||
|
||||
void
|
||||
load_server_config(const char *filename, Buffer *conf)
|
||||
load_server_config(const char *filename, struct sshbuf *conf)
|
||||
{
|
||||
char line[4096], *cp;
|
||||
FILE *f;
|
||||
@@ -1519,7 +1519,7 @@ parse_server_match_config(ServerOptions *options,
|
||||
ServerOptions mo;
|
||||
|
||||
initialize_server_options(&mo);
|
||||
parse_server_config(&mo, "reprocess config", &cfg, connectinfo);
|
||||
parse_server_config(&mo, "reprocess config", cfg, connectinfo);
|
||||
copy_set_server_options(options, &mo, 0);
|
||||
}
|
||||
|
||||
@@ -1637,8 +1637,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
||||
#undef M_CP_STRARRAYOPT
|
||||
|
||||
void
|
||||
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
|
||||
struct connection_info *connectinfo)
|
||||
parse_server_config(ServerOptions *options, const char *filename,
|
||||
struct sshbuf *conf, struct connection_info *connectinfo)
|
||||
{
|
||||
int active, linenum, bad_options = 0;
|
||||
char *cp, *obuf, *cbuf;
|
||||
|
||||
116
ssh/serverloop.c
116
ssh/serverloop.c
@@ -57,7 +57,7 @@
|
||||
#define PACKET_SKIP_COMPAT
|
||||
#define PACKET_SKIP_COMPAT2
|
||||
#include "packet.h"
|
||||
#include "buffer.h"
|
||||
#include "sshbuf.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "sshpty.h"
|
||||
@@ -83,17 +83,17 @@ extern ServerOptions options;
|
||||
extern Authctxt *the_authctxt;
|
||||
extern int use_privsep;
|
||||
|
||||
static Buffer stdin_buffer; /* Buffer for stdin data. */
|
||||
static Buffer stdout_buffer; /* Buffer for stdout data. */
|
||||
static Buffer stderr_buffer; /* Buffer for stderr data. */
|
||||
static struct sshbuf *stdin_buffer; /* Buffer for stdin data. */
|
||||
static struct sshbuf *stdout_buffer; /* Buffer for stdout data. */
|
||||
static struct sshbuf *stderr_buffer; /* Buffer for stderr data. */
|
||||
static int fdin; /* Descriptor for stdin (for writing) */
|
||||
static int fdout; /* Descriptor for stdout (for reading);
|
||||
May be same number as fdin. */
|
||||
static int fderr; /* Descriptor for stderr. May be -1. */
|
||||
static long stdin_bytes = 0; /* Number of bytes written to stdin. */
|
||||
static long stdout_bytes = 0; /* Number of stdout bytes sent to client. */
|
||||
static long stderr_bytes = 0; /* Number of stderr bytes sent to client. */
|
||||
static long fdout_bytes = 0; /* Number of stdout bytes read from program. */
|
||||
static size_t stdin_bytes = 0; /* Number of bytes written to stdin. */
|
||||
static size_t stdout_bytes = 0; /* Number of stdout bytes sent to client. */
|
||||
static size_t stderr_bytes = 0; /* Number of stderr bytes sent to client. */
|
||||
static size_t fdout_bytes = 0; /* Number of stdout bytes read from program. */
|
||||
static int stdin_eof = 0; /* EOF message received from client. */
|
||||
static int fdout_eof = 0; /* EOF encountered reading from fdout. */
|
||||
static int fderr_eof = 0; /* EOF encountered readung from fderr. */
|
||||
@@ -187,13 +187,13 @@ sigterm_handler(int sig)
|
||||
static void
|
||||
make_packets_from_stderr_data(struct ssh *ssh)
|
||||
{
|
||||
u_int len;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
/* Send buffered stderr data to the client. */
|
||||
while (buffer_len(&stderr_buffer) > 0 &&
|
||||
while (sshbuf_len(stderr_buffer) > 0 &&
|
||||
ssh_packet_not_very_much_data_to_write(ssh)) {
|
||||
len = buffer_len(&stderr_buffer);
|
||||
len = sshbuf_len(stderr_buffer);
|
||||
if (ssh_packet_is_interactive(ssh)) {
|
||||
if (len > 512)
|
||||
len = 512;
|
||||
@@ -203,11 +203,12 @@ make_packets_from_stderr_data(struct ssh *ssh)
|
||||
len = ssh_packet_get_maxsize(ssh);
|
||||
}
|
||||
if ((r = sshpkt_start(ssh, SSH_SMSG_STDERR_DATA)) != 0 ||
|
||||
(r = sshpkt_put_string(ssh, buffer_ptr(&stderr_buffer),
|
||||
(r = sshpkt_put_string(ssh, sshbuf_ptr(stderr_buffer),
|
||||
len)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
fatal("%s: %s", __func__, ssh_err(r));
|
||||
buffer_consume(&stderr_buffer, len);
|
||||
if ((r = sshbuf_consume(stderr_buffer, len)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
stderr_bytes += len;
|
||||
}
|
||||
}
|
||||
@@ -219,13 +220,13 @@ make_packets_from_stderr_data(struct ssh *ssh)
|
||||
static void
|
||||
make_packets_from_stdout_data(struct ssh *ssh)
|
||||
{
|
||||
u_int len;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
/* Send buffered stdout data to the client. */
|
||||
while (buffer_len(&stdout_buffer) > 0 &&
|
||||
while (sshbuf_len(stdout_buffer) > 0 &&
|
||||
ssh_packet_not_very_much_data_to_write(ssh)) {
|
||||
len = buffer_len(&stdout_buffer);
|
||||
len = sshbuf_len(stdout_buffer);
|
||||
if (ssh_packet_is_interactive(ssh)) {
|
||||
if (len > 512)
|
||||
len = 512;
|
||||
@@ -235,11 +236,12 @@ make_packets_from_stdout_data(struct ssh *ssh)
|
||||
len = ssh_packet_get_maxsize(ssh);
|
||||
}
|
||||
if ((r = sshpkt_start(ssh, SSH_SMSG_STDOUT_DATA)) != 0 ||
|
||||
(r = sshpkt_put_string(ssh, buffer_ptr(&stdout_buffer),
|
||||
(r = sshpkt_put_string(ssh, sshbuf_ptr(stdout_buffer),
|
||||
len)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
fatal("%s: %s", __func__, ssh_err(r));
|
||||
buffer_consume(&stdout_buffer, len);
|
||||
if ((r = sshbuf_consume(stdout_buffer, len)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
stdout_bytes += len;
|
||||
}
|
||||
}
|
||||
@@ -320,7 +322,7 @@ wait_until_can_do_something(struct ssh *ssh, fd_set **readsetp, fd_set **writese
|
||||
* Read packets from the client unless we have too much
|
||||
* buffered stdin or channel data.
|
||||
*/
|
||||
if (buffer_len(&stdin_buffer) < buffer_high &&
|
||||
if (sshbuf_len(stdin_buffer) < buffer_high &&
|
||||
channel_not_very_much_buffered_data())
|
||||
FD_SET(connection_in, *readsetp);
|
||||
/*
|
||||
@@ -337,7 +339,7 @@ wait_until_can_do_something(struct ssh *ssh, fd_set **readsetp, fd_set **writese
|
||||
* If we have buffered data, try to write some of that data
|
||||
* to the program.
|
||||
*/
|
||||
if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
|
||||
if (fdin != -1 && sshbuf_len(stdin_buffer) > 0)
|
||||
FD_SET(fdin, *writesetp);
|
||||
}
|
||||
notify_prepare(*readsetp);
|
||||
@@ -386,7 +388,7 @@ wait_until_can_do_something(struct ssh *ssh, fd_set **readsetp, fd_set **writese
|
||||
static void
|
||||
process_input(struct ssh *ssh, fd_set *readset)
|
||||
{
|
||||
int len;
|
||||
int len, r;
|
||||
char buf[16384];
|
||||
|
||||
/* Read and buffer any input data from the client. */
|
||||
@@ -425,7 +427,9 @@ process_input(struct ssh *ssh, fd_set *readset)
|
||||
} else if (len <= 0) {
|
||||
fdout_eof = 1;
|
||||
} else {
|
||||
buffer_append(&stdout_buffer, buf, len);
|
||||
if ((r = sshbuf_put(stdout_buffer, buf, len)) != 0)
|
||||
fatal("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
fdout_bytes += len;
|
||||
}
|
||||
}
|
||||
@@ -437,7 +441,9 @@ process_input(struct ssh *ssh, fd_set *readset)
|
||||
} else if (len <= 0) {
|
||||
fderr_eof = 1;
|
||||
} else {
|
||||
buffer_append(&stderr_buffer, buf, len);
|
||||
if ((r = sshbuf_put(stderr_buffer, buf, len)) != 0)
|
||||
fatal("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -455,8 +461,8 @@ process_output(struct ssh *ssh, fd_set *writeset)
|
||||
|
||||
/* Write buffered data to program stdin. */
|
||||
if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) {
|
||||
data = buffer_ptr(&stdin_buffer);
|
||||
dlen = buffer_len(&stdin_buffer);
|
||||
data = sshbuf_ptr(stdin_buffer);
|
||||
dlen = sshbuf_len(stdin_buffer);
|
||||
len = write(fdin, data, dlen);
|
||||
if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
|
||||
/* do nothing */
|
||||
@@ -480,7 +486,9 @@ process_output(struct ssh *ssh, fd_set *writeset)
|
||||
fatal("%s: %s", __func__, ssh_err(r));
|
||||
}
|
||||
/* Consume the data from the buffer. */
|
||||
buffer_consume(&stdin_buffer, len);
|
||||
if ((r = sshbuf_consume(stdin_buffer, len)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__,
|
||||
ssh_err(r));
|
||||
/* Update the count of bytes written to the program. */
|
||||
stdin_bytes += len;
|
||||
}
|
||||
@@ -500,23 +508,23 @@ drain_output(struct ssh *ssh)
|
||||
int r;
|
||||
|
||||
/* Send any buffered stdout data to the client. */
|
||||
if (buffer_len(&stdout_buffer) > 0) {
|
||||
if (sshbuf_len(stdout_buffer) > 0) {
|
||||
if ((r = sshpkt_start(ssh, SSH_SMSG_STDOUT_DATA)) != 0 ||
|
||||
(r = sshpkt_put_string(ssh, buffer_ptr(&stdout_buffer),
|
||||
buffer_len(&stdout_buffer))) != 0 ||
|
||||
(r = sshpkt_put_string(ssh, sshbuf_ptr(stdout_buffer),
|
||||
sshbuf_len(stdout_buffer))) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
fatal("%s: %s", __func__, ssh_err(r));
|
||||
/* Update the count of sent bytes. */
|
||||
stdout_bytes += buffer_len(&stdout_buffer);
|
||||
stdout_bytes += sshbuf_len(stdout_buffer);
|
||||
}
|
||||
/* Send any buffered stderr data to the client. */
|
||||
if (buffer_len(&stderr_buffer) > 0) {
|
||||
if (sshbuf_len(stderr_buffer) > 0) {
|
||||
if ((r = sshpkt_start(ssh, SSH_SMSG_STDERR_DATA)) != 0 ||
|
||||
(r = sshpkt_put_string(ssh, buffer_ptr(&stderr_buffer),
|
||||
buffer_len(&stderr_buffer))) != 0 ||
|
||||
(r = sshpkt_put_string(ssh, sshbuf_ptr(stderr_buffer),
|
||||
sshbuf_len(stderr_buffer))) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
/* Update the count of sent bytes. */
|
||||
stderr_bytes += buffer_len(&stderr_buffer);
|
||||
stderr_bytes += sshbuf_len(stderr_buffer);
|
||||
}
|
||||
/* Wait until all buffered data has been written to the client. */
|
||||
ssh_packet_write_wait(ssh);
|
||||
@@ -603,9 +611,12 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
||||
#endif
|
||||
|
||||
/* Initialize Initialize buffers. */
|
||||
buffer_init(&stdin_buffer);
|
||||
buffer_init(&stdout_buffer);
|
||||
buffer_init(&stderr_buffer);
|
||||
if ((stdin_buffer = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((stdout_buffer = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((stderr_buffer = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
|
||||
/*
|
||||
* If we have no separate fderr (which is the case when we have a pty
|
||||
@@ -628,7 +639,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
||||
* If we have received eof, and there is no more pending
|
||||
* input data, cause a real eof by closing fdin.
|
||||
*/
|
||||
if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
|
||||
if (stdin_eof && fdin != -1 && sshbuf_len(stdin_buffer) == 0) {
|
||||
if (fdin != fdout)
|
||||
close(fdin);
|
||||
else
|
||||
@@ -646,7 +657,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
||||
* wake up readers from a pty after each separate character.
|
||||
*/
|
||||
max_time_milliseconds = 0;
|
||||
stdout_buffer_bytes = buffer_len(&stdout_buffer);
|
||||
stdout_buffer_bytes = sshbuf_len(stdout_buffer);
|
||||
if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
|
||||
stdout_buffer_bytes != previous_stdout_buffer_bytes) {
|
||||
/* try again after a while */
|
||||
@@ -655,7 +666,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
||||
/* Send it now. */
|
||||
make_packets_from_stdout_data(ssh);
|
||||
}
|
||||
previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);
|
||||
previous_stdout_buffer_bytes = sshbuf_len(stdout_buffer);
|
||||
|
||||
/* Send channel data to the client. */
|
||||
if (ssh_packet_not_very_much_data_to_write(ssh))
|
||||
@@ -667,18 +678,21 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
||||
* client, and there is no pending buffered data.
|
||||
*/
|
||||
if (fdout_eof && fderr_eof && !ssh_packet_have_data_to_write(ssh) &&
|
||||
buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
|
||||
sshbuf_len(stdout_buffer) == 0 && sshbuf_len(stderr_buffer) == 0) {
|
||||
if (!channel_still_open())
|
||||
break;
|
||||
if (!waiting_termination) {
|
||||
const char *s = "Waiting for forwarded connections to terminate...\r\n";
|
||||
char *cp;
|
||||
waiting_termination = 1;
|
||||
buffer_append(&stderr_buffer, s, strlen(s));
|
||||
char *cp = channel_open_message();
|
||||
|
||||
waiting_termination = 1;
|
||||
/* Display list of open channels. */
|
||||
cp = channel_open_message();
|
||||
buffer_append(&stderr_buffer, cp, strlen(cp));
|
||||
if ((r = sshbuf_put(stderr_buffer,
|
||||
s, strlen(s))) != 0 ||
|
||||
(r = sshbuf_put(stderr_buffer,
|
||||
s, strlen(s))) != 0)
|
||||
fatal("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
xfree(cp);
|
||||
}
|
||||
}
|
||||
@@ -721,9 +735,9 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
||||
stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);
|
||||
|
||||
/* Free and clear the buffers. */
|
||||
buffer_free(&stdin_buffer);
|
||||
buffer_free(&stdout_buffer);
|
||||
buffer_free(&stderr_buffer);
|
||||
sshbuf_free(stdin_buffer);
|
||||
sshbuf_free(stdout_buffer);
|
||||
sshbuf_free(stderr_buffer);
|
||||
|
||||
/* Close the file descriptors. */
|
||||
if (fdout != -1)
|
||||
@@ -907,9 +921,9 @@ server_input_stdin_data(int type, u_int32_t seq, struct ssh *ssh)
|
||||
if (fdin == -1)
|
||||
return 0;
|
||||
if ((r = sshpkt_get_string(ssh, &data, &data_len)) != 0 ||
|
||||
(r = sshpkt_get_end(ssh)) != 0)
|
||||
(r = sshpkt_get_end(ssh)) != 0 ||
|
||||
(r = sshbuf_put(stdin_buffer, data, data_len)) != 0)
|
||||
goto out;
|
||||
buffer_append(&stdin_buffer, data, data_len);
|
||||
r = 0;
|
||||
out:
|
||||
if (data) {
|
||||
|
||||
175
ssh/ssh-keygen.c
175
ssh/ssh-keygen.c
@@ -33,7 +33,7 @@
|
||||
#include "rsa.h"
|
||||
#include "authfile.h"
|
||||
#include "uuencode.h"
|
||||
#include "buffer.h"
|
||||
#include "sshbuf.h"
|
||||
#include "pathnames.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
@@ -361,51 +361,61 @@ do_convert_to(struct passwd *pw)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* XXX isn't this just the bignum1 encoding? */
|
||||
static void
|
||||
buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
|
||||
buffer_get_bignum_bits(struct sshbuf *b, BIGNUM *value)
|
||||
{
|
||||
u_int bignum_bits = buffer_get_int(b);
|
||||
u_int bytes = (bignum_bits + 7) / 8;
|
||||
u_int bytes, bignum_bits;
|
||||
int r;
|
||||
|
||||
if (buffer_len(b) < bytes)
|
||||
fatal("buffer_get_bignum_bits: input buffer too small: "
|
||||
"need %d have %d", bytes, buffer_len(b));
|
||||
if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL)
|
||||
fatal("buffer_get_bignum_bits: BN_bin2bn failed");
|
||||
buffer_consume(b, bytes);
|
||||
if ((r = sshbuf_get_u32(b, &bignum_bits)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
bytes = (bignum_bits + 7) / 8;
|
||||
if (sshbuf_len(b) < bytes)
|
||||
fatal("%s: input buffer too small: need %d have %zu",
|
||||
__func__, bytes, sshbuf_len(b));
|
||||
if (BN_bin2bn(sshbuf_ptr(b), bytes, value) == NULL)
|
||||
fatal("%s: BN_bin2bn failed", __func__);
|
||||
if ((r = sshbuf_consume(b, bytes)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
}
|
||||
|
||||
static struct sshkey *
|
||||
do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
|
||||
{
|
||||
Buffer b;
|
||||
struct sshbuf *b;
|
||||
struct sshkey *key = NULL;
|
||||
char *type, *cipher;
|
||||
u_char *sig = NULL, data[] = "abcde12345";
|
||||
int r, magic, rlen, ktype, i1, i2, i3, i4;
|
||||
u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345";
|
||||
int r, rlen, ktype;
|
||||
u_int magic, i1, i2, i3, i4;
|
||||
size_t slen;
|
||||
u_long e;
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, blob, blen);
|
||||
if ((b = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((r = sshbuf_put(b, blob, blen)) != 0 ||
|
||||
(r = sshbuf_get_u32(b, &magic)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
magic = buffer_get_int(&b);
|
||||
if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
|
||||
error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC);
|
||||
buffer_free(&b);
|
||||
error("bad magic 0x%x != 0x%x", magic,
|
||||
SSH_COM_PRIVATE_KEY_MAGIC);
|
||||
sshbuf_free(b);
|
||||
return NULL;
|
||||
}
|
||||
i1 = buffer_get_int(&b);
|
||||
type = buffer_get_string(&b, NULL);
|
||||
cipher = buffer_get_string(&b, NULL);
|
||||
i2 = buffer_get_int(&b);
|
||||
i3 = buffer_get_int(&b);
|
||||
i4 = buffer_get_int(&b);
|
||||
if ((r = sshbuf_get_u32(b, &i1)) != 0 ||
|
||||
(r = sshbuf_get_cstring(b, &type, NULL)) != 0 ||
|
||||
(r = sshbuf_get_cstring(b, &cipher, NULL)) != 0 ||
|
||||
(r = sshbuf_get_u32(b, &i2)) != 0 ||
|
||||
(r = sshbuf_get_u32(b, &i3)) != 0 ||
|
||||
(r = sshbuf_get_u32(b, &i4)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
debug("ignore (%d %d %d %d)", i1, i2, i3, i4);
|
||||
if (strcmp(cipher, "none") != 0) {
|
||||
error("unsupported cipher %s", cipher);
|
||||
xfree(cipher);
|
||||
buffer_free(&b);
|
||||
sshbuf_free(b);
|
||||
xfree(type);
|
||||
return NULL;
|
||||
}
|
||||
@@ -416,7 +426,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
|
||||
} else if (strstr(type, "rsa")) {
|
||||
ktype = KEY_RSA;
|
||||
} else {
|
||||
buffer_free(&b);
|
||||
sshbuf_free(b);
|
||||
xfree(type);
|
||||
return NULL;
|
||||
}
|
||||
@@ -426,42 +436,46 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
|
||||
|
||||
switch (key->type) {
|
||||
case KEY_DSA:
|
||||
buffer_get_bignum_bits(&b, key->dsa->p);
|
||||
buffer_get_bignum_bits(&b, key->dsa->g);
|
||||
buffer_get_bignum_bits(&b, key->dsa->q);
|
||||
buffer_get_bignum_bits(&b, key->dsa->pub_key);
|
||||
buffer_get_bignum_bits(&b, key->dsa->priv_key);
|
||||
buffer_get_bignum_bits(b, key->dsa->p);
|
||||
buffer_get_bignum_bits(b, key->dsa->g);
|
||||
buffer_get_bignum_bits(b, key->dsa->q);
|
||||
buffer_get_bignum_bits(b, key->dsa->pub_key);
|
||||
buffer_get_bignum_bits(b, key->dsa->priv_key);
|
||||
break;
|
||||
case KEY_RSA:
|
||||
e = buffer_get_char(&b);
|
||||
if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
|
||||
(e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||
|
||||
(e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0))
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
e = e1;
|
||||
debug("e %lx", e);
|
||||
if (e < 30) {
|
||||
e <<= 8;
|
||||
e += buffer_get_char(&b);
|
||||
e += e2;
|
||||
debug("e %lx", e);
|
||||
e <<= 8;
|
||||
e += buffer_get_char(&b);
|
||||
e += e3;
|
||||
debug("e %lx", e);
|
||||
}
|
||||
if (!BN_set_word(key->rsa->e, e)) {
|
||||
buffer_free(&b);
|
||||
sshbuf_free(b);
|
||||
sshkey_free(key);
|
||||
return NULL;
|
||||
}
|
||||
buffer_get_bignum_bits(&b, key->rsa->d);
|
||||
buffer_get_bignum_bits(&b, key->rsa->n);
|
||||
buffer_get_bignum_bits(&b, key->rsa->iqmp);
|
||||
buffer_get_bignum_bits(&b, key->rsa->q);
|
||||
buffer_get_bignum_bits(&b, key->rsa->p);
|
||||
buffer_get_bignum_bits(b, key->rsa->d);
|
||||
buffer_get_bignum_bits(b, key->rsa->n);
|
||||
buffer_get_bignum_bits(b, key->rsa->iqmp);
|
||||
buffer_get_bignum_bits(b, key->rsa->q);
|
||||
buffer_get_bignum_bits(b, key->rsa->p);
|
||||
if ((r = rsa_generate_additional_parameters(key->rsa)) != 0)
|
||||
fatal("generate RSA parameters failed: %s", ssh_err(r));
|
||||
break;
|
||||
}
|
||||
rlen = buffer_len(&b);
|
||||
rlen = sshbuf_len(b);
|
||||
if (rlen != 0)
|
||||
error("do_convert_private_ssh2_from_blob: "
|
||||
"remaining bytes in key blob %d", rlen);
|
||||
buffer_free(&b);
|
||||
sshbuf_free(b);
|
||||
|
||||
/* try the key */
|
||||
if (sshkey_sign(key, &sig, &slen, data, sizeof(data), 0) != 0 ||
|
||||
@@ -1453,34 +1467,39 @@ fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
|
||||
}
|
||||
|
||||
static void
|
||||
add_flag_option(Buffer *c, const char *name)
|
||||
add_flag_option(struct sshbuf *c, const char *name)
|
||||
{
|
||||
int r;
|
||||
|
||||
debug3("%s: %s", __func__, name);
|
||||
buffer_put_cstring(c, name);
|
||||
buffer_put_string(c, NULL, 0);
|
||||
if ((r = sshbuf_put_cstring(c, name)) != 0 ||
|
||||
(r = sshbuf_put_string(c, NULL, 0)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
}
|
||||
|
||||
static void
|
||||
add_string_option(Buffer *c, const char *name, const char *value)
|
||||
add_string_option(struct sshbuf *c, const char *name, const char *value)
|
||||
{
|
||||
Buffer b;
|
||||
struct sshbuf *b;
|
||||
int r;
|
||||
|
||||
debug3("%s: %s=%s", __func__, name, value);
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, value);
|
||||
if ((b = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((r = sshbuf_put_cstring(b, value)) != 0 ||
|
||||
(r = sshbuf_put_cstring(c, name)) != 0 ||
|
||||
(r = sshbuf_put_stringb(c, b)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
buffer_put_cstring(c, name);
|
||||
buffer_put_string(c, buffer_ptr(&b), buffer_len(&b));
|
||||
|
||||
buffer_free(&b);
|
||||
sshbuf_free(b);
|
||||
}
|
||||
|
||||
#define OPTIONS_CRITICAL 1
|
||||
#define OPTIONS_EXTENSIONS 2
|
||||
static void
|
||||
prepare_options_buf(Buffer *c, int which)
|
||||
prepare_options_buf(struct sshbuf *c, int which)
|
||||
{
|
||||
buffer_clear(c);
|
||||
sshbuf_reset(c);
|
||||
if ((which & OPTIONS_CRITICAL) != 0 &&
|
||||
certflags_command != NULL)
|
||||
add_string_option(c, "force-command", certflags_command);
|
||||
@@ -1797,21 +1816,23 @@ add_cert_option(char *opt)
|
||||
}
|
||||
|
||||
static void
|
||||
show_options(const Buffer *optbuf, int v00, int in_critical)
|
||||
show_options(const struct sshbuf *optbuf, int v00, int in_critical)
|
||||
{
|
||||
u_char *name, *data;
|
||||
const u_char *odata;
|
||||
u_int dlen;
|
||||
Buffer options, option;
|
||||
char *name, *data;
|
||||
struct sshbuf *options, *option;
|
||||
int r;
|
||||
|
||||
buffer_init(&options);
|
||||
buffer_append(&options, buffer_ptr(optbuf), buffer_len(optbuf));
|
||||
if ((options = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((r = sshbuf_putb(options, optbuf)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
buffer_init(&option);
|
||||
while (buffer_len(&options) != 0) {
|
||||
name = buffer_get_string(&options, NULL);
|
||||
odata = buffer_get_string_ptr(&options, &dlen);
|
||||
buffer_append(&option, odata, dlen);
|
||||
if ((option = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
while (sshbuf_len(options) != 0) {
|
||||
if ((r = sshbuf_get_cstring(options, &name, NULL)) != 0 ||
|
||||
(r = sshbuf_get_stringb(options, option)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
printf(" %s", name);
|
||||
if ((v00 || !in_critical) &&
|
||||
(strcmp(name, "permit-X11-forwarding") == 0 ||
|
||||
@@ -1823,20 +1844,22 @@ show_options(const Buffer *optbuf, int v00, int in_critical)
|
||||
else if ((v00 || in_critical) &&
|
||||
(strcmp(name, "force-command") == 0 ||
|
||||
strcmp(name, "source-address") == 0)) {
|
||||
data = buffer_get_string(&option, NULL);
|
||||
if ((r = sshbuf_get_cstring(option, &data, NULL)) != 0)
|
||||
fatal("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
printf(" %s\n", data);
|
||||
xfree(data);
|
||||
} else {
|
||||
printf(" UNKNOWN OPTION (len %u)\n",
|
||||
buffer_len(&option));
|
||||
buffer_clear(&option);
|
||||
printf(" UNKNOWN OPTION (len %zu)\n",
|
||||
sshbuf_len(option));
|
||||
sshbuf_reset(option);
|
||||
}
|
||||
xfree(name);
|
||||
if (buffer_len(&option) != 0)
|
||||
if (sshbuf_len(option) != 0)
|
||||
fatal("Option corrupt: extra data at end");
|
||||
}
|
||||
buffer_free(&option);
|
||||
buffer_free(&options);
|
||||
sshbuf_free(option);
|
||||
sshbuf_free(options);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1886,7 +1909,7 @@ do_show_cert(struct passwd *pw)
|
||||
printf("\n");
|
||||
}
|
||||
printf(" Critical Options: ");
|
||||
if (buffer_len(key->cert->critical) == 0)
|
||||
if (sshbuf_len(key->cert->critical) == 0)
|
||||
printf("(none)\n");
|
||||
else {
|
||||
printf("\n");
|
||||
@@ -1894,7 +1917,7 @@ do_show_cert(struct passwd *pw)
|
||||
}
|
||||
if (!v00) {
|
||||
printf(" Extensions: ");
|
||||
if (buffer_len(key->cert->extensions) == 0)
|
||||
if (sshbuf_len(key->cert->extensions) == 0)
|
||||
printf("(none)\n");
|
||||
else {
|
||||
printf("\n");
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "sshbuf.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "key.h"
|
||||
@@ -46,13 +45,9 @@ TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist;
|
||||
|
||||
#define MAX_MSG_LENGTH 10240 /*XXX*/
|
||||
|
||||
/* helper */
|
||||
#define get_int() buffer_get_int(&iqueue);
|
||||
#define get_string(lenp) buffer_get_string(&iqueue, lenp);
|
||||
|
||||
/* input and output queue */
|
||||
Buffer iqueue;
|
||||
Buffer oqueue;
|
||||
struct sshbuf *iqueue;
|
||||
struct sshbuf *oqueue;
|
||||
|
||||
static void
|
||||
add_key(struct sshkey *k, char *name)
|
||||
@@ -96,13 +91,12 @@ lookup_key(struct sshkey *k)
|
||||
}
|
||||
|
||||
static void
|
||||
send_msg(Buffer *m)
|
||||
send_msg(struct sshbuf *m)
|
||||
{
|
||||
int mlen = buffer_len(m);
|
||||
int r;
|
||||
|
||||
buffer_put_int(&oqueue, mlen);
|
||||
buffer_append(&oqueue, buffer_ptr(m), mlen);
|
||||
buffer_consume(m, mlen);
|
||||
if ((r = sshbuf_put_stringb(oqueue, m)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -113,20 +107,24 @@ process_add(void)
|
||||
int r, i, nkeys;
|
||||
u_char *blob;
|
||||
size_t blen;
|
||||
Buffer msg;
|
||||
struct sshbuf *msg;
|
||||
|
||||
buffer_init(&msg);
|
||||
name = get_string(NULL);
|
||||
pin = get_string(NULL);
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
|
||||
(r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
if ((nkeys = pkcs11_add_provider(name, pin, &keys)) > 0) {
|
||||
buffer_put_char(&msg, SSH2_AGENT_IDENTITIES_ANSWER);
|
||||
buffer_put_int(&msg, nkeys);
|
||||
if ((r = sshbuf_put_u8(msg,
|
||||
SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
|
||||
(r = sshbuf_put_u32(msg, nkeys)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
if ((r = sshkey_to_blob(keys[i], &blob, &blen)) != 0)
|
||||
fatal("%s: sshkey_to_blob: %s",
|
||||
__func__, ssh_err(r));
|
||||
if ((r = sshbuf_put_string(&msg, blob, blen)) != 0 ||
|
||||
(r = sshbuf_put_cstring(&msg, name)) != 0)
|
||||
if ((r = sshbuf_put_string(msg, blob, blen)) != 0 ||
|
||||
(r = sshbuf_put_cstring(msg, name)) != 0)
|
||||
fatal("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
xfree(blob);
|
||||
@@ -134,46 +132,50 @@ process_add(void)
|
||||
}
|
||||
xfree(keys);
|
||||
} else {
|
||||
buffer_put_char(&msg, SSH_AGENT_FAILURE);
|
||||
if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
}
|
||||
xfree(pin);
|
||||
xfree(name);
|
||||
send_msg(&msg);
|
||||
buffer_free(&msg);
|
||||
send_msg(msg);
|
||||
sshbuf_free(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
process_del(void)
|
||||
{
|
||||
char *name, *pin;
|
||||
Buffer msg;
|
||||
struct sshbuf *msg;
|
||||
int r;
|
||||
|
||||
buffer_init(&msg);
|
||||
name = get_string(NULL);
|
||||
pin = get_string(NULL);
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
|
||||
(r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
del_keys_by_name(name);
|
||||
if (pkcs11_del_provider(name) == 0)
|
||||
buffer_put_char(&msg, SSH_AGENT_SUCCESS);
|
||||
else
|
||||
buffer_put_char(&msg, SSH_AGENT_FAILURE);
|
||||
if ((r = sshbuf_put_u8(msg, pkcs11_del_provider(name) == 0 ?
|
||||
SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
xfree(pin);
|
||||
xfree(name);
|
||||
send_msg(&msg);
|
||||
buffer_free(&msg);
|
||||
send_msg(msg);
|
||||
sshbuf_free(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
process_sign(void)
|
||||
{
|
||||
u_char *blob, *data, *signature = NULL;
|
||||
u_int blen, dlen, slen = 0;
|
||||
size_t blen, dlen, slen = 0;
|
||||
int r, ok = -1, ret;
|
||||
struct sshkey *key, *found;
|
||||
Buffer msg;
|
||||
struct sshbuf *msg;
|
||||
|
||||
blob = get_string(&blen);
|
||||
data = get_string(&dlen);
|
||||
(void)get_int(); /* XXX ignore flags */
|
||||
if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 ||
|
||||
(r = sshbuf_get_string(iqueue, &data, &dlen)) != 0 ||
|
||||
(r = sshbuf_get_u32(iqueue, NULL)) != 0) /* ignore flags */
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
|
||||
error("%s: sshkey_from_blob: %s", __func__, ssh_err(r));
|
||||
@@ -189,19 +191,22 @@ process_sign(void)
|
||||
}
|
||||
sshkey_free(key);
|
||||
}
|
||||
buffer_init(&msg);
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if (ok == 0) {
|
||||
buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE);
|
||||
buffer_put_string(&msg, signature, slen);
|
||||
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
|
||||
(r = sshbuf_put_string(msg, signature, slen)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
} else {
|
||||
buffer_put_char(&msg, SSH_AGENT_FAILURE);
|
||||
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_FAILURE)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
}
|
||||
xfree(data);
|
||||
xfree(blob);
|
||||
if (signature != NULL)
|
||||
xfree(signature);
|
||||
send_msg(&msg);
|
||||
buffer_free(&msg);
|
||||
send_msg(msg);
|
||||
sshbuf_free(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -210,13 +215,14 @@ process(void)
|
||||
u_int msg_len;
|
||||
u_int buf_len;
|
||||
u_int consumed;
|
||||
u_int type;
|
||||
u_char type;
|
||||
u_char *cp;
|
||||
int r;
|
||||
|
||||
buf_len = buffer_len(&iqueue);
|
||||
buf_len = sshbuf_len(iqueue);
|
||||
if (buf_len < 5)
|
||||
return; /* Incomplete message. */
|
||||
cp = buffer_ptr(&iqueue);
|
||||
cp = sshbuf_ptr(iqueue);
|
||||
msg_len = get_u32(cp);
|
||||
if (msg_len > MAX_MSG_LENGTH) {
|
||||
error("bad message len %d", msg_len);
|
||||
@@ -224,9 +230,10 @@ process(void)
|
||||
}
|
||||
if (buf_len < msg_len + 4)
|
||||
return;
|
||||
buffer_consume(&iqueue, 4);
|
||||
if ((r = sshbuf_consume(iqueue, 4)) != 0 ||
|
||||
(r = sshbuf_get_u8(iqueue, &type)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
buf_len -= 4;
|
||||
type = buffer_get_char(&iqueue);
|
||||
switch (type) {
|
||||
case SSH_AGENTC_ADD_SMARTCARD_KEY:
|
||||
debug("process_add");
|
||||
@@ -245,17 +252,19 @@ process(void)
|
||||
break;
|
||||
}
|
||||
/* discard the remaining bytes from the current packet */
|
||||
if (buf_len < buffer_len(&iqueue)) {
|
||||
if (buf_len < sshbuf_len(iqueue)) {
|
||||
error("iqueue grew unexpectedly");
|
||||
cleanup_exit(255);
|
||||
}
|
||||
consumed = buf_len - buffer_len(&iqueue);
|
||||
consumed = buf_len - sshbuf_len(iqueue);
|
||||
if (msg_len < consumed) {
|
||||
error("msg_len %d < consumed %d", msg_len, consumed);
|
||||
cleanup_exit(255);
|
||||
}
|
||||
if (msg_len > consumed)
|
||||
buffer_consume(&iqueue, msg_len - consumed);
|
||||
if (msg_len > consumed) {
|
||||
if ((r = sshbuf_consume(iqueue, msg_len - consumed)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -269,7 +278,7 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
fd_set *rset, *wset;
|
||||
int in, out, max, log_stderr = 0;
|
||||
int r, in, out, max, log_stderr = 0;
|
||||
ssize_t len, olen, set_size;
|
||||
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
|
||||
LogLevel log_level = SYSLOG_LEVEL_ERROR;
|
||||
@@ -291,8 +300,10 @@ main(int argc, char **argv)
|
||||
if (out > max)
|
||||
max = out;
|
||||
|
||||
buffer_init(&iqueue);
|
||||
buffer_init(&oqueue);
|
||||
if ((iqueue = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((oqueue = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
|
||||
set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask);
|
||||
rset = (fd_set *)xmalloc(set_size);
|
||||
@@ -307,11 +318,13 @@ main(int argc, char **argv)
|
||||
* the worst-case length packet it can generate,
|
||||
* otherwise apply backpressure by stopping reads.
|
||||
*/
|
||||
if (buffer_check_alloc(&iqueue, sizeof(buf)) &&
|
||||
buffer_check_alloc(&oqueue, MAX_MSG_LENGTH))
|
||||
if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 &&
|
||||
(r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0)
|
||||
FD_SET(in, rset);
|
||||
else if (r != SSH_ERR_NO_BUFFER_SPACE)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
olen = buffer_len(&oqueue);
|
||||
olen = sshbuf_len(oqueue);
|
||||
if (olen > 0)
|
||||
FD_SET(out, wset);
|
||||
|
||||
@@ -331,18 +344,20 @@ main(int argc, char **argv)
|
||||
} else if (len < 0) {
|
||||
error("read: %s", strerror(errno));
|
||||
cleanup_exit(1);
|
||||
} else {
|
||||
buffer_append(&iqueue, buf, len);
|
||||
} else if ((r = sshbuf_put(iqueue, buf, len)) != 0) {
|
||||
fatal("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
}
|
||||
}
|
||||
/* send oqueue to stdout */
|
||||
if (FD_ISSET(out, wset)) {
|
||||
len = write(out, buffer_ptr(&oqueue), olen);
|
||||
len = write(out, sshbuf_ptr(oqueue), olen);
|
||||
if (len < 0) {
|
||||
error("write: %s", strerror(errno));
|
||||
cleanup_exit(1);
|
||||
} else {
|
||||
buffer_consume(&oqueue, len);
|
||||
} else if ((r = sshbuf_consume(oqueue, len)) != 0) {
|
||||
fatal("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,7 +366,9 @@ main(int argc, char **argv)
|
||||
* into the output buffer, otherwise stop processing input
|
||||
* and let the output queue drain.
|
||||
*/
|
||||
if (buffer_check_alloc(&oqueue, MAX_MSG_LENGTH))
|
||||
if ((r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0)
|
||||
process();
|
||||
else if (r != SSH_ERR_NO_BUFFER_SPACE)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
}
|
||||
}
|
||||
|
||||
144
ssh/sshd.c
144
ssh/sshd.c
@@ -77,7 +77,7 @@
|
||||
#define PACKET_SKIP_COMPAT2
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "sshbuf.h"
|
||||
#include "servconf.h"
|
||||
#include "uidswap.h"
|
||||
#include "compat.h"
|
||||
@@ -228,7 +228,7 @@ int privsep_is_preauth = 1;
|
||||
Authctxt *the_authctxt = NULL;
|
||||
|
||||
/* sshd_config buffer */
|
||||
Buffer cfg;
|
||||
struct sshbuf *cfg;
|
||||
|
||||
/* message to be displayed after login */
|
||||
struct sshbuf *loginmsg = NULL;
|
||||
@@ -743,13 +743,13 @@ privsep_postauth(struct ssh *ssh)
|
||||
static char *
|
||||
list_hostkey_types(void)
|
||||
{
|
||||
Buffer b;
|
||||
const char *p;
|
||||
struct sshbuf *b;
|
||||
char *ret;
|
||||
int i;
|
||||
int r, i;
|
||||
struct sshkey *key;
|
||||
|
||||
buffer_init(&b);
|
||||
if ((b = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
for (i = 0; i < options.num_host_key_files; i++) {
|
||||
key = sensitive_data.host_keys[i];
|
||||
if (key == NULL)
|
||||
@@ -758,10 +758,11 @@ list_hostkey_types(void)
|
||||
case KEY_RSA:
|
||||
case KEY_DSA:
|
||||
case KEY_ECDSA:
|
||||
if (buffer_len(&b) > 0)
|
||||
buffer_append(&b, ",", 1);
|
||||
p = sshkey_ssh_name(key);
|
||||
buffer_append(&b, p, strlen(p));
|
||||
if ((r = sshbuf_putf(b, "%s%s",
|
||||
sshbuf_len(b) > 0 ? "," : "",
|
||||
sshkey_ssh_name(key))) != 0)
|
||||
fatal("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
break;
|
||||
}
|
||||
/* If the private key has a cert peer, then list that too */
|
||||
@@ -774,16 +775,18 @@ list_hostkey_types(void)
|
||||
case KEY_RSA_CERT:
|
||||
case KEY_DSA_CERT:
|
||||
case KEY_ECDSA_CERT:
|
||||
if (buffer_len(&b) > 0)
|
||||
buffer_append(&b, ",", 1);
|
||||
p = sshkey_ssh_name(key);
|
||||
buffer_append(&b, p, strlen(p));
|
||||
if ((r = sshbuf_putf(b, "%s%s",
|
||||
sshbuf_len(b) > 0 ? "," : "",
|
||||
sshkey_ssh_name(key))) != 0)
|
||||
fatal("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
break;
|
||||
}
|
||||
}
|
||||
buffer_append(&b, "\0", 1);
|
||||
ret = xstrdup(buffer_ptr(&b));
|
||||
buffer_free(&b);
|
||||
if ((r = sshbuf_put_u8(b, 0)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
ret = xstrdup(sshbuf_ptr(b));
|
||||
sshbuf_free(b);
|
||||
debug("list_hostkey_types: %s", ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -893,12 +896,13 @@ usage(void)
|
||||
}
|
||||
|
||||
static void
|
||||
send_rexec_state(int fd, Buffer *conf)
|
||||
send_rexec_state(int fd, struct sshbuf *conf)
|
||||
{
|
||||
Buffer m;
|
||||
struct sshbuf *m;
|
||||
int r;
|
||||
|
||||
debug3("%s: entering fd = %d config len %d", __func__, fd,
|
||||
buffer_len(conf));
|
||||
debug3("%s: entering fd = %d config len %zu", __func__, fd,
|
||||
sshbuf_len(conf));
|
||||
|
||||
/*
|
||||
* Protocol from reexec master to child:
|
||||
@@ -911,68 +915,90 @@ send_rexec_state(int fd, Buffer *conf)
|
||||
* bignum p "
|
||||
* bignum q "
|
||||
*/
|
||||
buffer_init(&m);
|
||||
buffer_put_cstring(&m, buffer_ptr(conf));
|
||||
if ((m = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
/* servconf.c:load_server_config() ensures a \0 at the end of cfg */
|
||||
if ((r = sshbuf_put_cstring(m, sshbuf_ptr(conf))) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
if (sensitive_data.server_key != NULL &&
|
||||
sensitive_data.server_key->type == KEY_RSA1) {
|
||||
buffer_put_int(&m, 1);
|
||||
buffer_put_bignum(&m, sensitive_data.server_key->rsa->e);
|
||||
buffer_put_bignum(&m, sensitive_data.server_key->rsa->n);
|
||||
buffer_put_bignum(&m, sensitive_data.server_key->rsa->d);
|
||||
buffer_put_bignum(&m, sensitive_data.server_key->rsa->iqmp);
|
||||
buffer_put_bignum(&m, sensitive_data.server_key->rsa->p);
|
||||
buffer_put_bignum(&m, sensitive_data.server_key->rsa->q);
|
||||
} else
|
||||
buffer_put_int(&m, 0);
|
||||
if ((r = sshbuf_put_u32(m, 1)) != 0 ||
|
||||
(r = sshbuf_put_bignum1(m,
|
||||
sensitive_data.server_key->rsa->e)) != 0 ||
|
||||
(r = sshbuf_put_bignum1(m,
|
||||
sensitive_data.server_key->rsa->n)) != 0 ||
|
||||
(r = sshbuf_put_bignum1(m,
|
||||
sensitive_data.server_key->rsa->d)) != 0 ||
|
||||
(r = sshbuf_put_bignum1(m,
|
||||
sensitive_data.server_key->rsa->iqmp)) != 0 ||
|
||||
(r = sshbuf_put_bignum1(m,
|
||||
sensitive_data.server_key->rsa->p)) != 0 ||
|
||||
(r = sshbuf_put_bignum1(m,
|
||||
sensitive_data.server_key->rsa->q)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
} else if ((r = sshbuf_put_u32(m, 0)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
if (ssh_msg_send(fd, 0, &m) == -1)
|
||||
if (ssh_msg_send(fd, 0, m) == -1)
|
||||
fatal("%s: ssh_msg_send failed", __func__);
|
||||
|
||||
buffer_free(&m);
|
||||
sshbuf_free(m);
|
||||
|
||||
debug3("%s: done", __func__);
|
||||
}
|
||||
|
||||
static void
|
||||
recv_rexec_state(int fd, Buffer *conf)
|
||||
recv_rexec_state(int fd, struct sshbuf *conf)
|
||||
{
|
||||
Buffer m;
|
||||
struct sshbuf *m;
|
||||
char *cp;
|
||||
u_int len;
|
||||
size_t len;
|
||||
int r;
|
||||
u_char ver;
|
||||
u_int key_follows;
|
||||
|
||||
debug3("%s: entering fd = %d", __func__, fd);
|
||||
|
||||
buffer_init(&m);
|
||||
if ((m = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
|
||||
if (ssh_msg_recv(fd, &m) == -1)
|
||||
if (ssh_msg_recv(fd, m) == -1)
|
||||
fatal("%s: ssh_msg_recv failed", __func__);
|
||||
if (buffer_get_char(&m) != 0)
|
||||
if ((r = sshbuf_get_u8(m, &ver)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
if (ver != 0)
|
||||
fatal("%s: rexec version mismatch", __func__);
|
||||
|
||||
cp = buffer_get_string(&m, &len);
|
||||
if (conf != NULL)
|
||||
buffer_append(conf, cp, len + 1);
|
||||
if ((r = sshbuf_get_cstring(m, &cp, &len)) != 0 ||
|
||||
(conf != NULL && (r = sshbuf_put(conf, cp, len + 1)) != 0) ||
|
||||
(r = sshbuf_get_u32(m, &key_follows)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
xfree(cp);
|
||||
|
||||
if (buffer_get_int(&m)) {
|
||||
if (key_follows) {
|
||||
if (sensitive_data.server_key != NULL)
|
||||
sshkey_free(sensitive_data.server_key);
|
||||
sensitive_data.server_key = sshkey_new_private(KEY_RSA1);
|
||||
if (sensitive_data.server_key == NULL)
|
||||
fatal("%s: sshkey_new_private failed", __func__);
|
||||
buffer_get_bignum(&m, sensitive_data.server_key->rsa->e);
|
||||
buffer_get_bignum(&m, sensitive_data.server_key->rsa->n);
|
||||
buffer_get_bignum(&m, sensitive_data.server_key->rsa->d);
|
||||
buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp);
|
||||
buffer_get_bignum(&m, sensitive_data.server_key->rsa->p);
|
||||
buffer_get_bignum(&m, sensitive_data.server_key->rsa->q);
|
||||
if ((r = sshbuf_get_bignum1(m,
|
||||
sensitive_data.server_key->rsa->e)) != 0 ||
|
||||
(r = sshbuf_get_bignum1(m,
|
||||
sensitive_data.server_key->rsa->n)) != 0 ||
|
||||
(r = sshbuf_get_bignum1(m,
|
||||
sensitive_data.server_key->rsa->d)) != 0 ||
|
||||
(r = sshbuf_get_bignum1(m,
|
||||
sensitive_data.server_key->rsa->iqmp)) != 0 ||
|
||||
(r = sshbuf_get_bignum1(m,
|
||||
sensitive_data.server_key->rsa->p)) != 0 ||
|
||||
(r = sshbuf_get_bignum1(m,
|
||||
sensitive_data.server_key->rsa->q)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
if ((r = rsa_generate_additional_parameters(
|
||||
sensitive_data.server_key->rsa)) != 0)
|
||||
fatal("generate RSA parameters failed: %s", ssh_err(r));
|
||||
}
|
||||
buffer_free(&m);
|
||||
sshbuf_free(m);
|
||||
|
||||
debug3("%s: done", __func__);
|
||||
}
|
||||
@@ -1218,8 +1244,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
|
||||
startup_pipe = -1;
|
||||
pid = getpid();
|
||||
if (rexec_flag) {
|
||||
send_rexec_state(config_s[0],
|
||||
&cfg);
|
||||
send_rexec_state(config_s[0], cfg);
|
||||
close(config_s[0]);
|
||||
}
|
||||
break;
|
||||
@@ -1262,7 +1287,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
|
||||
close(startup_p[1]);
|
||||
|
||||
if (rexec_flag) {
|
||||
send_rexec_state(config_s[0], &cfg);
|
||||
send_rexec_state(config_s[0], cfg);
|
||||
close(config_s[0]);
|
||||
close(config_s[1]);
|
||||
}
|
||||
@@ -1482,14 +1507,15 @@ main(int ac, char **av)
|
||||
"test mode (-T)");
|
||||
|
||||
/* Fetch our configuration */
|
||||
buffer_init(&cfg);
|
||||
if ((cfg = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if (rexeced_flag)
|
||||
recv_rexec_state(REEXEC_CONFIG_PASS_FD, &cfg);
|
||||
recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg);
|
||||
else
|
||||
load_server_config(config_file_name, &cfg);
|
||||
load_server_config(config_file_name, cfg);
|
||||
|
||||
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
|
||||
&cfg, NULL);
|
||||
cfg, NULL);
|
||||
|
||||
/* Fill in default values for those options not explicitly set. */
|
||||
fill_default_server_options(&options);
|
||||
|
||||
Reference in New Issue
Block a user