from openbsd
This commit is contained in:
parent
d4e6ea9d15
commit
2a5e17aeda
|
@ -51,6 +51,46 @@ and ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic
|
|||
curve points encoded using point compression are NOT accepted or
|
||||
generated.
|
||||
|
||||
1.5 transport: Protocol 2 Encrypt-then-MAC MAC algorithms
|
||||
|
||||
OpenSSH supports MAC algorithms, whose names contain "-etm", that
|
||||
perform the calculations in a different order to that defined in RFC
|
||||
4253. These variants use the so-called "encrypt then MAC" ordering,
|
||||
calculating the MAC over the packet ciphertext rather than the
|
||||
plaintext. This ordering closes a security flaw in the SSH transport
|
||||
protocol, where decryption of unauthenticated ciphertext provided a
|
||||
"decryption oracle" that could, in conjunction with cipher flaws, reveal
|
||||
session plaintext.
|
||||
|
||||
Specifically, the "-etm" MAC algorithms modify the transport protocol
|
||||
to calculate the MAC over the packet ciphertext and to send the packet
|
||||
length unencrypted. This is necessary for the transport to obtain the
|
||||
length of the packet and location of the MAC tag so that it may be
|
||||
verified without decrypting unauthenticated data.
|
||||
|
||||
As such, the MAC covers:
|
||||
|
||||
mac = MAC(key, sequence_number || packet_length || encrypted_packet)
|
||||
|
||||
where "packet_length" is encoded as a uint32 and "encrypted_packet"
|
||||
contains:
|
||||
|
||||
byte padding_length
|
||||
byte[n1] payload; n1 = packet_length - padding_length - 1
|
||||
byte[n2] random padding; n2 = padding_length
|
||||
|
||||
1.6 transport: AES-GCM
|
||||
|
||||
OpenSSH supports the AES-GCM algorithm as specified in RFC 5647.
|
||||
Because of problems with the specification of the key exchange
|
||||
the behaviour of OpenSSH differs from the RFC as follows:
|
||||
|
||||
AES-GCM is only negotiated as the cipher algorithms
|
||||
"aes128-gcm@openssh.com" or "aes256-gcm@openssh.com" and never as
|
||||
an MAC algorithm. Additionally, if AES-GCM is selected as the cipher
|
||||
the exchanged MAC algorithms are ignored and there doesn't have to be
|
||||
a matching MAC.
|
||||
|
||||
2. Connection protocol changes
|
||||
|
||||
2.1. connection: Channel write close extension "eow@openssh.com"
|
||||
|
@ -291,4 +331,4 @@ link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
|
|||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
$OpenBSD: PROTOCOL,v 1.17 2010/12/04 00:18:01 djm Exp $
|
||||
$OpenBSD: PROTOCOL,v 1.20 2013/01/08 18:49:04 markus Exp $
|
||||
|
|
|
@ -152,7 +152,7 @@ fully specified using just rsa_q, rsa_p and rsa_e at the cost of extra
|
|||
computation.
|
||||
|
||||
"key_constraints" may only be present if the request type is
|
||||
SSH_AGENTC_ADD_RSA_IDENTITY.
|
||||
SSH_AGENTC_ADD_RSA_ID_CONSTRAINED.
|
||||
|
||||
The agent will reply with a SSH_AGENT_SUCCESS if the key has been
|
||||
successfully added or a SSH_AGENT_FAILURE if an error occurred.
|
||||
|
@ -557,4 +557,4 @@ Locking and unlocking affects both protocol 1 and protocol 2 keys.
|
|||
SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
|
||||
$OpenBSD: PROTOCOL.agent,v 1.6 2010/08/31 11:54:45 djm Exp $
|
||||
$OpenBSD: PROTOCOL.agent,v 1.7 2013/01/02 00:33:49 djm Exp $
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
This describes the key/certificate revocation list format for OpenSSH.
|
||||
|
||||
1. Overall format
|
||||
|
||||
The KRL consists of a header and zero or more sections. The header is:
|
||||
|
||||
#define KRL_MAGIC 0x5353484b524c0a00ULL /* "SSHKRL\n\0" */
|
||||
#define KRL_FORMAT_VERSION 1
|
||||
|
||||
uint64 KRL_MAGIC
|
||||
uint32 KRL_FORMAT_VERSION
|
||||
uint64 krl_version
|
||||
uint64 generated_date
|
||||
uint64 flags
|
||||
string reserved
|
||||
string comment
|
||||
|
||||
Where "krl_version" is a version number that increases each time the KRL
|
||||
is modified, "generated_date" is the time in seconds since 1970-01-01
|
||||
00:00:00 UTC that the KRL was generated, "comment" is an optional comment
|
||||
and "reserved" an extension field whose contents are currently ignored.
|
||||
No "flags" are currently defined.
|
||||
|
||||
Following the header are zero or more sections, each consisting of:
|
||||
|
||||
byte section_type
|
||||
string section_data
|
||||
|
||||
Where "section_type" indicates the type of the "section_data". An exception
|
||||
to this is the KRL_SECTION_SIGNATURE section, that has a slightly different
|
||||
format (see below).
|
||||
|
||||
The available section types are:
|
||||
|
||||
#define KRL_SECTION_CERTIFICATES 1
|
||||
#define KRL_SECTION_EXPLICIT_KEY 2
|
||||
#define KRL_SECTION_FINGERPRINT_SHA1 3
|
||||
#define KRL_SECTION_SIGNATURE 4
|
||||
|
||||
3. Certificate serial section
|
||||
|
||||
These sections use type KRL_SECTION_CERTIFICATES to revoke certificates by
|
||||
serial number or key ID. The consist of the CA key that issued the
|
||||
certificates to be revoked and a reserved field whose contents is currently
|
||||
ignored.
|
||||
|
||||
string ca_key
|
||||
string reserved
|
||||
|
||||
Followed by one or more sections:
|
||||
|
||||
byte cert_section_type
|
||||
string cert_section_data
|
||||
|
||||
The certificate section types are:
|
||||
|
||||
#define KRL_SECTION_CERT_SERIAL_LIST 0x20
|
||||
#define KRL_SECTION_CERT_SERIAL_RANGE 0x21
|
||||
#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22
|
||||
#define KRL_SECTION_CERT_KEY_ID 0x23
|
||||
|
||||
2.1 Certificate serial list section
|
||||
|
||||
This section is identified as KRL_SECTION_CERT_SERIAL_LIST. It revokes
|
||||
certificates by listing their serial numbers. The cert_section_data in this
|
||||
case contains:
|
||||
|
||||
uint64 revoked_cert_serial
|
||||
uint64 ...
|
||||
|
||||
This section may appear multiple times.
|
||||
|
||||
2.2. Certificate serial range section
|
||||
|
||||
These sections use type KRL_SECTION_CERT_SERIAL_RANGE and hold
|
||||
a range of serial numbers of certificates:
|
||||
|
||||
uint64 serial_min
|
||||
uint64 serial_max
|
||||
|
||||
All certificates in the range serial_min <= serial <= serial_max are
|
||||
revoked.
|
||||
|
||||
This section may appear multiple times.
|
||||
|
||||
2.3. Certificate serial bitmap section
|
||||
|
||||
Bitmap sections use type KRL_SECTION_CERT_SERIAL_BITMAP and revoke keys
|
||||
by listing their serial number in a bitmap.
|
||||
|
||||
uint64 serial_offset
|
||||
mpint revoked_keys_bitmap
|
||||
|
||||
A bit set at index N in the bitmap corresponds to revocation of a keys with
|
||||
serial number (serial_offset + N).
|
||||
|
||||
This section may appear multiple times.
|
||||
|
||||
2.4. Revoked key ID sections
|
||||
|
||||
KRL_SECTION_CERT_KEY_ID sections revoke particular certificate "key
|
||||
ID" strings. This may be useful in revoking all certificates
|
||||
associated with a particular identity, e.g. a host or a user.
|
||||
|
||||
string key_id[0]
|
||||
...
|
||||
|
||||
This section must contain at least one "key_id". This section may appear
|
||||
multiple times.
|
||||
|
||||
3. Explicit key sections
|
||||
|
||||
These sections, identified as KRL_SECTION_EXPLICIT_KEY, revoke keys
|
||||
(not certificates). They are less space efficient than serial numbers,
|
||||
but are able to revoke plain keys.
|
||||
|
||||
string public_key_blob[0]
|
||||
....
|
||||
|
||||
This section must contain at least one "public_key_blob". The blob
|
||||
must be a raw key (i.e. not a certificate).
|
||||
|
||||
This section may appear multiple times.
|
||||
|
||||
4. SHA1 fingerprint sections
|
||||
|
||||
These sections, identified as KRL_SECTION_FINGERPRINT_SHA1, revoke
|
||||
plain keys (i.e. not certificates) by listing their SHA1 hashes:
|
||||
|
||||
string public_key_hash[0]
|
||||
....
|
||||
|
||||
This section must contain at least one "public_key_hash". The hash blob
|
||||
is obtained by taking the SHA1 hash of the public key blob. Hashes in
|
||||
this section must appear in numeric order, treating each hash as a big-
|
||||
endian integer.
|
||||
|
||||
This section may appear multiple times.
|
||||
|
||||
5. KRL signature sections
|
||||
|
||||
The KRL_SECTION_SIGNATURE section serves a different purpose to the
|
||||
preceeding ones: to provide cryptographic authentication of a KRL that
|
||||
is retrieved over a channel that does not provide integrity protection.
|
||||
Its format is slightly different to the previously-described sections:
|
||||
in order to simplify the signature generation, it includes as a "body"
|
||||
two string components instead of one.
|
||||
|
||||
byte KRL_SECTION_SIGNATURE
|
||||
string signature_key
|
||||
string signature
|
||||
|
||||
The signature is calculated over the entire KRL from the KRL_MAGIC
|
||||
to this subsection's "signature_key", including both and using the
|
||||
signature generation rules appropriate for the type of "signature_key".
|
||||
|
||||
This section must appear last in the KRL. If multiple signature sections
|
||||
appear, they must appear consecutively at the end of the KRL file.
|
||||
|
||||
Implementations that retrieve KRLs over untrusted channels must verify
|
||||
signatures. Signature sections are optional for KRLs distributed by
|
||||
trusted means.
|
||||
|
||||
$OpenBSD: PROTOCOL.krl,v 1.2 2013/01/18 00:24:58 djm Exp $
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth-options.c,v 1.56 2011/10/18 04:58:26 djm Exp $ */
|
||||
/* $OpenBSD: auth-options.c,v 1.57 2012/12/02 20:46:11 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -347,7 +347,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
|||
xfree(patterns);
|
||||
goto bad_option;
|
||||
}
|
||||
if (options.allow_tcp_forwarding)
|
||||
if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0)
|
||||
channel_add_permitted_opens(host, port);
|
||||
xfree(patterns);
|
||||
goto next_option;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth-rsa.c,v 1.80 2011/05/23 03:30:07 djm Exp $ */
|
||||
/* $OpenBSD: auth-rsa.c,v 1.81 2012/10/30 21:29:54 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -273,6 +273,8 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
|
|||
temporarily_use_uid(pw);
|
||||
|
||||
for (i = 0; !allowed && i < options.num_authkeys_files; i++) {
|
||||
if (strcasecmp(options.authorized_keys_files[i], "none") == 0)
|
||||
continue;
|
||||
file = expand_authorized_keys(
|
||||
options.authorized_keys_files[i], pw);
|
||||
allowed = rsa_key_allowed_in_file(pw, file, client_n, rkey);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth.c,v 1.96 2012/05/13 01:42:32 dtucker Exp $ */
|
||||
/* $OpenBSD: auth.c,v 1.101 2013/02/06 00:22:21 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -57,6 +57,7 @@
|
|||
#endif
|
||||
#include "authfile.h"
|
||||
#include "monitor_wrap.h"
|
||||
#include "krl.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
@ -179,7 +180,8 @@ allowed_user(struct passwd * pw)
|
|||
}
|
||||
|
||||
void
|
||||
auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
|
||||
auth_log(Authctxt *authctxt, int authenticated, int partial,
|
||||
const char *method, const char *submethod, const char *info)
|
||||
{
|
||||
void (*authlog) (const char *fmt,...) = verbose;
|
||||
char *authmsg;
|
||||
|
@ -196,12 +198,15 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
|
|||
|
||||
if (authctxt->postponed)
|
||||
authmsg = "Postponed";
|
||||
else if (partial)
|
||||
authmsg = "Partial";
|
||||
else
|
||||
authmsg = authenticated ? "Accepted" : "Failed";
|
||||
|
||||
authlog("%s %s for %s%.100s from %.200s port %d%s",
|
||||
authlog("%s %s%s%s for %s%.100s from %.200s port %d%s",
|
||||
authmsg,
|
||||
method,
|
||||
submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
|
||||
authctxt->valid ? "" : "invalid user ",
|
||||
authctxt->user,
|
||||
get_remote_ipaddr(),
|
||||
|
@ -213,7 +218,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
|
|||
* Check whether root logins are disallowed.
|
||||
*/
|
||||
int
|
||||
auth_root_allowed(char *method)
|
||||
auth_root_allowed(const char *method)
|
||||
{
|
||||
switch (options.permit_root_login) {
|
||||
case PERMIT_YES:
|
||||
|
@ -319,41 +324,42 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
|
|||
return host_status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check a given file for security. This is defined as all components
|
||||
* Check a given path for security. This is defined as all components
|
||||
* of the path to the file must be owned by either the owner of
|
||||
* of the file or root and no directories must be group or world writable.
|
||||
*
|
||||
* XXX Should any specific check be done for sym links ?
|
||||
*
|
||||
* Takes an open file descriptor, the file name, a uid and and
|
||||
* Takes a file name, its stat information (preferably from fstat() to
|
||||
* avoid races), the uid of the expected owner, their home directory and an
|
||||
* error buffer plus max size as arguments.
|
||||
*
|
||||
* Returns 0 on success and -1 on failure
|
||||
*/
|
||||
static int
|
||||
secure_filename(FILE *f, const char *file, struct passwd *pw,
|
||||
char *err, size_t errlen)
|
||||
int
|
||||
auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
|
||||
uid_t uid, char *err, size_t errlen)
|
||||
{
|
||||
uid_t uid = pw->pw_uid;
|
||||
char buf[MAXPATHLEN], homedir[MAXPATHLEN];
|
||||
char *cp;
|
||||
int comparehome = 0;
|
||||
struct stat st;
|
||||
|
||||
if (realpath(file, buf) == NULL) {
|
||||
snprintf(err, errlen, "realpath %s failed: %s", file,
|
||||
if (realpath(name, buf) == NULL) {
|
||||
snprintf(err, errlen, "realpath %s failed: %s", name,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (realpath(pw->pw_dir, homedir) != NULL)
|
||||
if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
|
||||
comparehome = 1;
|
||||
|
||||
/* check the open file to avoid races */
|
||||
if (fstat(fileno(f), &st) < 0 ||
|
||||
(st.st_uid != 0 && st.st_uid != uid) ||
|
||||
(st.st_mode & 022) != 0) {
|
||||
if (!S_ISREG(stp->st_mode)) {
|
||||
snprintf(err, errlen, "%s is not a regular file", buf);
|
||||
return -1;
|
||||
}
|
||||
if ((stp->st_uid != 0 && stp->st_uid != uid) ||
|
||||
(stp->st_mode & 022) != 0) {
|
||||
snprintf(err, errlen, "bad ownership or modes for file %s",
|
||||
buf);
|
||||
return -1;
|
||||
|
@ -389,6 +395,27 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of secure_path() that accepts an open file descriptor to
|
||||
* avoid races.
|
||||
*
|
||||
* Returns 0 on success and -1 on failure
|
||||
*/
|
||||
static int
|
||||
secure_filename(FILE *f, const char *file, struct passwd *pw,
|
||||
char *err, size_t errlen)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
/* check the open file to avoid races */
|
||||
if (fstat(fileno(f), &st) < 0) {
|
||||
snprintf(err, errlen, "cannot stat file %s: %s",
|
||||
file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);
|
||||
}
|
||||
|
||||
static FILE *
|
||||
auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
||||
int log_missing, char *file_type)
|
||||
|
@ -488,7 +515,16 @@ auth_key_is_revoked(Key *key)
|
|||
|
||||
if (options.revoked_keys_file == NULL)
|
||||
return 0;
|
||||
|
||||
switch (ssh_krl_file_contains_key(options.revoked_keys_file, key)) {
|
||||
case 0:
|
||||
return 0; /* Not revoked */
|
||||
case -2:
|
||||
break; /* Not a KRL */
|
||||
default:
|
||||
goto revoked;
|
||||
}
|
||||
debug3("%s: treating %s as a key list", __func__,
|
||||
options.revoked_keys_file);
|
||||
switch (key_in_file(key, options.revoked_keys_file, 0)) {
|
||||
case 0:
|
||||
/* key not revoked */
|
||||
|
@ -499,6 +535,7 @@ auth_key_is_revoked(Key *key)
|
|||
"authentication");
|
||||
return 1;
|
||||
case 1:
|
||||
revoked:
|
||||
/* Key revoked */
|
||||
key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
error("WARNING: authentication attempt with a revoked "
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth.h,v 1.69 2011/05/23 03:30:07 djm Exp $ */
|
||||
/* $OpenBSD: auth.h,v 1.72 2012/12/02 20:34:09 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
|
@ -57,6 +57,8 @@ struct Authctxt {
|
|||
void *kbdintctxt;
|
||||
void *jpake_ctx;
|
||||
auth_session_t *as;
|
||||
char **auth_methods; /* modified from server config */
|
||||
u_int num_auth_methods;
|
||||
#ifdef KRB5
|
||||
krb5_context krb5_ctx;
|
||||
krb5_ccache krb5_fwd_ccache;
|
||||
|
@ -111,6 +113,10 @@ int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
|
|||
int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
|
||||
int user_key_allowed(struct passwd *, Key *);
|
||||
|
||||
struct stat;
|
||||
int auth_secure_path(const char *, struct stat *, const char *, uid_t,
|
||||
char *, size_t);
|
||||
|
||||
#ifdef KRB5
|
||||
int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
|
||||
int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
|
||||
|
@ -121,11 +127,15 @@ void krb5_cleanup_proc(Authctxt *authctxt);
|
|||
void do_authentication(Authctxt *);
|
||||
void do_authentication2(Authctxt *);
|
||||
|
||||
void auth_log(Authctxt *, int, char *, char *);
|
||||
void userauth_finish(Authctxt *, int, char *);
|
||||
int auth_root_allowed(char *);
|
||||
void auth_log(Authctxt *, int, int, const char *, const char *,
|
||||
const char *);
|
||||
void userauth_finish(Authctxt *, int, const char *, const char *);
|
||||
int auth_root_allowed(const char *);
|
||||
|
||||
char *auth2_read_banner(void);
|
||||
int auth2_methods_valid(const char *, int);
|
||||
int auth2_update_methods_lists(Authctxt *, const char *);
|
||||
int auth2_setup_methods_lists(Authctxt *);
|
||||
|
||||
void privsep_challenge_enable(void);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth1.c,v 1.75 2010/08/31 09:58:37 djm Exp $ */
|
||||
/* $OpenBSD: auth1.c,v 1.77 2012/12/02 20:34:09 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
|
@ -244,7 +244,7 @@ do_authloop(Authctxt *authctxt)
|
|||
(!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
|
||||
#endif
|
||||
PRIVSEP(auth_password(authctxt, ""))) {
|
||||
auth_log(authctxt, 1, "without authentication", "");
|
||||
auth_log(authctxt, 1, 0, "without authentication", NULL, "");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,8 @@ do_authloop(Authctxt *authctxt)
|
|||
|
||||
skip:
|
||||
/* Log before sending the reply */
|
||||
auth_log(authctxt, authenticated, get_authname(type), info);
|
||||
auth_log(authctxt, authenticated, 0, get_authname(type),
|
||||
NULL, info);
|
||||
|
||||
if (authenticated)
|
||||
return;
|
||||
|
@ -338,6 +339,11 @@ do_authentication(Authctxt *authctxt)
|
|||
authctxt->pw = fakepw();
|
||||
}
|
||||
|
||||
/* Configuration may have changed as a result of Match */
|
||||
if (options.num_auth_methods != 0)
|
||||
fatal("AuthenticationMethods is not supported with SSH "
|
||||
"protocol 1");
|
||||
|
||||
setproctitle("%s%s", authctxt->valid ? user : "unknown",
|
||||
use_privsep ? " [net]" : "");
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth2-chall.c,v 1.34 2008/12/09 04:32:22 djm Exp $ */
|
||||
/* $OpenBSD: auth2-chall.c,v 1.36 2012/12/03 00:14:06 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2001 Per Allansson. All rights reserved.
|
||||
|
@ -238,7 +238,8 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
|
|||
KbdintAuthctxt *kbdintctxt;
|
||||
int authenticated = 0, res;
|
||||
u_int i, nresp;
|
||||
char **response = NULL, *method;
|
||||
const char *devicename = NULL;
|
||||
char **response = NULL;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_info_response: no authctxt");
|
||||
|
@ -284,9 +285,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
|
|||
/* Failure! */
|
||||
break;
|
||||
}
|
||||
|
||||
xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name);
|
||||
|
||||
devicename = kbdintctxt->device->name;
|
||||
if (!authctxt->postponed) {
|
||||
if (authenticated) {
|
||||
auth2_challenge_stop(authctxt);
|
||||
|
@ -296,8 +295,8 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
|
|||
auth2_challenge_start(authctxt);
|
||||
}
|
||||
}
|
||||
userauth_finish(authctxt, authenticated, method);
|
||||
xfree(method);
|
||||
userauth_finish(authctxt, authenticated, "keyboard-interactive",
|
||||
devicename);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth2-gss.c,v 1.17 2011/03/10 02:52:57 djm Exp $ */
|
||||
/* $OpenBSD: auth2-gss.c,v 1.18 2012/12/02 20:34:09 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||
|
@ -159,7 +159,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
|
|||
}
|
||||
authctxt->postponed = 0;
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||
userauth_finish(authctxt, 0, "gssapi-with-mic");
|
||||
userauth_finish(authctxt, 0, "gssapi-with-mic", NULL);
|
||||
} else {
|
||||
if (send_tok.length != 0) {
|
||||
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
|
||||
|
@ -247,7 +247,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
|
|||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
|
||||
userauth_finish(authctxt, authenticated, "gssapi-with-mic");
|
||||
userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -287,7 +287,7 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
|
|||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
|
||||
userauth_finish(authctxt, authenticated, "gssapi-with-mic");
|
||||
userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
|
||||
}
|
||||
|
||||
Authmethod method_gssapi = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth2-jpake.c,v 1.4 2010/08/31 11:54:45 djm Exp $ */
|
||||
/* $OpenBSD: auth2-jpake.c,v 1.5 2012/12/02 20:34:09 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
*
|
||||
|
@ -556,7 +556,7 @@ input_userauth_jpake_client_confirm(int type, u_int32_t seq, void *ctxt)
|
|||
authctxt->postponed = 0;
|
||||
jpake_free(authctxt->jpake_ctx);
|
||||
authctxt->jpake_ctx = NULL;
|
||||
userauth_finish(authctxt, authenticated, method_jpake.name);
|
||||
userauth_finish(authctxt, authenticated, method_jpake.name, NULL);
|
||||
}
|
||||
|
||||
#endif /* JPAKE */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth2-pubkey.c,v 1.30 2011/09/25 05:44:47 djm Exp $ */
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.34 2013/02/14 21:35:59 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -26,9 +26,13 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
@ -239,7 +243,7 @@ match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert)
|
|||
if (strcmp(cp, cert->principals[i]) == 0) {
|
||||
debug3("matched principal \"%.100s\" "
|
||||
"from file \"%s\" on line %lu",
|
||||
cert->principals[i], file, linenum);
|
||||
cert->principals[i], file, linenum);
|
||||
if (auth_parse_options(pw, line_opts,
|
||||
file, linenum) != 1)
|
||||
continue;
|
||||
|
@ -252,31 +256,22 @@ match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert)
|
|||
fclose(f);
|
||||
restore_uid();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* return 1 if user allows given key */
|
||||
/*
|
||||
* Checks whether key is allowed in authorized_keys-format file,
|
||||
* returns 1 if the key is allowed or 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
||||
check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
|
||||
{
|
||||
char line[SSH_MAX_PUBKEY_BYTES];
|
||||
const char *reason;
|
||||
int found_key = 0;
|
||||
FILE *f;
|
||||
u_long linenum = 0;
|
||||
Key *found;
|
||||
char *fp;
|
||||
|
||||
/* Temporarily use the user's uid. */
|
||||
temporarily_use_uid(pw);
|
||||
|
||||
debug("trying public key file %s", file);
|
||||
f = auth_openkeyfile(file, pw, options.strict_modes);
|
||||
|
||||
if (!f) {
|
||||
restore_uid();
|
||||
return 0;
|
||||
}
|
||||
|
||||
found_key = 0;
|
||||
found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
|
||||
|
||||
|
@ -369,8 +364,6 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
|||
break;
|
||||
}
|
||||
}
|
||||
restore_uid();
|
||||
fclose(f);
|
||||
key_free(found);
|
||||
if (!found_key)
|
||||
debug2("key not found");
|
||||
|
@ -432,7 +425,180 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* check whether given key is in .ssh/authorized_keys* */
|
||||
/*
|
||||
* Checks whether key is allowed in file.
|
||||
* returns 1 if the key is allowed or 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
||||
{
|
||||
FILE *f;
|
||||
int found_key = 0;
|
||||
|
||||
/* Temporarily use the user's uid. */
|
||||
temporarily_use_uid(pw);
|
||||
|
||||
debug("trying public key file %s", file);
|
||||
if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) {
|
||||
found_key = check_authkeys_file(f, file, key, pw);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
restore_uid();
|
||||
return found_key;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether key is allowed in output of command.
|
||||
* returns 1 if the key is allowed or 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
user_key_command_allowed2(struct passwd *user_pw, Key *key)
|
||||
{
|
||||
FILE *f;
|
||||
int ok, found_key = 0;
|
||||
struct passwd *pw;
|
||||
struct stat st;
|
||||
int status, devnull, p[2], i;
|
||||
pid_t pid;
|
||||
char *username, errmsg[512];
|
||||
|
||||
if (options.authorized_keys_command == NULL ||
|
||||
options.authorized_keys_command[0] != '/')
|
||||
return 0;
|
||||
|
||||
if (options.authorized_keys_command_user == NULL) {
|
||||
error("No user for AuthorizedKeysCommand specified, skipping");
|
||||
return 0;
|
||||
}
|
||||
|
||||
username = percent_expand(options.authorized_keys_command_user,
|
||||
"u", user_pw->pw_name, (char *)NULL);
|
||||
pw = getpwnam(username);
|
||||
if (pw == NULL) {
|
||||
error("AuthorizedKeysCommandUser \"%s\" not found: %s",
|
||||
username, strerror(errno));
|
||||
free(username);
|
||||
return 0;
|
||||
}
|
||||
free(username);
|
||||
|
||||
temporarily_use_uid(pw);
|
||||
|
||||
if (stat(options.authorized_keys_command, &st) < 0) {
|
||||
error("Could not stat AuthorizedKeysCommand \"%s\": %s",
|
||||
options.authorized_keys_command, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0,
|
||||
errmsg, sizeof(errmsg)) != 0) {
|
||||
error("Unsafe AuthorizedKeysCommand: %s", errmsg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pipe(p) != 0) {
|
||||
error("%s: pipe: %s", __func__, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
debug3("Running AuthorizedKeysCommand: \"%s %s\" as \"%s\"",
|
||||
options.authorized_keys_command, user_pw->pw_name, pw->pw_name);
|
||||
|
||||
/*
|
||||
* Don't want to call this in the child, where it can fatal() and
|
||||
* run cleanup_exit() code.
|
||||
*/
|
||||
restore_uid();
|
||||
|
||||
switch ((pid = fork())) {
|
||||
case -1: /* error */
|
||||
error("%s: fork: %s", __func__, strerror(errno));
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
return 0;
|
||||
case 0: /* child */
|
||||
for (i = 0; i < NSIG; i++)
|
||||
signal(i, SIG_DFL);
|
||||
|
||||
if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
|
||||
error("%s: open %s: %s", __func__, _PATH_DEVNULL,
|
||||
strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
/* Keep stderr around a while longer to catch errors */
|
||||
if (dup2(devnull, STDIN_FILENO) == -1 ||
|
||||
dup2(p[1], STDOUT_FILENO) == -1) {
|
||||
error("%s: dup2: %s", __func__, strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
/* Don't use permanently_set_uid() here to avoid fatal() */
|
||||
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
|
||||
error("setresgid %u: %s", (u_int)pw->pw_gid,
|
||||
strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
|
||||
error("setresuid %u: %s", (u_int)pw->pw_uid,
|
||||
strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
/* stdin is pointed to /dev/null at this point */
|
||||
if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
|
||||
error("%s: dup2: %s", __func__, strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
execl(options.authorized_keys_command,
|
||||
options.authorized_keys_command, user_pw->pw_name, NULL);
|
||||
|
||||
error("AuthorizedKeysCommand %s exec failed: %s",
|
||||
options.authorized_keys_command, strerror(errno));
|
||||
_exit(127);
|
||||
default: /* parent */
|
||||
break;
|
||||
}
|
||||
|
||||
temporarily_use_uid(pw);
|
||||
|
||||
close(p[1]);
|
||||
if ((f = fdopen(p[0], "r")) == NULL) {
|
||||
error("%s: fdopen: %s", __func__, strerror(errno));
|
||||
close(p[0]);
|
||||
/* Don't leave zombie child */
|
||||
kill(pid, SIGTERM);
|
||||
while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
|
||||
;
|
||||
goto out;
|
||||
}
|
||||
ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
|
||||
fclose(f);
|
||||
|
||||
while (waitpid(pid, &status, 0) == -1) {
|
||||
if (errno != EINTR) {
|
||||
error("%s: waitpid: %s", __func__, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (WIFSIGNALED(status)) {
|
||||
error("AuthorizedKeysCommand %s exited on signal %d",
|
||||
options.authorized_keys_command, WTERMSIG(status));
|
||||
goto out;
|
||||
} else if (WEXITSTATUS(status) != 0) {
|
||||
error("AuthorizedKeysCommand %s returned status %d",
|
||||
options.authorized_keys_command, WEXITSTATUS(status));
|
||||
goto out;
|
||||
}
|
||||
found_key = ok;
|
||||
out:
|
||||
restore_uid();
|
||||
return found_key;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether key authenticates and authorises the user.
|
||||
*/
|
||||
int
|
||||
user_key_allowed(struct passwd *pw, Key *key)
|
||||
{
|
||||
|
@ -448,9 +614,17 @@ user_key_allowed(struct passwd *pw, Key *key)
|
|||
if (success)
|
||||
return success;
|
||||
|
||||
success = user_key_command_allowed2(pw, key);
|
||||
if (success > 0)
|
||||
return success;
|
||||
|
||||
for (i = 0; !success && i < options.num_authkeys_files; i++) {
|
||||
|
||||
if (strcasecmp(options.authorized_keys_files[i], "none") == 0)
|
||||
continue;
|
||||
file = expand_authorized_keys(
|
||||
options.authorized_keys_files[i], pw);
|
||||
|
||||
success = user_key_allowed2(pw, key, file);
|
||||
xfree(file);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth2.c,v 1.124 2011/12/07 05:44:38 djm Exp $ */
|
||||
/* $OpenBSD: auth2.c,v 1.126 2012/12/02 20:34:09 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -92,8 +92,10 @@ static void input_service_request(int, u_int32_t, void *);
|
|||
static void input_userauth_request(int, u_int32_t, void *);
|
||||
|
||||
/* helper */
|
||||
static Authmethod *authmethod_lookup(const char *);
|
||||
static char *authmethods_get(void);
|
||||
static Authmethod *authmethod_lookup(Authctxt *, const char *);
|
||||
static char *authmethods_get(Authctxt *authctxt);
|
||||
static int method_allowed(Authctxt *, const char *);
|
||||
static int list_starts_with(const char *, const char *);
|
||||
|
||||
char *
|
||||
auth2_read_banner(void)
|
||||
|
@ -235,6 +237,8 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
|||
if (use_privsep)
|
||||
mm_inform_authserv(service, style);
|
||||
userauth_banner();
|
||||
if (auth2_setup_methods_lists(authctxt) != 0)
|
||||
packet_disconnect("no authentication methods enabled");
|
||||
} else if (strcmp(user, authctxt->user) != 0 ||
|
||||
strcmp(service, authctxt->service) != 0) {
|
||||
packet_disconnect("Change of username or service not allowed: "
|
||||
|
@ -257,12 +261,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
|||
authctxt->server_caused_failure = 0;
|
||||
|
||||
/* try to authenticate user */
|
||||
m = authmethod_lookup(method);
|
||||
m = authmethod_lookup(authctxt, method);
|
||||
if (m != NULL && authctxt->failures < options.max_authtries) {
|
||||
debug2("input_userauth_request: try method %s", method);
|
||||
authenticated = m->userauth(authctxt);
|
||||
}
|
||||
userauth_finish(authctxt, authenticated, method);
|
||||
userauth_finish(authctxt, authenticated, method, NULL);
|
||||
|
||||
xfree(service);
|
||||
xfree(user);
|
||||
|
@ -270,26 +274,36 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
|||
}
|
||||
|
||||
void
|
||||
userauth_finish(Authctxt *authctxt, int authenticated, char *method)
|
||||
userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
|
||||
const char *submethod)
|
||||
{
|
||||
char *methods;
|
||||
int partial = 0;
|
||||
|
||||
if (!authctxt->valid && authenticated)
|
||||
fatal("INTERNAL ERROR: authenticated invalid user %s",
|
||||
authctxt->user);
|
||||
if (authenticated && authctxt->postponed)
|
||||
fatal("INTERNAL ERROR: authenticated and postponed");
|
||||
|
||||
/* Special handling for root */
|
||||
if (authenticated && authctxt->pw->pw_uid == 0 &&
|
||||
!auth_root_allowed(method))
|
||||
authenticated = 0;
|
||||
|
||||
if (authenticated && options.num_auth_methods != 0) {
|
||||
if (!auth2_update_methods_lists(authctxt, method)) {
|
||||
authenticated = 0;
|
||||
partial = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Log before sending the reply */
|
||||
auth_log(authctxt, authenticated, method, " ssh2");
|
||||
auth_log(authctxt, authenticated, partial, method, submethod, " ssh2");
|
||||
|
||||
if (authctxt->postponed)
|
||||
return;
|
||||
|
||||
/* XXX todo: check if multiple auth methods are needed */
|
||||
if (authenticated == 1) {
|
||||
/* turn off userauth */
|
||||
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
|
||||
|
@ -305,34 +319,61 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
|
|||
authctxt->failures++;
|
||||
if (authctxt->failures >= options.max_authtries)
|
||||
packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
|
||||
methods = authmethods_get();
|
||||
methods = authmethods_get(authctxt);
|
||||
debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
|
||||
partial, methods);
|
||||
packet_start(SSH2_MSG_USERAUTH_FAILURE);
|
||||
packet_put_cstring(methods);
|
||||
packet_put_char(0); /* XXX partial success, unused */
|
||||
packet_put_char(partial);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
xfree(methods);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether method is allowed by at least one AuthenticationMethods
|
||||
* methods list. Returns 1 if allowed, or no methods lists configured.
|
||||
* 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
method_allowed(Authctxt *authctxt, const char *method)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
/*
|
||||
* NB. authctxt->num_auth_methods might be zero as a result of
|
||||
* auth2_setup_methods_lists(), so check the configuration.
|
||||
*/
|
||||
if (options.num_auth_methods == 0)
|
||||
return 1;
|
||||
for (i = 0; i < authctxt->num_auth_methods; i++) {
|
||||
if (list_starts_with(authctxt->auth_methods[i], method))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
authmethods_get(void)
|
||||
authmethods_get(Authctxt *authctxt)
|
||||
{
|
||||
Buffer b;
|
||||
char *list;
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
buffer_init(&b);
|
||||
for (i = 0; authmethods[i] != NULL; i++) {
|
||||
if (strcmp(authmethods[i]->name, "none") == 0)
|
||||
continue;
|
||||
if (authmethods[i]->enabled != NULL &&
|
||||
*(authmethods[i]->enabled) != 0) {
|
||||
if (buffer_len(&b) > 0)
|
||||
buffer_append(&b, ",", 1);
|
||||
buffer_append(&b, authmethods[i]->name,
|
||||
strlen(authmethods[i]->name));
|
||||
}
|
||||
if (authmethods[i]->enabled == NULL ||
|
||||
*(authmethods[i]->enabled) == 0)
|
||||
continue;
|
||||
if (!method_allowed(authctxt, authmethods[i]->name))
|
||||
continue;
|
||||
if (buffer_len(&b) > 0)
|
||||
buffer_append(&b, ",", 1);
|
||||
buffer_append(&b, authmethods[i]->name,
|
||||
strlen(authmethods[i]->name));
|
||||
}
|
||||
buffer_append(&b, "\0", 1);
|
||||
list = xstrdup(buffer_ptr(&b));
|
||||
|
@ -341,7 +382,7 @@ authmethods_get(void)
|
|||
}
|
||||
|
||||
static Authmethod *
|
||||
authmethod_lookup(const char *name)
|
||||
authmethod_lookup(Authctxt *authctxt, const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -349,10 +390,154 @@ authmethod_lookup(const char *name)
|
|||
for (i = 0; authmethods[i] != NULL; i++)
|
||||
if (authmethods[i]->enabled != NULL &&
|
||||
*(authmethods[i]->enabled) != 0 &&
|
||||
strcmp(name, authmethods[i]->name) == 0)
|
||||
strcmp(name, authmethods[i]->name) == 0 &&
|
||||
method_allowed(authctxt, authmethods[i]->name))
|
||||
return authmethods[i];
|
||||
debug2("Unrecognized authentication method name: %s",
|
||||
name ? name : "NULL");
|
||||
return 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;
|
||||
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 (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
|
||||
* leave authctxt->num_auth_methods == 0, even when multiple required auth
|
||||
* has been requested. For this reason, all tests for whether multiple is
|
||||
* enabled should consult options.num_auth_methods directly.
|
||||
*/
|
||||
int
|
||||
auth2_setup_methods_lists(Authctxt *authctxt)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
if (options.num_auth_methods == 0)
|
||||
return 0;
|
||||
debug3("%s: checking methods", __func__);
|
||||
authctxt->auth_methods = xcalloc(options.num_auth_methods,
|
||||
sizeof(*authctxt->auth_methods));
|
||||
authctxt->num_auth_methods = 0;
|
||||
for (i = 0; i < options.num_auth_methods; i++) {
|
||||
if (auth2_methods_valid(options.auth_methods[i], 1) != 0) {
|
||||
logit("Authentication methods list \"%s\" contains "
|
||||
"disabled method, skipping",
|
||||
options.auth_methods[i]);
|
||||
continue;
|
||||
}
|
||||
debug("authentication methods list %d: %s",
|
||||
authctxt->num_auth_methods, options.auth_methods[i]);
|
||||
authctxt->auth_methods[authctxt->num_auth_methods++] =
|
||||
xstrdup(options.auth_methods[i]);
|
||||
}
|
||||
if (authctxt->num_auth_methods == 0) {
|
||||
error("No AuthenticationMethods left after eliminating "
|
||||
"disabled methods");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
list_starts_with(const char *methods, const char *method)
|
||||
{
|
||||
size_t l = strlen(method);
|
||||
|
||||
if (strncmp(methods, method, l) != 0)
|
||||
return 0;
|
||||
if (methods[l] != ',' && methods[l] != '\0')
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove method from the start of a comma-separated list of methods.
|
||||
* Returns 0 if the list of methods did not start with that method or 1
|
||||
* if it did.
|
||||
*/
|
||||
static int
|
||||
remove_method(char **methods, const char *method)
|
||||
{
|
||||
char *omethods = *methods;
|
||||
size_t l = strlen(method);
|
||||
|
||||
if (!list_starts_with(omethods, method))
|
||||
return 0;
|
||||
*methods = xstrdup(omethods + l + (omethods[l] == ',' ? 1 : 0));
|
||||
free(omethods);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after successful authentication. Will remove the successful method
|
||||
* from the start of each list in which it occurs. If it was the last method
|
||||
* in any list, then authentication is deemed successful.
|
||||
* Returns 1 if the method completed any authentication list or 0 otherwise.
|
||||
*/
|
||||
int
|
||||
auth2_update_methods_lists(Authctxt *authctxt, const char *method)
|
||||
{
|
||||
u_int i, found = 0;
|
||||
|
||||
debug3("%s: updating methods list after \"%s\"", __func__, method);
|
||||
for (i = 0; i < authctxt->num_auth_methods; i++) {
|
||||
if (!remove_method(&(authctxt->auth_methods[i]), method))
|
||||
continue;
|
||||
found = 1;
|
||||
if (*authctxt->auth_methods[i] == '\0') {
|
||||
debug2("authentication methods list %d complete", i);
|
||||
return 1;
|
||||
}
|
||||
debug3("authentication methods list %d remaining: \"%s\"",
|
||||
i, authctxt->auth_methods[i]);
|
||||
}
|
||||
/* This should not happen, but would be bad if it did */
|
||||
if (!found)
|
||||
fatal("%s: method not in AuthenticationMethods", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: authfile.c,v 1.93 2012/01/25 19:36:31 markus Exp $ */
|
||||
/* $OpenBSD: authfile.c,v 1.95 2013/01/08 18:49:04 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -145,7 +145,7 @@ key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
|
|||
cipher_set_key_string(&ciphercontext, cipher, passphrase,
|
||||
CIPHER_ENCRYPT);
|
||||
cipher_crypt(&ciphercontext, cp,
|
||||
buffer_ptr(&buffer), buffer_len(&buffer));
|
||||
buffer_ptr(&buffer), buffer_len(&buffer), 0, 0);
|
||||
cipher_cleanup(&ciphercontext);
|
||||
memset(&ciphercontext, 0, sizeof(ciphercontext));
|
||||
|
||||
|
@ -463,7 +463,7 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
|
|||
cipher_set_key_string(&ciphercontext, cipher, passphrase,
|
||||
CIPHER_DECRYPT);
|
||||
cipher_crypt(&ciphercontext, cp,
|
||||
buffer_ptr(©), buffer_len(©));
|
||||
buffer_ptr(©), buffer_len(©), 0, 0);
|
||||
cipher_cleanup(&ciphercontext);
|
||||
memset(&ciphercontext, 0, sizeof(ciphercontext));
|
||||
buffer_free(©);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: channels.c,v 1.318 2012/04/23 08:18:17 djm Exp $ */
|
||||
/* $OpenBSD: channels.c,v 1.319 2012/12/02 20:46:11 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -3135,12 +3135,10 @@ channel_add_adm_permitted_opens(char *host, int port)
|
|||
void
|
||||
channel_disable_adm_local_opens(void)
|
||||
{
|
||||
if (num_adm_permitted_opens == 0) {
|
||||
permitted_adm_opens = xmalloc(sizeof(*permitted_adm_opens));
|
||||
permitted_adm_opens[num_adm_permitted_opens].host_to_connect
|
||||
= NULL;
|
||||
num_adm_permitted_opens = 1;
|
||||
}
|
||||
channel_clear_adm_permitted_opens();
|
||||
permitted_adm_opens = xmalloc(sizeof(*permitted_adm_opens));
|
||||
permitted_adm_opens[num_adm_permitted_opens].host_to_connect = NULL;
|
||||
num_adm_permitted_opens = 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: cipher.c,v 1.82 2009/01/26 09:58:15 markus Exp $ */
|
||||
/* $OpenBSD: cipher.c,v 1.87 2013/01/26 06:11:05 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -49,40 +49,45 @@
|
|||
extern const EVP_CIPHER *evp_ssh1_bf(void);
|
||||
extern const EVP_CIPHER *evp_ssh1_3des(void);
|
||||
extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
|
||||
extern const EVP_CIPHER *evp_aes_128_ctr(void);
|
||||
extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
|
||||
|
||||
struct Cipher {
|
||||
char *name;
|
||||
int number; /* for ssh1 only */
|
||||
u_int block_size;
|
||||
u_int key_len;
|
||||
u_int iv_len; /* defaults to block_size */
|
||||
u_int auth_len;
|
||||
u_int discard_len;
|
||||
u_int cbc_mode;
|
||||
const EVP_CIPHER *(*evptype)(void);
|
||||
} ciphers[] = {
|
||||
{ "none", SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null },
|
||||
{ "des", SSH_CIPHER_DES, 8, 8, 0, 1, EVP_des_cbc },
|
||||
{ "3des", SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des },
|
||||
{ "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 1, evp_ssh1_bf },
|
||||
{ "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
|
||||
{ "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
|
||||
{ "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
|
||||
{ "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
|
||||
|
||||
{ "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc },
|
||||
{ "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_bf_cbc },
|
||||
{ "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_cast5_cbc },
|
||||
{ "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, EVP_rc4 },
|
||||
{ "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, 0, EVP_rc4 },
|
||||
{ "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, 0, EVP_rc4 },
|
||||
{ "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc },
|
||||
{ "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc },
|
||||
{ "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
|
||||
{ "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
|
||||
{ "blowfish-cbc",
|
||||
SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
|
||||
{ "cast128-cbc",
|
||||
SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc },
|
||||
{ "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 },
|
||||
{ "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 },
|
||||
{ "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 },
|
||||
{ "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc },
|
||||
{ "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc },
|
||||
{ "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
|
||||
{ "rijndael-cbc@lysator.liu.se",
|
||||
SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
|
||||
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr },
|
||||
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr },
|
||||
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr },
|
||||
{ "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss },
|
||||
SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
|
||||
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr },
|
||||
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr },
|
||||
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr },
|
||||
{ "aes128-gcm@openssh.com",
|
||||
SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },
|
||||
{ "aes256-gcm@openssh.com",
|
||||
SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
|
||||
|
||||
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL }
|
||||
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
/*--*/
|
||||
|
@ -99,6 +104,18 @@ cipher_keylen(const Cipher *c)
|
|||
return (c->key_len);
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_authlen(const Cipher *c)
|
||||
{
|
||||
return (c->auth_len);
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_ivlen(const Cipher *c)
|
||||
{
|
||||
return (c->iv_len ? c->iv_len : c->block_size);
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_get_number(const Cipher *c)
|
||||
{
|
||||
|
@ -214,11 +231,12 @@ cipher_init(CipherContext *cc, Cipher *cipher,
|
|||
keylen = 8;
|
||||
}
|
||||
cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
|
||||
cc->encrypt = do_encrypt;
|
||||
|
||||
if (keylen < cipher->key_len)
|
||||
fatal("cipher_init: key length %d is insufficient for %s.",
|
||||
keylen, cipher->name);
|
||||
if (iv != NULL && ivlen < cipher->block_size)
|
||||
if (iv != NULL && ivlen < cipher_ivlen(cipher))
|
||||
fatal("cipher_init: iv length %d is insufficient for %s.",
|
||||
ivlen, cipher->name);
|
||||
cc->cipher = cipher;
|
||||
|
@ -230,6 +248,11 @@ cipher_init(CipherContext *cc, Cipher *cipher,
|
|||
(do_encrypt == CIPHER_ENCRYPT)) == 0)
|
||||
fatal("cipher_init: EVP_CipherInit failed for %s",
|
||||
cipher->name);
|
||||
if (cipher_authlen(cipher) &&
|
||||
!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
|
||||
-1, (u_char *)iv))
|
||||
fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s",
|
||||
cipher->name);
|
||||
klen = EVP_CIPHER_CTX_key_length(&cc->evp);
|
||||
if (klen > 0 && keylen != (u_int)klen) {
|
||||
debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
|
||||
|
@ -253,13 +276,59 @@ cipher_init(CipherContext *cc, Cipher *cipher,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* cipher_crypt() operates as following:
|
||||
* Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.
|
||||
* Theses bytes are treated as additional authenticated data for
|
||||
* authenticated encryption modes.
|
||||
* En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.
|
||||
* Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
|
||||
* This tag is written on encryption and verified on decryption.
|
||||
* Both 'aadlen' and 'authlen' can be set to 0.
|
||||
*/
|
||||
void
|
||||
cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
|
||||
cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src,
|
||||
u_int len, u_int aadlen, u_int authlen)
|
||||
{
|
||||
if (authlen) {
|
||||
u_char lastiv[1];
|
||||
|
||||
if (authlen != cipher_authlen(cc->cipher))
|
||||
fatal("%s: authlen mismatch %d", __func__, authlen);
|
||||
/* increment IV */
|
||||
if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
|
||||
1, lastiv))
|
||||
fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__);
|
||||
/* set tag on decyption */
|
||||
if (!cc->encrypt &&
|
||||
!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG,
|
||||
authlen, (u_char *)src + aadlen + len))
|
||||
fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__);
|
||||
}
|
||||
if (aadlen) {
|
||||
if (authlen &&
|
||||
EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0)
|
||||
fatal("%s: EVP_Cipher(aad) failed", __func__);
|
||||
memcpy(dest, src, aadlen);
|
||||
}
|
||||
if (len % cc->cipher->block_size)
|
||||
fatal("cipher_encrypt: bad plaintext length %d", len);
|
||||
if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
|
||||
fatal("evp_crypt: EVP_Cipher failed");
|
||||
fatal("%s: bad plaintext length %d", __func__, len);
|
||||
if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen,
|
||||
len) < 0)
|
||||
fatal("%s: EVP_Cipher failed", __func__);
|
||||
if (authlen) {
|
||||
/* compute tag (on encrypt) or verify tag (on decrypt) */
|
||||
if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) {
|
||||
if (cc->encrypt)
|
||||
fatal("%s: EVP_Cipher(final) failed", __func__);
|
||||
else
|
||||
fatal("Decryption integrity check failed");
|
||||
}
|
||||
if (cc->encrypt &&
|
||||
!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG,
|
||||
authlen, dest + aadlen + len))
|
||||
fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -326,9 +395,11 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
|
|||
if ((u_int)evplen != len)
|
||||
fatal("%s: wrong iv length %d != %d", __func__,
|
||||
evplen, len);
|
||||
if (c->evptype == evp_aes_128_ctr)
|
||||
ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
|
||||
else
|
||||
if (cipher_authlen(c)) {
|
||||
if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
|
||||
len, iv))
|
||||
fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__);
|
||||
} else
|
||||
memcpy(iv, cc->evp.iv, len);
|
||||
break;
|
||||
case SSH_CIPHER_3DES:
|
||||
|
@ -352,9 +423,12 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv)
|
|||
evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
|
||||
if (evplen == 0)
|
||||
return;
|
||||
if (c->evptype == evp_aes_128_ctr)
|
||||
ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
|
||||
else
|
||||
if (cipher_authlen(c)) {
|
||||
if (!EVP_CIPHER_CTX_ctrl(&cc->evp,
|
||||
EVP_CTRL_GCM_SET_IV_FIXED, -1, iv))
|
||||
fatal("%s: EVP_CTRL_GCM_SET_IV_FIXED failed",
|
||||
__func__);
|
||||
} else
|
||||
memcpy(cc->evp.iv, iv, evplen);
|
||||
break;
|
||||
case SSH_CIPHER_3DES:
|
||||
|
@ -374,7 +448,7 @@ cipher_get_keycontext(const CipherContext *cc, u_char *dat)
|
|||
Cipher *c = cc->cipher;
|
||||
int plen = 0;
|
||||
|
||||
if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
|
||||
if (c->evptype == EVP_rc4) {
|
||||
plen = EVP_X_STATE_LEN(cc->evp);
|
||||
if (dat == NULL)
|
||||
return (plen);
|
||||
|
@ -389,7 +463,7 @@ cipher_set_keycontext(CipherContext *cc, u_char *dat)
|
|||
Cipher *c = cc->cipher;
|
||||
int plen;
|
||||
|
||||
if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
|
||||
if (c->evptype == EVP_rc4) {
|
||||
plen = EVP_X_STATE_LEN(cc->evp);
|
||||
memcpy(EVP_X_STATE(cc->evp), dat, plen);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: cipher.h,v 1.37 2009/01/26 09:58:15 markus Exp $ */
|
||||
/* $OpenBSD: cipher.h,v 1.39 2013/01/08 18:49:04 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -64,6 +64,7 @@ typedef struct CipherContext CipherContext;
|
|||
struct Cipher;
|
||||
struct CipherContext {
|
||||
int plaintext;
|
||||
int encrypt;
|
||||
EVP_CIPHER_CTX evp;
|
||||
Cipher *cipher;
|
||||
};
|
||||
|
@ -76,11 +77,14 @@ char *cipher_name(int);
|
|||
int ciphers_valid(const char *);
|
||||
void cipher_init(CipherContext *, Cipher *, const u_char *, u_int,
|
||||
const u_char *, u_int, int);
|
||||
void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int);
|
||||
void cipher_crypt(CipherContext *, u_char *, const u_char *,
|
||||
u_int, u_int, u_int);
|
||||
void cipher_cleanup(CipherContext *);
|
||||
void cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
|
||||
u_int cipher_blocksize(const Cipher *);
|
||||
u_int cipher_keylen(const Cipher *);
|
||||
u_int cipher_authlen(const Cipher *);
|
||||
u_int cipher_ivlen(const Cipher *);
|
||||
u_int cipher_is_cbc(const Cipher *);
|
||||
|
||||
u_int cipher_get_number(const Cipher *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: clientloop.c,v 1.240 2012/06/20 04:42:58 djm Exp $ */
|
||||
/* $OpenBSD: clientloop.c,v 1.248 2013/01/02 00:32:07 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -959,9 +959,9 @@ process_cmdline(void)
|
|||
goto out;
|
||||
}
|
||||
if (local || dynamic) {
|
||||
if (channel_setup_local_fwd_listener(fwd.listen_host,
|
||||
if (!channel_setup_local_fwd_listener(fwd.listen_host,
|
||||
fwd.listen_port, fwd.connect_host,
|
||||
fwd.connect_port, options.gateway_ports) < 0) {
|
||||
fwd.connect_port, options.gateway_ports)) {
|
||||
logit("Port forwarding failed.");
|
||||
goto out;
|
||||
}
|
||||
|
@ -987,6 +987,63 @@ out:
|
|||
xfree(fwd.connect_host);
|
||||
}
|
||||
|
||||
/* reasons to suppress output of an escape command in help output */
|
||||
#define SUPPRESS_NEVER 0 /* never suppress, always show */
|
||||
#define SUPPRESS_PROTO1 1 /* don't show in protocol 1 sessions */
|
||||
#define SUPPRESS_MUXCLIENT 2 /* don't show in mux client sessions */
|
||||
#define SUPPRESS_MUXMASTER 4 /* don't show in mux master sessions */
|
||||
#define SUPPRESS_SYSLOG 8 /* don't show when logging to syslog */
|
||||
struct escape_help_text {
|
||||
const char *cmd;
|
||||
const char *text;
|
||||
unsigned int flags;
|
||||
};
|
||||
static struct escape_help_text esc_txt[] = {
|
||||
{".", "terminate session", SUPPRESS_MUXMASTER},
|
||||
{".", "terminate connection (and any multiplexed sessions)",
|
||||
SUPPRESS_MUXCLIENT},
|
||||
{"B", "send a BREAK to the remote system", SUPPRESS_PROTO1},
|
||||
{"C", "open a command line", SUPPRESS_MUXCLIENT},
|
||||
{"R", "request rekey", SUPPRESS_PROTO1},
|
||||
{"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT},
|
||||
{"^Z", "suspend ssh", SUPPRESS_MUXCLIENT},
|
||||
{"#", "list forwarded connections", SUPPRESS_NEVER},
|
||||
{"&", "background ssh (when waiting for connections to terminate)",
|
||||
SUPPRESS_MUXCLIENT},
|
||||
{"?", "this message", SUPPRESS_NEVER},
|
||||
};
|
||||
|
||||
static void
|
||||
print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,
|
||||
int using_stderr)
|
||||
{
|
||||
unsigned int i, suppress_flags;
|
||||
char string[1024];
|
||||
|
||||
snprintf(string, sizeof string, "%c?\r\n"
|
||||
"Supported escape sequences:\r\n", escape_char);
|
||||
buffer_append(b, string, strlen(string));
|
||||
|
||||
suppress_flags = (protocol2 ? 0 : SUPPRESS_PROTO1) |
|
||||
(mux_client ? SUPPRESS_MUXCLIENT : 0) |
|
||||
(mux_client ? 0 : SUPPRESS_MUXMASTER) |
|
||||
(using_stderr ? 0 : SUPPRESS_SYSLOG);
|
||||
|
||||
for (i = 0; i < sizeof(esc_txt)/sizeof(esc_txt[0]); i++) {
|
||||
if (esc_txt[i].flags & suppress_flags)
|
||||
continue;
|
||||
snprintf(string, sizeof string, " %c%-3s - %s\r\n",
|
||||
escape_char, esc_txt[i].cmd, esc_txt[i].text);
|
||||
buffer_append(b, string, strlen(string));
|
||||
}
|
||||
|
||||
snprintf(string, sizeof string,
|
||||
" %c%c - send the escape character by typing it twice\r\n"
|
||||
"(Note that escapes are only recognized immediately after "
|
||||
"newline.)\r\n", escape_char, escape_char);
|
||||
buffer_append(b, string, strlen(string));
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the characters one by one, call with c==NULL for proto1 case.
|
||||
*/
|
||||
|
@ -1037,6 +1094,8 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
|||
if (c && c->ctl_chan != -1) {
|
||||
chan_read_failed(c);
|
||||
chan_write_failed(c);
|
||||
mux_master_session_cleanup_cb(c->self,
|
||||
NULL);
|
||||
return 0;
|
||||
} else
|
||||
quit_pending = 1;
|
||||
|
@ -1045,11 +1104,16 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
|||
case 'Z' - 64:
|
||||
/* XXX support this for mux clients */
|
||||
if (c && c->ctl_chan != -1) {
|
||||
char b[16];
|
||||
noescape:
|
||||
if (ch == 'Z' - 64)
|
||||
snprintf(b, sizeof b, "^Z");
|
||||
else
|
||||
snprintf(b, sizeof b, "%c", ch);
|
||||
snprintf(string, sizeof string,
|
||||
"%c%c escape not available to "
|
||||
"%c%s escape not available to "
|
||||
"multiplexed sessions\r\n",
|
||||
escape_char, ch);
|
||||
escape_char, b);
|
||||
buffer_append(berr, string,
|
||||
strlen(string));
|
||||
continue;
|
||||
|
@ -1088,6 +1152,31 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
|||
}
|
||||
continue;
|
||||
|
||||
case 'V':
|
||||
/* FALLTHROUGH */
|
||||
case 'v':
|
||||
if (c && c->ctl_chan != -1)
|
||||
goto noescape;
|
||||
if (!log_is_on_stderr()) {
|
||||
snprintf(string, sizeof string,
|
||||
"%c%c [Logging to syslog]\r\n",
|
||||
escape_char, ch);
|
||||
buffer_append(berr, string,
|
||||
strlen(string));
|
||||
continue;
|
||||
}
|
||||
if (ch == 'V' && options.log_level >
|
||||
SYSLOG_LEVEL_QUIET)
|
||||
log_change_level(--options.log_level);
|
||||
if (ch == 'v' && options.log_level <
|
||||
SYSLOG_LEVEL_DEBUG3)
|
||||
log_change_level(++options.log_level);
|
||||
snprintf(string, sizeof string,
|
||||
"%c%c [LogLevel %s]\r\n", escape_char, ch,
|
||||
log_level_name(options.log_level));
|
||||
buffer_append(berr, string, strlen(string));
|
||||
continue;
|
||||
|
||||
case '&':
|
||||
if (c && c->ctl_chan != -1)
|
||||
goto noescape;
|
||||
|
@ -1141,43 +1230,9 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
|||
continue;
|
||||
|
||||
case '?':
|
||||
if (c && c->ctl_chan != -1) {
|
||||
snprintf(string, sizeof string,
|
||||
"%c?\r\n\
|
||||
Supported escape sequences:\r\n\
|
||||
%c. - terminate session\r\n\
|
||||
%cB - send a BREAK to the remote system\r\n\
|
||||
%cR - Request rekey (SSH protocol 2 only)\r\n\
|
||||
%c# - list forwarded connections\r\n\
|
||||
%c? - this message\r\n\
|
||||
%c%c - send the escape character by typing it twice\r\n\
|
||||
(Note that escapes are only recognized immediately after newline.)\r\n",
|
||||
escape_char, escape_char,
|
||||
escape_char, escape_char,
|
||||
escape_char, escape_char,
|
||||
escape_char, escape_char);
|
||||
} else {
|
||||
snprintf(string, sizeof string,
|
||||
"%c?\r\n\
|
||||
Supported escape sequences:\r\n\
|
||||
%c. - terminate connection (and any multiplexed sessions)\r\n\
|
||||
%cB - send a BREAK to the remote system\r\n\
|
||||
%cC - open a command line\r\n\
|
||||
%cR - Request rekey (SSH protocol 2 only)\r\n\
|
||||
%c^Z - suspend ssh\r\n\
|
||||
%c# - list forwarded connections\r\n\
|
||||
%c& - background ssh (when waiting for connections to terminate)\r\n\
|
||||
%c? - this message\r\n\
|
||||
%c%c - send the escape character by typing it twice\r\n\
|
||||
(Note that escapes are only recognized immediately after newline.)\r\n",
|
||||
escape_char, escape_char,
|
||||
escape_char, escape_char,
|
||||
escape_char, escape_char,
|
||||
escape_char, escape_char,
|
||||
escape_char, escape_char,
|
||||
escape_char);
|
||||
}
|
||||
buffer_append(berr, string, strlen(string));
|
||||
print_escape_help(berr, escape_char, compat20,
|
||||
(c && c->ctl_chan != -1),
|
||||
log_is_on_stderr());
|
||||
continue;
|
||||
|
||||
case '#':
|
||||
|
@ -2171,10 +2226,10 @@ client_stop_mux(void)
|
|||
if (options.control_path != NULL && muxserver_sock != -1)
|
||||
unlink(options.control_path);
|
||||
/*
|
||||
* If we are in persist mode, signal that we should close when all
|
||||
* active channels are closed.
|
||||
* If we are in persist mode, or don't have a shell, signal that we
|
||||
* should close when all active channels are closed.
|
||||
*/
|
||||
if (options.control_persist) {
|
||||
if (options.control_persist || no_shell_flag) {
|
||||
session_closed = 1;
|
||||
setproctitle("[stopped mux]");
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: clientloop.h,v 1.29 2011/09/09 22:46:44 djm Exp $ */
|
||||
/* $OpenBSD: clientloop.h,v 1.30 2012/08/17 00:45:45 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -76,4 +76,5 @@ void muxserver_listen(void);
|
|||
void muxclient(const char *);
|
||||
void mux_exit_message(Channel *, int);
|
||||
void mux_tty_alloc_failed(Channel *);
|
||||
void mux_master_session_cleanup_cb(int, void *);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: compat.c,v 1.79 2011/09/23 07:45:05 markus Exp $ */
|
||||
/* $OpenBSD: compat.c,v 1.80 2012/08/17 01:30:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -43,6 +43,8 @@ int datafellows = 0;
|
|||
void
|
||||
enable_compat20(void)
|
||||
{
|
||||
if (compat20)
|
||||
return;
|
||||
debug("Enabling compatibility mode for protocol 2.0");
|
||||
compat20 = 1;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kex.c,v 1.86 2010/09/22 05:01:29 djm Exp $ */
|
||||
/* $OpenBSD: kex.c,v 1.88 2013/01/08 18:49:04 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -231,8 +231,18 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
|
|||
packet_get_char();
|
||||
for (i = 0; i < PROPOSAL_MAX; i++)
|
||||
xfree(packet_get_string(NULL));
|
||||
(void) packet_get_char();
|
||||
(void) packet_get_int();
|
||||
/*
|
||||
* XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
|
||||
* KEX method has the server move first, but a server might be using
|
||||
* a custom method or one that we otherwise don't support. We should
|
||||
* be prepared to remember first_kex_follows here so we can eat a
|
||||
* packet later.
|
||||
* XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
|
||||
* for cases where the server *doesn't* go first. I guess we should
|
||||
* ignore it when it is set for these cases, which is what we do now.
|
||||
*/
|
||||
(void) packet_get_char(); /* first_kex_follows */
|
||||
(void) packet_get_int(); /* reserved */
|
||||
packet_check_eom();
|
||||
|
||||
kex_kexinit_finish(kex);
|
||||
|
@ -283,6 +293,7 @@ choose_enc(Enc *enc, char *client, char *server)
|
|||
enc->name = name;
|
||||
enc->enabled = 0;
|
||||
enc->iv = NULL;
|
||||
enc->iv_len = cipher_ivlen(enc->cipher);
|
||||
enc->key = NULL;
|
||||
enc->key_len = cipher_keylen(enc->cipher);
|
||||
enc->block_size = cipher_blocksize(enc->cipher);
|
||||
|
@ -392,7 +403,7 @@ kex_choose_conf(Kex *kex)
|
|||
char **my, **peer;
|
||||
char **cprop, **sprop;
|
||||
int nenc, nmac, ncomp;
|
||||
u_int mode, ctos, need;
|
||||
u_int mode, ctos, need, authlen;
|
||||
int first_kex_follows, type;
|
||||
|
||||
my = kex_buf2prop(&kex->my, NULL);
|
||||
|
@ -425,13 +436,16 @@ kex_choose_conf(Kex *kex)
|
|||
nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC;
|
||||
nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC;
|
||||
ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
|
||||
choose_enc (&newkeys->enc, cprop[nenc], sprop[nenc]);
|
||||
choose_mac (&newkeys->mac, cprop[nmac], sprop[nmac]);
|
||||
choose_enc(&newkeys->enc, cprop[nenc], sprop[nenc]);
|
||||
/* ignore mac for authenticated encryption */
|
||||
authlen = cipher_authlen(newkeys->enc.cipher);
|
||||
if (authlen == 0)
|
||||
choose_mac(&newkeys->mac, cprop[nmac], sprop[nmac]);
|
||||
choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
|
||||
debug("kex: %s %s %s %s",
|
||||
ctos ? "client->server" : "server->client",
|
||||
newkeys->enc.name,
|
||||
newkeys->mac.name,
|
||||
authlen == 0 ? newkeys->mac.name : "<implicit>",
|
||||
newkeys->comp.name);
|
||||
}
|
||||
choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
|
||||
|
@ -444,6 +458,8 @@ kex_choose_conf(Kex *kex)
|
|||
need = newkeys->enc.key_len;
|
||||
if (need < newkeys->enc.block_size)
|
||||
need = newkeys->enc.block_size;
|
||||
if (need < newkeys->enc.iv_len)
|
||||
need = newkeys->enc.iv_len;
|
||||
if (need < newkeys->mac.key_len)
|
||||
need = newkeys->mac.key_len;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: kex.h,v 1.52 2010/09/22 05:01:29 djm Exp $ */
|
||||
/* $OpenBSD: kex.h,v 1.54 2013/01/08 18:49:04 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -86,6 +86,7 @@ struct Enc {
|
|||
Cipher *cipher;
|
||||
int enabled;
|
||||
u_int key_len;
|
||||
u_int iv_len;
|
||||
u_int block_size;
|
||||
u_char *key;
|
||||
u_char *iv;
|
||||
|
@ -97,6 +98,7 @@ struct Mac {
|
|||
u_char *key;
|
||||
u_int key_len;
|
||||
int type;
|
||||
int etm; /* Encrypt-then-MAC */
|
||||
const EVP_MD *evp_md;
|
||||
HMAC_CTX evp_ctx;
|
||||
struct umac_ctx *umac_ctx;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: key.c,v 1.99 2012/05/23 03:28:28 djm Exp $ */
|
||||
/* $OpenBSD: key.c,v 1.100 2013/01/17 23:00:01 djm Exp $ */
|
||||
/*
|
||||
* read_bignum():
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -51,6 +51,8 @@
|
|||
#include "misc.h"
|
||||
#include "ssh2.h"
|
||||
|
||||
static int to_blob(const Key *, u_char **, u_int *, int);
|
||||
|
||||
static struct KeyCert *
|
||||
cert_new(void)
|
||||
{
|
||||
|
@ -312,14 +314,15 @@ key_equal(const Key *a, const Key *b)
|
|||
}
|
||||
|
||||
u_char*
|
||||
key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
|
||||
key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
|
||||
u_int *dgst_raw_length)
|
||||
{
|
||||
const EVP_MD *md = NULL;
|
||||
EVP_MD_CTX ctx;
|
||||
u_char *blob = NULL;
|
||||
u_char *retval = NULL;
|
||||
u_int len = 0;
|
||||
int nlen, elen, otype;
|
||||
int nlen, elen;
|
||||
|
||||
*dgst_raw_length = 0;
|
||||
|
||||
|
@ -357,10 +360,7 @@ key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
|
|||
case KEY_ECDSA_CERT:
|
||||
case KEY_RSA_CERT:
|
||||
/* We want a fingerprint of the _key_ not of the cert */
|
||||
otype = k->type;
|
||||
k->type = key_type_plain(k->type);
|
||||
key_to_blob(k, &blob, &len);
|
||||
k->type = otype;
|
||||
to_blob(k, &blob, &len, 1);
|
||||
break;
|
||||
case KEY_UNSPEC:
|
||||
return retval;
|
||||
|
@ -1530,18 +1530,19 @@ key_from_blob(const u_char *blob, u_int blen)
|
|||
return key;
|
||||
}
|
||||
|
||||
int
|
||||
key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
|
||||
static int
|
||||
to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain)
|
||||
{
|
||||
Buffer b;
|
||||
int len;
|
||||
int len, type;
|
||||
|
||||
if (key == NULL) {
|
||||
error("key_to_blob: key == NULL");
|
||||
return 0;
|
||||
}
|
||||
buffer_init(&b);
|
||||
switch (key->type) {
|
||||
type = force_plain ? key_type_plain(key->type) : key->type;
|
||||
switch (type) {
|
||||
case KEY_DSA_CERT_V00:
|
||||
case KEY_RSA_CERT_V00:
|
||||
case KEY_DSA_CERT:
|
||||
|
@ -1552,20 +1553,23 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
|
|||
buffer_len(&key->cert->certblob));
|
||||
break;
|
||||
case KEY_DSA:
|
||||
buffer_put_cstring(&b, key_ssh_name(key));
|
||||
buffer_put_cstring(&b,
|
||||
key_ssh_name_from_type_nid(type, key->ecdsa_nid));
|
||||
buffer_put_bignum2(&b, key->dsa->p);
|
||||
buffer_put_bignum2(&b, key->dsa->q);
|
||||
buffer_put_bignum2(&b, key->dsa->g);
|
||||
buffer_put_bignum2(&b, key->dsa->pub_key);
|
||||
break;
|
||||
case KEY_ECDSA:
|
||||
buffer_put_cstring(&b, key_ssh_name(key));
|
||||
buffer_put_cstring(&b,
|
||||
key_ssh_name_from_type_nid(type, key->ecdsa_nid));
|
||||
buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid));
|
||||
buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa),
|
||||
EC_KEY_get0_public_key(key->ecdsa));
|
||||
break;
|
||||
case KEY_RSA:
|
||||
buffer_put_cstring(&b, key_ssh_name(key));
|
||||
buffer_put_cstring(&b,
|
||||
key_ssh_name_from_type_nid(type, key->ecdsa_nid));
|
||||
buffer_put_bignum2(&b, key->rsa->e);
|
||||
buffer_put_bignum2(&b, key->rsa->n);
|
||||
break;
|
||||
|
@ -1586,6 +1590,12 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
|
|||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
|
||||
{
|
||||
return to_blob(key, blobp, lenp, 0);
|
||||
}
|
||||
|
||||
int
|
||||
key_sign(
|
||||
const Key *key,
|
||||
|
@ -1957,7 +1967,7 @@ key_cert_check_authority(const Key *k, int want_host, int require_principal,
|
|||
}
|
||||
|
||||
int
|
||||
key_cert_is_legacy(Key *k)
|
||||
key_cert_is_legacy(const Key *k)
|
||||
{
|
||||
switch (k->type) {
|
||||
case KEY_DSA_CERT_V00:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: key.h,v 1.34 2012/05/23 03:28:28 djm Exp $ */
|
||||
/* $OpenBSD: key.h,v 1.35 2013/01/17 23:00:01 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -90,7 +90,7 @@ Key *key_demote(const Key *);
|
|||
int key_equal_public(const Key *, const Key *);
|
||||
int key_equal(const Key *, const Key *);
|
||||
char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
|
||||
u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *);
|
||||
u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *);
|
||||
const char *key_type(const Key *);
|
||||
const char *key_cert_type(const Key *);
|
||||
int key_write(const Key *, FILE *);
|
||||
|
@ -108,7 +108,7 @@ int key_certify(Key *, Key *);
|
|||
void key_cert_copy(const Key *, struct Key *);
|
||||
int key_cert_check_authority(const Key *, int, int, const char *,
|
||||
const char **);
|
||||
int key_cert_is_legacy(Key *);
|
||||
int key_cert_is_legacy(const Key *);
|
||||
|
||||
int key_ecdsa_nid_from_name(const char *);
|
||||
int key_curve_name_to_nid(const char *);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
/* $OpenBSD: krl.h,v 1.2 2013/01/18 00:24:58 djm Exp $ */
|
||||
|
||||
#ifndef _KRL_H
|
||||
#define _KRL_H
|
||||
|
||||
/* Functions to manage key revocation lists */
|
||||
|
||||
#define KRL_MAGIC "SSHKRL\n\0"
|
||||
#define KRL_FORMAT_VERSION 1
|
||||
|
||||
/* KRL section types */
|
||||
#define KRL_SECTION_CERTIFICATES 1
|
||||
#define KRL_SECTION_EXPLICIT_KEY 2
|
||||
#define KRL_SECTION_FINGERPRINT_SHA1 3
|
||||
#define KRL_SECTION_SIGNATURE 4
|
||||
|
||||
/* KRL_SECTION_CERTIFICATES subsection types */
|
||||
#define KRL_SECTION_CERT_SERIAL_LIST 0x20
|
||||
#define KRL_SECTION_CERT_SERIAL_RANGE 0x21
|
||||
#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22
|
||||
#define KRL_SECTION_CERT_KEY_ID 0x23
|
||||
|
||||
struct ssh_krl;
|
||||
|
||||
struct ssh_krl *ssh_krl_init(void);
|
||||
void ssh_krl_free(struct ssh_krl *krl);
|
||||
void ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version);
|
||||
void ssh_krl_set_sign_key(struct ssh_krl *krl, const Key *sign_key);
|
||||
void ssh_krl_set_comment(struct ssh_krl *krl, const char *comment);
|
||||
int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const Key *ca_key,
|
||||
u_int64_t serial);
|
||||
int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, const Key *ca_key,
|
||||
u_int64_t lo, u_int64_t hi);
|
||||
int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const Key *ca_key,
|
||||
const char *key_id);
|
||||
int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const Key *key);
|
||||
int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const Key *key);
|
||||
int ssh_krl_revoke_key(struct ssh_krl *krl, const Key *key);
|
||||
int ssh_krl_to_blob(struct ssh_krl *krl, Buffer *buf, const Key **sign_keys,
|
||||
u_int nsign_keys);
|
||||
int ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp,
|
||||
const Key **sign_ca_keys, u_int nsign_ca_keys);
|
||||
int ssh_krl_check_key(struct ssh_krl *krl, const Key *key);
|
||||
int ssh_krl_file_contains_key(const char *path, const Key *key);
|
||||
|
||||
#endif /* _KRL_H */
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: log.c,v 1.42 2011/06/17 21:44:30 djm Exp $ */
|
||||
/* $OpenBSD: log.c,v 1.43 2012/09/06 04:37:39 dtucker Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -295,6 +295,21 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
log_change_level(LogLevel new_log_level)
|
||||
{
|
||||
/* no-op if log_init has not been called */
|
||||
if (argv0 == NULL)
|
||||
return;
|
||||
log_init(argv0, new_log_level, log_facility, log_on_stderr);
|
||||
}
|
||||
|
||||
int
|
||||
log_is_on_stderr(void)
|
||||
{
|
||||
return log_on_stderr;
|
||||
}
|
||||
|
||||
#define MSGBUFSIZ 1024
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: log.h,v 1.18 2011/06/17 21:44:30 djm Exp $ */
|
||||
/* $OpenBSD: log.h,v 1.19 2012/09/06 04:37:39 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -46,6 +46,8 @@ typedef enum {
|
|||
typedef void (log_handler_fn)(LogLevel, const char *, void *);
|
||||
|
||||
void log_init(char *, LogLevel, SyslogFacility, int);
|
||||
void log_change_level(LogLevel);
|
||||
int log_is_on_stderr(void);
|
||||
|
||||
SyslogFacility log_facility_number(char *);
|
||||
const char * log_facility_name(SyslogFacility);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: mac.c,v 1.18 2012/06/28 05:07:45 dtucker Exp $ */
|
||||
/* $OpenBSD: mac.c,v 1.21 2012/12/11 22:51:45 sthen Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -43,6 +43,7 @@
|
|||
|
||||
#define SSH_EVP 1 /* OpenSSL EVP-based MAC */
|
||||
#define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */
|
||||
#define SSH_UMAC128 3
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
|
@ -51,17 +52,32 @@ struct {
|
|||
int truncatebits; /* truncate digest if != 0 */
|
||||
int key_len; /* just for UMAC */
|
||||
int len; /* just for UMAC */
|
||||
int etm; /* Encrypt-then-MAC */
|
||||
} macs[] = {
|
||||
{ "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 },
|
||||
{ "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, -1, -1 },
|
||||
{ "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, -1, -1 },
|
||||
{ "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, -1, -1 },
|
||||
{ "hmac-md5", SSH_EVP, EVP_md5, 0, -1, -1 },
|
||||
{ "hmac-md5-96", SSH_EVP, EVP_md5, 96, -1, -1 },
|
||||
{ "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, -1, -1 },
|
||||
{ "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, -1, -1 },
|
||||
{ "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64 },
|
||||
{ NULL, 0, NULL, 0, -1, -1 }
|
||||
/* Encrypt-and-MAC (encrypt-and-authenticate) variants */
|
||||
{ "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 },
|
||||
{ "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 },
|
||||
{ "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, 0, 0, 0 },
|
||||
{ "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, 0, 0, 0 },
|
||||
{ "hmac-md5", SSH_EVP, EVP_md5, 0, 0, 0, 0 },
|
||||
{ "hmac-md5-96", SSH_EVP, EVP_md5, 96, 0, 0, 0 },
|
||||
{ "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 },
|
||||
{ "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 },
|
||||
{ "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 0 },
|
||||
{ "umac-128@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 0 },
|
||||
|
||||
/* Encrypt-then-MAC variants */
|
||||
{ "hmac-sha1-etm@openssh.com", SSH_EVP, EVP_sha1, 0, 0, 0, 1 },
|
||||
{ "hmac-sha1-96-etm@openssh.com", SSH_EVP, EVP_sha1, 96, 0, 0, 1 },
|
||||
{ "hmac-sha2-256-etm@openssh.com", SSH_EVP, EVP_sha256, 0, 0, 0, 1 },
|
||||
{ "hmac-sha2-512-etm@openssh.com", SSH_EVP, EVP_sha512, 0, 0, 0, 1 },
|
||||
{ "hmac-md5-etm@openssh.com", SSH_EVP, EVP_md5, 0, 0, 0, 1 },
|
||||
{ "hmac-md5-96-etm@openssh.com", SSH_EVP, EVP_md5, 96, 0, 0, 1 },
|
||||
{ "hmac-ripemd160-etm@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 1 },
|
||||
{ "umac-64-etm@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 1 },
|
||||
{ "umac-128-etm@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 1 },
|
||||
|
||||
{ NULL, 0, NULL, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -81,6 +97,7 @@ mac_setup_by_id(Mac *mac, int which)
|
|||
}
|
||||
if (macs[which].truncatebits != 0)
|
||||
mac->mac_len = macs[which].truncatebits / 8;
|
||||
mac->etm = macs[which].etm;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -115,6 +132,9 @@ mac_init(Mac *mac)
|
|||
case SSH_UMAC:
|
||||
mac->umac_ctx = umac_new(mac->key);
|
||||
return 0;
|
||||
case SSH_UMAC128:
|
||||
mac->umac_ctx = umac128_new(mac->key);
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -144,6 +164,11 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
|
|||
umac_update(mac->umac_ctx, data, datalen);
|
||||
umac_final(mac->umac_ctx, m, nonce);
|
||||
break;
|
||||
case SSH_UMAC128:
|
||||
put_u64(nonce, seqno);
|
||||
umac128_update(mac->umac_ctx, data, datalen);
|
||||
umac128_final(mac->umac_ctx, m, nonce);
|
||||
break;
|
||||
default:
|
||||
fatal("mac_compute: unknown MAC type");
|
||||
}
|
||||
|
@ -156,6 +181,9 @@ mac_clear(Mac *mac)
|
|||
if (mac->type == SSH_UMAC) {
|
||||
if (mac->umac_ctx != NULL)
|
||||
umac_delete(mac->umac_ctx);
|
||||
} else if (mac->type == SSH_UMAC128) {
|
||||
if (mac->umac_ctx != NULL)
|
||||
umac128_delete(mac->umac_ctx);
|
||||
} else if (mac->evp_md != NULL)
|
||||
HMAC_cleanup(&mac->evp_ctx);
|
||||
mac->evp_md = NULL;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: monitor.c,v 1.117 2012/06/22 12:30:26 dtucker Exp $ */
|
||||
/* $OpenBSD: monitor.c,v 1.120 2012/12/11 22:16:21 markus Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
|
@ -163,6 +163,7 @@ static int key_blobtype = MM_NOKEY;
|
|||
static char *hostbased_cuser = NULL;
|
||||
static char *hostbased_chost = NULL;
|
||||
static char *auth_method = "unknown";
|
||||
static char *auth_submethod = NULL;
|
||||
static u_int session_id2_len = 0;
|
||||
static u_char *session_id2 = NULL;
|
||||
static pid_t monitor_child_pid;
|
||||
|
@ -274,7 +275,7 @@ void
|
|||
monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
|
||||
{
|
||||
struct mon_table *ent;
|
||||
int authenticated = 0;
|
||||
int authenticated = 0, partial = 0;
|
||||
|
||||
debug3("preauth child monitor started");
|
||||
|
||||
|
@ -299,8 +300,26 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
|
|||
|
||||
/* The first few requests do not require asynchronous access */
|
||||
while (!authenticated) {
|
||||
partial = 0;
|
||||
auth_method = "unknown";
|
||||
auth_submethod = NULL;
|
||||
authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
|
||||
|
||||
/* Special handling for multiple required authentications */
|
||||
if (options.num_auth_methods != 0) {
|
||||
if (!compat20)
|
||||
fatal("AuthenticationMethods is not supported"
|
||||
"with SSH protocol 1");
|
||||
if (authenticated &&
|
||||
!auth2_update_methods_lists(authctxt,
|
||||
auth_method)) {
|
||||
debug3("%s: method %s: partial", __func__,
|
||||
auth_method);
|
||||
authenticated = 0;
|
||||
partial = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (authenticated) {
|
||||
if (!(ent->flags & MON_AUTHDECIDE))
|
||||
fatal("%s: unexpected authentication from %d",
|
||||
|
@ -309,9 +328,9 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
|
|||
!auth_root_allowed(auth_method))
|
||||
authenticated = 0;
|
||||
}
|
||||
|
||||
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
|
||||
auth_log(authctxt, authenticated, auth_method,
|
||||
auth_log(authctxt, authenticated, partial,
|
||||
auth_method, auth_submethod,
|
||||
compat20 ? " ssh2" : "");
|
||||
if (!authenticated)
|
||||
authctxt->failures++;
|
||||
|
@ -327,10 +346,6 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Drain any buffered messages from the child */
|
||||
while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
|
||||
;
|
||||
|
||||
if (!authctxt->valid)
|
||||
fatal("%s: authenticated invalid user", __func__);
|
||||
if (strcmp(auth_method, "unknown") == 0)
|
||||
|
@ -341,6 +356,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
|
|||
|
||||
mm_get_keystate(pmonitor);
|
||||
|
||||
/* Drain any buffered messages from the child */
|
||||
while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
|
||||
;
|
||||
|
||||
close(pmonitor->m_sendfd);
|
||||
close(pmonitor->m_log_recvfd);
|
||||
pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1;
|
||||
|
@ -687,7 +706,17 @@ mm_answer_pwnamallow(int sock, Buffer *m)
|
|||
COPY_MATCH_STRING_OPTS();
|
||||
#undef M_CP_STROPT
|
||||
#undef M_CP_STRARRAYOPT
|
||||
|
||||
|
||||
/* Create valid auth method lists */
|
||||
if (compat20 && auth2_setup_methods_lists(authctxt) != 0) {
|
||||
/*
|
||||
* The monitor will continue long enough to let the child
|
||||
* run to it's packet_disconnect(), but it must not allow any
|
||||
* authentication to succeed.
|
||||
*/
|
||||
debug("%s: no valid authentication method lists", __func__);
|
||||
}
|
||||
|
||||
debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
|
||||
mm_request_send(sock, MONITOR_ANS_PWNAM, m);
|
||||
|
||||
|
@ -819,7 +848,10 @@ mm_answer_bsdauthrespond(int sock, Buffer *m)
|
|||
debug3("%s: sending authenticated: %d", __func__, authok);
|
||||
mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m);
|
||||
|
||||
auth_method = "bsdauth";
|
||||
if (compat20)
|
||||
auth_method = "keyboard-interactive"; /* XXX auth_submethod */
|
||||
else
|
||||
auth_method = "bsdauth";
|
||||
|
||||
return (authok != 0);
|
||||
}
|
||||
|
@ -893,7 +925,8 @@ mm_answer_keyallowed(int sock, Buffer *m)
|
|||
hostbased_chost = chost;
|
||||
} else {
|
||||
/* Log failed attempt */
|
||||
auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : "");
|
||||
auth_log(authctxt, 0, 0, auth_method, NULL,
|
||||
compat20 ? " ssh2" : "");
|
||||
xfree(blob);
|
||||
xfree(cuser);
|
||||
xfree(chost);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: monitor.h,v 1.16 2011/06/17 21:44:31 djm Exp $ */
|
||||
/* $OpenBSD: monitor.h,v 1.17 2012/12/02 20:34:10 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
|
@ -28,37 +28,39 @@
|
|||
#ifndef _MONITOR_H_
|
||||
#define _MONITOR_H_
|
||||
|
||||
/* Please keep *_REQ_* values on even numbers and *_ANS_* on odd numbers */
|
||||
enum monitor_reqtype {
|
||||
MONITOR_REQ_MODULI, MONITOR_ANS_MODULI,
|
||||
MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,
|
||||
MONITOR_REQ_SIGN, MONITOR_ANS_SIGN,
|
||||
MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM,
|
||||
MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER,
|
||||
MONITOR_REQ_AUTHPASSWORD, MONITOR_ANS_AUTHPASSWORD,
|
||||
MONITOR_REQ_BSDAUTHQUERY, MONITOR_ANS_BSDAUTHQUERY,
|
||||
MONITOR_REQ_BSDAUTHRESPOND, MONITOR_ANS_BSDAUTHRESPOND,
|
||||
MONITOR_REQ_SKEYQUERY, MONITOR_ANS_SKEYQUERY,
|
||||
MONITOR_REQ_SKEYRESPOND, MONITOR_ANS_SKEYRESPOND,
|
||||
MONITOR_REQ_KEYALLOWED, MONITOR_ANS_KEYALLOWED,
|
||||
MONITOR_REQ_KEYVERIFY, MONITOR_ANS_KEYVERIFY,
|
||||
MONITOR_REQ_KEYEXPORT,
|
||||
MONITOR_REQ_PTY, MONITOR_ANS_PTY,
|
||||
MONITOR_REQ_PTYCLEANUP,
|
||||
MONITOR_REQ_SESSKEY, MONITOR_ANS_SESSKEY,
|
||||
MONITOR_REQ_SESSID,
|
||||
MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED,
|
||||
MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE,
|
||||
MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE,
|
||||
MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
|
||||
MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
|
||||
MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
|
||||
MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
|
||||
MONITOR_REQ_TERM,
|
||||
MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1,
|
||||
MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
|
||||
MONITOR_REQ_JPAKE_STEP2, MONITOR_ANS_JPAKE_STEP2,
|
||||
MONITOR_REQ_JPAKE_KEY_CONFIRM, MONITOR_ANS_JPAKE_KEY_CONFIRM,
|
||||
MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM,
|
||||
MONITOR_REQ_MODULI = 0, MONITOR_ANS_MODULI = 1,
|
||||
MONITOR_REQ_FREE = 2,
|
||||
MONITOR_REQ_AUTHSERV = 4,
|
||||
MONITOR_REQ_SIGN = 6, MONITOR_ANS_SIGN = 7,
|
||||
MONITOR_REQ_PWNAM = 8, MONITOR_ANS_PWNAM = 9,
|
||||
MONITOR_REQ_AUTH2_READ_BANNER = 10, MONITOR_ANS_AUTH2_READ_BANNER = 11,
|
||||
MONITOR_REQ_AUTHPASSWORD = 12, MONITOR_ANS_AUTHPASSWORD = 13,
|
||||
MONITOR_REQ_BSDAUTHQUERY = 14, MONITOR_ANS_BSDAUTHQUERY = 15,
|
||||
MONITOR_REQ_BSDAUTHRESPOND = 16, MONITOR_ANS_BSDAUTHRESPOND = 17,
|
||||
MONITOR_REQ_SKEYQUERY = 18, MONITOR_ANS_SKEYQUERY = 19,
|
||||
MONITOR_REQ_SKEYRESPOND = 20, MONITOR_ANS_SKEYRESPOND = 21,
|
||||
MONITOR_REQ_KEYALLOWED = 22, MONITOR_ANS_KEYALLOWED = 23,
|
||||
MONITOR_REQ_KEYVERIFY = 24, MONITOR_ANS_KEYVERIFY = 25,
|
||||
MONITOR_REQ_KEYEXPORT = 26,
|
||||
MONITOR_REQ_PTY = 28, MONITOR_ANS_PTY = 29,
|
||||
MONITOR_REQ_PTYCLEANUP = 30,
|
||||
MONITOR_REQ_SESSKEY = 32, MONITOR_ANS_SESSKEY = 33,
|
||||
MONITOR_REQ_SESSID = 34,
|
||||
MONITOR_REQ_RSAKEYALLOWED = 36, MONITOR_ANS_RSAKEYALLOWED = 37,
|
||||
MONITOR_REQ_RSACHALLENGE = 38, MONITOR_ANS_RSACHALLENGE = 39,
|
||||
MONITOR_REQ_RSARESPONSE = 40, MONITOR_ANS_RSARESPONSE = 41,
|
||||
MONITOR_REQ_GSSSETUP = 42, MONITOR_ANS_GSSSETUP = 43,
|
||||
MONITOR_REQ_GSSSTEP = 44, MONITOR_ANS_GSSSTEP = 45,
|
||||
MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47,
|
||||
MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49,
|
||||
MONITOR_REQ_TERM = 50,
|
||||
MONITOR_REQ_JPAKE_STEP1 = 52, MONITOR_ANS_JPAKE_STEP1 = 53,
|
||||
MONITOR_REQ_JPAKE_GET_PWDATA = 54, MONITOR_ANS_JPAKE_GET_PWDATA = 55,
|
||||
MONITOR_REQ_JPAKE_STEP2 = 56, MONITOR_ANS_JPAKE_STEP2 = 57,
|
||||
MONITOR_REQ_JPAKE_KEY_CONFIRM = 58, MONITOR_ANS_JPAKE_KEY_CONFIRM = 59,
|
||||
MONITOR_REQ_JPAKE_CHECK_CONFIRM = 60, MONITOR_ANS_JPAKE_CHECK_CONFIRM = 61,
|
||||
};
|
||||
|
||||
struct mm_master;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: monitor_wrap.c,v 1.73 2011/06/17 21:44:31 djm Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.75 2013/01/08 18:49:04 markus Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
|
@ -480,25 +480,24 @@ mm_newkeys_from_blob(u_char *blob, int blen)
|
|||
enc->enabled = buffer_get_int(&b);
|
||||
enc->block_size = buffer_get_int(&b);
|
||||
enc->key = buffer_get_string(&b, &enc->key_len);
|
||||
enc->iv = buffer_get_string(&b, &len);
|
||||
if (len != enc->block_size)
|
||||
fatal("%s: bad ivlen: expected %u != %u", __func__,
|
||||
enc->block_size, len);
|
||||
enc->iv = buffer_get_string(&b, &enc->iv_len);
|
||||
|
||||
if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher)
|
||||
fatal("%s: bad cipher name %s or pointer %p", __func__,
|
||||
enc->name, enc->cipher);
|
||||
|
||||
/* Mac structure */
|
||||
mac->name = buffer_get_string(&b, NULL);
|
||||
if (mac->name == NULL || mac_setup(mac, mac->name) == -1)
|
||||
fatal("%s: can not setup mac %s", __func__, mac->name);
|
||||
mac->enabled = buffer_get_int(&b);
|
||||
mac->key = buffer_get_string(&b, &len);
|
||||
if (len > mac->key_len)
|
||||
fatal("%s: bad mac key length: %u > %d", __func__, len,
|
||||
mac->key_len);
|
||||
mac->key_len = len;
|
||||
if (cipher_authlen(enc->cipher) == 0) {
|
||||
mac->name = buffer_get_string(&b, NULL);
|
||||
if (mac->name == NULL || mac_setup(mac, mac->name) == -1)
|
||||
fatal("%s: can not setup mac %s", __func__, mac->name);
|
||||
mac->enabled = buffer_get_int(&b);
|
||||
mac->key = buffer_get_string(&b, &len);
|
||||
if (len > mac->key_len)
|
||||
fatal("%s: bad mac key length: %u > %d", __func__, len,
|
||||
mac->key_len);
|
||||
mac->key_len = len;
|
||||
}
|
||||
|
||||
/* Comp structure */
|
||||
comp->type = buffer_get_int(&b);
|
||||
|
@ -540,13 +539,15 @@ mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
|
|||
buffer_put_int(&b, enc->enabled);
|
||||
buffer_put_int(&b, enc->block_size);
|
||||
buffer_put_string(&b, enc->key, enc->key_len);
|
||||
packet_get_keyiv(mode, enc->iv, enc->block_size);
|
||||
buffer_put_string(&b, enc->iv, enc->block_size);
|
||||
packet_get_keyiv(mode, enc->iv, enc->iv_len);
|
||||
buffer_put_string(&b, enc->iv, enc->iv_len);
|
||||
|
||||
/* Mac structure */
|
||||
buffer_put_cstring(&b, mac->name);
|
||||
buffer_put_int(&b, mac->enabled);
|
||||
buffer_put_string(&b, mac->key, mac->key_len);
|
||||
if (cipher_authlen(enc->cipher) == 0) {
|
||||
buffer_put_cstring(&b, mac->name);
|
||||
buffer_put_int(&b, mac->enabled);
|
||||
buffer_put_string(&b, mac->key, mac->key_len);
|
||||
}
|
||||
|
||||
/* Comp structure */
|
||||
buffer_put_int(&b, comp->type);
|
||||
|
@ -610,7 +611,7 @@ mm_send_keystate(struct monitor *monitor)
|
|||
ivlen = packet_get_keyiv_len(MODE_OUT);
|
||||
packet_get_keyiv(MODE_OUT, iv, ivlen);
|
||||
buffer_put_string(&m, iv, ivlen);
|
||||
ivlen = packet_get_keyiv_len(MODE_OUT);
|
||||
ivlen = packet_get_keyiv_len(MODE_IN);
|
||||
packet_get_keyiv(MODE_IN, iv, ivlen);
|
||||
buffer_put_string(&m, iv, ivlen);
|
||||
goto skip;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: mux.c,v 1.36 2012/07/06 01:37:21 djm Exp $ */
|
||||
/* $OpenBSD: mux.c,v 1.38 2013/01/02 00:32:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
|
@ -171,7 +171,7 @@ static const struct {
|
|||
|
||||
/* Cleanup callback fired on closure of mux slave _session_ channel */
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
void
|
||||
mux_master_session_cleanup_cb(int cid, void *unused)
|
||||
{
|
||||
Channel *cc, *c = channel_by_id(cid);
|
||||
|
@ -721,9 +721,9 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
}
|
||||
|
||||
if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
|
||||
if (channel_setup_local_fwd_listener(fwd.listen_host,
|
||||
if (!channel_setup_local_fwd_listener(fwd.listen_host,
|
||||
fwd.listen_port, fwd.connect_host, fwd.connect_port,
|
||||
options.gateway_ports) < 0) {
|
||||
options.gateway_ports)) {
|
||||
fail:
|
||||
logit("slave-requested %s failed", fwd_desc);
|
||||
buffer_put_int(r, MUX_S_FAILURE);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: myproposal.h,v 1.29 2012/06/28 05:07:45 dtucker Exp $ */
|
||||
/* $OpenBSD: myproposal.h,v 1.32 2013/01/08 18:49:04 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
|
@ -50,12 +50,23 @@
|
|||
#define KEX_DEFAULT_ENCRYPT \
|
||||
"aes128-ctr,aes192-ctr,aes256-ctr," \
|
||||
"arcfour256,arcfour128," \
|
||||
"aes128-gcm@openssh.com,aes256-gcm@openssh.com," \
|
||||
"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
|
||||
"aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se"
|
||||
#define KEX_DEFAULT_MAC \
|
||||
"hmac-md5-etm@openssh.com," \
|
||||
"hmac-sha1-etm@openssh.com," \
|
||||
"umac-64-etm@openssh.com," \
|
||||
"umac-128-etm@openssh.com," \
|
||||
"hmac-sha2-256-etm@openssh.com," \
|
||||
"hmac-sha2-512-etm@openssh.com," \
|
||||
"hmac-ripemd160-etm@openssh.com," \
|
||||
"hmac-sha1-96-etm@openssh.com," \
|
||||
"hmac-md5-96-etm@openssh.com," \
|
||||
"hmac-md5," \
|
||||
"hmac-sha1," \
|
||||
"umac-64@openssh.com," \
|
||||
"umac-128@openssh.com," \
|
||||
"hmac-sha2-256," \
|
||||
"hmac-sha2-512," \
|
||||
"hmac-ripemd160," \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: packet.c,v 1.176 2012/01/25 19:40:09 markus Exp $ */
|
||||
/* $OpenBSD: packet.c,v 1.181 2013/02/10 23:35:24 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -271,7 +271,7 @@ packet_stop_discard(void)
|
|||
static void
|
||||
packet_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard)
|
||||
{
|
||||
if (enc == NULL || !cipher_is_cbc(enc->cipher))
|
||||
if (enc == NULL || !cipher_is_cbc(enc->cipher) || (mac && mac->etm))
|
||||
packet_disconnect("Packet corrupt");
|
||||
if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
|
||||
active_state->packet_discard_mac = mac;
|
||||
|
@ -698,7 +698,7 @@ packet_send1(void)
|
|||
buffer_len(&active_state->outgoing_packet));
|
||||
cipher_crypt(&active_state->send_context, cp,
|
||||
buffer_ptr(&active_state->outgoing_packet),
|
||||
buffer_len(&active_state->outgoing_packet));
|
||||
buffer_len(&active_state->outgoing_packet), 0, 0);
|
||||
|
||||
#ifdef PACKET_DEBUG
|
||||
fprintf(stderr, "encrypted: ");
|
||||
|
@ -746,6 +746,9 @@ set_newkeys(int mode)
|
|||
mac = &active_state->newkeys[mode]->mac;
|
||||
comp = &active_state->newkeys[mode]->comp;
|
||||
mac_clear(mac);
|
||||
memset(enc->iv, 0, enc->iv_len);
|
||||
memset(enc->key, 0, enc->key_len);
|
||||
memset(mac->key, 0, mac->key_len);
|
||||
xfree(enc->name);
|
||||
xfree(enc->iv);
|
||||
xfree(enc->key);
|
||||
|
@ -760,11 +763,11 @@ set_newkeys(int mode)
|
|||
enc = &active_state->newkeys[mode]->enc;
|
||||
mac = &active_state->newkeys[mode]->mac;
|
||||
comp = &active_state->newkeys[mode]->comp;
|
||||
if (mac_init(mac) == 0)
|
||||
if (cipher_authlen(enc->cipher) == 0 && mac_init(mac) == 0)
|
||||
mac->enabled = 1;
|
||||
DBG(debug("cipher_init_context: %d", mode));
|
||||
cipher_init(cc, enc->cipher, enc->key, enc->key_len,
|
||||
enc->iv, enc->block_size, crypt_type);
|
||||
enc->iv, enc->iv_len, crypt_type);
|
||||
/* Deleting the keys does not gain extra security */
|
||||
/* memset(enc->iv, 0, enc->block_size);
|
||||
memset(enc->key, 0, enc->key_len);
|
||||
|
@ -831,9 +834,8 @@ static void
|
|||
packet_send2_wrapped(void)
|
||||
{
|
||||
u_char type, *cp, *macbuf = NULL;
|
||||
u_char padlen, pad;
|
||||
u_int packet_length = 0;
|
||||
u_int i, len;
|
||||
u_char padlen, pad = 0;
|
||||
u_int i, len, authlen = 0, aadlen = 0;
|
||||
u_int32_t rnd = 0;
|
||||
Enc *enc = NULL;
|
||||
Mac *mac = NULL;
|
||||
|
@ -844,8 +846,12 @@ packet_send2_wrapped(void)
|
|||
enc = &active_state->newkeys[MODE_OUT]->enc;
|
||||
mac = &active_state->newkeys[MODE_OUT]->mac;
|
||||
comp = &active_state->newkeys[MODE_OUT]->comp;
|
||||
/* disable mac for authenticated encryption */
|
||||
if ((authlen = cipher_authlen(enc->cipher)) != 0)
|
||||
mac = NULL;
|
||||
}
|
||||
block_size = enc ? enc->block_size : 8;
|
||||
aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;
|
||||
|
||||
cp = buffer_ptr(&active_state->outgoing_packet);
|
||||
type = cp[5];
|
||||
|
@ -878,6 +884,7 @@ packet_send2_wrapped(void)
|
|||
* calc size of padding, alloc space, get random data,
|
||||
* minimum padding is 4 bytes
|
||||
*/
|
||||
len -= aadlen; /* packet length is not encrypted for EtM modes */
|
||||
padlen = block_size - (len % block_size);
|
||||
if (padlen < 4)
|
||||
padlen += block_size;
|
||||
|
@ -905,29 +912,37 @@ packet_send2_wrapped(void)
|
|||
/* clear padding */
|
||||
memset(cp, 0, padlen);
|
||||
}
|
||||
/* packet_length includes payload, padding and padding length field */
|
||||
packet_length = buffer_len(&active_state->outgoing_packet) - 4;
|
||||
/* sizeof (packet_len + pad_len + payload + padding) */
|
||||
len = buffer_len(&active_state->outgoing_packet);
|
||||
cp = buffer_ptr(&active_state->outgoing_packet);
|
||||
put_u32(cp, packet_length);
|
||||
/* packet_length includes payload, padding and padding length field */
|
||||
put_u32(cp, len - 4);
|
||||
cp[4] = padlen;
|
||||
DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
|
||||
DBG(debug("send: len %d (includes padlen %d, aadlen %d)",
|
||||
len, padlen, aadlen));
|
||||
|
||||
/* compute MAC over seqnr and packet(length fields, payload, padding) */
|
||||
if (mac && mac->enabled) {
|
||||
if (mac && mac->enabled && !mac->etm) {
|
||||
macbuf = mac_compute(mac, active_state->p_send.seqnr,
|
||||
buffer_ptr(&active_state->outgoing_packet),
|
||||
buffer_len(&active_state->outgoing_packet));
|
||||
buffer_ptr(&active_state->outgoing_packet), len);
|
||||
DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr));
|
||||
}
|
||||
/* encrypt packet and append to output buffer. */
|
||||
cp = buffer_append_space(&active_state->output,
|
||||
buffer_len(&active_state->outgoing_packet));
|
||||
cp = buffer_append_space(&active_state->output, len + authlen);
|
||||
cipher_crypt(&active_state->send_context, cp,
|
||||
buffer_ptr(&active_state->outgoing_packet),
|
||||
buffer_len(&active_state->outgoing_packet));
|
||||
len - aadlen, aadlen, authlen);
|
||||
/* append unencrypted MAC */
|
||||
if (mac && mac->enabled)
|
||||
if (mac && mac->enabled) {
|
||||
if (mac->etm) {
|
||||
/* EtM: compute mac over aadlen + cipher text */
|
||||
macbuf = mac_compute(mac,
|
||||
active_state->p_send.seqnr, cp, len);
|
||||
DBG(debug("done calc MAC(EtM) out #%d",
|
||||
active_state->p_send.seqnr));
|
||||
}
|
||||
buffer_append(&active_state->output, macbuf, mac->mac_len);
|
||||
}
|
||||
#ifdef PACKET_DEBUG
|
||||
fprintf(stderr, "encrypted: ");
|
||||
buffer_dump(&active_state->output);
|
||||
|
@ -938,8 +953,8 @@ packet_send2_wrapped(void)
|
|||
if (++active_state->p_send.packets == 0)
|
||||
if (!(datafellows & SSH_BUG_NOREKEY))
|
||||
fatal("XXX too many packets with same key");
|
||||
active_state->p_send.blocks += (packet_length + 4) / block_size;
|
||||
active_state->p_send.bytes += packet_length + 4;
|
||||
active_state->p_send.blocks += len / block_size;
|
||||
active_state->p_send.bytes += len;
|
||||
buffer_clear(&active_state->outgoing_packet);
|
||||
|
||||
if (type == SSH2_MSG_NEWKEYS)
|
||||
|
@ -1175,7 +1190,7 @@ packet_read_poll1(void)
|
|||
buffer_clear(&active_state->incoming_packet);
|
||||
cp = buffer_append_space(&active_state->incoming_packet, padded_len);
|
||||
cipher_crypt(&active_state->receive_context, cp,
|
||||
buffer_ptr(&active_state->input), padded_len);
|
||||
buffer_ptr(&active_state->input), padded_len, 0, 0);
|
||||
|
||||
buffer_consume(&active_state->input, padded_len);
|
||||
|
||||
|
@ -1223,8 +1238,8 @@ static int
|
|||
packet_read_poll2(u_int32_t *seqnr_p)
|
||||
{
|
||||
u_int padlen, need;
|
||||
u_char *macbuf, *cp, type;
|
||||
u_int maclen, block_size;
|
||||
u_char *macbuf = NULL, *cp, type;
|
||||
u_int maclen, authlen = 0, aadlen = 0, block_size;
|
||||
Enc *enc = NULL;
|
||||
Mac *mac = NULL;
|
||||
Comp *comp = NULL;
|
||||
|
@ -1236,11 +1251,29 @@ packet_read_poll2(u_int32_t *seqnr_p)
|
|||
enc = &active_state->newkeys[MODE_IN]->enc;
|
||||
mac = &active_state->newkeys[MODE_IN]->mac;
|
||||
comp = &active_state->newkeys[MODE_IN]->comp;
|
||||
/* disable mac for authenticated encryption */
|
||||
if ((authlen = cipher_authlen(enc->cipher)) != 0)
|
||||
mac = NULL;
|
||||
}
|
||||
maclen = mac && mac->enabled ? mac->mac_len : 0;
|
||||
block_size = enc ? enc->block_size : 8;
|
||||
aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;
|
||||
|
||||
if (active_state->packlen == 0) {
|
||||
if (aadlen && active_state->packlen == 0) {
|
||||
if (buffer_len(&active_state->input) < 4)
|
||||
return SSH_MSG_NONE;
|
||||
cp = buffer_ptr(&active_state->input);
|
||||
active_state->packlen = get_u32(cp);
|
||||
if (active_state->packlen < 1 + 4 ||
|
||||
active_state->packlen > PACKET_MAX_SIZE) {
|
||||
#ifdef PACKET_DEBUG
|
||||
buffer_dump(&active_state->input);
|
||||
#endif
|
||||
logit("Bad packet length %u.", active_state->packlen);
|
||||
packet_disconnect("Packet corrupt");
|
||||
}
|
||||
buffer_clear(&active_state->incoming_packet);
|
||||
} else if (active_state->packlen == 0) {
|
||||
/*
|
||||
* check if input size is less than the cipher block size,
|
||||
* decrypt first block and extract length of incoming packet
|
||||
|
@ -1251,7 +1284,7 @@ packet_read_poll2(u_int32_t *seqnr_p)
|
|||
cp = buffer_append_space(&active_state->incoming_packet,
|
||||
block_size);
|
||||
cipher_crypt(&active_state->receive_context, cp,
|
||||
buffer_ptr(&active_state->input), block_size);
|
||||
buffer_ptr(&active_state->input), block_size, 0, 0);
|
||||
cp = buffer_ptr(&active_state->incoming_packet);
|
||||
active_state->packlen = get_u32(cp);
|
||||
if (active_state->packlen < 1 + 4 ||
|
||||
|
@ -1264,13 +1297,21 @@ packet_read_poll2(u_int32_t *seqnr_p)
|
|||
PACKET_MAX_SIZE);
|
||||
return SSH_MSG_NONE;
|
||||
}
|
||||
DBG(debug("input: packet len %u", active_state->packlen+4));
|
||||
buffer_consume(&active_state->input, block_size);
|
||||
}
|
||||
/* we have a partial packet of block_size bytes */
|
||||
need = 4 + active_state->packlen - block_size;
|
||||
DBG(debug("partial packet %d, need %d, maclen %d", block_size,
|
||||
need, maclen));
|
||||
DBG(debug("input: packet len %u", active_state->packlen+4));
|
||||
if (aadlen) {
|
||||
/* only the payload is encrypted */
|
||||
need = active_state->packlen;
|
||||
} else {
|
||||
/*
|
||||
* the payload size and the payload are encrypted, but we
|
||||
* have a partial packet of block_size bytes
|
||||
*/
|
||||
need = 4 + active_state->packlen - block_size;
|
||||
}
|
||||
DBG(debug("partial packet: block %d, need %d, maclen %d, authlen %d,"
|
||||
" aadlen %d", block_size, need, maclen, authlen, aadlen));
|
||||
if (need % block_size != 0) {
|
||||
logit("padding error: need %d block %d mod %d",
|
||||
need, block_size, need % block_size);
|
||||
|
@ -1280,26 +1321,35 @@ packet_read_poll2(u_int32_t *seqnr_p)
|
|||
}
|
||||
/*
|
||||
* check if the entire packet has been received and
|
||||
* decrypt into incoming_packet
|
||||
* decrypt into incoming_packet:
|
||||
* 'aadlen' bytes are unencrypted, but authenticated.
|
||||
* 'need' bytes are encrypted, followed by either
|
||||
* 'authlen' bytes of authentication tag or
|
||||
* 'maclen' bytes of message authentication code.
|
||||
*/
|
||||
if (buffer_len(&active_state->input) < need + maclen)
|
||||
if (buffer_len(&active_state->input) < aadlen + need + authlen + maclen)
|
||||
return SSH_MSG_NONE;
|
||||
#ifdef PACKET_DEBUG
|
||||
fprintf(stderr, "read_poll enc/full: ");
|
||||
buffer_dump(&active_state->input);
|
||||
#endif
|
||||
cp = buffer_append_space(&active_state->incoming_packet, need);
|
||||
/* EtM: compute mac over encrypted input */
|
||||
if (mac && mac->enabled && mac->etm)
|
||||
macbuf = mac_compute(mac, active_state->p_read.seqnr,
|
||||
buffer_ptr(&active_state->input), aadlen + need);
|
||||
cp = buffer_append_space(&active_state->incoming_packet, aadlen + need);
|
||||
cipher_crypt(&active_state->receive_context, cp,
|
||||
buffer_ptr(&active_state->input), need);
|
||||
buffer_consume(&active_state->input, need);
|
||||
buffer_ptr(&active_state->input), need, aadlen, authlen);
|
||||
buffer_consume(&active_state->input, aadlen + need + authlen);
|
||||
/*
|
||||
* compute MAC over seqnr and packet,
|
||||
* increment sequence number for incoming packet
|
||||
*/
|
||||
if (mac && mac->enabled) {
|
||||
macbuf = mac_compute(mac, active_state->p_read.seqnr,
|
||||
buffer_ptr(&active_state->incoming_packet),
|
||||
buffer_len(&active_state->incoming_packet));
|
||||
if (!mac->etm)
|
||||
macbuf = mac_compute(mac, active_state->p_read.seqnr,
|
||||
buffer_ptr(&active_state->incoming_packet),
|
||||
buffer_len(&active_state->incoming_packet));
|
||||
if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input),
|
||||
mac->mac_len) != 0) {
|
||||
logit("Corrupted MAC on input.");
|
||||
|
@ -1398,7 +1448,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
|
|||
case SSH2_MSG_DISCONNECT:
|
||||
reason = packet_get_int();
|
||||
msg = packet_get_string(NULL);
|
||||
logit("Received disconnect from %s: %u: %.400s",
|
||||
error("Received disconnect from %s: %u: %.400s",
|
||||
get_remote_ipaddr(), reason, msg);
|
||||
xfree(msg);
|
||||
cleanup_exit(255);
|
||||
|
@ -1423,7 +1473,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
|
|||
break;
|
||||
case SSH_MSG_DISCONNECT:
|
||||
msg = packet_get_string(NULL);
|
||||
logit("Received disconnect from %s: %.400s",
|
||||
error("Received disconnect from %s: %.400s",
|
||||
get_remote_ipaddr(), msg);
|
||||
cleanup_exit(255);
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
/* $OpenBSD: servconf.c,v 1.229 2012/07/13 01:35:21 dtucker Exp $ */
|
||||
/* $OpenBSD: servconf.c,v 1.234 2013/02/06 00:20:42 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
|
@ -46,6 +46,8 @@
|
|||
#include "groupaccess.h"
|
||||
#include "canohost.h"
|
||||
#include "packet.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
|
||||
static void add_listen_addr(ServerOptions *, char *, int);
|
||||
static void add_one_listen_addr(ServerOptions *, char *, int);
|
||||
|
@ -128,6 +130,8 @@ initialize_server_options(ServerOptions *options)
|
|||
options->num_permitted_opens = -1;
|
||||
options->adm_forced_command = NULL;
|
||||
options->chroot_directory = NULL;
|
||||
options->authorized_keys_command = NULL;
|
||||
options->authorized_keys_command_user = NULL;
|
||||
options->zero_knowledge_password_authentication = -1;
|
||||
options->revoked_keys_file = NULL;
|
||||
options->trusted_user_ca_keys = NULL;
|
||||
|
@ -232,17 +236,17 @@ fill_default_server_options(ServerOptions *options)
|
|||
if (options->compression == -1)
|
||||
options->compression = COMP_DELAYED;
|
||||
if (options->allow_tcp_forwarding == -1)
|
||||
options->allow_tcp_forwarding = 1;
|
||||
options->allow_tcp_forwarding = FORWARD_ALLOW;
|
||||
if (options->allow_agent_forwarding == -1)
|
||||
options->allow_agent_forwarding = 1;
|
||||
if (options->gateway_ports == -1)
|
||||
options->gateway_ports = 0;
|
||||
if (options->max_startups == -1)
|
||||
options->max_startups = 10;
|
||||
options->max_startups = 100;
|
||||
if (options->max_startups_rate == -1)
|
||||
options->max_startups_rate = 100; /* 100% */
|
||||
options->max_startups_rate = 30; /* 30% */
|
||||
if (options->max_startups_begin == -1)
|
||||
options->max_startups_begin = options->max_startups;
|
||||
options->max_startups_begin = 10;
|
||||
if (options->max_authtries == -1)
|
||||
options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
|
||||
if (options->max_sessions == -1)
|
||||
|
@ -302,6 +306,8 @@ typedef enum {
|
|||
sZeroKnowledgePasswordAuthentication, sHostCertificate,
|
||||
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
||||
sKexAlgorithms, sIPQoS, sVersionAddendum,
|
||||
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
|
||||
sAuthenticationMethods,
|
||||
sDeprecated, sUnsupported
|
||||
} ServerOpCodes;
|
||||
|
||||
|
@ -414,7 +420,10 @@ static struct {
|
|||
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
|
||||
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
|
||||
{ "ipqos", sIPQoS, SSHCFG_ALL },
|
||||
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
|
||||
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
|
||||
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
|
||||
{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
|
||||
{ NULL, sBadOption, 0 }
|
||||
};
|
||||
|
||||
|
@ -579,8 +588,9 @@ out:
|
|||
}
|
||||
|
||||
/*
|
||||
* All of the attributes on a single Match line are ANDed together, so we need to check every
|
||||
* attribute and set the result to zero if any attribute does not match.
|
||||
* All of the attributes on a single Match line are ANDed together, so we need
|
||||
* to check every * attribute and set the result to zero if any attribute does
|
||||
* not match.
|
||||
*/
|
||||
static int
|
||||
match_cfg_line(char **condition, int line, struct connection_info *ci)
|
||||
|
@ -737,6 +747,14 @@ static const struct multistate multistate_privsep[] = {
|
|||
{ "no", PRIVSEP_OFF },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
static const struct multistate multistate_tcpfwd[] = {
|
||||
{ "yes", FORWARD_ALLOW },
|
||||
{ "all", FORWARD_ALLOW },
|
||||
{ "no", FORWARD_DENY },
|
||||
{ "remote", FORWARD_REMOTE },
|
||||
{ "local", FORWARD_LOCAL },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
|
||||
int
|
||||
process_server_config_line(ServerOptions *options, char *line,
|
||||
|
@ -1088,7 +1106,8 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
|
||||
case sAllowTcpForwarding:
|
||||
intptr = &options->allow_tcp_forwarding;
|
||||
goto parse_flag;
|
||||
multistate_ptr = multistate_tcpfwd;
|
||||
goto parse_multistate;
|
||||
|
||||
case sAllowAgentForwarding:
|
||||
intptr = &options->allow_agent_forwarding;
|
||||
|
@ -1368,7 +1387,6 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
}
|
||||
if (strcmp(arg, "none") == 0) {
|
||||
if (*activep && n == -1) {
|
||||
channel_clear_adm_permitted_opens();
|
||||
options->num_permitted_opens = 1;
|
||||
channel_disable_adm_local_opens();
|
||||
}
|
||||
|
@ -1452,6 +1470,43 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
}
|
||||
return 0;
|
||||
|
||||
case sAuthorizedKeysCommand:
|
||||
len = strspn(cp, WHITESPACE);
|
||||
if (*activep && options->authorized_keys_command == NULL) {
|
||||
if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
|
||||
fatal("%.200s line %d: AuthorizedKeysCommand "
|
||||
"must be an absolute path",
|
||||
filename, linenum);
|
||||
options->authorized_keys_command = xstrdup(cp + len);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case sAuthorizedKeysCommandUser:
|
||||
charptr = &options->authorized_keys_command_user;
|
||||
|
||||
arg = strdelim(&cp);
|
||||
if (*activep && *charptr == NULL)
|
||||
*charptr = xstrdup(arg);
|
||||
break;
|
||||
|
||||
case sAuthenticationMethods:
|
||||
if (*activep && options->num_auth_methods == 0) {
|
||||
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
||||
if (options->num_auth_methods >=
|
||||
MAX_AUTH_METHODS)
|
||||
fatal("%s line %d: "
|
||||
"too many authentication methods.",
|
||||
filename, linenum);
|
||||
if (auth2_methods_valid(arg, 0) != 0)
|
||||
fatal("%s line %d: invalid "
|
||||
"authentication method list.",
|
||||
filename, linenum);
|
||||
options->auth_methods[
|
||||
options->num_auth_methods++] = xstrdup(arg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case sDeprecated:
|
||||
logit("%s line %d: Deprecated option %s",
|
||||
filename, linenum, arg);
|
||||
|
@ -1602,6 +1657,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
|||
M_CP_INTOPT(hostbased_uses_name_from_packet_only);
|
||||
M_CP_INTOPT(kbd_interactive_authentication);
|
||||
M_CP_INTOPT(zero_knowledge_password_authentication);
|
||||
M_CP_STROPT(authorized_keys_command);
|
||||
M_CP_STROPT(authorized_keys_command_user);
|
||||
M_CP_INTOPT(permit_root_login);
|
||||
M_CP_INTOPT(permit_empty_passwd);
|
||||
|
||||
|
@ -1686,6 +1743,8 @@ fmt_intarg(ServerOpCodes code, int val)
|
|||
return fmt_multistate_int(val, multistate_compression);
|
||||
case sUsePrivilegeSeparation:
|
||||
return fmt_multistate_int(val, multistate_privsep);
|
||||
case sAllowTcpForwarding:
|
||||
return fmt_multistate_int(val, multistate_tcpfwd);
|
||||
case sProtocol:
|
||||
switch (val) {
|
||||
case SSH_PROTO_1:
|
||||
|
@ -1857,6 +1916,8 @@ dump_config(ServerOptions *o)
|
|||
dump_cfg_string(sAuthorizedPrincipalsFile,
|
||||
o->authorized_principals_file);
|
||||
dump_cfg_string(sVersionAddendum, o->version_addendum);
|
||||
dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
|
||||
dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
|
||||
|
||||
/* string arguments requiring a lookup */
|
||||
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
|
||||
|
@ -1874,6 +1935,8 @@ dump_config(ServerOptions *o)
|
|||
dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
|
||||
dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
|
||||
dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
|
||||
dump_cfg_strarray_oneline(sAuthenticationMethods,
|
||||
o->num_auth_methods, o->auth_methods);
|
||||
|
||||
/* other arguments */
|
||||
for (i = 0; i < o->num_subsystems; i++)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: servconf.h,v 1.103 2012/07/10 02:19:15 djm Exp $ */
|
||||
/* $OpenBSD: servconf.h,v 1.107 2013/01/03 05:49:36 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -28,6 +28,7 @@
|
|||
#define MAX_ACCEPT_ENV 256 /* Max # of env vars. */
|
||||
#define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */
|
||||
#define MAX_AUTHKEYS_FILES 256 /* Max # of authorized_keys files. */
|
||||
#define MAX_AUTH_METHODS 256 /* Max # of AuthenticationMethods. */
|
||||
|
||||
/* permit_root_login */
|
||||
#define PERMIT_NOT_SET -1
|
||||
|
@ -41,6 +42,12 @@
|
|||
#define PRIVSEP_ON 1
|
||||
#define PRIVSEP_NOSANDBOX 2
|
||||
|
||||
/* AllowTCPForwarding */
|
||||
#define FORWARD_DENY 0
|
||||
#define FORWARD_REMOTE (1)
|
||||
#define FORWARD_LOCAL (1<<1)
|
||||
#define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL)
|
||||
|
||||
#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
|
||||
#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
|
||||
|
||||
|
@ -115,7 +122,7 @@ typedef struct {
|
|||
int permit_user_env; /* If true, read ~/.ssh/environment */
|
||||
int use_login; /* If true, login(1) is used */
|
||||
int compression; /* If true, compression is allowed */
|
||||
int allow_tcp_forwarding;
|
||||
int allow_tcp_forwarding; /* One of FORWARD_* */
|
||||
int allow_agent_forwarding;
|
||||
u_int num_allow_users;
|
||||
char *allow_users[MAX_ALLOW_USERS];
|
||||
|
@ -164,8 +171,13 @@ typedef struct {
|
|||
char *revoked_keys_file;
|
||||
char *trusted_user_ca_keys;
|
||||
char *authorized_principals_file;
|
||||
char *authorized_keys_command;
|
||||
char *authorized_keys_command_user;
|
||||
|
||||
char *version_addendum; /* Appended to SSH banner */
|
||||
|
||||
u_int num_auth_methods;
|
||||
char *auth_methods[MAX_AUTH_METHODS];
|
||||
} ServerOptions;
|
||||
|
||||
/* Information about the incoming connection as used by Match */
|
||||
|
@ -189,12 +201,15 @@ struct connection_info {
|
|||
M_CP_STROPT(trusted_user_ca_keys); \
|
||||
M_CP_STROPT(revoked_keys_file); \
|
||||
M_CP_STROPT(authorized_principals_file); \
|
||||
M_CP_STROPT(authorized_keys_command); \
|
||||
M_CP_STROPT(authorized_keys_command_user); \
|
||||
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
|
||||
M_CP_STRARRAYOPT(allow_users, num_allow_users); \
|
||||
M_CP_STRARRAYOPT(deny_users, num_deny_users); \
|
||||
M_CP_STRARRAYOPT(allow_groups, num_allow_groups); \
|
||||
M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \
|
||||
M_CP_STRARRAYOPT(accept_env, num_accept_env); \
|
||||
M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
|
||||
} while (0)
|
||||
|
||||
struct connection_info *get_connection_info(int, int);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: serverloop.c,v 1.162 2012/06/20 04:42:58 djm Exp $ */
|
||||
/* $OpenBSD: serverloop.c,v 1.164 2012/12/07 01:51:35 dtucker Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -676,7 +676,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
|||
&nalloc, max_time_milliseconds);
|
||||
|
||||
if (received_sigterm) {
|
||||
logit("Exiting on signal %d", received_sigterm);
|
||||
logit("Exiting on signal %d", (int)received_sigterm);
|
||||
/* Clean up sessions, utmp, etc. */
|
||||
cleanup_exit(255);
|
||||
}
|
||||
|
@ -826,7 +826,7 @@ server_loop2(Authctxt *authctxt)
|
|||
&nalloc, 0);
|
||||
|
||||
if (received_sigterm) {
|
||||
logit("Exiting on signal %d", received_sigterm);
|
||||
logit("Exiting on signal %d", (int)received_sigterm);
|
||||
/* Clean up sessions, utmp, etc. */
|
||||
cleanup_exit(255);
|
||||
}
|
||||
|
@ -918,7 +918,7 @@ server_input_window_size(int type, u_int32_t seq, void *ctxt)
|
|||
static Channel *
|
||||
server_request_direct_tcpip(void)
|
||||
{
|
||||
Channel *c;
|
||||
Channel *c = NULL;
|
||||
char *target, *originator;
|
||||
u_short target_port, originator_port;
|
||||
|
||||
|
@ -931,9 +931,16 @@ server_request_direct_tcpip(void)
|
|||
debug("server_request_direct_tcpip: originator %s port %d, target %s "
|
||||
"port %d", originator, originator_port, target, target_port);
|
||||
|
||||
/* XXX check permission */
|
||||
c = channel_connect_to(target, target_port,
|
||||
"direct-tcpip", "direct-tcpip");
|
||||
/* XXX fine grained permissions */
|
||||
if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
|
||||
!no_port_forwarding_flag) {
|
||||
c = channel_connect_to(target, target_port,
|
||||
"direct-tcpip", "direct-tcpip");
|
||||
} else {
|
||||
logit("refused local port forward: "
|
||||
"originator %s port %d, target %s port %d",
|
||||
originator, originator_port, target, target_port);
|
||||
}
|
||||
|
||||
xfree(originator);
|
||||
xfree(target);
|
||||
|
@ -1089,7 +1096,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
|
|||
listen_address, listen_port);
|
||||
|
||||
/* check permissions */
|
||||
if (!options.allow_tcp_forwarding ||
|
||||
if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
|
||||
no_port_forwarding_flag ||
|
||||
(!want_reply && listen_port == 0) ||
|
||||
(listen_port != 0 && listen_port < IPPORT_RESERVED &&
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: session.c,v 1.260 2012/03/15 03:10:27 guenther Exp $ */
|
||||
/* $OpenBSD: session.c,v 1.261 2012/12/02 20:46:11 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
|
@ -256,7 +256,10 @@ do_authenticated(Authctxt *authctxt)
|
|||
setproctitle("%s", authctxt->pw->pw_name);
|
||||
|
||||
/* setup the channel layer */
|
||||
if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
|
||||
if (no_port_forwarding_flag ||
|
||||
(options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
|
||||
channel_disable_adm_local_opens();
|
||||
else
|
||||
channel_permit_all_opens();
|
||||
|
||||
auth_debug_send();
|
||||
|
@ -366,7 +369,7 @@ do_authenticated1(Authctxt *authctxt)
|
|||
debug("Port forwarding not permitted for this authentication.");
|
||||
break;
|
||||
}
|
||||
if (!options.allow_tcp_forwarding) {
|
||||
if (!(options.allow_tcp_forwarding & FORWARD_REMOTE)) {
|
||||
debug("Port forwarding not permitted.");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $OpenBSD: sftp-server.8,v 1.19 2010/01/09 03:36:00 jmc Exp $
|
||||
.\" $OpenBSD: sftp-server.8,v 1.21 2013/01/04 19:26:38 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
.\"
|
||||
|
@ -22,7 +22,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: January 9 2010 $
|
||||
.Dd $Mdocdate: January 4 2013 $
|
||||
.Dt SFTP-SERVER 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -31,6 +31,7 @@
|
|||
.Sh SYNOPSIS
|
||||
.Nm sftp-server
|
||||
.Op Fl ehR
|
||||
.Op Fl d Ar start_directory
|
||||
.Op Fl f Ar log_facility
|
||||
.Op Fl l Ar log_level
|
||||
.Op Fl u Ar umask
|
||||
|
@ -56,6 +57,17 @@ for more information.
|
|||
.Pp
|
||||
Valid options are:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl d Ar start_directory
|
||||
specifies an alternate starting directory for users.
|
||||
The pathname may contain the following tokens that are expanded at runtime:
|
||||
%% is replaced by a literal '%',
|
||||
%h is replaced by the home directory of the user being authenticated,
|
||||
and %u is replaced by the username of that user.
|
||||
The default is to use the user's home directory.
|
||||
This option is useful in conjunction with the
|
||||
.Xr sshd_config 5
|
||||
.Cm ChrootDirectory
|
||||
option.
|
||||
.It Fl e
|
||||
Causes
|
||||
.Nm
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sftp-server.c,v 1.94 2011/06/17 21:46:16 djm Exp $ */
|
||||
/* $OpenBSD: sftp-server.c,v 1.96 2013/01/04 19:26:38 jmc Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -1362,7 +1362,8 @@ sftp_server_usage(void)
|
|||
extern char *__progname;
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: %s [-ehR] [-f log_facility] [-l log_level] [-u umask]\n",
|
||||
"usage: %s [-ehR] [-d start_directory] [-f log_facility] "
|
||||
"[-l log_level]\n\t[-u umask]\n",
|
||||
__progname);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1374,7 +1375,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
|||
int in, out, max, ch, skipargs = 0, log_stderr = 0;
|
||||
ssize_t len, olen, set_size;
|
||||
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
|
||||
char *cp, buf[4*4096];
|
||||
char *cp, *homedir = NULL, buf[4*4096];
|
||||
long mask;
|
||||
|
||||
extern char *optarg;
|
||||
|
@ -1382,7 +1383,9 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
|||
|
||||
log_init(__progname, log_level, log_facility, log_stderr);
|
||||
|
||||
while (!skipargs && (ch = getopt(argc, argv, "f:l:u:cehR")) != -1) {
|
||||
pw = pwcopy(user_pw);
|
||||
|
||||
while (!skipargs && (ch = getopt(argc, argv, "d:f:l:u:cehR")) != -1) {
|
||||
switch (ch) {
|
||||
case 'R':
|
||||
readonly = 1;
|
||||
|
@ -1407,6 +1410,12 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
|||
if (log_facility == SYSLOG_FACILITY_NOT_SET)
|
||||
error("Invalid log facility \"%s\"", optarg);
|
||||
break;
|
||||
case 'd':
|
||||
cp = tilde_expand_filename(optarg, user_pw->pw_uid);
|
||||
homedir = percent_expand(cp, "d", user_pw->pw_dir,
|
||||
"u", user_pw->pw_name, (char *)NULL);
|
||||
free(cp);
|
||||
break;
|
||||
case 'u':
|
||||
errno = 0;
|
||||
mask = strtol(optarg, &cp, 8);
|
||||
|
@ -1434,8 +1443,6 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
|||
} else
|
||||
client_addr = xstrdup("UNKNOWN");
|
||||
|
||||
pw = pwcopy(user_pw);
|
||||
|
||||
logit("session opened for local user %s from [%s]",
|
||||
pw->pw_name, client_addr);
|
||||
|
||||
|
@ -1455,6 +1462,13 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
|||
rset = (fd_set *)xmalloc(set_size);
|
||||
wset = (fd_set *)xmalloc(set_size);
|
||||
|
||||
if (homedir != NULL) {
|
||||
if (chdir(homedir) != 0) {
|
||||
error("chdir to \"%s\" failed: %s", homedir,
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
memset(rset, 0, set_size);
|
||||
memset(wset, 0, set_size);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sftp.c,v 1.136 2012/06/22 14:36:33 dtucker Exp $ */
|
||||
/* $OpenBSD: sftp.c,v 1.142 2013/02/08 00:41:12 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
|
@ -968,6 +968,10 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
|
|||
state = MA_START;
|
||||
i = j = 0;
|
||||
for (;;) {
|
||||
if ((size_t)argc >= sizeof(argv) / sizeof(*argv)){
|
||||
error("Too many arguments.");
|
||||
return NULL;
|
||||
}
|
||||
if (isspace(arg[i])) {
|
||||
if (state == MA_UNQUOTED) {
|
||||
/* Terminate current argument */
|
||||
|
@ -1118,7 +1122,7 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
|
|||
|
||||
/* Figure out which command we have */
|
||||
for (i = 0; cmds[i].c != NULL; i++) {
|
||||
if (strcasecmp(cmds[i].c, argv[0]) == 0)
|
||||
if (argv[0] != NULL && strcasecmp(cmds[i].c, argv[0]) == 0)
|
||||
break;
|
||||
}
|
||||
cmdnum = cmds[i].n;
|
||||
|
@ -1671,7 +1675,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
|
|||
{
|
||||
glob_t g;
|
||||
char *tmp, *tmp2, ins[3];
|
||||
u_int i, hadglob, pwdlen, len, tmplen, filelen;
|
||||
u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs;
|
||||
const LineInfo *lf;
|
||||
|
||||
/* Glob from "file" location */
|
||||
|
@ -1680,6 +1684,9 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
|
|||
else
|
||||
xasprintf(&tmp, "%s*", file);
|
||||
|
||||
/* Check if the path is absolute. */
|
||||
isabs = tmp[0] == '/';
|
||||
|
||||
memset(&g, 0, sizeof(g));
|
||||
if (remote != LOCAL) {
|
||||
tmp = make_absolute(tmp, remote_path);
|
||||
|
@ -1714,7 +1721,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
|
|||
goto out;
|
||||
|
||||
tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc);
|
||||
tmp = path_strip(tmp2, remote_path);
|
||||
tmp = path_strip(tmp2, isabs ? NULL : remote_path);
|
||||
xfree(tmp2);
|
||||
|
||||
if (tmp == NULL)
|
||||
|
@ -1723,8 +1730,18 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
|
|||
tmplen = strlen(tmp);
|
||||
filelen = strlen(file);
|
||||
|
||||
if (tmplen > filelen) {
|
||||
tmp2 = tmp + filelen;
|
||||
/* Count the number of escaped characters in the input string. */
|
||||
cesc = isesc = 0;
|
||||
for (i = 0; i < filelen; i++) {
|
||||
if (!isesc && file[i] == '\\' && i + 1 < filelen){
|
||||
isesc = 1;
|
||||
cesc++;
|
||||
} else
|
||||
isesc = 0;
|
||||
}
|
||||
|
||||
if (tmplen > (filelen - cesc)) {
|
||||
tmp2 = tmp + filelen - cesc;
|
||||
len = strlen(tmp2);
|
||||
/* quote argument on way out */
|
||||
for (i = 0; i < len; i++) {
|
||||
|
@ -1738,6 +1755,8 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
|
|||
case '\t':
|
||||
case '[':
|
||||
case ' ':
|
||||
case '#':
|
||||
case '*':
|
||||
if (quote == '\0' || tmp2[i] == quote) {
|
||||
if (el_insertstr(el, ins) == -1)
|
||||
fatal("el_insertstr "
|
||||
|
@ -1890,6 +1909,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
|||
return (-1);
|
||||
}
|
||||
} else {
|
||||
/* XXX this is wrong wrt quoting */
|
||||
if (file2 == NULL)
|
||||
snprintf(cmd, sizeof cmd, "get %s", dir);
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $OpenBSD: ssh-add.1,v 1.56 2011/10/18 05:00:48 djm Exp $
|
||||
.\" $OpenBSD: ssh-add.1,v 1.58 2012/12/03 08:33:02 jmc Exp $
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -35,7 +35,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: October 18 2011 $
|
||||
.Dd $Mdocdate: December 3 2012 $
|
||||
.Dt SSH-ADD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -98,10 +98,10 @@ Deletes all identities from the agent.
|
|||
Instead of adding identities, removes identities from the agent.
|
||||
If
|
||||
.Nm
|
||||
has been run without arguments, the keys for the default identities will
|
||||
be removed.
|
||||
has been run without arguments, the keys for the default identities and
|
||||
their corresponding certificates will be removed.
|
||||
Otherwise, the argument list will be interpreted as a list of paths to
|
||||
public key files and matching keys will be removed from the agent.
|
||||
public key files to specify keys and certificates to be removed from the agent.
|
||||
If no public key is found at a given path,
|
||||
.Nm
|
||||
will append
|
||||
|
@ -111,8 +111,8 @@ and retry.
|
|||
Remove keys provided by the PKCS#11 shared library
|
||||
.Ar pkcs11 .
|
||||
.It Fl k
|
||||
When loading keys into the agent, load plain private keys only and skip
|
||||
certificates.
|
||||
When loading keys into or deleting keys from the agent, process plain private
|
||||
keys only and skip certificates.
|
||||
.It Fl L
|
||||
Lists public key parameters of all identities currently represented
|
||||
by the agent.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-add.c,v 1.103 2011/10/18 23:37:42 djm Exp $ */
|
||||
/* $OpenBSD: ssh-add.c,v 1.105 2012/12/05 15:42:52 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -90,10 +90,10 @@ clear_pass(void)
|
|||
}
|
||||
|
||||
static int
|
||||
delete_file(AuthenticationConnection *ac, const char *filename)
|
||||
delete_file(AuthenticationConnection *ac, const char *filename, int key_only)
|
||||
{
|
||||
Key *public;
|
||||
char *comment = NULL;
|
||||
Key *public = NULL, *cert = NULL;
|
||||
char *certpath = NULL, *comment = NULL;
|
||||
int ret = -1;
|
||||
|
||||
public = key_load_public(filename, &comment);
|
||||
|
@ -107,8 +107,33 @@ delete_file(AuthenticationConnection *ac, const char *filename)
|
|||
} else
|
||||
fprintf(stderr, "Could not remove identity: %s\n", filename);
|
||||
|
||||
key_free(public);
|
||||
xfree(comment);
|
||||
if (key_only)
|
||||
goto out;
|
||||
|
||||
/* Now try to delete the corresponding certificate too */
|
||||
free(comment);
|
||||
comment = NULL;
|
||||
xasprintf(&certpath, "%s-cert.pub", filename);
|
||||
if ((cert = key_load_public(certpath, &comment)) == NULL)
|
||||
goto out;
|
||||
if (!key_equal_public(cert, public))
|
||||
fatal("Certificate %s does not match private key %s",
|
||||
certpath, filename);
|
||||
|
||||
if (ssh_remove_identity(ac, cert)) {
|
||||
fprintf(stderr, "Identity removed: %s (%s)\n", certpath,
|
||||
comment);
|
||||
ret = 0;
|
||||
} else
|
||||
fprintf(stderr, "Could not remove identity: %s\n", certpath);
|
||||
|
||||
out:
|
||||
if (cert != NULL)
|
||||
key_free(cert);
|
||||
if (public != NULL)
|
||||
key_free(public);
|
||||
free(certpath);
|
||||
free(comment);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -348,7 +373,7 @@ static int
|
|||
do_file(AuthenticationConnection *ac, int deleting, int key_only, char *file)
|
||||
{
|
||||
if (deleting) {
|
||||
if (delete_file(ac, file) == -1)
|
||||
if (delete_file(ac, file, key_only) == -1)
|
||||
return -1;
|
||||
} else {
|
||||
if (add_file(ac, file, key_only) == -1)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $OpenBSD: ssh-keygen.1,v 1.109 2012/07/06 00:41:59 dtucker Exp $
|
||||
.\" $OpenBSD: ssh-keygen.1,v 1.115 2013/01/19 07:13:25 jmc Exp $
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -35,7 +35,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 6 2012 $
|
||||
.Dd $Mdocdate: January 19 2013 $
|
||||
.Dt SSH-KEYGEN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -122,6 +122,17 @@
|
|||
.Op Fl f Ar input_keyfile
|
||||
.Nm ssh-keygen
|
||||
.Fl A
|
||||
.Nm ssh-keygen
|
||||
.Fl k
|
||||
.Fl f Ar krl_file
|
||||
.Op Fl u
|
||||
.Op Fl s Ar ca_public
|
||||
.Op Fl z Ar version_number
|
||||
.Ar
|
||||
.Nm ssh-keygen
|
||||
.Fl Q
|
||||
.Fl f Ar krl_file
|
||||
.Ar
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
|
@ -144,6 +155,14 @@ See the
|
|||
.Sx MODULI GENERATION
|
||||
section for details.
|
||||
.Pp
|
||||
Finally,
|
||||
.Nm
|
||||
can be used to generate and update Key Revocation Lists, and to test whether
|
||||
given keys have been revoked by one.
|
||||
See the
|
||||
.Sx KEY REVOCATION LISTS
|
||||
section for details.
|
||||
.Pp
|
||||
Normally each user wishing to use SSH
|
||||
with public key authentication runs this once to create the authentication
|
||||
key in
|
||||
|
@ -321,6 +340,17 @@ This option allows importing keys from other software, including several
|
|||
commercial SSH implementations.
|
||||
The default import format is
|
||||
.Dq RFC4716 .
|
||||
.It Fl k
|
||||
Generate a KRL file.
|
||||
In this mode,
|
||||
.Nm
|
||||
will generate a KRL file at the location specified via the
|
||||
.Fl f
|
||||
flag that revokes every key or certificate presented on the command line.
|
||||
Keys/certificates to be revoked may be specified by public key file or
|
||||
using the format described in the
|
||||
.Sx KEY REVOCATION LISTS
|
||||
section.
|
||||
.It Fl L
|
||||
Prints the contents of a certificate.
|
||||
.It Fl l
|
||||
|
@ -425,6 +455,8 @@ creating a new private key.
|
|||
The program will prompt for the file
|
||||
containing the private key, for the old passphrase, and twice for the
|
||||
new passphrase.
|
||||
.It Fl Q
|
||||
Test whether keys have been revoked in a KRL.
|
||||
.It Fl q
|
||||
Silence
|
||||
.Nm ssh-keygen .
|
||||
|
@ -448,6 +480,14 @@ Certify (sign) a public key using the specified CA key.
|
|||
Please see the
|
||||
.Sx CERTIFICATES
|
||||
section for details.
|
||||
.Pp
|
||||
When generating a KRL,
|
||||
.Fl s
|
||||
specifies a path to a CA public key file used to revoke certificates directly
|
||||
by key ID or serial number.
|
||||
See the
|
||||
.Sx KEY REVOCATION LISTS
|
||||
section for details.
|
||||
.It Fl T Ar output_file
|
||||
Test DH group exchange candidate primes (generated using the
|
||||
.Fl G
|
||||
|
@ -462,6 +502,12 @@ for protocol version 1 and
|
|||
or
|
||||
.Dq rsa
|
||||
for protocol version 2.
|
||||
.It Fl u
|
||||
Update a KRL.
|
||||
When specified with
|
||||
.Fl k ,
|
||||
keys listed via the command line are added to the existing KRL rather than
|
||||
a new KRL being created.
|
||||
.It Fl V Ar validity_interval
|
||||
Specify a validity interval when signing a certificate.
|
||||
A validity interval may consist of a single time, indicating that the
|
||||
|
@ -504,6 +550,10 @@ OpenSSH format file and print an OpenSSH public key to stdout.
|
|||
Specifies a serial number to be embedded in the certificate to distinguish
|
||||
this certificate from others from the same CA.
|
||||
The default serial number is zero.
|
||||
.Pp
|
||||
When generating a KRL, the
|
||||
.Fl z
|
||||
flag is used to specify a KRL version number.
|
||||
.El
|
||||
.Sh MODULI GENERATION
|
||||
.Nm
|
||||
|
@ -628,7 +678,9 @@ The
|
|||
option allows specification of certificate start and end times.
|
||||
A certificate that is presented at a time outside this range will not be
|
||||
considered valid.
|
||||
By default, certificates have a maximum validity interval.
|
||||
By default, certificates are valid from
|
||||
.Ux
|
||||
Epoch to the distant future.
|
||||
.Pp
|
||||
For certificates to be used for user or host authentication, the CA
|
||||
public key must be trusted by
|
||||
|
@ -636,6 +688,73 @@ public key must be trusted by
|
|||
or
|
||||
.Xr ssh 1 .
|
||||
Please refer to those manual pages for details.
|
||||
.Sh KEY REVOCATION LISTS
|
||||
.Nm
|
||||
is able to manage OpenSSH format Key Revocation Lists (KRLs).
|
||||
These binary files specify keys or certificates to be revoked using a
|
||||
compact format, taking as little a one bit per certificate if they are being
|
||||
revoked by serial number.
|
||||
.Pp
|
||||
KRLs may be generated using the
|
||||
.Fl k
|
||||
flag.
|
||||
This option reads one or more files from the command line and generates a new
|
||||
KRL.
|
||||
The files may either contain a KRL specification (see below) or public keys,
|
||||
listed one per line.
|
||||
Plain public keys are revoked by listing their hash or contents in the KRL and
|
||||
certificates revoked by serial number or key ID (if the serial is zero or
|
||||
not available).
|
||||
.Pp
|
||||
Revoking keys using a KRL specification offers explicit control over the
|
||||
types of record used to revoke keys and may be used to directly revoke
|
||||
certificates by serial number or key ID without having the complete original
|
||||
certificate on hand.
|
||||
A KRL specification consists of lines containing one of the following directives
|
||||
followed by a colon and some directive-specific information.
|
||||
.Bl -tag -width Ds
|
||||
.It Cm serial : Ar serial_number Ns Op - Ns Ar serial_number
|
||||
Revokes a certificate with the specified serial number.
|
||||
Serial numbers are 64-bit values, not including zero and may be expressed
|
||||
in decimal, hex or octal.
|
||||
If two serial numbers are specified separated by a hyphen, then the range
|
||||
of serial numbers including and between each is revoked.
|
||||
The CA key must have been specified on the
|
||||
.Nm
|
||||
command line using the
|
||||
.Fl s
|
||||
option.
|
||||
.It Cm id : Ar key_id
|
||||
Revokes a certificate with the specified key ID string.
|
||||
The CA key must have been specified on the
|
||||
.Nm
|
||||
command line using the
|
||||
.Fl s
|
||||
option.
|
||||
.It Cm key : Ar public_key
|
||||
Revokes the specified key.
|
||||
If a certificate is listed, then it is revoked as a plain public key.
|
||||
.It Cm sha1 : Ar public_key
|
||||
Revokes the specified key by its SHA1 hash.
|
||||
.El
|
||||
.Pp
|
||||
KRLs may be updated using the
|
||||
.Fl u
|
||||
flag in addition to
|
||||
.Fl k .
|
||||
When this option is specified, keys listed via the command line are merged into
|
||||
the KRL, adding to those already there.
|
||||
.Pp
|
||||
It is also possible, given a KRL, to test whether it revokes a particular key
|
||||
(or keys).
|
||||
The
|
||||
.Fl Q
|
||||
flag will query an existing KRL, testing each key specified on the commandline.
|
||||
If any key listed on the command line has been revoked (or an error encountered)
|
||||
then
|
||||
.Nm
|
||||
will exit with a non-zero exit status.
|
||||
A zero exit status will only be returned if no key was revoked.
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Pa ~/.ssh/identity
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-keygen.c,v 1.216 2012/07/06 06:38:03 jmc Exp $ */
|
||||
/* $OpenBSD: ssh-keygen.c,v 1.225 2013/02/10 23:32:10 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -40,7 +40,10 @@
|
|||
#include "match.h"
|
||||
#include "hostfile.h"
|
||||
#include "dns.h"
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
#include "atomicio.h"
|
||||
#include "krl.h"
|
||||
|
||||
#ifdef ENABLE_PKCS11
|
||||
#include "ssh-pkcs11.h"
|
||||
|
@ -99,7 +102,7 @@ char *identity_comment = NULL;
|
|||
char *ca_key_path = NULL;
|
||||
|
||||
/* Certificate serial number */
|
||||
long long cert_serial = 0;
|
||||
unsigned long long cert_serial = 0;
|
||||
|
||||
/* Key type when certifying */
|
||||
u_int cert_key_type = SSH2_CERT_TYPE_USER;
|
||||
|
@ -710,15 +713,33 @@ do_download(struct passwd *pw)
|
|||
#ifdef ENABLE_PKCS11
|
||||
Key **keys = NULL;
|
||||
int i, nkeys;
|
||||
enum fp_rep rep;
|
||||
enum fp_type fptype;
|
||||
char *fp, *ra;
|
||||
|
||||
fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
|
||||
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
|
||||
|
||||
pkcs11_init(0);
|
||||
nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
|
||||
if (nkeys <= 0)
|
||||
fatal("cannot read public key from pkcs11");
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
key_write(keys[i], stdout);
|
||||
if (print_fingerprint) {
|
||||
fp = key_fingerprint(keys[i], fptype, rep);
|
||||
ra = key_fingerprint(keys[i], SSH_FP_MD5,
|
||||
SSH_FP_RANDOMART);
|
||||
printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]),
|
||||
fp, key_type(keys[i]));
|
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE)
|
||||
printf("%s\n", ra);
|
||||
xfree(ra);
|
||||
xfree(fp);
|
||||
} else {
|
||||
key_write(keys[i], stdout);
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
key_free(keys[i]);
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
xfree(keys);
|
||||
pkcs11_terminate();
|
||||
|
@ -1073,8 +1094,14 @@ do_known_hosts(struct passwd *pw, const char *name)
|
|||
ca ? " (CA key)" : "");
|
||||
printhost(out, cp, pub, ca, 0);
|
||||
}
|
||||
if (delete_host && !c && !ca)
|
||||
printhost(out, cp, pub, ca, 0);
|
||||
if (delete_host) {
|
||||
if (!c && !ca)
|
||||
printhost(out, cp, pub, ca, 0);
|
||||
else
|
||||
printf("# Host %s found: "
|
||||
"line %d type %s\n", name,
|
||||
num, key_type(pub));
|
||||
}
|
||||
} else if (hash_hosts)
|
||||
printhost(out, cp, pub, ca, 0);
|
||||
} else {
|
||||
|
@ -1089,8 +1116,14 @@ do_known_hosts(struct passwd *pw, const char *name)
|
|||
printhost(out, name, pub,
|
||||
ca, hash_hosts && !ca);
|
||||
}
|
||||
if (delete_host && !c && !ca)
|
||||
printhost(out, cp, pub, ca, 0);
|
||||
if (delete_host) {
|
||||
if (!c && !ca)
|
||||
printhost(out, cp, pub, ca, 0);
|
||||
else
|
||||
printf("# Host %s found: "
|
||||
"line %d type %s\n", name,
|
||||
num, key_type(pub));
|
||||
}
|
||||
} else if (hash_hosts) {
|
||||
for (cp2 = strsep(&cp, ",");
|
||||
cp2 != NULL && *cp2 != '\0';
|
||||
|
@ -1851,6 +1884,226 @@ do_show_cert(struct passwd *pw)
|
|||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
load_krl(const char *path, struct ssh_krl **krlp)
|
||||
{
|
||||
Buffer krlbuf;
|
||||
int fd;
|
||||
|
||||
buffer_init(&krlbuf);
|
||||
if ((fd = open(path, O_RDONLY)) == -1)
|
||||
fatal("open %s: %s", path, strerror(errno));
|
||||
if (!key_load_file(fd, path, &krlbuf))
|
||||
fatal("Unable to load KRL");
|
||||
close(fd);
|
||||
/* XXX check sigs */
|
||||
if (ssh_krl_from_blob(&krlbuf, krlp, NULL, 0) != 0 ||
|
||||
*krlp == NULL)
|
||||
fatal("Invalid KRL file");
|
||||
buffer_free(&krlbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
update_krl_from_file(struct passwd *pw, const char *file, const Key *ca,
|
||||
struct ssh_krl *krl)
|
||||
{
|
||||
Key *key = NULL;
|
||||
u_long lnum = 0;
|
||||
char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES];
|
||||
unsigned long long serial, serial2;
|
||||
int i, was_explicit_key, was_sha1, r;
|
||||
FILE *krl_spec;
|
||||
|
||||
path = tilde_expand_filename(file, pw->pw_uid);
|
||||
if (strcmp(path, "-") == 0) {
|
||||
krl_spec = stdin;
|
||||
free(path);
|
||||
path = xstrdup("(standard input)");
|
||||
} else if ((krl_spec = fopen(path, "r")) == NULL)
|
||||
fatal("fopen %s: %s", path, strerror(errno));
|
||||
|
||||
if (!quiet)
|
||||
printf("Revoking from %s\n", path);
|
||||
while (read_keyfile_line(krl_spec, path, line, sizeof(line),
|
||||
&lnum) == 0) {
|
||||
was_explicit_key = was_sha1 = 0;
|
||||
cp = line + strspn(line, " \t");
|
||||
/* Trim trailing space, comments and strip \n */
|
||||
for (i = 0, r = -1; cp[i] != '\0'; i++) {
|
||||
if (cp[i] == '#' || cp[i] == '\n') {
|
||||
cp[i] = '\0';
|
||||
break;
|
||||
}
|
||||
if (cp[i] == ' ' || cp[i] == '\t') {
|
||||
/* Remember the start of a span of whitespace */
|
||||
if (r == -1)
|
||||
r = i;
|
||||
} else
|
||||
r = -1;
|
||||
}
|
||||
if (r != -1)
|
||||
cp[r] = '\0';
|
||||
if (*cp == '\0')
|
||||
continue;
|
||||
if (strncasecmp(cp, "serial:", 7) == 0) {
|
||||
if (ca == NULL) {
|
||||
fatal("revoking certificated by serial number "
|
||||
"requires specification of a CA key");
|
||||
}
|
||||
cp += 7;
|
||||
cp = cp + strspn(cp, " \t");
|
||||
errno = 0;
|
||||
serial = strtoull(cp, &ep, 0);
|
||||
if (*cp == '\0' || (*ep != '\0' && *ep != '-'))
|
||||
fatal("%s:%lu: invalid serial \"%s\"",
|
||||
path, lnum, cp);
|
||||
if (errno == ERANGE && serial == ULLONG_MAX)
|
||||
fatal("%s:%lu: serial out of range",
|
||||
path, lnum);
|
||||
serial2 = serial;
|
||||
if (*ep == '-') {
|
||||
cp = ep + 1;
|
||||
errno = 0;
|
||||
serial2 = strtoull(cp, &ep, 0);
|
||||
if (*cp == '\0' || *ep != '\0')
|
||||
fatal("%s:%lu: invalid serial \"%s\"",
|
||||
path, lnum, cp);
|
||||
if (errno == ERANGE && serial2 == ULLONG_MAX)
|
||||
fatal("%s:%lu: serial out of range",
|
||||
path, lnum);
|
||||
if (serial2 <= serial)
|
||||
fatal("%s:%lu: invalid serial range "
|
||||
"%llu:%llu", path, lnum,
|
||||
(unsigned long long)serial,
|
||||
(unsigned long long)serial2);
|
||||
}
|
||||
if (ssh_krl_revoke_cert_by_serial_range(krl,
|
||||
ca, serial, serial2) != 0) {
|
||||
fatal("%s: revoke serial failed",
|
||||
__func__);
|
||||
}
|
||||
} else if (strncasecmp(cp, "id:", 3) == 0) {
|
||||
if (ca == NULL) {
|
||||
fatal("revoking certificated by key ID "
|
||||
"requires specification of a CA key");
|
||||
}
|
||||
cp += 3;
|
||||
cp = cp + strspn(cp, " \t");
|
||||
if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0)
|
||||
fatal("%s: revoke key ID failed", __func__);
|
||||
} else {
|
||||
if (strncasecmp(cp, "key:", 4) == 0) {
|
||||
cp += 4;
|
||||
cp = cp + strspn(cp, " \t");
|
||||
was_explicit_key = 1;
|
||||
} else if (strncasecmp(cp, "sha1:", 5) == 0) {
|
||||
cp += 5;
|
||||
cp = cp + strspn(cp, " \t");
|
||||
was_sha1 = 1;
|
||||
} else {
|
||||
/*
|
||||
* Just try to process the line as a key.
|
||||
* Parsing will fail if it isn't.
|
||||
*/
|
||||
}
|
||||
if ((key = key_new(KEY_UNSPEC)) == NULL)
|
||||
fatal("key_new");
|
||||
if (key_read(key, &cp) != 1)
|
||||
fatal("%s:%lu: invalid key", path, lnum);
|
||||
if (was_explicit_key)
|
||||
r = ssh_krl_revoke_key_explicit(krl, key);
|
||||
else if (was_sha1)
|
||||
r = ssh_krl_revoke_key_sha1(krl, key);
|
||||
else
|
||||
r = ssh_krl_revoke_key(krl, key);
|
||||
if (r != 0)
|
||||
fatal("%s: revoke key failed", __func__);
|
||||
key_free(key);
|
||||
}
|
||||
}
|
||||
if (strcmp(path, "-") != 0)
|
||||
fclose(krl_spec);
|
||||
}
|
||||
|
||||
static void
|
||||
do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
|
||||
{
|
||||
struct ssh_krl *krl;
|
||||
struct stat sb;
|
||||
Key *ca = NULL;
|
||||
int fd, i;
|
||||
char *tmp;
|
||||
Buffer kbuf;
|
||||
|
||||
if (*identity_file == '\0')
|
||||
fatal("KRL generation requires an output file");
|
||||
if (stat(identity_file, &sb) == -1) {
|
||||
if (errno != ENOENT)
|
||||
fatal("Cannot access KRL \"%s\": %s",
|
||||
identity_file, strerror(errno));
|
||||
if (updating)
|
||||
fatal("KRL \"%s\" does not exist", identity_file);
|
||||
}
|
||||
if (ca_key_path != NULL) {
|
||||
tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
|
||||
if ((ca = key_load_public(tmp, NULL)) == NULL)
|
||||
fatal("Cannot load CA public key %s", tmp);
|
||||
xfree(tmp);
|
||||
}
|
||||
|
||||
if (updating)
|
||||
load_krl(identity_file, &krl);
|
||||
else if ((krl = ssh_krl_init()) == NULL)
|
||||
fatal("couldn't create KRL");
|
||||
|
||||
if (cert_serial != 0)
|
||||
ssh_krl_set_version(krl, cert_serial);
|
||||
if (identity_comment != NULL)
|
||||
ssh_krl_set_comment(krl, identity_comment);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
update_krl_from_file(pw, argv[i], ca, krl);
|
||||
|
||||
buffer_init(&kbuf);
|
||||
if (ssh_krl_to_blob(krl, &kbuf, NULL, 0) != 0)
|
||||
fatal("Couldn't generate KRL");
|
||||
if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
|
||||
fatal("open %s: %s", identity_file, strerror(errno));
|
||||
if (atomicio(vwrite, fd, buffer_ptr(&kbuf), buffer_len(&kbuf)) !=
|
||||
buffer_len(&kbuf))
|
||||
fatal("write %s: %s", identity_file, strerror(errno));
|
||||
close(fd);
|
||||
buffer_free(&kbuf);
|
||||
ssh_krl_free(krl);
|
||||
}
|
||||
|
||||
static void
|
||||
do_check_krl(struct passwd *pw, int argc, char **argv)
|
||||
{
|
||||
int i, r, ret = 0;
|
||||
char *comment;
|
||||
struct ssh_krl *krl;
|
||||
Key *k;
|
||||
|
||||
if (*identity_file == '\0')
|
||||
fatal("KRL checking requires an input file");
|
||||
load_krl(identity_file, &krl);
|
||||
for (i = 0; i < argc; i++) {
|
||||
if ((k = key_load_public(argv[i], &comment)) == NULL)
|
||||
fatal("Cannot load public key %s", argv[i]);
|
||||
r = ssh_krl_check_key(krl, k);
|
||||
printf("%s%s%s%s: %s\n", argv[i],
|
||||
*comment ? " (" : "", comment, *comment ? ")" : "",
|
||||
r == 0 ? "ok" : "REVOKED");
|
||||
if (r != 0)
|
||||
ret = 1;
|
||||
key_free(k);
|
||||
free(comment);
|
||||
}
|
||||
ssh_krl_free(krl);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
@ -1877,6 +2130,7 @@ usage(void)
|
|||
fprintf(stderr, " -J number Screen this number of moduli lines.\n");
|
||||
fprintf(stderr, " -j number Start screening moduli at specified line.\n");
|
||||
fprintf(stderr, " -K checkpt Write checkpoints to this file.\n");
|
||||
fprintf(stderr, " -k Generate a KRL file.\n");
|
||||
fprintf(stderr, " -L Print the contents of a certificate.\n");
|
||||
fprintf(stderr, " -l Show fingerprint of key file.\n");
|
||||
fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n");
|
||||
|
@ -1886,6 +2140,7 @@ usage(void)
|
|||
fprintf(stderr, " -O option Specify a certificate option.\n");
|
||||
fprintf(stderr, " -P phrase Provide old passphrase.\n");
|
||||
fprintf(stderr, " -p Change passphrase of private key file.\n");
|
||||
fprintf(stderr, " -Q Test whether key(s) are revoked in KRL.\n");
|
||||
fprintf(stderr, " -q Quiet.\n");
|
||||
fprintf(stderr, " -R hostname Remove host from known_hosts file.\n");
|
||||
fprintf(stderr, " -r hostname Print DNS resource record.\n");
|
||||
|
@ -1893,6 +2148,7 @@ usage(void)
|
|||
fprintf(stderr, " -s ca_key Certify keys with CA key.\n");
|
||||
fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n");
|
||||
fprintf(stderr, " -t type Specify type of key to create.\n");
|
||||
fprintf(stderr, " -u Update KRL rather than creating a new one.\n");
|
||||
fprintf(stderr, " -V from:to Specify certificate validity interval.\n");
|
||||
fprintf(stderr, " -v Verbose.\n");
|
||||
fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n");
|
||||
|
@ -1910,14 +2166,14 @@ main(int argc, char **argv)
|
|||
{
|
||||
char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
|
||||
char *checkpoint = NULL;
|
||||
char out_file[MAXPATHLEN], *rr_hostname = NULL;
|
||||
char out_file[MAXPATHLEN], *ep, *rr_hostname = NULL;
|
||||
Key *private, *public;
|
||||
struct passwd *pw;
|
||||
struct stat st;
|
||||
int opt, type, fd;
|
||||
u_int32_t memory = 0, generator_wanted = 0, trials = 100;
|
||||
int do_gen_candidates = 0, do_screen_candidates = 0;
|
||||
int gen_all_hostkeys = 0;
|
||||
int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
|
||||
unsigned long start_lineno = 0, lines_to_process = 0;
|
||||
BIGNUM *start = NULL;
|
||||
FILE *f;
|
||||
|
@ -1943,8 +2199,8 @@ main(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:J:j:K:P:"
|
||||
"m:N:n:O:C:r:g:R:T:G:M:S:s:a:V:W:z")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "ABHLQXceghiklpquvxy"
|
||||
"C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'A':
|
||||
gen_all_hostkeys = 1;
|
||||
|
@ -2023,6 +2279,9 @@ main(int argc, char **argv)
|
|||
case 'N':
|
||||
identity_new_passphrase = optarg;
|
||||
break;
|
||||
case 'Q':
|
||||
check_krl = 1;
|
||||
break;
|
||||
case 'O':
|
||||
add_cert_option(optarg);
|
||||
break;
|
||||
|
@ -2041,6 +2300,9 @@ main(int argc, char **argv)
|
|||
cert_key_type = SSH2_CERT_TYPE_HOST;
|
||||
certflags_flags = 0;
|
||||
break;
|
||||
case 'k':
|
||||
gen_krl = 1;
|
||||
break;
|
||||
case 'i':
|
||||
case 'X':
|
||||
/* import key */
|
||||
|
@ -2058,6 +2320,9 @@ main(int argc, char **argv)
|
|||
case 'D':
|
||||
pkcs11provider = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
update_krl = 1;
|
||||
break;
|
||||
case 'v':
|
||||
if (log_level == SYSLOG_LEVEL_INFO)
|
||||
log_level = SYSLOG_LEVEL_DEBUG1;
|
||||
|
@ -2114,9 +2379,11 @@ main(int argc, char **argv)
|
|||
parse_cert_times(optarg);
|
||||
break;
|
||||
case 'z':
|
||||
cert_serial = strtonum(optarg, 0, LLONG_MAX, &errstr);
|
||||
if (errstr)
|
||||
fatal("Invalid serial number: %s", errstr);
|
||||
errno = 0;
|
||||
cert_serial = strtoull(optarg, &ep, 10);
|
||||
if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
|
||||
(errno == ERANGE && cert_serial == ULLONG_MAX))
|
||||
fatal("Invalid serial number \"%s\"", optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
|
@ -2131,11 +2398,11 @@ main(int argc, char **argv)
|
|||
argc -= optind;
|
||||
|
||||
if (ca_key_path != NULL) {
|
||||
if (argc < 1) {
|
||||
if (argc < 1 && !gen_krl) {
|
||||
printf("Too few arguments.\n");
|
||||
usage();
|
||||
}
|
||||
} else if (argc > 0) {
|
||||
} else if (argc > 0 && !gen_krl && !check_krl) {
|
||||
printf("Too many arguments.\n");
|
||||
usage();
|
||||
}
|
||||
|
@ -2144,9 +2411,17 @@ main(int argc, char **argv)
|
|||
usage();
|
||||
}
|
||||
if (print_fingerprint && (delete_host || hash_hosts)) {
|
||||
printf("Cannot use -l with -D or -R.\n");
|
||||
printf("Cannot use -l with -H or -R.\n");
|
||||
usage();
|
||||
}
|
||||
if (gen_krl) {
|
||||
do_gen_krl(pw, update_krl, argc, argv);
|
||||
return (0);
|
||||
}
|
||||
if (check_krl) {
|
||||
do_check_krl(pw, argc, argv);
|
||||
return (0);
|
||||
}
|
||||
if (ca_key_path != NULL) {
|
||||
if (cert_key_id == NULL)
|
||||
fatal("Must specify key id (-I) when certifying");
|
||||
|
@ -2156,6 +2431,8 @@ main(int argc, char **argv)
|
|||
do_show_cert(pw);
|
||||
if (delete_host || hash_hosts || find_host)
|
||||
do_known_hosts(pw, rr_hostname);
|
||||
if (pkcs11provider != NULL)
|
||||
do_download(pw);
|
||||
if (print_fingerprint || print_bubblebabble)
|
||||
do_fingerprint(pw);
|
||||
if (change_passphrase)
|
||||
|
@ -2193,8 +2470,6 @@ main(int argc, char **argv)
|
|||
exit(0);
|
||||
}
|
||||
}
|
||||
if (pkcs11provider != NULL)
|
||||
do_download(pw);
|
||||
|
||||
if (do_gen_candidates) {
|
||||
FILE *out = fopen(out_file, "w");
|
||||
|
@ -2214,7 +2489,7 @@ main(int argc, char **argv)
|
|||
|
||||
if (do_screen_candidates) {
|
||||
FILE *in;
|
||||
FILE *out = fopen(out_file, "w");
|
||||
FILE *out = fopen(out_file, "a");
|
||||
|
||||
if (have_identity && strcmp(identity_file, "-") != 0) {
|
||||
if ((in = fopen(identity_file, "r")) == NULL) {
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh.1,v 1.326 2012/06/18 12:17:18 dtucker Exp $
|
||||
.Dd $Mdocdate: June 18 2012 $
|
||||
.\" $OpenBSD: ssh.1,v 1.330 2012/10/04 13:21:50 markus Exp $
|
||||
.Dd $Mdocdate: October 4 2012 $
|
||||
.Dt SSH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -674,7 +674,7 @@ it provides additional mechanisms for confidentiality
|
|||
(the traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour)
|
||||
and integrity (hmac-md5, hmac-sha1,
|
||||
hmac-sha2-256, hmac-sha2-512,
|
||||
umac-64, hmac-ripemd160).
|
||||
umac-64, umac-128, hmac-ripemd160).
|
||||
Protocol 1 lacks a strong mechanism for ensuring the
|
||||
integrity of the connection.
|
||||
.Pp
|
||||
|
@ -926,6 +926,14 @@ option.
|
|||
.It Cm ~R
|
||||
Request rekeying of the connection
|
||||
(only useful for SSH protocol version 2 and if the peer supports it).
|
||||
.It Cm ~V
|
||||
Decrease the verbosity
|
||||
.Pq Ic LogLevel
|
||||
when errors are being written to stderr.
|
||||
.It Cm ~v
|
||||
Increase the verbosity
|
||||
.Pq Ic LogLevel
|
||||
when errors are being written to stderr.
|
||||
.El
|
||||
.Sh TCP FORWARDING
|
||||
Forwarding of arbitrary TCP connections over the secure channel can
|
||||
|
@ -1426,77 +1434,118 @@ if an error occurred.
|
|||
.Xr ssh_config 5 ,
|
||||
.Xr ssh-keysign 8 ,
|
||||
.Xr sshd 8
|
||||
.Sh STANDARDS
|
||||
.Rs
|
||||
.%A S. Lehtinen
|
||||
.%A C. Lonvick
|
||||
.%D January 2006
|
||||
.%R RFC 4250
|
||||
.%T "The Secure Shell (SSH) Protocol Assigned Numbers"
|
||||
.%D 2006
|
||||
.%T The Secure Shell (SSH) Protocol Assigned Numbers
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A T. Ylonen
|
||||
.%A C. Lonvick
|
||||
.%D January 2006
|
||||
.%R RFC 4251
|
||||
.%T "The Secure Shell (SSH) Protocol Architecture"
|
||||
.%D 2006
|
||||
.%T The Secure Shell (SSH) Protocol Architecture
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A T. Ylonen
|
||||
.%A C. Lonvick
|
||||
.%D January 2006
|
||||
.%R RFC 4252
|
||||
.%T "The Secure Shell (SSH) Authentication Protocol"
|
||||
.%D 2006
|
||||
.%T The Secure Shell (SSH) Authentication Protocol
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A T. Ylonen
|
||||
.%A C. Lonvick
|
||||
.%D January 2006
|
||||
.%R RFC 4253
|
||||
.%T "The Secure Shell (SSH) Transport Layer Protocol"
|
||||
.%D 2006
|
||||
.%T The Secure Shell (SSH) Transport Layer Protocol
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A T. Ylonen
|
||||
.%A C. Lonvick
|
||||
.%D January 2006
|
||||
.%R RFC 4254
|
||||
.%T "The Secure Shell (SSH) Connection Protocol"
|
||||
.%D 2006
|
||||
.%T The Secure Shell (SSH) Connection Protocol
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A J. Schlyter
|
||||
.%A W. Griffin
|
||||
.%D January 2006
|
||||
.%R RFC 4255
|
||||
.%T "Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints"
|
||||
.%D 2006
|
||||
.%T Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A F. Cusack
|
||||
.%A M. Forssen
|
||||
.%D January 2006
|
||||
.%R RFC 4256
|
||||
.%T "Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)"
|
||||
.%D 2006
|
||||
.%T Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A J. Galbraith
|
||||
.%A P. Remaker
|
||||
.%D January 2006
|
||||
.%R RFC 4335
|
||||
.%T "The Secure Shell (SSH) Session Channel Break Extension"
|
||||
.%D 2006
|
||||
.%T The Secure Shell (SSH) Session Channel Break Extension
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A M. Bellare
|
||||
.%A T. Kohno
|
||||
.%A C. Namprempre
|
||||
.%D January 2006
|
||||
.%R RFC 4344
|
||||
.%T "The Secure Shell (SSH) Transport Layer Encryption Modes"
|
||||
.%D 2006
|
||||
.%T The Secure Shell (SSH) Transport Layer Encryption Modes
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A B. Harris
|
||||
.%D January 2006
|
||||
.%R RFC 4345
|
||||
.%T "Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol"
|
||||
.%D 2006
|
||||
.%T Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A M. Friedl
|
||||
.%A N. Provos
|
||||
.%A W. Simpson
|
||||
.%D March 2006
|
||||
.%R RFC 4419
|
||||
.%T "Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol"
|
||||
.%D 2006
|
||||
.%T Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A J. Galbraith
|
||||
.%A R. Thayer
|
||||
.%D November 2006
|
||||
.%R RFC 4716
|
||||
.%T "The Secure Shell (SSH) Public Key File Format"
|
||||
.%D 2006
|
||||
.%T The Secure Shell (SSH) Public Key File Format
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%A D. Stebila
|
||||
.%A J. Green
|
||||
.%D December 2009
|
||||
.%R RFC 5656
|
||||
.%T "Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer"
|
||||
.%D 2009
|
||||
.%T Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
|
||||
.Re
|
||||
.Pp
|
||||
.Rs
|
||||
.%T "Hash Visualization: a New Technique to improve Real-World Security"
|
||||
.%A A. Perrig
|
||||
.%A D. Song
|
||||
.%D 1999
|
||||
.%O "International Workshop on Cryptographic Techniques and E-Commerce (CrypTEC '99)"
|
||||
.%O International Workshop on Cryptographic Techniques and E-Commerce (CrypTEC '99)
|
||||
.%T Hash Visualization: a New Technique to improve Real-World Security
|
||||
.Re
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh_config.5,v 1.157 2012/06/29 13:57:25 naddy Exp $
|
||||
.Dd $Mdocdate: June 29 2012 $
|
||||
.\" $OpenBSD: ssh_config.5,v 1.161 2013/01/08 18:49:04 markus Exp $
|
||||
.Dd $Mdocdate: January 8 2013 $
|
||||
.Dt SSH_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -204,6 +204,8 @@ The supported ciphers are
|
|||
.Dq aes128-ctr ,
|
||||
.Dq aes192-ctr ,
|
||||
.Dq aes256-ctr ,
|
||||
.Dq aes128-gcm@openssh.com ,
|
||||
.Dq aes256-gcm@openssh.com ,
|
||||
.Dq arcfour128 ,
|
||||
.Dq arcfour256 ,
|
||||
.Dq arcfour ,
|
||||
|
@ -213,6 +215,7 @@ and
|
|||
The default is:
|
||||
.Bd -literal -offset 3n
|
||||
aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,
|
||||
aes128-gcm@openssh.com,aes256-gcm@openssh.com,
|
||||
aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,
|
||||
aes256-cbc,arcfour
|
||||
.Ed
|
||||
|
@ -602,6 +605,8 @@ should only use the authentication identity files configured in the
|
|||
files,
|
||||
even if
|
||||
.Xr ssh-agent 1
|
||||
or a
|
||||
.Cm PKCS11Provider
|
||||
offers more identities.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
|
@ -790,9 +795,18 @@ in order of preference.
|
|||
The MAC algorithm is used in protocol version 2
|
||||
for data integrity protection.
|
||||
Multiple algorithms must be comma-separated.
|
||||
The algorithms that contain
|
||||
.Dq -etm
|
||||
calculate the MAC after encryption (encrypt-then-mac).
|
||||
These are considered safer and their use recommended.
|
||||
The default is:
|
||||
.Bd -literal -offset indent
|
||||
hmac-md5,hmac-sha1,umac-64@openssh.com,
|
||||
hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,
|
||||
umac-64-etm@openssh.com,umac-128-etm@openssh.com,
|
||||
hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
|
||||
hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,
|
||||
hmac-md5-96-etm@openssh.com,
|
||||
hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,
|
||||
hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,
|
||||
hmac-sha1-96,hmac-md5-96
|
||||
.Ed
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshconnect.c,v 1.234 2011/05/24 07:15:47 djm Exp $ */
|
||||
/* $OpenBSD: sshconnect.c,v 1.236 2012/09/14 16:51:34 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -419,6 +419,24 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
send_client_banner(int connection_out, int minor1)
|
||||
{
|
||||
/* Send our own protocol version identification. */
|
||||
if (compat20) {
|
||||
xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n",
|
||||
PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);
|
||||
} else {
|
||||
xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n",
|
||||
PROTOCOL_MAJOR_1, minor1, SSH_VERSION);
|
||||
}
|
||||
if (roaming_atomicio(vwrite, connection_out, client_version_string,
|
||||
strlen(client_version_string)) != strlen(client_version_string))
|
||||
fatal("write: %.100s", strerror(errno));
|
||||
chop(client_version_string);
|
||||
debug("Local version string %.100s", client_version_string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Waits for the server identification string, and sends our own
|
||||
* identification string.
|
||||
|
@ -430,7 +448,7 @@ ssh_exchange_identification(int timeout_ms)
|
|||
int remote_major, remote_minor, mismatch;
|
||||
int connection_in = packet_get_connection_in();
|
||||
int connection_out = packet_get_connection_out();
|
||||
int minor1 = PROTOCOL_MINOR_1;
|
||||
int minor1 = PROTOCOL_MINOR_1, client_banner_sent = 0;
|
||||
u_int i, n;
|
||||
size_t len;
|
||||
int fdsetsz, remaining, rc;
|
||||
|
@ -440,6 +458,16 @@ ssh_exchange_identification(int timeout_ms)
|
|||
fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);
|
||||
fdset = xcalloc(1, fdsetsz);
|
||||
|
||||
/*
|
||||
* If we are SSH2-only then we can send the banner immediately and
|
||||
* save a round-trip.
|
||||
*/
|
||||
if (options.protocol == SSH_PROTO_2) {
|
||||
enable_compat20();
|
||||
send_client_banner(connection_out, 0);
|
||||
client_banner_sent = 1;
|
||||
}
|
||||
|
||||
/* Read other side's version identification. */
|
||||
remaining = timeout_ms;
|
||||
for (n = 0;;) {
|
||||
|
@ -542,18 +570,9 @@ ssh_exchange_identification(int timeout_ms)
|
|||
fatal("Protocol major versions differ: %d vs. %d",
|
||||
(options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
|
||||
remote_major);
|
||||
/* Send our own protocol version identification. */
|
||||
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s",
|
||||
compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
|
||||
compat20 ? PROTOCOL_MINOR_2 : minor1,
|
||||
SSH_VERSION, compat20 ? "\r\n" : "\n");
|
||||
if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf))
|
||||
!= strlen(buf))
|
||||
fatal("write: %.100s", strerror(errno));
|
||||
client_version_string = xstrdup(buf);
|
||||
chop(client_version_string);
|
||||
if (!client_banner_sent)
|
||||
send_client_banner(connection_out, minor1);
|
||||
chop(server_version_string);
|
||||
debug("Local version string %.100s", client_version_string);
|
||||
}
|
||||
|
||||
/* defaults to 'no' */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshconnect2.c,v 1.189 2012/06/22 12:30:26 dtucker Exp $ */
|
||||
/* $OpenBSD: sshconnect2.c,v 1.191 2013/02/15 00:21:01 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
|
@ -242,6 +242,7 @@ struct identity {
|
|||
char *filename; /* comment for agent-only keys */
|
||||
int tried;
|
||||
int isprivate; /* key points to the private key */
|
||||
int userprovided;
|
||||
};
|
||||
TAILQ_HEAD(idlist, identity);
|
||||
|
||||
|
@ -306,7 +307,7 @@ void userauth(Authctxt *, char *);
|
|||
static int sign_and_send_pubkey(Authctxt *, Identity *);
|
||||
static void pubkey_prepare(Authctxt *);
|
||||
static void pubkey_cleanup(Authctxt *);
|
||||
static Key *load_identity_file(char *);
|
||||
static Key *load_identity_file(char *, int);
|
||||
|
||||
static Authmethod *authmethod_get(char *authlist);
|
||||
static Authmethod *authmethod_lookup(const char *name);
|
||||
|
@ -1180,7 +1181,7 @@ identity_sign(Identity *id, u_char **sigp, u_int *lenp,
|
|||
if (id->isprivate || (id->key->flags & KEY_FLAG_EXT))
|
||||
return (key_sign(id->key, sigp, lenp, data, datalen));
|
||||
/* load the private key from the file */
|
||||
if ((prv = load_identity_file(id->filename)) == NULL)
|
||||
if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL)
|
||||
return (-1);
|
||||
ret = key_sign(prv, sigp, lenp, data, datalen);
|
||||
key_free(prv);
|
||||
|
@ -1305,7 +1306,7 @@ send_pubkey_test(Authctxt *authctxt, Identity *id)
|
|||
}
|
||||
|
||||
static Key *
|
||||
load_identity_file(char *filename)
|
||||
load_identity_file(char *filename, int userprovided)
|
||||
{
|
||||
Key *private;
|
||||
char prompt[300], *passphrase;
|
||||
|
@ -1313,7 +1314,8 @@ load_identity_file(char *filename)
|
|||
struct stat st;
|
||||
|
||||
if (stat(filename, &st) < 0) {
|
||||
debug3("no such identity: %s", filename);
|
||||
(userprovided ? logit : debug3)("no such identity: %s: %s",
|
||||
filename, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok);
|
||||
|
@ -1353,7 +1355,7 @@ load_identity_file(char *filename)
|
|||
static void
|
||||
pubkey_prepare(Authctxt *authctxt)
|
||||
{
|
||||
Identity *id;
|
||||
Identity *id, *id2, *tmp;
|
||||
Idlist agent, files, *preferred;
|
||||
Key *key;
|
||||
AuthenticationConnection *ac;
|
||||
|
@ -1365,7 +1367,7 @@ pubkey_prepare(Authctxt *authctxt)
|
|||
preferred = &authctxt->keys;
|
||||
TAILQ_INIT(preferred); /* preferred order of keys */
|
||||
|
||||
/* list of keys stored in the filesystem */
|
||||
/* list of keys stored in the filesystem and PKCS#11 */
|
||||
for (i = 0; i < options.num_identity_files; i++) {
|
||||
key = options.identity_keys[i];
|
||||
if (key && key->type == KEY_RSA1)
|
||||
|
@ -1376,8 +1378,32 @@ pubkey_prepare(Authctxt *authctxt)
|
|||
id = xcalloc(1, sizeof(*id));
|
||||
id->key = key;
|
||||
id->filename = xstrdup(options.identity_files[i]);
|
||||
id->userprovided = 1;
|
||||
TAILQ_INSERT_TAIL(&files, id, next);
|
||||
}
|
||||
/* Prefer PKCS11 keys that are explicitly listed */
|
||||
TAILQ_FOREACH_SAFE(id, &files, next, tmp) {
|
||||
if (id->key == NULL || (id->key->flags & KEY_FLAG_EXT) == 0)
|
||||
continue;
|
||||
found = 0;
|
||||
TAILQ_FOREACH(id2, &files, next) {
|
||||
if (id2->key == NULL ||
|
||||
(id2->key->flags & KEY_FLAG_EXT) != 0)
|
||||
continue;
|
||||
if (key_equal(id->key, id2->key)) {
|
||||
TAILQ_REMOVE(&files, id, next);
|
||||
TAILQ_INSERT_TAIL(preferred, id, next);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If IdentitiesOnly set and key not found then don't use it */
|
||||
if (!found && options.identities_only) {
|
||||
TAILQ_REMOVE(&files, id, next);
|
||||
bzero(id, sizeof(id));
|
||||
free(id);
|
||||
}
|
||||
}
|
||||
/* list of keys supported by the agent */
|
||||
if ((ac = ssh_get_authentication_connection())) {
|
||||
for (key = ssh_get_first_identity(ac, &comment, 2);
|
||||
|
@ -1417,7 +1443,8 @@ pubkey_prepare(Authctxt *authctxt)
|
|||
TAILQ_INSERT_TAIL(preferred, id, next);
|
||||
}
|
||||
TAILQ_FOREACH(id, preferred, next) {
|
||||
debug2("key: %s (%p)", id->filename, id->key);
|
||||
debug2("key: %s (%p),%s", id->filename, id->key,
|
||||
id->userprovided ? " explicit" : "");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1462,7 +1489,8 @@ userauth_pubkey(Authctxt *authctxt)
|
|||
sent = send_pubkey_test(authctxt, id);
|
||||
} else if (id->key == NULL) {
|
||||
debug("Trying private key: %s", id->filename);
|
||||
id->key = load_identity_file(id->filename);
|
||||
id->key = load_identity_file(id->filename,
|
||||
id->userprovided);
|
||||
if (id->key != NULL) {
|
||||
id->isprivate = 1;
|
||||
sent = sign_and_send_pubkey(authctxt, id);
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd.8,v 1.266 2012/06/18 12:07:07 dtucker Exp $
|
||||
.Dd $Mdocdate: June 18 2012 $
|
||||
.\" $OpenBSD: sshd.8,v 1.267 2012/10/04 13:21:50 markus Exp $
|
||||
.Dd $Mdocdate: October 4 2012 $
|
||||
.Dt SSHD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -316,7 +316,7 @@ The client selects the encryption algorithm
|
|||
to use from those offered by the server.
|
||||
Additionally, session integrity is provided
|
||||
through a cryptographic message authentication code
|
||||
(hmac-md5, hmac-sha1, umac-64, hmac-ripemd160,
|
||||
(hmac-md5, hmac-sha1, umac-64, umac-128, hmac-ripemd160,
|
||||
hmac-sha2-256 or hmac-sha2-512).
|
||||
.Pp
|
||||
Finally, the server and the client enter an authentication dialog.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshd.c,v 1.393 2012/07/10 02:19:15 djm Exp $ */
|
||||
/* $OpenBSD: sshd.c,v 1.397 2013/02/11 21:21:58 dtucker Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -339,6 +339,15 @@ grace_alarm_handler(int sig)
|
|||
if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0)
|
||||
kill(pmonitor->m_pid, SIGALRM);
|
||||
|
||||
/*
|
||||
* Try to kill any processes that we have spawned, E.g. authorized
|
||||
* keys command helpers.
|
||||
*/
|
||||
if (getpgid(0) == getpid()) {
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
killpg(0, SIGTERM);
|
||||
}
|
||||
|
||||
/* Log error and exit. */
|
||||
sigdie("Timeout before authentication for %s", get_remote_ipaddr());
|
||||
}
|
||||
|
@ -1293,6 +1302,7 @@ main(int ac, char **av)
|
|||
int remote_port;
|
||||
char *line;
|
||||
int config_s[2] = { -1 , -1 };
|
||||
u_int n;
|
||||
u_int64_t ibytes, obytes;
|
||||
mode_t new_umask;
|
||||
Key *key;
|
||||
|
@ -1481,6 +1491,33 @@ main(int ac, char **av)
|
|||
if (options.challenge_response_authentication)
|
||||
options.kbd_interactive_authentication = 1;
|
||||
|
||||
/* Check that options are sensible */
|
||||
if (options.authorized_keys_command_user == NULL &&
|
||||
(options.authorized_keys_command != NULL &&
|
||||
strcasecmp(options.authorized_keys_command, "none") != 0))
|
||||
fatal("AuthorizedKeysCommand set without "
|
||||
"AuthorizedKeysCommandUser");
|
||||
|
||||
/*
|
||||
* Check whether there is any path through configured auth methods.
|
||||
* Unfortunately it is not possible to verify this generally before
|
||||
* daemonisation in the presence of Match block, but this catches
|
||||
* and warns for trivial misconfigurations that could break login.
|
||||
*/
|
||||
if (options.num_auth_methods != 0) {
|
||||
if ((options.protocol & SSH_PROTO_1))
|
||||
fatal("AuthenticationMethods is not supported with "
|
||||
"SSH protocol 1");
|
||||
for (n = 0; n < options.num_auth_methods; n++) {
|
||||
if (auth2_methods_valid(options.auth_methods[n],
|
||||
1) == 0)
|
||||
break;
|
||||
}
|
||||
if (n >= options.num_auth_methods)
|
||||
fatal("AuthenticationMethods cannot be satisfied by "
|
||||
"enabled authentication methods");
|
||||
}
|
||||
|
||||
/* set default channel AF */
|
||||
channel_set_af(options.address_family);
|
||||
|
||||
|
@ -1490,7 +1527,8 @@ main(int ac, char **av)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
debug("sshd version %.100s", SSH_VERSION);
|
||||
debug("sshd version %s, %s", SSH_VERSION,
|
||||
SSLeay_version(SSLEAY_VERSION));
|
||||
|
||||
/* load private host keys */
|
||||
sensitive_data.host_keys = xcalloc(options.num_host_key_files,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: sshd_config,v 1.87 2012/07/10 02:19:15 djm Exp $
|
||||
# $OpenBSD: sshd_config,v 1.89 2013/02/06 00:20:42 dtucker Exp $
|
||||
|
||||
# This is the sshd server system-wide configuration file. See
|
||||
# sshd_config(5) for more information.
|
||||
|
@ -49,6 +49,9 @@ AuthorizedKeysFile .ssh/authorized_keys
|
|||
|
||||
#AuthorizedPrincipalsFile none
|
||||
|
||||
#AuthorizedKeysCommand none
|
||||
#AuthorizedKeysCommandUser nobody
|
||||
|
||||
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
|
||||
#RhostsRSAAuthentication no
|
||||
# similar for protocol version 2
|
||||
|
@ -93,7 +96,7 @@ UsePrivilegeSeparation sandbox # Default for new installations.
|
|||
#ClientAliveCountMax 3
|
||||
#UseDNS yes
|
||||
#PidFile /var/run/sshd.pid
|
||||
#MaxStartups 10
|
||||
#MaxStartups 10:30:100
|
||||
#PermitTunnel no
|
||||
#ChrootDirectory none
|
||||
#VersionAddendum none
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd_config.5,v 1.144 2012/06/29 13:57:25 naddy Exp $
|
||||
.Dd $Mdocdate: June 29 2012 $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.156 2013/02/06 00:20:42 dtucker Exp $
|
||||
.Dd $Mdocdate: February 6 2013 $
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -124,6 +124,19 @@ in
|
|||
for more information on patterns.
|
||||
.It Cm AllowTcpForwarding
|
||||
Specifies whether TCP forwarding is permitted.
|
||||
The available options are
|
||||
.Dq yes
|
||||
or
|
||||
.Dq all
|
||||
to allow TCP forwarding,
|
||||
.Dq no
|
||||
to prevent all TCP forwarding,
|
||||
.Dq local
|
||||
to allow local (from the perspective of
|
||||
.Xr ssh 1 )
|
||||
forwarding only or
|
||||
.Dq remote
|
||||
to allow remote forwarding only.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that disabling TCP forwarding does not improve security unless
|
||||
|
@ -151,6 +164,45 @@ See
|
|||
in
|
||||
.Xr ssh_config 5
|
||||
for more information on patterns.
|
||||
.It Cm AuthenticationMethods
|
||||
Specifies the authentication methods that must be successfully completed
|
||||
for a user to be granted access.
|
||||
This option must be followed by one or more comma-separated lists of
|
||||
authentication method names.
|
||||
Successful authentication requires completion of every method in at least
|
||||
one of these lists.
|
||||
.Pp
|
||||
For example, an argument of
|
||||
.Dq publickey,password publickey,keyboard-interactive
|
||||
would require the user to complete public key authentication, followed by
|
||||
either password or keyboard interactive authentication.
|
||||
Only methods that are next in one or more lists are offered at each stage,
|
||||
so for this example, it would not be possible to attempt password or
|
||||
keyboard-interactive authentication before public key.
|
||||
.Pp
|
||||
This option is only available for SSH protocol 2 and will yield a fatal
|
||||
error if enabled if protocol 1 is also enabled.
|
||||
Note that each authentication method listed should also be explicitly enabled
|
||||
in the configuration.
|
||||
The default is not to require multiple authentication; successful completion
|
||||
of a single authentication method is sufficient.
|
||||
.It Cm AuthorizedKeysCommand
|
||||
Specifies a program to be used to look up the user's public keys.
|
||||
The program will be invoked with a single argument of the username
|
||||
being authenticated, and should produce on standard output zero or
|
||||
more lines of authorized_keys output (see
|
||||
.Sx AUTHORIZED_KEYS
|
||||
in
|
||||
.Xr sshd 8 ) .
|
||||
If a key supplied by AuthorizedKeysCommand does not successfully authenticate
|
||||
and authorize the user then public key authentication continues using the usual
|
||||
.Cm AuthorizedKeysFile
|
||||
files.
|
||||
By default, no AuthorizedKeysCommand is run.
|
||||
.It Cm AuthorizedKeysCommandUser
|
||||
Specifies the user under whose account the AuthorizedKeysCommand is run.
|
||||
It is recommended to use a dedicated user that has no other role on the host
|
||||
than running authorized keys commands.
|
||||
.It Cm AuthorizedKeysFile
|
||||
Specifies the file that contains the public keys that can be used
|
||||
for user authentication.
|
||||
|
@ -285,6 +337,8 @@ The supported ciphers are
|
|||
.Dq aes128-ctr ,
|
||||
.Dq aes192-ctr ,
|
||||
.Dq aes256-ctr ,
|
||||
.Dq aes128-gcm@openssh.com ,
|
||||
.Dq aes256-gcm@openssh.com ,
|
||||
.Dq arcfour128 ,
|
||||
.Dq arcfour256 ,
|
||||
.Dq arcfour ,
|
||||
|
@ -294,6 +348,7 @@ and
|
|||
The default is:
|
||||
.Bd -literal -offset 3n
|
||||
aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,
|
||||
aes128-gcm@openssh.com,aes256-gcm@openssh.com,
|
||||
aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,
|
||||
aes256-cbc,arcfour
|
||||
.Ed
|
||||
|
@ -655,9 +710,18 @@ Specifies the available MAC (message authentication code) algorithms.
|
|||
The MAC algorithm is used in protocol version 2
|
||||
for data integrity protection.
|
||||
Multiple algorithms must be comma-separated.
|
||||
The algorithms that contain
|
||||
.Dq -etm
|
||||
calculate the MAC after encryption (encrypt-then-mac).
|
||||
These are considered safer and their use recommended.
|
||||
The default is:
|
||||
.Bd -literal -offset indent
|
||||
hmac-md5,hmac-sha1,umac-64@openssh.com,
|
||||
hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,
|
||||
umac-64-etm@openssh.com,umac-128-etm@openssh.com,
|
||||
hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
|
||||
hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,
|
||||
hmac-md5-96-etm@openssh.com,
|
||||
hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,
|
||||
hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,
|
||||
hmac-sha1-96,hmac-md5-96
|
||||
.Ed
|
||||
|
@ -712,6 +776,9 @@ Available keywords are
|
|||
.Cm AllowGroups ,
|
||||
.Cm AllowTcpForwarding ,
|
||||
.Cm AllowUsers ,
|
||||
.Cm AuthenticationMethods ,
|
||||
.Cm AuthorizedKeysCommand ,
|
||||
.Cm AuthorizedKeysCommandUser ,
|
||||
.Cm AuthorizedKeysFile ,
|
||||
.Cm AuthorizedPrincipalsFile ,
|
||||
.Cm Banner ,
|
||||
|
@ -754,7 +821,7 @@ SSH daemon.
|
|||
Additional connections will be dropped until authentication succeeds or the
|
||||
.Cm LoginGraceTime
|
||||
expires for a connection.
|
||||
The default is 10.
|
||||
The default is 10:30:100.
|
||||
.Pp
|
||||
Alternatively, random early drop can be enabled by specifying
|
||||
the three colon separated values
|
||||
|
@ -928,10 +995,17 @@ The default is
|
|||
.Dq yes .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm RevokedKeys
|
||||
Specifies a list of revoked public keys.
|
||||
Specifies revoked public keys.
|
||||
Keys listed in this file will be refused for public key authentication.
|
||||
Note that if this file is not readable, then public key authentication will
|
||||
be refused for all users.
|
||||
Keys may be specified as a text file, listing one public key per line, or as
|
||||
an OpenSSH Key Revocation List (KRL) as generated by
|
||||
.Xr ssh-keygen 1 .
|
||||
For more information on KRLs, see the
|
||||
.Sx KEY REVOCATION LISTS
|
||||
section in
|
||||
.Xr ssh-keygen 1 .
|
||||
.It Cm RhostsRSAAuthentication
|
||||
Specifies whether rhosts or /etc/hosts.equiv authentication together
|
||||
with successful RSA host authentication is allowed.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: umac.h,v 1.1 2007/06/07 19:37:34 pvalchev Exp $ */
|
||||
/* $OpenBSD: umac.h,v 1.2 2012/10/04 13:21:50 markus Exp $ */
|
||||
/* -----------------------------------------------------------------------
|
||||
*
|
||||
* umac.h -- C Implementation UMAC Message Authentication
|
||||
|
@ -116,6 +116,12 @@ int uhash(uhash_ctx_t ctx,
|
|||
|
||||
#endif
|
||||
|
||||
/* matching umac-128 API, we reuse umac_ctx, since it's opaque */
|
||||
struct umac_ctx *umac128_new(u_char key[]);
|
||||
int umac128_update(struct umac_ctx *ctx, u_char *input, long len);
|
||||
int umac128_final(struct umac_ctx *ctx, u_char tag[], u_char nonce[8]);
|
||||
int umac128_delete(struct umac_ctx *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
/* $OpenBSD: version.h,v 1.65 2012/07/22 18:19:21 markus Exp $ */
|
||||
/* $OpenBSD: version.h,v 1.66 2013/02/10 21:19:34 markus Exp $ */
|
||||
|
||||
#define SSH_VERSION "OpenSSH_6.1"
|
||||
#define SSH_VERSION "OpenSSH_6.2"
|
||||
|
|
Loading…
Reference in New Issue