sync with OpenBSD -current

This commit is contained in:
purplerain 2024-05-21 00:16:53 +00:00
parent 57ecf9bd1d
commit b5356a44af
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
156 changed files with 3600 additions and 2644 deletions

View file

@ -1,8 +1,9 @@
# $OpenBSD: Makefile,v 1.17 2019/10/31 21:22:01 djm Exp $
# $OpenBSD: Makefile,v 1.18 2024/05/17 00:30:23 djm Exp $
.include <bsd.own.mk>
SUBDIR= ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server \
SUBDIR= ssh sshd sshd-session \
ssh-add ssh-keygen ssh-agent scp sftp-server \
ssh-keysign ssh-keyscan sftp ssh-pkcs11-helper ssh-sk-helper
distribution:

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile.inc,v 1.89 2024/01/11 01:45:36 djm Exp $
# $OpenBSD: Makefile.inc,v 1.90 2024/05/17 00:30:23 djm Exp $
.include <bsd.own.mk>
@ -25,7 +25,7 @@ CDIAGFLAGS+= -Wstrict-aliasing=2
CDIAGFLAGS+= -Wold-style-definition
.endif
#CDIAGFLAGS+= -Werror
CDIAGFLAGS+= -Werror
#CDIAGFLAGS+= -fno-common
#DEBUG=-g
#INSTALL_STRIP=
@ -111,14 +111,17 @@ SRCS_KEYP+= atomicio.c
SRCS_KRL+= bitmap.c
SRCS_KRL+= krl.c
SRCS_MAC+= mac.c
SRCS_MAC+= hmac.c
SRCS_MAC+= umac.c
SRCS_MAC+= umac128.c
SRCS_PKT+= canohost.c
SRCS_PKT+= dispatch.c
SRCS_PKT+= hmac.c
SRCS_PKT+= kex.c
SRCS_PKT+= mac.c
SRCS_PKT+= kex-names.c
SRCS_PKT+= packet.c
SRCS_PKT+= umac.c
SRCS_PKT+= umac128.c
SRCS_PKT+= ${SRCS_MAC}
SRCS_PROT+= channels.c
SRCS_PROT+= monitor_fdpass.c

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth-rhosts.c,v 1.57 2022/12/09 00:17:40 dtucker Exp $ */
/* $OpenBSD: auth-rhosts.c,v 1.58 2024/05/17 00:30:23 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -42,7 +42,6 @@
/* import */
extern ServerOptions options;
extern int use_privsep;
/*
* This function processes an rhosts-style file (.rhosts, .shosts, or

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.160 2023/03/05 05:34:09 dtucker Exp $ */
/* $OpenBSD: auth.c,v 1.161 2024/05/17 00:30:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -67,7 +67,6 @@
/* import */
extern ServerOptions options;
extern struct include_list includes;
extern int use_privsep;
extern struct sshauthopt *auth_opts;
/* Debugging messages */
@ -246,7 +245,7 @@ auth_log(struct ssh *ssh, int authenticated, int partial,
const char *authmsg;
char *extra = NULL;
if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
if (!mm_is_monitor() && !authctxt->postponed)
return;
/* Raise logging level */
@ -420,14 +419,14 @@ getpwnamallow(struct ssh *ssh, const char *user)
struct connection_info *ci;
u_int i;
ci = get_connection_info(ssh, 1, options.use_dns);
ci = server_get_connection_info(ssh, 1, options.use_dns);
ci->user = user;
parse_server_match_config(&options, &includes, ci);
log_change_level(options.log_level);
log_verbose_reset();
for (i = 0; i < options.num_log_verbose; i++)
log_verbose_add(options.log_verbose[i]);
process_permitopen(ssh, &options);
server_process_permitopen(ssh);
pw = getpwnam(user);
if (pw == NULL) {
@ -562,93 +561,6 @@ fakepw(void)
return (&fake);
}
/*
* Returns the remote DNS hostname as a string. The returned string must not
* be freed. NB. this will usually trigger a DNS query the first time it is
* called.
* This function does additional checks on the hostname to mitigate some
* attacks on based on conflation of hostnames and IP addresses.
*/
static char *
remote_hostname(struct ssh *ssh)
{
struct sockaddr_storage from;
socklen_t fromlen;
struct addrinfo hints, *ai, *aitop;
char name[NI_MAXHOST], ntop2[NI_MAXHOST];
const char *ntop = ssh_remote_ipaddr(ssh);
/* Get IP address of client. */
fromlen = sizeof(from);
memset(&from, 0, sizeof(from));
if (getpeername(ssh_packet_get_connection_in(ssh),
(struct sockaddr *)&from, &fromlen) == -1) {
debug("getpeername failed: %.100s", strerror(errno));
return xstrdup(ntop);
}
debug3("Trying to reverse map address %.100s.", ntop);
/* Map the IP address to a host name. */
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
NULL, 0, NI_NAMEREQD) != 0) {
/* Host name not found. Use ip address. */
return xstrdup(ntop);
}
/*
* if reverse lookup result looks like a numeric hostname,
* someone is trying to trick us by PTR record like following:
* 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
*/
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
name, ntop);
freeaddrinfo(ai);
return xstrdup(ntop);
}
/* Names are stored in lowercase. */
lowercase(name);
/*
* Map it back to an IP address and check that the given
* address actually is an address of this host. This is
* necessary because anyone with access to a name server can
* define arbitrary names for an IP address. Mapping from
* name to IP address can be trusted better (but can still be
* fooled if the intruder has access to the name server of
* the domain).
*/
memset(&hints, 0, sizeof(hints));
hints.ai_family = from.ss_family;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
logit("reverse mapping checking getaddrinfo for %.700s "
"[%s] failed.", name, ntop);
return xstrdup(ntop);
}
/* Look for the address from the list of addresses. */
for (ai = aitop; ai; ai = ai->ai_next) {
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
(strcmp(ntop, ntop2) == 0))
break;
}
freeaddrinfo(aitop);
/* If we reached the end of the list, the address was not there. */
if (ai == NULL) {
/* Address not found for the host name. */
logit("Address %.100s maps to %.600s, but this does not "
"map back to the address.", ntop, name);
return xstrdup(ntop);
}
return xstrdup(name);
}
/*
* Return the canonical name of the host in the other side of the current
* connection. The host name is cached, so it is efficient to call this
@ -662,12 +574,10 @@ auth_get_canonical_hostname(struct ssh *ssh, int use_dns)
if (!use_dns)
return ssh_remote_ipaddr(ssh);
else if (dnsname != NULL)
if (dnsname != NULL)
return dnsname;
else {
dnsname = remote_hostname(ssh);
return dnsname;
}
dnsname = ssh_remote_hostname(ssh);
return dnsname;
}
/* These functions link key/cert options to the auth framework */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth.h,v 1.106 2022/06/15 16:08:25 djm Exp $ */
/* $OpenBSD: auth.h,v 1.108 2024/05/17 06:42:04 jsg Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -95,11 +95,15 @@ struct Authctxt {
* the client.
*/
struct authmethod_cfg {
const char *name;
const char *synonym;
int *enabled;
};
struct Authmethod {
char *name;
char *synonym;
struct authmethod_cfg *cfg;
int (*userauth)(struct ssh *, const char *);
int *enabled;
};
/*
@ -142,8 +146,6 @@ void auth2_record_info(Authctxt *authctxt, const char *, ...)
void auth2_update_session_info(Authctxt *, const char *, const char *);
#ifdef KRB5
int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
int auth_krb5_password(Authctxt *authctxt, const char *password);
void krb5_cleanup_proc(Authctxt *authctxt);
#endif /* KRB5 */
@ -192,7 +194,6 @@ int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *,
u_char **, size_t *, const u_char *, size_t, const char *);
/* Key / cert options linkage to auth layer */
const struct sshauthopt *auth_options(struct ssh *);
int auth_activate_options(struct ssh *, struct sshauthopt *);
void auth_restrict_session(struct ssh *);
void auth_log_authopts(const char *, const struct sshauthopt *, int);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-gss.c,v 1.34 2023/03/31 04:22:27 djm Exp $ */
/* $OpenBSD: auth2-gss.c,v 1.36 2024/05/17 04:42:13 djm Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@ -46,6 +46,7 @@
#define SSH_GSSAPI_MAX_MECHS 2048
extern ServerOptions options;
extern struct authmethod_cfg methodcfg_gssapi;
static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh);
static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh);
@ -111,7 +112,7 @@ userauth_gssapi(struct ssh *ssh, const char *method)
return (0);
}
if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) {
if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, &goid))) {
if (ctxt != NULL)
ssh_gssapi_delete_ctx(&ctxt);
free(doid);
@ -148,7 +149,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
size_t len;
int r;
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
if (authctxt == NULL)
fatal("No authentication or GSSAPI context");
gssctxt = authctxt->methoddata;
@ -158,8 +159,8 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
recv_tok.value = p;
recv_tok.length = len;
maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
&send_tok, &flags));
maj_status = mm_ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
&send_tok, &flags);
free(p);
@ -212,7 +213,7 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
u_char *p;
size_t len;
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
if (authctxt == NULL)
fatal("No authentication or GSSAPI context");
gssctxt = authctxt->methoddata;
@ -223,8 +224,8 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
recv_tok.length = len;
/* Push the error token into GSSAPI to see what it says */
maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
&send_tok, NULL));
maj_status = mm_ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
&send_tok, NULL);
free(recv_tok.value);
@ -249,9 +250,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
int r, authenticated;
const char *displayname;
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
if (authctxt == NULL)
fatal("No authentication or GSSAPI context");
/*
@ -262,11 +262,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
if ((r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "parse packet");
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
if ((!use_privsep || mm_is_monitor()) &&
(displayname = ssh_gssapi_displayname()) != NULL)
auth2_record_info(authctxt, "%s", displayname);
authenticated = mm_ssh_gssapi_userok(authctxt->user);
authctxt->postponed = 0;
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
@ -285,11 +281,10 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
int r, authenticated = 0;
struct sshbuf *b;
gss_buffer_desc mic, gssbuf;
const char *displayname;
u_char *p;
size_t len;
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
if (authctxt == NULL)
fatal("No authentication or GSSAPI context");
gssctxt = authctxt->methoddata;
@ -307,18 +302,14 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
fatal_f("sshbuf_mutable_ptr failed");
gssbuf.length = sshbuf_len(b);
if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))
authenticated = mm_ssh_gssapi_userok(authctxt->user);
else
logit("GSSAPI MIC check failed");
sshbuf_free(b);
free(mic.value);
if ((!use_privsep || mm_is_monitor()) &&
(displayname = ssh_gssapi_displayname()) != NULL)
auth2_record_info(authctxt, "%s", displayname);
authctxt->postponed = 0;
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
@ -329,9 +320,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
}
Authmethod method_gssapi = {
"gssapi-with-mic",
NULL,
&methodcfg_gssapi,
userauth_gssapi,
&options.gss_authentication
};
#endif

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-hostbased.c,v 1.52 2023/03/05 05:34:09 dtucker Exp $ */
/* $OpenBSD: auth2-hostbased.c,v 1.53 2024/05/17 00:30:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -53,6 +53,7 @@
/* import */
extern ServerOptions options;
extern struct authmethod_cfg methodcfg_hostbased;
static int
userauth_hostbased(struct ssh *ssh, const char *method)
@ -144,10 +145,10 @@ userauth_hostbased(struct ssh *ssh, const char *method)
/* test for allowed key and correct signature */
authenticated = 0;
if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser,
chost, key)) &&
PRIVSEP(sshkey_verify(key, sig, slen,
sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0)
if (mm_hostbased_key_allowed(ssh, authctxt->pw, cuser,
chost, key) &&
mm_sshkey_verify(key, sig, slen,
sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL) == 0)
authenticated = 1;
auth2_record_key(authctxt, authenticated, key);
@ -251,8 +252,6 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
}
Authmethod method_hostbased = {
"hostbased",
NULL,
&methodcfg_hostbased,
userauth_hostbased,
&options.hostbased_authentication
};

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-kbdint.c,v 1.14 2021/12/19 22:12:07 djm Exp $ */
/* $OpenBSD: auth2-kbdint.c,v 1.15 2024/05/17 00:30:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -40,6 +40,7 @@
/* import */
extern ServerOptions options;
extern struct authmethod_cfg methodcfg_kbdint;
static int
userauth_kbdint(struct ssh *ssh, const char *method)
@ -63,8 +64,6 @@ userauth_kbdint(struct ssh *ssh, const char *method)
}
Authmethod method_kbdint = {
"keyboard-interactive",
NULL,
&methodcfg_kbdint,
userauth_kbdint,
&options.kbd_interactive_authentication
};

