sync with OpenBSD -current
This commit is contained in:
parent
57ecf9bd1d
commit
b5356a44af
156 changed files with 3600 additions and 2644 deletions
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
133
usr.bin/ssh/auth2-methods.c
Normal 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;
|
||||
}
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)));
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
319
usr.bin/ssh/kex-names.c
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)--;
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
1354
usr.bin/ssh/sshd-session.c
Normal file
File diff suppressed because it is too large
Load diff
71
usr.bin/ssh/sshd-session/Makefile
Normal file
71
usr.bin/ssh/sshd-session/Makefile
Normal 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
|
1227
usr.bin/ssh/sshd.c
1227
usr.bin/ssh/sshd.c
File diff suppressed because it is too large
Load diff
|
@ -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" > $@
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue