Skip to content

Commit

Permalink
Merge pull request #7 from tigeli/master
Browse files Browse the repository at this point in the history
fix security issues
  • Loading branch information
tigeli committed Mar 30, 2015
2 parents 24366e9 + 688db91 commit 994e71a
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 26 deletions.
2 changes: 1 addition & 1 deletion openssh/auth-options.c
Expand Up @@ -172,7 +172,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
goto bad_option;
}
forced_command[i] = '\0';
auth_debug_add("Forced command: %.900s", forced_command);
auth_debug_add("Forced command.");
opts++;
goto next_option;
}
Expand Down
33 changes: 33 additions & 0 deletions openssh/bufaux.c
Expand Up @@ -202,6 +202,39 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr)
return (ret);
}

char *
buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr)
{
u_int length;
char *cp, *ret = buffer_get_string_ret(buffer, &length);

if (ret == NULL)
return NULL;
if ((cp = memchr(ret, '\0', length)) != NULL) {
/* XXX allow \0 at end-of-string for a while, remove later */
if (cp == ret + length - 1)
error("buffer_get_cstring_ret: string contains \\0");
else {
bzero(ret, length);
xfree(ret);
return NULL;
}
}
if (length_ptr != NULL)
*length_ptr = length;
return ret;
}

char *
buffer_get_cstring(Buffer *buffer, u_int *length_ptr)
{
char *ret;

if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL)
fatal("buffer_get_cstring: buffer error");
return ret;
}

void *
buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr)
{
Expand Down
2 changes: 2 additions & 0 deletions openssh/buffer.h
Expand Up @@ -68,6 +68,7 @@ void buffer_put_char(Buffer *, int);
void *buffer_get_string(Buffer *, u_int *);
void *buffer_get_string_ptr(Buffer *, u_int *);
void buffer_put_string(Buffer *, const void *, u_int);
char *buffer_get_cstring(Buffer *, u_int *);
void buffer_put_cstring(Buffer *, const char *);

#define buffer_skip_string(b) \
Expand All @@ -81,6 +82,7 @@ int buffer_get_short_ret(u_short *, Buffer *);
int buffer_get_int_ret(u_int *, Buffer *);
int buffer_get_int64_ret(u_int64_t *, Buffer *);
void *buffer_get_string_ret(Buffer *, u_int *);
char *buffer_get_cstring_ret(Buffer *, u_int *);
void *buffer_get_string_ptr_ret(Buffer *, u_int *);
int buffer_get_char_ret(char *, Buffer *);

Expand Down
2 changes: 2 additions & 0 deletions openssh/gss-serv.c
Expand Up @@ -229,6 +229,8 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
name->length = get_u32(tok+offset);
offset += 4;

if (UINT_MAX - offset < name->length)
return GSS_S_FAILURE;
if (ename->length < offset+name->length)
return GSS_S_FAILURE;

Expand Down
2 changes: 1 addition & 1 deletion openssh/key.c
Expand Up @@ -1515,8 +1515,8 @@ key_certify(Key *k, Key *ca)
buffer_put_cstring(&k->cert->certblob, key_ssh_name(k));

/* -v01 certs put nonce first */
arc4random_buf(&nonce, sizeof(nonce));
if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) {
arc4random_buf(&nonce, sizeof(nonce));
buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
}

Expand Down
7 changes: 7 additions & 0 deletions openssh/packet.c
Expand Up @@ -1546,6 +1546,13 @@ packet_get_string_ptr(u_int *length_ptr)
return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
}

/* Ensures the returned string has no embedded \0 characters in it. */
char *
packet_get_cstring(u_int *length_ptr)
{
return buffer_get_cstring(&active_state->incoming_packet, length_ptr);
}

