convert serverloop.c ssh-keygen.c ssh-pkcs11-helper.c to new buffer API

This commit is contained in:
Damien Miller
2012-09-21 03:50:06 +10:00
parent 75875617b2
commit ece6575b3c
5 changed files with 337 additions and 257 deletions

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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");

View File

@@ -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));
}
}

View File

@@ -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);