133
usr.bin/ssh/auth2-methods.c Normal file
View file

@ -0,0 +1,133 @@
/*
* Copyright (c) 2012,2023 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <stdlib.h>
#include <string.h>
#include "log.h"
#include "misc.h"
#include "servconf.h"
#include "xmalloc.h"
#include "hostfile.h"
#include "auth.h"
extern ServerOptions options;
/*
* Configuration of enabled authentication methods. Separate to the rest of
* auth2-*.c because we want to query it during server configuration validity
* checking in the sshd listener process without pulling all the auth code in
* too.
*/
/* "none" is allowed only one time and it cleared by userauth_none() later */
int none_enabled = 1;
struct authmethod_cfg methodcfg_none = {
"none",
NULL,
&none_enabled
};
struct authmethod_cfg methodcfg_pubkey = {
"publickey",
"publickey-hostbound-v00@openssh.com",
&options.pubkey_authentication
};
#ifdef GSSAPI
struct authmethod_cfg methodcfg_gssapi = {
"gssapi-with-mic",
NULL,
&options.gss_authentication
};
#endif
struct authmethod_cfg methodcfg_passwd = {
"password",
NULL,
&options.password_authentication
};
struct authmethod_cfg methodcfg_kbdint = {
"keyboard-interactive",
NULL,
&options.kbd_interactive_authentication
};
struct authmethod_cfg methodcfg_hostbased = {
"hostbased",
NULL,
&options.hostbased_authentication
};
static struct authmethod_cfg *authmethod_cfgs[] = {
&methodcfg_none,
&methodcfg_pubkey,
#ifdef GSSAPI
&methodcfg_gssapi,
#endif
&methodcfg_passwd,
&methodcfg_kbdint,
&methodcfg_hostbased,
NULL
};
/*
* Check a comma-separated list of methods for validity. Is need_enable is
* non-zero, then also require that the methods are enabled.
* Returns 0 on success or -1 if the methods list is invalid.
*/
int
auth2_methods_valid(const char *_methods, int need_enable)
{
char *methods, *omethods, *method, *p;
u_int i, found;
int ret = -1;
const struct authmethod_cfg *cfg;
if (*_methods == '\0') {
error("empty authentication method list");
return -1;
}
omethods = methods = xstrdup(_methods);
while ((method = strsep(&methods, ",")) != NULL) {
for (found = i = 0; !found && authmethod_cfgs[i] != NULL; i++) {
cfg = authmethod_cfgs[i];
if ((p = strchr(method, ':')) != NULL)
*p = '\0';
if (strcmp(method, cfg->name) != 0)
continue;
if (need_enable) {
if (cfg->enabled == NULL ||
*(cfg->enabled) == 0) {
error("Disabled method \"%s\" in "
"AuthenticationMethods list \"%s\"",
method, _methods);
goto out;
}
}
found = 1;
break;
}
if (!found) {
error("Unknown authentication method \"%s\" in list",
method);
goto out;
}
}
ret = 0;
out:
free(omethods);
return ret;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-none.c,v 1.25 2023/03/05 05:34:09 dtucker Exp $ */
/* $OpenBSD: auth2-none.c,v 1.26 2024/05/17 00:30:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -44,9 +44,9 @@
/* import */
extern ServerOptions options;
extern struct authmethod_cfg methodcfg_none;
/* "none" is allowed only one time */
static int none_enabled = 1;
extern int none_enabled;
static int
userauth_none(struct ssh *ssh, const char *method)
@ -57,13 +57,11 @@ userauth_none(struct ssh *ssh, const char *method)
if ((r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "parse packet");
if (options.permit_empty_passwd && options.password_authentication)
return (PRIVSEP(auth_password(ssh, "")));
return mm_auth_password(ssh, "");
return (0);
}
Authmethod method_none = {
"none",
NULL,
&methodcfg_none,
userauth_none,
&none_enabled
};

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-passwd.c,v 1.21 2022/05/27 04:29:40 dtucker Exp $ */
/* $OpenBSD: auth2-passwd.c,v 1.22 2024/05/17 00:30:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -45,6 +45,7 @@
/* import */
extern ServerOptions options;
extern struct authmethod_cfg methodcfg_passwd;
static int
userauth_passwd(struct ssh *ssh, const char *method)
@ -64,15 +65,13 @@ userauth_passwd(struct ssh *ssh, const char *method)
if (change)
logit("password change not supported");
else if (PRIVSEP(auth_password(ssh, password)) == 1)
else if (mm_auth_password(ssh, password) == 1)
authenticated = 1;
freezero(password, len);
return authenticated;
}
Authmethod method_passwd = {
"password",
NULL,
&methodcfg_passwd,
userauth_passwd,
&options.password_authentication
};

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.119 2023/07/27 22:25:17 djm Exp $ */
/* $OpenBSD: auth2-pubkey.c,v 1.120 2024/05/17 00:30:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@ -69,6 +69,7 @@
/* import */
extern ServerOptions options;
extern struct authmethod_cfg methodcfg_pubkey;
static char *
format_key(const struct sshkey *key)
@ -216,11 +217,11 @@ userauth_pubkey(struct ssh *ssh, const char *method)
#endif
/* test for correct signature */
authenticated = 0;
if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) &&
PRIVSEP(sshkey_verify(key, sig, slen,
if (mm_user_key_allowed(ssh, pw, key, 1, &authopts) &&
mm_sshkey_verify(key, sig, slen,
sshbuf_ptr(b), sshbuf_len(b),
(ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL,
ssh->compat, &sig_details)) == 0) {
ssh->compat, &sig_details) == 0) {
authenticated = 1;
}
if (authenticated == 1 && sig_details != NULL) {
@ -278,7 +279,7 @@ userauth_pubkey(struct ssh *ssh, const char *method)
* if a user is not allowed to login. is this an
* issue? -markus
*/
if (PRIVSEP(user_key_allowed(ssh, pw, key, 0, NULL))) {
if (mm_user_key_allowed(ssh, pw, key, 0, NULL)) {
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_PK_OK))
!= 0 ||
(r = sshpkt_put_cstring(ssh, pkalg)) != 0 ||
@ -810,8 +811,6 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
}
Authmethod method_pubkey = {
"publickey",
"publickey-hostbound-v00@openssh.com",
&methodcfg_pubkey,
userauth_pubkey,
&options.pubkey_authentication
};

View file

@ -1,4 +1,4 @@
/* $OpenBSD: auth2.c,v 1.168 2023/12/18 14:45:49 djm Exp $ */
/* $OpenBSD: auth2.c,v 1.169 2024/05/17 00:30:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -141,7 +141,7 @@ userauth_banner(struct ssh *ssh)
if (options.banner == NULL)
return;
if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
if ((banner = mm_auth2_read_banner()) == NULL)
goto done;
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_BANNER)) != 0 ||
@ -281,7 +281,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
auth_maxtries_exceeded(ssh);
if (authctxt->attempt++ == 0) {
/* setup auth context */
authctxt->pw = PRIVSEP(getpwnamallow(ssh, user));
authctxt->pw = mm_getpwnamallow(ssh, user);
if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
authctxt->valid = 1;
debug2_f("setting up authctxt for %s", user);
@ -292,13 +292,11 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
}
ssh_packet_set_log_preamble(ssh, "%suser %s",
authctxt->valid ? "authenticating " : "invalid ", user);
setproctitle("%s%s", authctxt->valid ? user : "unknown",
use_privsep ? " [net]" : "");
setproctitle("%s [net]", authctxt->valid ? user : "unknown");
authctxt->user = xstrdup(user);
authctxt->service = xstrdup(service);
authctxt->style = style ? xstrdup(style) : NULL;
if (use_privsep)
mm_inform_authserv(service, style);
mm_inform_authserv(service, style);
userauth_banner(ssh);
if ((r = kex_server_update_ext_info(ssh)) != 0)
fatal_fr(r, "kex_server_update_ext_info failed");
@ -362,7 +360,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
/* prefer primary authmethod name to possible synonym */
if ((m = authmethod_byname(method)) == NULL)
fatal("INTERNAL ERROR: bad method %s", method);
method = m->name;
method = m->cfg->name;
}
/* Special handling for root */
@ -453,16 +451,16 @@ authmethods_get(Authctxt *authctxt)
if ((b = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
for (i = 0; authmethods[i] != NULL; i++) {
if (strcmp(authmethods[i]->name, "none") == 0)
if (strcmp(authmethods[i]->cfg->name, "none") == 0)
continue;
if (authmethods[i]->enabled == NULL ||
*(authmethods[i]->enabled) == 0)
if (authmethods[i]->cfg->enabled == NULL ||
*(authmethods[i]->cfg->enabled) == 0)
continue;
if (!auth2_method_allowed(authctxt, authmethods[i]->name,
if (!auth2_method_allowed(authctxt, authmethods[i]->cfg->name,
NULL))
continue;
if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) ? "," : "",
authmethods[i]->name)) != 0)
authmethods[i]->cfg->name)) != 0)
fatal_fr(r, "buffer error");
}
if ((list = sshbuf_dup_string(b)) == NULL)
@ -479,9 +477,9 @@ authmethod_byname(const char *name)
if (name == NULL)
fatal_f("NULL authentication method name");
for (i = 0; authmethods[i] != NULL; i++) {
if (strcmp(name, authmethods[i]->name) == 0 ||
(authmethods[i]->synonym != NULL &&
strcmp(name, authmethods[i]->synonym) == 0))
if (strcmp(name, authmethods[i]->cfg->name) == 0 ||
(authmethods[i]->cfg->synonym != NULL &&
strcmp(name, authmethods[i]->cfg->synonym) == 0))
return authmethods[i];
}
debug_f("unrecognized authentication method name: %s", name);
@ -496,11 +494,11 @@ authmethod_lookup(Authctxt *authctxt, const char *name)
if ((method = authmethod_byname(name)) == NULL)
return NULL;
if (method->enabled == NULL || *(method->enabled) == 0) {
if (method->cfg->enabled == NULL || *(method->cfg->enabled) == 0) {
debug3_f("method %s not enabled", name);
return NULL;
}
if (!auth2_method_allowed(authctxt, method->name, NULL)) {
if (!auth2_method_allowed(authctxt, method->cfg->name, NULL)) {
debug3_f("method %s not allowed "
"by AuthenticationMethods", name);
return NULL;
@ -508,53 +506,6 @@ authmethod_lookup(Authctxt *authctxt, const char *name)
return method;
}
/*
* Check a comma-separated list of methods for validity. Is need_enable is
* non-zero, then also require that the methods are enabled.
* Returns 0 on success or -1 if the methods list is invalid.
*/
int
auth2_methods_valid(const char *_methods, int need_enable)
{
char *methods, *omethods, *method, *p;
u_int i, found;
int ret = -1;
if (*_methods == '\0') {
error("empty authentication method list");
return -1;
}
omethods = methods = xstrdup(_methods);
while ((method = strsep(&methods, ",")) != NULL) {
for (found = i = 0; !found && authmethods[i] != NULL; i++) {
if ((p = strchr(method, ':')) != NULL)
*p = '\0';
if (strcmp(method, authmethods[i]->name) != 0)
continue;
if (need_enable) {
if (authmethods[i]->enabled == NULL ||
*(authmethods[i]->enabled) == 0) {
error("Disabled method \"%s\" in "
"AuthenticationMethods list \"%s\"",
method, _methods);
goto out;
}
}
found = 1;
break;
}
if (!found) {
error("Unknown authentication method \"%s\" in list",
method);
goto out;
}
}
ret = 0;
out:
free(omethods);
return ret;
}
/*
* Prune the AuthenticationMethods supplied in the configuration, removing
* any methods lists that include disabled methods. Note that this might

View file

@ -1,4 +1,4 @@
/* $OpenBSD: channels.c,v 1.437 2024/03/06 02:59:59 djm Exp $ */
/* $OpenBSD: channels.c,v 1.438 2024/05/17 00:30:23 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -85,13 +85,6 @@
/* -- agent forwarding */
#define NUM_SOCKS 10
/* -- tcp forwarding */
/* special-case port number meaning allow any port */
#define FWD_PERMIT_ANY_PORT 0
/* special-case wildcard meaning allow any host */
#define FWD_PERMIT_ANY_HOST "*"
/* -- X11 forwarding */
/* Maximum number of fake X11 displays to try. */
#define MAX_DISPLAYS 1000
@ -4530,19 +4523,6 @@ channel_update_permission(struct ssh *ssh, int idx, int newport)
}
}
/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */
int
permitopen_port(const char *p)
{
int port;
if (strcmp(p, "*") == 0)
return FWD_PERMIT_ANY_PORT;
if ((port = a2port(p)) > 0)
return port;
return -1;
}
/* Try to start non-blocking connect to next host in cctx list */
static int
connect_next(struct channel_connect *cctx)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: channels.h,v 1.154 2023/12/18 14:47:20 djm Exp $ */
/* $OpenBSD: channels.h,v 1.155 2024/05/17 06:42:04 jsg Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -322,7 +322,6 @@ int channel_input_ieof(int, u_int32_t, struct ssh *);
int channel_input_oclose(int, u_int32_t, struct ssh *);
int channel_input_open_confirmation(int, u_int32_t, struct ssh *);
int channel_input_open_failure(int, u_int32_t, struct ssh *);
int channel_input_port_open(int, u_int32_t, struct ssh *);
int channel_input_window_adjust(int, u_int32_t, struct ssh *);
int channel_input_status_confirm(int, u_int32_t, struct ssh *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: cipher.c,v 1.120 2023/10/10 06:49:54 tb Exp $ */
/* $OpenBSD: cipher.c,v 1.121 2024/05/17 02:39:11 jsg Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -366,7 +366,7 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
1, lastiv))
return SSH_ERR_LIBCRYPTO_ERROR;
/* set tag on decyption */
/* set tag on decryption */
if (!cc->encrypt &&
!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG,
authlen, (u_char *)src + aadlen + len))

View file

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.406 2024/05/09 09:46:47 djm Exp $ */
/* $OpenBSD: clientloop.c,v 1.407 2024/05/17 06:42:04 jsg Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -184,7 +184,6 @@ TAILQ_HEAD(global_confirms, global_confirm);
static struct global_confirms global_confirms =
TAILQ_HEAD_INITIALIZER(global_confirms);
void ssh_process_session2_setup(int, int, int, struct sshbuf *);
static void quit_message(const char *fmt, ...)
__attribute__((__format__ (printf, 1, 2)));

View file

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.h,v 1.37 2020/04/03 02:40:32 djm Exp $ */
/* $OpenBSD: clientloop.h,v 1.38 2024/05/17 06:42:04 jsg Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -43,7 +43,6 @@ struct ssh;
int client_loop(struct ssh *, int, int, int);
int client_x11_get_proto(struct ssh *, const char *, const char *,
u_int, u_int, char **, char **);
void client_global_request_reply_fwd(int, u_int32_t, void *);
void client_session2_setup(struct ssh *, int, int, int,
const char *, struct termios *, int, struct sshbuf *, char **);
char *client_request_tun_fwd(struct ssh *, int, int, int,

View file

@ -1,5 +1,5 @@
#!/bin/sh
# $OpenBSD: ed25519.sh,v 1.1 2023/01/15 23:05:32 djm Exp $
# $OpenBSD: ed25519.sh,v 1.2 2024/05/17 02:39:11 jsg Exp $
# Placed in the Public Domain.
#
AUTHOR="supercop-20221122/crypto_sign/ed25519/ref/implementors"
@ -74,7 +74,7 @@ for i in $FILES; do
sed -e "s/crypto_sign_open/crypto_sign_ed25519_open/g"
;;
*/crypto_sign/ed25519/ref/fe25519.*)
# avoid a couple of name collions with other files
# avoid a couple of name collisions with other files
sed -e "s/reduce_add_sub/fe25519_reduce_add_sub/g" \
-e "s/ equal[(]/ fe25519_equal(/g" \
-e "s/^int /static int /g"

319
usr.bin/ssh/kex-names.c Normal file
View file

@ -0,0 +1,319 @@
/* $OpenBSD: kex-names.c,v 1.1 2024/05/17 00:32:32 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
#include <openssl/evp.h>
#endif
#include "kex.h"
#include "log.h"
#include "match.h"
#include "digest.h"
#include "misc.h"
#include "ssherr.h"
#include "xmalloc.h"
struct kexalg {
char *name;
u_int type;
int ec_nid;
int hash_alg;
};
static const struct kexalg kexalgs[] = {
#ifdef WITH_OPENSSL
{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
{ KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 },
{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
{ KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
SSH_DIGEST_SHA384 },
{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
SSH_DIGEST_SHA512 },
#endif
{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0,
SSH_DIGEST_SHA512 },
{ NULL, 0, -1, -1},
};
char *
kex_alg_list(char sep)
{
char *ret = NULL, *tmp;
size_t nlen, rlen = 0;
const struct kexalg *k;
for (k = kexalgs; k->name != NULL; k++) {
if (ret != NULL)
ret[rlen++] = sep;
nlen = strlen(k->name);
if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
free(ret);
return NULL;
}
ret = tmp;
memcpy(ret + rlen, k->name, nlen + 1);
rlen += nlen;
}
return ret;
}
static const struct kexalg *
kex_alg_by_name(const char *name)
{
const struct kexalg *k;
for (k = kexalgs; k->name != NULL; k++) {
if (strcmp(k->name, name) == 0)
return k;
}
return NULL;
}
int
kex_name_valid(const char *name)
{
return kex_alg_by_name(name) != NULL;
}
u_int
kex_type_from_name(const char *name)
{
const struct kexalg *k;
if ((k = kex_alg_by_name(name)) == NULL)
return 0;
return k->type;
}
int
kex_hash_from_name(const char *name)
{
const struct kexalg *k;
if ((k = kex_alg_by_name(name)) == NULL)
return -1;
return k->hash_alg;
}
int
kex_nid_from_name(const char *name)
{
const struct kexalg *k;
if ((k = kex_alg_by_name(name)) == NULL)
return -1;
return k->ec_nid;
}
/* Validate KEX method name list */
int
kex_names_valid(const char *names)
{
char *s, *cp, *p;
if (names == NULL || strcmp(names, "") == 0)
return 0;
if ((s = cp = strdup(names)) == NULL)
return 0;
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
if (kex_alg_by_name(p) == NULL) {
error("Unsupported KEX algorithm \"%.100s\"", p);
free(s);
return 0;
}
}
debug3("kex names ok: [%s]", names);
free(s);
return 1;
}
/* returns non-zero if proposal contains any algorithm from algs */
int
kex_has_any_alg(const char *proposal, const char *algs)
{
char *cp;
if ((cp = match_list(proposal, algs, NULL)) == NULL)
return 0;
free(cp);
return 1;
}
/*
* Concatenate algorithm names, avoiding duplicates in the process.
* Caller must free returned string.
*/
char *
kex_names_cat(const char *a, const char *b)
{
char *ret = NULL, *tmp = NULL, *cp, *p;
size_t len;
if (a == NULL || *a == '\0')
return strdup(b);
if (b == NULL || *b == '\0')
return strdup(a);
if (strlen(b) > 1024*1024)
return NULL;
len = strlen(a) + strlen(b) + 2;
if ((tmp = cp = strdup(b)) == NULL ||
(ret = calloc(1, len)) == NULL) {
free(tmp);
return NULL;
}
strlcpy(ret, a, len);
for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {
if (kex_has_any_alg(ret, p))
continue; /* Algorithm already present */
if (strlcat(ret, ",", len) >= len ||
strlcat(ret, p, len) >= len) {
free(tmp);
free(ret);
return NULL; /* Shouldn't happen */
}
}
free(tmp);
return ret;
}
/*
* Assemble a list of algorithms from a default list and a string from a
* configuration file. The user-provided string may begin with '+' to
* indicate that it should be appended to the default, '-' that the
* specified names should be removed, or '^' that they should be placed
* at the head.
*/
int
kex_assemble_names(char **listp, const char *def, const char *all)
{
char *cp, *tmp, *patterns;
char *list = NULL, *ret = NULL, *matching = NULL, *opatterns = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
if (listp == NULL || def == NULL || all == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (*listp == NULL || **listp == '\0') {
if ((*listp = strdup(def)) == NULL)
return SSH_ERR_ALLOC_FAIL;
return 0;
}
list = *listp;
*listp = NULL;
if (*list == '+') {
/* Append names to default list */
if ((tmp = kex_names_cat(def, list + 1)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(list);
list = tmp;
} else if (*list == '-') {
/* Remove names from default list */
if ((*listp = match_filter_denylist(def, list + 1)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(list);
/* filtering has already been done */
return 0;
} else if (*list == '^') {
/* Place names at head of default list */
if ((tmp = kex_names_cat(list + 1, def)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(list);
list = tmp;
} else {
/* Explicit list, overrides default - just use "list" as is */
}
/*
* The supplied names may be a pattern-list. For the -list case,
* the patterns are applied above. For the +list and explicit list
* cases we need to do it now.
*/
ret = NULL;
if ((patterns = opatterns = strdup(list)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
/* Apply positive (i.e. non-negated) patterns from the list */
while ((cp = strsep(&patterns, ",")) != NULL) {
if (*cp == '!') {
/* negated matches are not supported here */
r = SSH_ERR_INVALID_ARGUMENT;
goto fail;
}
free(matching);
if ((matching = match_filter_allowlist(all, cp)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
if ((tmp = kex_names_cat(ret, matching)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(ret);
ret = tmp;
}
if (ret == NULL || *ret == '\0') {
/* An empty name-list is an error */
/* XXX better error code? */
r = SSH_ERR_INVALID_ARGUMENT;
goto fail;
}
/* success */
*listp = ret;
ret = NULL;
r = 0;
fail:
free(matching);
free(opatterns);
free(list);
free(ret);
return r;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kex.c,v 1.185 2024/01/08 00:34:33 djm Exp $ */
/* $OpenBSD: kex.c,v 1.186 2024/05/17 00:30:23 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@ -76,244 +76,6 @@ static const char * const proposal_names[PROPOSAL_MAX] = {
"languages stoc",
};
struct kexalg {
char *name;
u_int type;
int ec_nid;
int hash_alg;
};
static const struct kexalg kexalgs[] = {
#ifdef WITH_OPENSSL
{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
{ KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 },
{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
{ KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
SSH_DIGEST_SHA384 },
{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
SSH_DIGEST_SHA512 },
#endif
{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0,
SSH_DIGEST_SHA512 },
{ NULL, 0, -1, -1},
};
char *
kex_alg_list(char sep)
{
char *ret = NULL, *tmp;
size_t nlen, rlen = 0;
const struct kexalg *k;
for (k = kexalgs; k->name != NULL; k++) {
if (ret != NULL)
ret[rlen++] = sep;
nlen = strlen(k->name);
if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
free(ret);
return NULL;
}
ret = tmp;
memcpy(ret + rlen, k->name, nlen + 1);
rlen += nlen;
}
return ret;
}
static const struct kexalg *
kex_alg_by_name(const char *name)
{
const struct kexalg *k;
for (k = kexalgs; k->name != NULL; k++) {
if (strcmp(k->name, name) == 0)
return k;
}
return NULL;
}
/* Validate KEX method name list */
int
kex_names_valid(const char *names)
{
char *s, *cp, *p;
if (names == NULL || strcmp(names, "") == 0)
return 0;
if ((s = cp = strdup(names)) == NULL)
return 0;
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
if (kex_alg_by_name(p) == NULL) {
error("Unsupported KEX algorithm \"%.100s\"", p);
free(s);
return 0;
}
}
debug3("kex names ok: [%s]", names);
free(s);
return 1;
}
/* returns non-zero if proposal contains any algorithm from algs */
static int
has_any_alg(const char *proposal, const char *algs)
{
char *cp;
if ((cp = match_list(proposal, algs, NULL)) == NULL)
return 0;
free(cp);
return 1;
}
/*
* Concatenate algorithm names, avoiding duplicates in the process.
* Caller must free returned string.
*/
char *
kex_names_cat(const char *a, const char *b)
{
char *ret = NULL, *tmp = NULL, *cp, *p;
size_t len;
if (a == NULL || *a == '\0')
return strdup(b);
if (b == NULL || *b == '\0')
return strdup(a);
if (strlen(b) > 1024*1024)
return NULL;
len = strlen(a) + strlen(b) + 2;
if ((tmp = cp = strdup(b)) == NULL ||
(ret = calloc(1, len)) == NULL) {
free(tmp);
return NULL;
}
strlcpy(ret, a, len);
for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {
if (has_any_alg(ret, p))
continue; /* Algorithm already present */
if (strlcat(ret, ",", len) >= len ||
strlcat(ret, p, len) >= len) {
free(tmp);
free(ret);
return NULL; /* Shouldn't happen */
}
}
free(tmp);
return ret;
}
/*
* Assemble a list of algorithms from a default list and a string from a
* configuration file. The user-provided string may begin with '+' to
* indicate that it should be appended to the default, '-' that the
* specified names should be removed, or '^' that they should be placed
* at the head.
*/
int
kex_assemble_names(char **listp, const char *def, const char *all)
{
char *cp, *tmp, *patterns;
char *list = NULL, *ret = NULL, *matching = NULL, *opatterns = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
if (listp == NULL || def == NULL || all == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (*listp == NULL || **listp == '\0') {
if ((*listp = strdup(def)) == NULL)
return SSH_ERR_ALLOC_FAIL;
return 0;
}
list = *listp;
*listp = NULL;
if (*list == '+') {
/* Append names to default list */
if ((tmp = kex_names_cat(def, list + 1)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(list);
list = tmp;
} else if (*list == '-') {
/* Remove names from default list */
if ((*listp = match_filter_denylist(def, list + 1)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(list);
/* filtering has already been done */
return 0;
} else if (*list == '^') {
/* Place names at head of default list */
if ((tmp = kex_names_cat(list + 1, def)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(list);
list = tmp;
} else {
/* Explicit list, overrides default - just use "list" as is */
}
/*
* The supplied names may be a pattern-list. For the -list case,
* the patterns are applied above. For the +list and explicit list
* cases we need to do it now.
*/
ret = NULL;
if ((patterns = opatterns = strdup(list)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
/* Apply positive (i.e. non-negated) patterns from the list */
while ((cp = strsep(&patterns, ",")) != NULL) {
if (*cp == '!') {
/* negated matches are not supported here */
r = SSH_ERR_INVALID_ARGUMENT;
goto fail;
}
free(matching);
if ((matching = match_filter_allowlist(all, cp)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
if ((tmp = kex_names_cat(ret, matching)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(ret);
ret = tmp;
}
if (ret == NULL || *ret == '\0') {
/* An empty name-list is an error */
/* XXX better error code? */
r = SSH_ERR_INVALID_ARGUMENT;
goto fail;
}
/* success */
*listp = ret;
ret = NULL;
r = 0;
fail:
free(matching);
free(opatterns);
free(list);
free(ret);
return r;
}
/*
* Fill out a proposal array with dynamically allocated values, which may
* be modified as required for compatibility reasons.
@ -512,11 +274,11 @@ kex_set_server_sig_algs(struct ssh *ssh, const char *allowed_algs)
(alg = strsep(&algs, ","))) {
if ((sigalg = sshkey_sigalg_by_name(alg)) == NULL)
continue;
if (!has_any_alg(sigalg, sigalgs))
if (!kex_has_any_alg(sigalg, sigalgs))
continue;
/* Don't add an algorithm twice. */
if (ssh->kex->server_sig_algs != NULL &&
has_any_alg(sigalg, ssh->kex->server_sig_algs))
kex_has_any_alg(sigalg, ssh->kex->server_sig_algs))
continue;
xextendf(&ssh->kex->server_sig_algs, ",", "%s", sigalg);
}
@ -1091,20 +853,18 @@ choose_comp(struct sshcomp *comp, char *client, char *server)
static int
choose_kex(struct kex *k, char *client, char *server)
{
const struct kexalg *kexalg;
k->name = match_list(client, server, NULL);
debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
if (k->name == NULL)
return SSH_ERR_NO_KEX_ALG_MATCH;
if ((kexalg = kex_alg_by_name(k->name)) == NULL) {
if (!kex_name_valid(k->name)) {
error_f("unsupported KEX method %s", k->name);
return SSH_ERR_INTERNAL_ERROR;
}
k->kex_type = kexalg->type;
k->hash_alg = kexalg->hash_alg;
k->ec_nid = kexalg->ec_nid;
k->kex_type = kex_type_from_name(k->name);
k->hash_alg = kex_hash_from_name(k->name);
k->ec_nid = kex_nid_from_name(k->name);
return 0;
}
@ -1154,7 +914,7 @@ proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
static int
kexalgs_contains(char **peer, const char *ext)
{
return has_any_alg(peer[PROPOSAL_KEX_ALGS], ext);
return kex_has_any_alg(peer[PROPOSAL_KEX_ALGS], ext);
}
static int
@ -1205,10 +965,10 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq)
/* Check whether client supports rsa-sha2 algorithms */
if (kex->server && (kex->flags & KEX_INITIAL)) {
if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
if (kex_has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
"rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com"))
kex->flags |= KEX_RSA_SHA2_256_SUPPORTED;
if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
if (kex_has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
"rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com"))
kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kex.h,v 1.122 2024/02/02 00:13:34 djm Exp $ */
/* $OpenBSD: kex.h,v 1.123 2024/05/17 00:30:23 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -85,7 +85,7 @@ enum kex_modes {
};
enum kex_exchange {
KEX_DH_GRP1_SHA1,
KEX_DH_GRP1_SHA1 = 1,
KEX_DH_GRP14_SHA1,
KEX_DH_GRP14_SHA256,
KEX_DH_GRP16_SHA512,
@ -176,9 +176,14 @@ struct kex {
struct sshbuf *client_pub;
};
int kex_name_valid(const char *);
u_int kex_type_from_name(const char *);
int kex_hash_from_name(const char *);
int kex_nid_from_name(const char *);
int kex_names_valid(const char *);
char *kex_alg_list(char);
char *kex_names_cat(const char *, const char *);
int kex_has_any_alg(const char *, const char *);
int kex_assemble_names(char **, const char *, const char *);
void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX],
const char *, const char *, const char *, const char *, const char *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kexgexs.c,v 1.46 2023/03/29 01:07:48 dtucker Exp $ */
/* $OpenBSD: kexgexs.c,v 1.47 2024/05/17 00:30:23 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -91,7 +91,7 @@ input_kex_dh_gex_request(int type, u_int32_t seq, struct ssh *ssh)
}
/* Contact privileged parent */
kex->dh = PRIVSEP(choose_dh(min, nbits, max));
kex->dh = mm_choose_dh(min, nbits, max);
if (kex->dh == NULL) {
(void)sshpkt_disconnect(ssh, "no matching DH grp found");
r = SSH_ERR_ALLOC_FAIL;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.193 2024/04/02 10:02:08 deraadt Exp $ */
/* $OpenBSD: misc.c,v 1.195 2024/05/17 06:11:17 deraadt Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005-2020 Damien Miller. All rights reserved.
@ -544,7 +544,7 @@ int
convtime(const char *s)
{
int secs, total = 0, multiplier;
char *p, *os, *np, c;
char *p, *os, *np, c = 0;
const char *errstr;
if (s == NULL || *s == '\0')
@ -1909,6 +1909,19 @@ forward_equals(const struct Forward *a, const struct Forward *b)
return 1;
}
/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */
int
permitopen_port(const char *p)
{
int port;
if (strcmp(p, "*") == 0)
return FWD_PERMIT_ANY_PORT;
if ((port = a2port(p)) > 0)
return port;
return -1;
}
/* returns 1 if process is already daemonized, 0 otherwise */
int
daemonized(void)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: misc.h,v 1.107 2024/03/04 02:16:11 djm Exp $ */
/* $OpenBSD: misc.h,v 1.108 2024/05/17 00:30:24 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -21,6 +21,12 @@
#include <stdio.h>
#include <signal.h>
/* special-case port number meaning allow any port */
#define FWD_PERMIT_ANY_PORT 0
/* special-case wildcard meaning allow any host */
#define FWD_PERMIT_ANY_HOST "*"
/* Data structure for representing a forwarding request. */
struct Forward {
char *listen_host; /* Host (address) to listen on. */
@ -34,6 +40,8 @@ struct Forward {
};
int forward_equals(const struct Forward *, const struct Forward *);
int permitopen_port(const char *p);
int daemonized(void);
/* Common server and client forwarding options. */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.237 2023/08/16 16:14:11 djm Exp $ */
/* $OpenBSD: monitor.c,v 1.239 2024/05/17 06:42:04 jsg Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -110,8 +110,6 @@ int mm_answer_keyverify(struct ssh *, int, struct sshbuf *);
int mm_answer_pty(struct ssh *, int, struct sshbuf *);
int mm_answer_pty_cleanup(struct ssh *, int, struct sshbuf *);
int mm_answer_term(struct ssh *, int, struct sshbuf *);
int mm_answer_sesskey(struct ssh *, int, struct sshbuf *);
int mm_answer_sessid(struct ssh *, int, struct sshbuf *);
#ifdef GSSAPI
int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *);
@ -641,13 +639,39 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m)
fatal_fr(r, "assemble %s", #id); \
} while (0)
void
mm_encode_server_options(struct sshbuf *m)
{
int r;
u_int i;
/* XXX this leaks raw pointers to the unpriv child processes */
if ((r = sshbuf_put_string(m, &options, sizeof(options))) != 0)
fatal_fr(r, "assemble options");
#define M_CP_STROPT(x) do { \
if (options.x != NULL && \
(r = sshbuf_put_cstring(m, options.x)) != 0) \
fatal_fr(r, "assemble %s", #x); \
} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
for (i = 0; i < options.nx; i++) { \
if ((r = sshbuf_put_cstring(m, options.x[i])) != 0) \
fatal_fr(r, "assemble %s", #x); \
} \
} while (0)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
}
/* Retrieves the password entry and also checks if the user is permitted */
int
mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
{
struct passwd *pwent;
int r, allowed = 0;
u_int i;
debug3_f("entering");
@ -692,24 +716,9 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
out:
ssh_packet_set_log_preamble(ssh, "%suser %s",
authctxt->valid ? "authenticating" : "invalid ", authctxt->user);
if ((r = sshbuf_put_string(m, &options, sizeof(options))) != 0)
fatal_fr(r, "assemble options");
#define M_CP_STROPT(x) do { \
if (options.x != NULL && \
(r = sshbuf_put_cstring(m, options.x)) != 0) \
fatal_fr(r, "assemble %s", #x); \
} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
for (i = 0; i < options.nx; i++) { \
if ((r = sshbuf_put_cstring(m, options.x[i])) != 0) \
fatal_fr(r, "assemble %s", #x); \
} \
} while (0)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
/* Send active options to unpriv */
mm_encode_server_options(m);
/* Create valid auth method lists */
if (auth2_setup_methods_lists(authctxt) != 0) {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.h,v 1.23 2019/01/19 21:43:56 djm Exp $ */
/* $OpenBSD: monitor.h,v 1.24 2024/05/17 00:30:24 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -59,6 +59,7 @@ enum monitor_reqtype {
};
struct ssh;
struct sshbuf;
struct monitor {
int m_recvfd;
@ -85,4 +86,7 @@ void mm_request_receive(int, struct sshbuf *);
void mm_request_receive_expect(int, enum monitor_reqtype, struct sshbuf *);
void mm_get_keystate(struct ssh *, struct monitor *);
/* XXX: should be returned via a monitor call rather than config_fd */
void mm_encode_server_options(struct sshbuf *);
#endif /* _MONITOR_H_ */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.c,v 1.129 2023/12/18 14:45:49 djm Exp $ */
/* $OpenBSD: monitor_wrap.c,v 1.130 2024/05/17 00:30:24 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -61,7 +61,6 @@
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "atomicio.h"
#include "monitor_fdpass.h"
#include "misc.h"
@ -69,6 +68,7 @@
#include "channels.h"
#include "session.h"
#include "servconf.h"
#include "monitor_wrap.h"
#include "ssherr.h"
@ -143,8 +143,10 @@ mm_request_receive(int sock, struct sshbuf *m)
debug3_f("entering");
if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
if (errno == EPIPE)
if (errno == EPIPE) {
debug3_f("monitor fd closed");
cleanup_exit(255);
}
fatal_f("read: %s", strerror(errno));
}
msg_len = PEEK_U32(buf);
@ -239,6 +241,49 @@ mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
return (0);
}
void
mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m)
{
const u_char *p;
size_t len;
u_int i;
ServerOptions *newopts;
int r;
if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0)
fatal_fr(r, "parse opts");
if (len != sizeof(*newopts))
fatal_f("option block size mismatch");
newopts = xcalloc(sizeof(*newopts), 1);
memcpy(newopts, p, sizeof(*newopts));
#define M_CP_STROPT(x) do { \
if (newopts->x != NULL && \
(r = sshbuf_get_cstring(m, &newopts->x, NULL)) != 0) \
fatal_fr(r, "parse %s", #x); \
} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
newopts->x = newopts->nx == 0 ? \
NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
for (i = 0; i < newopts->nx; i++) { \
if ((r = sshbuf_get_cstring(m, \
&newopts->x[i], NULL)) != 0) \
fatal_fr(r, "parse %s", #x); \
} \
} while (0)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
copy_set_server_options(&options, newopts, 1);
log_change_level(options.log_level);
log_verbose_reset();
for (i = 0; i < options.num_log_verbose; i++)
log_verbose_add(options.log_verbose[i]);
free(newopts);
}
#define GETPW(b, id) \
do { \
if ((r = sshbuf_get_string_direct(b, &p, &len)) != 0) \
@ -254,8 +299,6 @@ mm_getpwnamallow(struct ssh *ssh, const char *username)
struct sshbuf *m;
struct passwd *pw;
size_t len;
u_int i;
ServerOptions *newopts;
int r;
u_char ok;
const u_char *p;
@ -294,41 +337,10 @@ mm_getpwnamallow(struct ssh *ssh, const char *username)
out:
/* copy options block as a Match directive may have changed some */
if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0)
fatal_fr(r, "parse opts");
if (len != sizeof(*newopts))
fatal_f("option block size mismatch");
newopts = xcalloc(sizeof(*newopts), 1);
memcpy(newopts, p, sizeof(*newopts));
#define M_CP_STROPT(x) do { \
if (newopts->x != NULL && \
(r = sshbuf_get_cstring(m, &newopts->x, NULL)) != 0) \
fatal_fr(r, "parse %s", #x); \
} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
newopts->x = newopts->nx == 0 ? \
NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
for (i = 0; i < newopts->nx; i++) { \
if ((r = sshbuf_get_cstring(m, \
&newopts->x[i], NULL)) != 0) \
fatal_fr(r, "parse %s", #x); \
} \
} while (0)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
copy_set_server_options(&options, newopts, 1);
log_change_level(options.log_level);
log_verbose_reset();
for (i = 0; i < options.num_log_verbose; i++)
log_verbose_add(options.log_verbose[i]);
process_permitopen(ssh, &options);
process_channel_timeouts(ssh, &options);
mm_decode_activate_server_options(ssh, m);
server_process_permitopen(ssh);
server_process_channel_timeouts(ssh);
kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos);
free(newopts);
sshbuf_free(m);
return (pw);
@ -807,3 +819,91 @@ mm_ssh_gssapi_userok(char *user)
return (authenticated);
}
#endif /* GSSAPI */
/*
* Inform channels layer of permitopen options for a single forwarding
* direction (local/remote).
*/
static void
server_process_permitopen_list(struct ssh *ssh, int listen,
char **opens, u_int num_opens)
{
u_int i;
int port;
char *host, *arg, *oarg;
int where = listen ? FORWARD_REMOTE : FORWARD_LOCAL;
const char *what = listen ? "permitlisten" : "permitopen";
channel_clear_permission(ssh, FORWARD_ADM, where);
if (num_opens == 0)
return; /* permit any */
/* handle keywords: "any" / "none" */
if (num_opens == 1 && strcmp(opens[0], "any") == 0)
return;
if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
channel_disable_admin(ssh, where);
return;
}
/* Otherwise treat it as a list of permitted host:port */
for (i = 0; i < num_opens; i++) {
oarg = arg = xstrdup(opens[i]);
host = hpdelim(&arg);
if (host == NULL)
fatal_f("missing host in %s", what);
host = cleanhostname(host);
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
fatal_f("bad port number in %s", what);
/* Send it to channels layer */
channel_add_permission(ssh, FORWARD_ADM,
where, host, port);
free(oarg);
}
}
/*
* Inform channels layer of permitopen options from configuration.
*/
void
server_process_permitopen(struct ssh *ssh)
{
server_process_permitopen_list(ssh, 0,
options.permitted_opens, options.num_permitted_opens);
server_process_permitopen_list(ssh, 1,
options.permitted_listens, options.num_permitted_listens);
}
void
server_process_channel_timeouts(struct ssh *ssh)
{
u_int i, secs;
char *type;
debug3_f("setting %u timeouts", options.num_channel_timeouts);
channel_clear_timeouts(ssh);
for (i = 0; i < options.num_channel_timeouts; i++) {
if (parse_pattern_interval(options.channel_timeouts[i],
&type, &secs) != 0) {
fatal_f("internal error: bad timeout %s",
options.channel_timeouts[i]);
}
channel_add_timeout(ssh, type, secs);
free(type);
}
}
struct connection_info *
server_get_connection_info(struct ssh *ssh, int populate, int use_dns)
{
static struct connection_info ci;
if (ssh == NULL || !populate)
return &ci;
ci.host = use_dns ? ssh_remote_hostname(ssh) : ssh_remote_ipaddr(ssh);
ci.address = ssh_remote_ipaddr(ssh);
ci.laddress = ssh_local_ipaddr(ssh);
ci.lport = ssh_local_port(ssh);
ci.rdomain = ssh_packet_rdomain_in(ssh);
return &ci;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.h,v 1.49 2022/06/15 16:08:25 djm Exp $ */
/* $OpenBSD: monitor_wrap.h,v 1.51 2024/05/17 06:42:04 jsg Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -28,9 +28,6 @@
#ifndef _MM_WRAP_H_
#define _MM_WRAP_H_
extern int use_privsep;
#define PRIVSEP(x) (use_privsep ? mm_##x : x)
enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY };
struct ssh;
@ -61,6 +58,8 @@ int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *,
int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m);
#ifdef GSSAPI
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
@ -74,14 +73,16 @@ void mm_terminate(void);
int mm_pty_allocate(int *, int *, char *, size_t);
void mm_session_pty_cleanup2(struct Session *);
/* Key export functions */
struct newkeys *mm_newkeys_from_blob(u_char *, int);
int mm_newkeys_to_blob(int, u_char **, u_int *);
void mm_send_keystate(struct ssh *, struct monitor*);
/* bsdauth */
int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
int mm_bsdauth_respond(void *, u_int, char **);
/* config / channels glue */
void server_process_permitopen(struct ssh *);
void server_process_channel_timeouts(struct ssh *ssh);
struct connection_info *
server_get_connection_info(struct ssh *, int, int);
#endif /* _MM_WRAP_H_ */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: msg.c,v 1.20 2020/10/18 11:32:01 djm Exp $ */
/* $OpenBSD: msg.c,v 1.21 2024/05/17 00:30:24 djm Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@ -45,7 +45,7 @@ ssh_msg_send(int fd, u_char type, struct sshbuf *m)
u_char buf[5];
u_int mlen = sshbuf_len(m);
debug3_f("type %u", (unsigned int)type & 0xff);
debug3_f("type %u len %zu", (unsigned int)type & 0xff, sshbuf_len(m));
put_u32(buf, mlen + 1);
buf[4] = type; /* 1st byte of payload is mesg-type */
@ -57,6 +57,7 @@ ssh_msg_send(int fd, u_char type, struct sshbuf *m)
error_f("write: %s", strerror(errno));
return (-1);
}
debug3_f("done");
return (0);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.313 2023/12/18 14:45:17 djm Exp $ */
/* $OpenBSD: packet.c,v 1.314 2024/05/17 00:30:24 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -514,6 +514,94 @@ ssh_remote_ipaddr(struct ssh *ssh)
return ssh->remote_ipaddr;
}
/*
* Returns the remote DNS hostname as a string. The returned string must not
* be freed. NB. this will usually trigger a DNS query. Return value is on
* heap and no caching is performed.
* This function does additional checks on the hostname to mitigate some
* attacks on based on conflation of hostnames and addresses and will
* fall back to returning an address on error.
*/
char *
ssh_remote_hostname(struct ssh *ssh)
{
struct sockaddr_storage from;
socklen_t fromlen;
struct addrinfo hints, *ai, *aitop;
char name[NI_MAXHOST], ntop2[NI_MAXHOST];
const char *ntop = ssh_remote_ipaddr(ssh);
/* Get IP address of client. */
fromlen = sizeof(from);
memset(&from, 0, sizeof(from));
if (getpeername(ssh_packet_get_connection_in(ssh),
(struct sockaddr *)&from, &fromlen) == -1) {
debug_f("getpeername failed: %.100s", strerror(errno));
return xstrdup(ntop);
}
debug3_f("trying to reverse map address %.100s.", ntop);
/* Map the IP address to a host name. */
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
NULL, 0, NI_NAMEREQD) != 0) {
/* Host name not found. Use ip address. */
return xstrdup(ntop);
}
/*
* if reverse lookup result looks like a numeric hostname,
* someone is trying to trick us by PTR record like following:
* 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
*/
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
name, ntop);
freeaddrinfo(ai);
return xstrdup(ntop);
}
/* Names are stored in lowercase. */
lowercase(name);
/*
* Map it back to an IP address and check that the given
* address actually is an address of this host. This is
* necessary because anyone with access to a name server can
* define arbitrary names for an IP address. Mapping from
* name to IP address can be trusted better (but can still be
* fooled if the intruder has access to the name server of
* the domain).
*/
memset(&hints, 0, sizeof(hints));
hints.ai_family = from.ss_family;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
logit("reverse mapping checking getaddrinfo for %.700s "
"[%s] failed.", name, ntop);
return xstrdup(ntop);
}
/* Look for the address from the list of addresses. */
for (ai = aitop; ai; ai = ai->ai_next) {
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
(strcmp(ntop, ntop2) == 0))
break;
}
freeaddrinfo(aitop);
/* If we reached the end of the list, the address was not there. */
if (ai == NULL) {
/* Address not found for the host name. */
logit("Address %.100s maps to %.600s, but this does not "
"map back to the address.", ntop, name);
return xstrdup(ntop);
}
return xstrdup(name);
}
/* Returns the port number of the remote host. */
int

View file

@ -1,4 +1,4 @@
/* $OpenBSD: packet.h,v 1.96 2023/12/18 14:45:17 djm Exp $ */
/* $OpenBSD: packet.h,v 1.98 2024/05/17 06:42:04 jsg Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -118,14 +118,12 @@ int ssh_packet_send2_wrapped(struct ssh *);
int ssh_packet_send2(struct ssh *);
int ssh_packet_read(struct ssh *);
int ssh_packet_read_poll(struct ssh *);
int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p);
int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len);
int ssh_packet_process_read(struct ssh *, int);
int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p);
int ssh_packet_read_poll_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p);
const void *ssh_packet_get_string_ptr(struct ssh *, u_int *length_ptr);
void ssh_packet_disconnect(struct ssh *, const char *fmt, ...)
__attribute__((format(printf, 2, 3)))
__attribute__((noreturn));
@ -159,6 +157,7 @@ int ssh_remote_port(struct ssh *);
const char *ssh_local_ipaddr(struct ssh *);
int ssh_local_port(struct ssh *);
const char *ssh_packet_rdomain_in(struct ssh *);
char *ssh_remote_hostname(struct ssh *);
void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, u_int32_t);
time_t ssh_packet_get_rekey_timeout(struct ssh *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: pathnames.h,v 1.31 2019/11/12 19:33:08 markus Exp $ */
/* $OpenBSD: pathnames.h,v 1.32 2024/05/17 00:30:24 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -39,6 +39,9 @@
#define _PATH_SSH_PROGRAM "/usr/bin/ssh"
/* Binary paths for the sshd components */
#define _PATH_SSHD_SESSION "/usr/libexec/sshd-session"
/*
* The process id of the daemon listening for connections is saved here to
* make it easier to kill the correct daemon when necessary.

View file

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.386 2024/03/04 04:13:18 djm Exp $ */
/* $OpenBSD: readconf.c,v 1.387 2024/05/17 02:39:11 jsg Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -3307,7 +3307,7 @@ parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
return r;
}
/* XXX the following is a near-vebatim copy from servconf.c; refactor */
/* XXX the following is a near-verbatim copy from servconf.c; refactor */
static const char *
fmt_multistate_int(int val, const struct multistate *m)
{

View file

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.c,v 1.405 2024/03/04 02:16:11 djm Exp $ */
/* $OpenBSD: servconf.c,v 1.407 2024/05/17 01:17:40 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -64,8 +64,6 @@ static void parse_server_config_depth(ServerOptions *options,
const char *filename, struct sshbuf *conf, struct include_list *includes,
struct connection_info *connectinfo, int flags, int *activep, int depth);
/* Use of privilege separation or not */
extern int use_privsep;
extern struct sshbuf *cfg;
/* Initializes the server options to their default values. */
@ -179,6 +177,7 @@ initialize_server_options(ServerOptions *options)
options->channel_timeouts = NULL;
options->num_channel_timeouts = 0;
options->unused_connection_timeout = -1;
options->sshd_session_path = NULL;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
@ -422,13 +421,11 @@ fill_default_server_options(ServerOptions *options)
options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
if (options->unused_connection_timeout == -1)
options->unused_connection_timeout = 0;
if (options->sshd_session_path == NULL)
options->sshd_session_path = xstrdup(_PATH_SSHD_SESSION);
assemble_algorithms(options);
/* Turn privilege separation and sandboxing on by default */
if (use_privsep == -1)
use_privsep = PRIVSEP_ON;
#define CLEAR_ON_NONE(v) \
do { \
if (option_clear_or_none(v)) { \
@ -503,6 +500,7 @@ typedef enum {
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout,
sSshdSessionPath,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
@ -649,6 +647,7 @@ static struct {
{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
{ "channeltimeout", sChannelTimeout, SSHCFG_ALL },
{ "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },
{ "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL },
{ NULL, sBadOption, 0 }
};
@ -851,95 +850,6 @@ process_queued_listen_addrs(ServerOptions *options)
options->num_queued_listens = 0;
}
/*
* Inform channels layer of permitopen options for a single forwarding
* direction (local/remote).
*/
static void
process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
char **opens, u_int num_opens)
{
u_int i;
int port;
char *host, *arg, *oarg;
int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
const char *what = lookup_opcode_name(opcode);
channel_clear_permission(ssh, FORWARD_ADM, where);
if (num_opens == 0)
return; /* permit any */
/* handle keywords: "any" / "none" */
if (num_opens == 1 && strcmp(opens[0], "any") == 0)
return;
if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
channel_disable_admin(ssh, where);
return;
}
/* Otherwise treat it as a list of permitted host:port */
for (i = 0; i < num_opens; i++) {
oarg = arg = xstrdup(opens[i]);
host = hpdelim(&arg);
if (host == NULL)
fatal_f("missing host in %s", what);
host = cleanhostname(host);
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
fatal_f("bad port number in %s", what);
/* Send it to channels layer */
channel_add_permission(ssh, FORWARD_ADM,
where, host, port);
free(oarg);
}
}
/*
* Inform channels layer of permitopen options from configuration.
*/
void
process_permitopen(struct ssh *ssh, ServerOptions *options)
{
process_permitopen_list(ssh, sPermitOpen,
options->permitted_opens, options->num_permitted_opens);
process_permitopen_list(ssh, sPermitListen,
options->permitted_listens,
options->num_permitted_listens);
}
void
process_channel_timeouts(struct ssh *ssh, ServerOptions *options)
{
int secs;
u_int i;
char *type;
debug3_f("setting %u timeouts", options->num_channel_timeouts);
channel_clear_timeouts(ssh);
for (i = 0; i < options->num_channel_timeouts; i++) {
if (parse_pattern_interval(options->channel_timeouts[i],
&type, &secs) != 0) {
fatal_f("internal error: bad timeout %s",
options->channel_timeouts[i]);
}
channel_add_timeout(ssh, type, secs);
free(type);
}
}
struct connection_info *
get_connection_info(struct ssh *ssh, int populate, int use_dns)
{
static struct connection_info ci;
if (ssh == NULL || !populate)
return &ci;
ci.host = auth_get_canonical_hostname(ssh, use_dns);
ci.address = ssh_remote_ipaddr(ssh);
ci.laddress = ssh_local_ipaddr(ssh);
ci.lport = ssh_local_port(ssh);
ci.rdomain = ssh_packet_rdomain_in(ssh);
return &ci;
}
/*
* The strategy for the Match blocks is that the config file is parsed twice.
*
@ -2532,6 +2442,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
}
goto parse_time;
case sSshdSessionPath:
charptr = &options->sshd_session_path;
goto parse_filename;
case sDeprecated:
case sIgnore:
case sUnsupported:
@ -3097,6 +3011,7 @@ dump_config(ServerOptions *o)
dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
dump_cfg_string(sRDomain, o->routing_domain);
dump_cfg_string(sSshdSessionPath, o->sshd_session_path);
/* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level));

View file

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.160 2023/09/06 23:35:35 djm Exp $ */
/* $OpenBSD: servconf.h,v 1.162 2024/05/17 06:42:04 jsg Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -27,11 +27,6 @@
#define PERMIT_NO_PASSWD 2
#define PERMIT_YES 3
/* use_privsep */
#define PRIVSEP_OFF 0
#define PRIVSEP_ON 1
#define PRIVSEP_NOSANDBOX 2
/* PermitOpen */
#define PERMITOPEN_ANY 0
#define PERMITOPEN_NONE -2
@ -231,6 +226,8 @@ typedef struct {
u_int num_channel_timeouts;
int unused_connection_timeout;
char *sshd_session_path;
} ServerOptions;
/* Information about the incoming connection as used by Match */
@ -295,20 +292,16 @@ TAILQ_HEAD(include_list, include_item);
M_CP_STRARRAYOPT(subsystem_args, num_subsystems); \
} while (0)
struct connection_info *get_connection_info(struct ssh *, int, int);
void initialize_server_options(ServerOptions *);
void fill_default_server_options(ServerOptions *);
int process_server_config_line(ServerOptions *, char *, const char *, int,
int *, struct connection_info *, struct include_list *includes);
void process_permitopen(struct ssh *ssh, ServerOptions *options);
void process_channel_timeouts(struct ssh *ssh, ServerOptions *);
void load_server_config(const char *, struct sshbuf *);
void parse_server_config(ServerOptions *, const char *, struct sshbuf *,
struct include_list *includes, struct connection_info *, int);
void parse_server_match_config(ServerOptions *,
struct include_list *includes, struct connection_info *);
int parse_server_match_testspec(struct connection_info *, char *);
int server_match_spec_complete(struct connection_info *);
void servconf_merge_subsystems(ServerOptions *, ServerOptions *);
void copy_set_server_options(ServerOptions *, ServerOptions *, int);
void dump_config(ServerOptions *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: serverloop.c,v 1.238 2024/04/30 02:14:10 djm Exp $ */
/* $OpenBSD: serverloop.c,v 1.239 2024/05/17 00:30:24 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -80,44 +80,23 @@ extern ServerOptions options;
/* XXX */
extern Authctxt *the_authctxt;
extern struct sshauthopt *auth_opts;
extern int use_privsep;
static int no_more_sessions = 0; /* Disallow further sessions. */
static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */
/* Cleanup on signals (!use_privsep case only) */
static volatile sig_atomic_t received_sigterm = 0;
/* prototypes */
static void server_init_dispatch(struct ssh *);
/* requested tunnel forwarding interface(s), shared with session.c */
char *tun_fwd_ifnames = NULL;
/* returns 1 if bind to specified port by specified user is permitted */
static int
bind_permitted(int port, uid_t uid)
{
if (use_privsep)
return 1; /* allow system to decide */
if (port < IPPORT_RESERVED && uid != 0)
return 0;
return 1;
}
static void
sigchld_handler(int sig)
{
child_terminated = 1;
}
static void
sigterm_handler(int sig)
{
received_sigterm = sig;
}
static void
client_alive_check(struct ssh *ssh)
{
@ -348,12 +327,6 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
connection_in = ssh_packet_get_connection_in(ssh);
connection_out = ssh_packet_get_connection_out(ssh);
if (!use_privsep) {
ssh_signal(SIGTERM, sigterm_handler);
ssh_signal(SIGINT, sigterm_handler);
ssh_signal(SIGQUIT, sigterm_handler);
}
server_init_dispatch(ssh);
for (;;) {
@ -377,12 +350,6 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
if (sigprocmask(SIG_SETMASK, &osigset, NULL) == -1)
error_f("osigset sigprocmask: %s", strerror(errno));
if (received_sigterm) {
logit("Exiting on signal %d", (int)received_sigterm);
/* Clean up sessions, utmp, etc. */
cleanup_exit(255);
}
channel_after_poll(ssh, pfd, npfd_active);
if (conn_in_ready &&
process_input(ssh, connection_in) < 0)
@ -492,7 +459,7 @@ server_request_direct_streamlocal(struct ssh *ssh)
/* XXX fine grained permissions */
if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 &&
auth_opts->permit_port_forwarding_flag &&
!options.disable_forwarding && (pw->pw_uid == 0 || use_privsep)) {
!options.disable_forwarding) {
c = channel_connect_to_path(ssh, target,
"direct-streamlocal@openssh.com", "direct-streamlocal");
} else {
@ -781,9 +748,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
(options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
!auth_opts->permit_port_forwarding_flag ||
options.disable_forwarding ||
(!want_reply && fwd.listen_port == 0) ||
(fwd.listen_port != 0 &&
!bind_permitted(fwd.listen_port, pw->pw_uid))) {
(!want_reply && fwd.listen_port == 0)) {
success = 0;
ssh_packet_send_debug(ssh, "Server has disabled port forwarding.");
} else {
@ -816,8 +781,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
/* check permissions */
if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0
|| !auth_opts->permit_port_forwarding_flag ||
options.disable_forwarding ||
(pw->pw_uid != 0 && !use_privsep)) {
options.disable_forwarding) {
success = 0;
ssh_packet_send_debug(ssh, "Server has disabled "
"streamlocal forwarding.");

View file

@ -1,4 +1,4 @@
/* $OpenBSD: session.c,v 1.337 2024/02/01 02:37:33 djm Exp $ */
/* $OpenBSD: session.c,v 1.338 2024/05/17 00:30:24 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -705,8 +705,6 @@ do_login(struct ssh *ssh, Session *s, const char *command)
{
socklen_t fromlen;
struct sockaddr_storage from;
struct passwd * pw = s->pw;
pid_t pid = getpid();
/*
* Get IP address of client. If the connection is not a socket, let
@ -722,13 +720,6 @@ do_login(struct ssh *ssh, Session *s, const char *command)
}
}
/* Record that there was a login on that tty from the remote host. */
if (!use_privsep)
record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
session_get_remote_name_or_ip(ssh, utmp_len,
options.use_dns),
(struct sockaddr *)&from, fromlen);
if (check_quietlogin(s, command))
return;
@ -1606,8 +1597,7 @@ session_pty_req(struct ssh *ssh, Session *s)
/* Allocate a pty and open it. */
debug("Allocating pty.");
if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty,
sizeof(s->tty)))) {
if (!mm_pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) {
free(s->term);
s->term = NULL;
s->ptyfd = -1;
@ -1622,9 +1612,6 @@ session_pty_req(struct ssh *ssh, Session *s)
if ((r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (!use_privsep)
pty_setowner(s->pw, s->tty);
/* Set window size from the packet. */
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
@ -1840,7 +1827,7 @@ session_signal_req(struct ssh *ssh, Session *s)
signame, s->forced ? "forced-command" : "subsystem");
goto out;
}
if (!use_privsep || mm_is_monitor()) {
if (mm_is_monitor()) {
error_f("session signalling requires privilege separation");
goto out;
}
@ -1983,7 +1970,7 @@ session_pty_cleanup2(Session *s)
void
session_pty_cleanup(Session *s)
{
PRIVSEP(session_pty_cleanup2(s));
mm_session_pty_cleanup2(s);
}
static char *
@ -2354,7 +2341,7 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt)
* Cleanup ptys/utmp only if privsep is disabled,
* or if running in monitor.
*/
if (!use_privsep || mm_is_monitor())
if (mm_is_monitor())
session_destroy_all(ssh, session_pty_cleanup2);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sftp-client.c,v 1.175 2023/11/13 09:18:19 tobhe Exp $ */
/* $OpenBSD: sftp-client.c,v 1.176 2024/05/17 02:39:11 jsg Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@ -2415,7 +2415,7 @@ handle_dest_replies(struct sftp_conn *to, const char *to_path, int synchronous,
* server not to have reordered replies that could have
* inserted holes where none existed in the source file.
*
* XXX we could get a more accutate progress bar if we updated
* XXX we could get a more accurate progress bar if we updated
* the counter based on the reply from the destination...
*/
(*nreqsp)--;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-gss.h,v 1.15 2021/01/27 10:05:28 djm Exp $ */
/* $OpenBSD: ssh-gss.h,v 1.16 2024/05/17 06:42:04 jsg Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
*
@ -82,7 +82,6 @@ int ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
void ssh_gssapi_set_oid(Gssctxt *, gss_OID);
void ssh_gssapi_supported_oids(gss_OID_set *);
ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *);
void ssh_gssapi_prepare_supported_oids(void);
OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh_api.c,v 1.28 2024/01/09 21:39:14 djm Exp $ */
/* $OpenBSD: ssh_api.c,v 1.29 2024/05/17 00:30:24 djm Exp $ */
/*
* Copyright (c) 2012 Markus Friedl. All rights reserved.
*
@ -25,6 +25,7 @@
#include "log.h"
#include "authfile.h"
#include "sshkey.h"
#include "dh.h"
#include "misc.h"
#include "ssh2.h"
#include "version.h"
@ -45,10 +46,8 @@ int _ssh_host_key_sign(struct ssh *, struct sshkey *, struct sshkey *,
u_char **, size_t *, const u_char *, size_t, const char *);
/*
* stubs for the server side implementation of kex.
* disable privsep so our stubs will never be called.
* stubs for privsep calls in the server side implementation of kex.
*/
int use_privsep = 0;
int mm_sshkey_sign(struct sshkey *, u_char **, u_int *,
const u_char *, u_int, const char *, const char *, const char *, u_int);
@ -61,14 +60,20 @@ mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp,
const u_char *data, u_int datalen, const char *alg,
const char *sk_provider, const char *sk_pin, u_int compat)
{
return (-1);
size_t slen = 0;
int ret;
ret = sshkey_sign(key, sigp, &slen, data, datalen, alg,
sk_provider, sk_pin, compat);
*lenp = slen;
return ret;
}
#ifdef WITH_OPENSSL
DH *
mm_choose_dh(int min, int nbits, int max)
{
return (NULL);
return choose_dh(min, nbits, max);
}
#endif

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect2.c,v 1.372 2024/01/08 00:34:34 djm Exp $ */
/* $OpenBSD: sshconnect2.c,v 1.373 2024/05/17 06:38:00 jsg Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@ -75,8 +75,6 @@
#endif
/* import */
extern char *client_version_string;
extern char *server_version_string;
extern Options options;
/*

1354
usr.bin/ssh/sshd-session.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,71 @@
# $OpenBSD: Makefile,v 1.3 2024/05/17 14:42:00 naddy Exp $
.PATH: ${.CURDIR}/..
SRCS= sshd-session.c auth2-methods.c \
auth-rhosts.c auth-passwd.c sshpty.c sshlogin.c servconf.c \
serverloop.c auth.c auth2.c auth-options.c session.c auth2-chall.c \
groupaccess.c auth-bsdauth.c auth2-hostbased.c auth2-kbdint.c \
auth2-none.c auth2-passwd.c auth2-pubkey.c auth2-pubkeyfile.c \
monitor.c monitor_wrap.c \
sftp-server.c sftp-common.c sftp-realpath.c sandbox-pledge.c srclimit.c
SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c utf8.c uidswap.c
SRCS+= ${SRCS_BASE} ${SRCS_KEX} ${SRCS_KEXS} ${SRCS_KEY} ${SRCS_KEYP} \
${SRCS_KRL} ${SRCS_PROT} ${SRCS_PKT} ${SRCS_UTL} ${SRCS_PKCS11} \
${SRCS_SK_CLIENT}
PROG= sshd-session
BINDIR= /usr/libexec
BINMODE=511
NOMAN= 1
.include <bsd.own.mk> # for KERBEROS and AFS
KERBEROS5=no
.if (${KERBEROS5:L} == "yes")
CFLAGS+=-DKRB5 -I${DESTDIR}/usr/include/kerberosV -DGSSAPI
SRCS+= auth-krb5.c auth2-gss.c gss-serv.c gss-serv-krb5.c
.endif
.include <bsd.prog.mk>
.if (${KERBEROS5:L} == "yes")
LDADD+= -lgssapi -lkrb5 -lasn1
LDADD+= -lwind -lroken -lcom_err -lpthread -lheimbase -lkafs
DPADD+= ${LIBGSSAPI} ${LIBKRB5}
.endif
.if (${OPENSSL:L} == "yes")
LDADD+= -lcrypto
DPADD+= ${LIBCRYPTO}
.endif
LDADD+= -lutil
DPADD+= ${LIBUTIL}
.if (${ZLIB:L} == "yes")
LDADD+= -lz
DPADD+= ${LIBZ}
.endif
# The random relink kit, used on OpenBSD by /etc/rc
CLEANFILES+= ${PROG}.tar install.sh
install.sh: Makefile
echo "set -o errexit" > $@
echo "${CC} ${LDFLAGS} ${LDSTATIC} -o ${PROG}" \
"\`echo " ${OBJS} "| tr ' ' '\\\n' | sort -R\`" ${LDADD} >> $@
echo "./${PROG} -V # test it works" >> $@
echo "install -c -s -o root -g bin -m ${BINMODE} ${PROG} " \
"${BINDIR}/${PROG}" >> $@
${PROG}.tar: ${OBJS} install.sh
tar cf $@ ${OBJS} install.sh
afterinstall: ${PROG}.tar
install -d -o root -g wheel -m 755 \
${DESTDIR}/usr/share/relink/${BINDIR}/${PROG}
install -o ${BINOWN} -g ${BINGRP} -m 640 \
${PROG}.tar ${DESTDIR}/usr/share/relink/${BINDIR}/${PROG}/${PROG}.tar

File diff suppressed because it is too large Load diff

View file

@ -1,17 +1,11 @@
# $OpenBSD: Makefile,v 1.110 2024/04/01 15:48:16 deraadt Exp $
# $OpenBSD: Makefile,v 1.111 2024/05/17 00:30:24 djm Exp $
.PATH: ${.CURDIR}/..
SRCS= sshd.c auth-rhosts.c auth-passwd.c sshpty.c sshlogin.c servconf.c \
serverloop.c auth.c auth2.c auth-options.c session.c auth2-chall.c \
groupaccess.c auth-bsdauth.c auth2-hostbased.c auth2-kbdint.c \
auth2-none.c auth2-passwd.c auth2-pubkey.c auth2-pubkeyfile.c \
monitor.c monitor_wrap.c \
sftp-server.c sftp-common.c sftp-realpath.c sandbox-pledge.c srclimit.c
SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c utf8.c uidswap.c
SRCS+= ${SRCS_BASE} ${SRCS_KEX} ${SRCS_KEXS} ${SRCS_KEY} ${SRCS_KEYP} \
${SRCS_KRL} ${SRCS_PROT} ${SRCS_PKT} ${SRCS_UTL} ${SRCS_PKCS11} \
${SRCS_SK_CLIENT}
SRCS= sshd.c servconf.c sshpty.c srclimit.c groupaccess.c auth2-methods.c
SRCS+= dns.c fatal.c compat.c utf8.c authfd.c canohost.c kex-names.c
SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} \
${SRCS_MAC} ${SRCS_UTL} ${SRCS_SK_CLIENT}
PROG= sshd
BINMODE=511
@ -50,7 +44,7 @@ DPADD+= ${LIBZ}
# The random relink kit, used on OpenBSD by /etc/rc
CLEANFILES+= sshd.tar install.sh
CLEANFILES+= ${PROG}.tar install.sh
install.sh: Makefile
echo "set -o errexit" > $@

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sshkey.h,v 1.62 2023/06/21 05:10:26 djm Exp $ */
/* $OpenBSD: sshkey.h,v 1.63 2024/05/17 06:42:04 jsg Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -310,7 +310,6 @@ int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *);
int sshkey_set_filename(struct sshkey *, const char *);
int sshkey_enable_maxsign(struct sshkey *, u_int32_t);
u_int32_t sshkey_signatures_left(const struct sshkey *);
int sshkey_forward_state(const struct sshkey *, u_int32_t, int);
int sshkey_private_serialize_maxsign(struct sshkey *key,
struct sshbuf *buf, u_int32_t maxsign, int);