/*
* Sends a diagnostic message from the server to the client. This message
* can be sent at any time (but not while constructing another message). The
Expand Down
1 change: 1 addition & 0 deletions openssh/packet.h
Expand Up @@ -61,6 +61,7 @@ void packet_get_bignum(BIGNUM * value);
void packet_get_bignum2(BIGNUM * value);
void *packet_get_raw(u_int *length_ptr);
void *packet_get_string(u_int *length_ptr);
char *packet_get_cstring(u_int *length_ptr);
void *packet_get_string_ptr(u_int *length_ptr);
void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2)));
void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2)));
Expand Down
6 changes: 3 additions & 3 deletions openssh/servconf.c
Expand Up @@ -242,11 +242,11 @@ fill_default_server_options(ServerOptions *options)
if (options->gateway_ports == -1)
options->gateway_ports = 0;
if (options->max_startups == -1)
options->max_startups = 10;
options->max_startups = 100;
if (options->max_startups_rate == -1)
options->max_startups_rate = 100; /* 100% */
options->max_startups_rate = 30; /* 30% */
if (options->max_startups_begin == -1)
options->max_startups_begin = options->max_startups;
options->max_startups_begin = 10;
if (options->max_authtries == -1)
options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
if (options->max_sessions == -1)
Expand Down
9 changes: 7 additions & 2 deletions openssh/session.c
Expand Up @@ -946,6 +946,11 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
u_int envsize;
u_int i, namelen;

if (strchr(name, '=') != NULL) {
error("Invalid environment variable \"%.100s\"", name);
return;
}

/*
* If we're passed an uninitialized list, allocate a single null
* entry before continuing.
Expand Down Expand Up @@ -2234,8 +2239,8 @@ session_env_req(Session *s)
char *name, *val;
u_int name_len, val_len, i;

name = packet_get_string(&name_len);
val = packet_get_string(&val_len);
name = packet_get_cstring(&name_len);
val = packet_get_cstring(&val_len);
packet_check_eom();

/* Don't set too many environment variables */
Expand Down
43 changes: 26 additions & 17 deletions openssh/sshconnect.c
Expand Up @@ -1052,26 +1052,35 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
{
struct stat st;
int flags = 0;
Key *plain = NULL;

/* XXX certs are not yet supported for DNS */
if (!key_is_cert(host_key) && options.verify_host_key_dns &&
verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {

if (flags & DNS_VERIFY_FOUND) {

if (options.verify_host_key_dns == 1 &&
flags & DNS_VERIFY_MATCH &&
flags & DNS_VERIFY_SECURE)
return 0;

if (flags & DNS_VERIFY_MATCH) {
matching_host_key_dns = 1;
} else {
warn_changed_key(host_key);
error("Update the SSHFP RR in DNS with the new "
"host key to get rid of this message.");
if (options.verify_host_key_dns) {
/*
* XXX certs are not yet supported for DNS, so downgrade
* them and try the plain key.
*/
plain = key_from_private(host_key);
if (key_is_cert(plain))
key_drop_cert(plain);
if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) {
if (flags & DNS_VERIFY_FOUND) {
if (options.verify_host_key_dns == 1 &&
flags & DNS_VERIFY_MATCH &&
flags & DNS_VERIFY_SECURE) {
key_free(plain);
return 0;
}
if (flags & DNS_VERIFY_MATCH) {
matching_host_key_dns = 1;
} else {
warn_changed_key(plain);
error("Update the SSHFP RR in DNS "
"with the new host key to get rid "
"of this message.");
}
}
}
key_free(plain);
}

/* return ok if the key can be found in an old keyfile */
Expand Down
2 changes: 1 addition & 1 deletion openssh/sshd_config
Expand Up @@ -117,7 +117,7 @@ X11Forwarding yes
#ShowPatchLevel no
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none

Expand Down
2 changes: 1 addition & 1 deletion openssh/sshd_config.5
Expand Up @@ -701,7 +701,7 @@ SSH daemon.
Additional connections will be dropped until authentication succeeds or the
.Cm LoginGraceTime
expires for a connection.
The default is 10.
The default is 10:30:100.
.Pp
Alternatively, random early drop can be enabled by specifying
the three colon separated values
Expand Down

0 comments on commit 994e71a

Please sign in to comment.