Merge remote-tracking branch 'openssh/master' into latestw

This commit is contained in:
Manoj Ampalam 2017-06-07 21:46:18 -07:00
commit f7e6475b96
76 changed files with 989 additions and 1531 deletions

1
.gitignore vendored
View File

@ -10,6 +10,7 @@ openbsd-compat/regress/Makefile
openssh.xml
opensshd.init
survey.sh
**/*.0
**/*.o
**/*.out
**/*.a

View File

@ -16,3 +16,4 @@ f6ae971186ba68d066cd102e57d5b0b2c211a5ee systrace is dead.
1e6b51ddf767cbad0a4e63eb08026c127e654308 integrity.sh reliability
fe5b31f69a60d47171836911f144acff77810217 Makefile.inc bits
5781670c0578fe89663c9085ed3ba477cf7e7913 Delete sshconnect1.c
ea80f445e819719ccdcb237022cacfac990fdc5c Makefile.inc warning flags

View File

@ -33,8 +33,8 @@ The method is documented in:
https://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
1.3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com",
"ssh-dsa-cert-v00@openssh.com",
1.3. transport: New public key algorithms "ssh-rsa-cert-v01@openssh.com",
"ssh-dsa-cert-v01@openssh.com",
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
"ecdsa-sha2-nistp384-cert-v01@openssh.com" and
"ecdsa-sha2-nistp521-cert-v01@openssh.com"
@ -454,4 +454,4 @@ respond with a SSH_FXP_STATUS message.
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".
$OpenBSD: PROTOCOL,v 1.30 2016/04/08 06:35:54 djm Exp $
$OpenBSD: PROTOCOL,v 1.31 2017/05/26 01:40:07 djm Exp $

View File

@ -1,582 +1,3 @@
This describes the protocol used by OpenSSH's ssh-agent.
OpenSSH's agent supports managing keys for the standard SSH protocol
2 as well as the legacy SSH protocol 1. Support for these key types
is almost completely disjoint - in all but a few cases, operations on
protocol 2 keys cannot see or affect protocol 1 keys and vice-versa.
Protocol 1 and protocol 2 keys are separated because of the differing
cryptographic usage: protocol 1 private RSA keys are used to decrypt
challenges that were encrypted with the corresponding public key,
whereas protocol 2 RSA private keys are used to sign challenges with
a private key for verification with the corresponding public key. It
is considered unsound practice to use the same key for signing and
encryption.
With a couple of exceptions, the protocol message names used in this
document indicate which type of key the message relates to. SSH_*
messages refer to protocol 1 keys only. SSH2_* messages refer to
protocol 2 keys. Furthermore, the names also indicate whether the
message is a request to the agent (*_AGENTC_*) or a reply from the
agent (*_AGENT_*). Section 3 below contains the mapping of the
protocol message names to their integer values.
1. Data types
Because of support for legacy SSH protocol 1 keys, OpenSSH's agent
protocol makes use of some data types not defined in RFC 4251.
1.1 uint16
The "uint16" data type is a simple MSB-first 16 bit unsigned integer
encoded in two bytes.
1.2 mpint1
The "mpint1" type represents an arbitrary precision integer (bignum).
Its format is as follows:
uint16 bits
byte[(bits + 7) / 8] bignum
"bignum" contains an unsigned arbitrary precision integer encoded as
eight bits per byte in big-endian (MSB first) format.
Note the difference between the "mpint1" encoding and the "mpint"
encoding defined in RFC 4251. Also note that the length of the encoded
integer is specified in bits, not bytes and that the byte length of
the integer must be calculated by rounding up the number of bits to the
nearest eight.
2. Protocol Messages
All protocol messages are prefixed with their length in bytes, encoded
as a 32 bit unsigned integer. Specifically:
uint32 message_length
byte[message_length] message
The following message descriptions refer only to the content the
"message" field.
2.1 Generic server responses
The following generic messages may be sent by the server in response to
requests from the client. On success the agent may reply either with:
byte SSH_AGENT_SUCCESS
or a request-specific success message.
On failure, the agent may reply with:
byte SSH_AGENT_FAILURE
SSH_AGENT_FAILURE messages are also sent in reply to unknown request
types.
2.2 Adding keys to the agent
Keys are added to the agent using the SSH_AGENTC_ADD_RSA_IDENTITY and
SSH2_AGENTC_ADD_IDENTITY requests for protocol 1 and protocol 2 keys
respectively.
Two variants of these requests are SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
and SSH2_AGENTC_ADD_ID_CONSTRAINED - these add keys with optional
"constraints" on their usage.
OpenSSH may be built with support for keys hosted on a smartcard
or other hardware security module. These keys may be added
to the agent using the SSH_AGENTC_ADD_SMARTCARD_KEY and
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED requests.
2.2.1 Key constraints
The OpenSSH agent supports some basic optional constraints on key usage.
At present there are two constraints defined.
The first constraint limits the validity duration of a key. It is
encoded as:
byte SSH_AGENT_CONSTRAIN_LIFETIME
uint32 seconds
Where "seconds" contains the number of seconds that the key shall remain
valid measured from the moment that the agent receives it. After the
validity period has expired, OpenSSH's agent will erase these keys from
memory.
The second constraint requires the agent to seek explicit user
confirmation before performing private key operations with the loaded
key. This constraint is encoded as:
byte SSH_AGENT_CONSTRAIN_CONFIRM
Zero or more constraints may be specified when adding a key with one
of the *_CONSTRAINED requests. Multiple constraints are appended
consecutively to the end of the request:
byte constraint1_type
.... constraint1_data
byte constraint2_type
.... constraint2_data
....
byte constraintN_type
.... constraintN_data
Such a sequence of zero or more constraints will be referred to below
as "constraint[]". Agents may determine whether there are constraints
by checking whether additional data exists in the "add key" request
after the key data itself. OpenSSH will refuse to add a key if it
contains unknown constraints.
2.2.2 Add protocol 1 key
A client may add a protocol 1 key to an agent with the following
request:
byte SSH_AGENTC_ADD_RSA_IDENTITY or
SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
uint32 ignored
mpint1 rsa_n
mpint1 rsa_e
mpint1 rsa_d
mpint1 rsa_iqmp
mpint1 rsa_q
mpint1 rsa_p
string key_comment
constraint[] key_constraints
Note that there is some redundancy in the key parameters; a key could be
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_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.
2.2.3 Add protocol 2 key
The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA
keys may be added using the following request
byte SSH2_AGENTC_ADD_IDENTITY or
SSH2_AGENTC_ADD_ID_CONSTRAINED
string "ssh-dss"
mpint dsa_p
mpint dsa_q
mpint dsa_g
mpint dsa_public_key
mpint dsa_private_key
string key_comment
constraint[] key_constraints
DSA certificates may be added with:
byte SSH2_AGENTC_ADD_IDENTITY or
SSH2_AGENTC_ADD_ID_CONSTRAINED
string "ssh-dss-cert-v00@openssh.com"
string certificate
mpint dsa_private_key
string key_comment
constraint[] key_constraints
ECDSA keys may be added using the following request
byte SSH2_AGENTC_ADD_IDENTITY or
SSH2_AGENTC_ADD_ID_CONSTRAINED
string "ecdsa-sha2-nistp256" |
"ecdsa-sha2-nistp384" |
"ecdsa-sha2-nistp521"
string ecdsa_curve_name
string ecdsa_public_key
mpint ecdsa_private
string key_comment
constraint[] key_constraints
ECDSA certificates may be added with:
byte SSH2_AGENTC_ADD_IDENTITY or
SSH2_AGENTC_ADD_ID_CONSTRAINED
string "ecdsa-sha2-nistp256-cert-v01@openssh.com" |
"ecdsa-sha2-nistp384-cert-v01@openssh.com" |
"ecdsa-sha2-nistp521-cert-v01@openssh.com"
string certificate
mpint ecdsa_private_key
string key_comment
constraint[] key_constraints
ED25519 keys may be added using the following request
byte SSH2_AGENTC_ADD_IDENTITY or
SSH2_AGENTC_ADD_ID_CONSTRAINED
string "ssh-ed25519"
string ed25519_public_key
string ed25519_private_key || ed25519_public_key
string key_comment
constraint[] key_constraints
ED25519 certificates may be added with:
byte SSH2_AGENTC_ADD_IDENTITY or
SSH2_AGENTC_ADD_ID_CONSTRAINED
string "ssh-ed25519-cert-v01@openssh.com"
string certificate
string ed25519_public_key
string ed25519_private_key || ed25519_public_key
string key_comment
constraint[] key_constraints
For both ssh-ed25519 and ssh-ed25519-cert-v01@openssh.com keys, the private
key has the public key appended (for historical reasons).
RSA keys may be added with this request:
byte SSH2_AGENTC_ADD_IDENTITY or
SSH2_AGENTC_ADD_ID_CONSTRAINED
string "ssh-rsa"
mpint rsa_n
mpint rsa_e
mpint rsa_d
mpint rsa_iqmp
mpint rsa_p
mpint rsa_q
string key_comment
constraint[] key_constraints
RSA certificates may be added with this request:
byte SSH2_AGENTC_ADD_IDENTITY or
SSH2_AGENTC_ADD_ID_CONSTRAINED
string "ssh-rsa-cert-v00@openssh.com"
string certificate
mpint rsa_d
mpint rsa_iqmp
mpint rsa_p
mpint rsa_q
string key_comment
constraint[] key_constraints
Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse
order to the protocol 1 add keys message. As with the corresponding
protocol 1 "add key" request, the private key is overspecified to avoid
redundant processing.
For DSA, ECDSA and RSA key add requests, "key_constraints" may only be
present if the request type is SSH2_AGENTC_ADD_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.
2.2.4 Loading keys from a smartcard
The OpenSSH agent may have optional smartcard support built in to it. If
so, it supports an operation to load keys from a smartcard. Technically,
only the public components of the keys are loaded into the agent so
this operation really arranges for future private key operations to be
delegated to the smartcard.
byte SSH_AGENTC_ADD_SMARTCARD_KEY or
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
string reader_id
string pin
constraint[] key_constraints
"reader_id" is an identifier to a smartcard reader and "pin"
is a PIN or passphrase used to unlock the private key(s) on the
device. "key_constraints" may only be present if the request type is
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED.
This operation may load all SSH keys that are unlocked using the
"pin" on the specified reader. The type of key loaded (protocol 1
or protocol 2) will be specified by the smartcard itself, it is not
client-specified.
The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
been successfully loaded or a SSH_AGENT_FAILURE if an error occurred.
The agent will also return SSH_AGENT_FAILURE if it does not support
smartcards.
2.3 Removing multiple keys
A client may request that an agent delete all protocol 1 keys using the
following request:
byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES
This message requests the deletion of all protocol 2 keys:
byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES
On success, the agent will delete all keys of the requested type and
reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent
will reply with SSH_AGENT_FAILURE.
Note that, to delete all keys (both protocol 1 and 2), a client
must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a
SSH2_AGENTC_REMOVE_ALL_IDENTITIES request.
2.4 Removing specific keys
2.4.1 Removing a protocol 1 key
Removal of a protocol 1 key may be requested with the following message:
byte SSH_AGENTC_REMOVE_RSA_IDENTITY
uint32 key_bits
mpint1 rsa_e
mpint1 rsa_n
Note that key_bits is strictly redundant, as it may be inferred by the
length of rsa_n.
The agent will delete any private key matching the specified public key
and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
return SSH_AGENT_FAILURE.
2.4.2 Removing a protocol 2 key
Protocol 2 keys may be removed with the following request:
byte SSH2_AGENTC_REMOVE_IDENTITY
string key_blob
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
Algorithms" for any of the supported protocol 2 key types.
The agent will delete any private key matching the specified public key
and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
return SSH_AGENT_FAILURE.
2.4.3 Removing keys loaded from a smartcard
A client may request that a server remove one or more smartcard-hosted
keys using this message:
byte SSH_AGENTC_REMOVE_SMARTCARD_KEY
string reader_id
string pin
"reader_id" the an identifier to a smartcard reader and "pin" is a PIN
or passphrase used to unlock the private key(s) on the device.
When this message is received, and if the agent supports
smartcard-hosted keys, it will delete all keys that are hosted on the
specified smartcard that may be accessed with the given "pin".
The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
been successfully removed or a SSH_AGENT_FAILURE if an error occurred.
The agent will also return SSH_AGENT_FAILURE if it does not support
smartcards.
2.5 Requesting a list of known keys
An agent may be requested to list which keys it holds. Different
requests exist for protocol 1 and protocol 2 keys.
2.5.1 Requesting a list of protocol 1 keys
To request a list of protocol 1 keys that are held in the agent, a
client may send the following message:
byte SSH_AGENTC_REQUEST_RSA_IDENTITIES
The agent will reply with the following message:
byte SSH_AGENT_RSA_IDENTITIES_ANSWER
uint32 num_keys
Followed by zero or more consecutive keys, encoded as:
uint32 bits
mpint1 rsa_e
mpint1 rsa_n
string key_comment
2.5.2 Requesting a list of protocol 2 keys
A client may send the following message to request a list of
protocol 2 keys that are stored in the agent:
byte SSH2_AGENTC_REQUEST_IDENTITIES
The agent will reply with the following message header:
byte SSH2_AGENT_IDENTITIES_ANSWER
uint32 num_keys
Followed by zero or more consecutive keys, encoded as:
string key_blob
string key_comment
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
Algorithms" for any of the supported protocol 2 key types.
2.6 Private key operations
The purpose of the agent is to perform private key operations, such as
signing and encryption without requiring a passphrase to unlock the
key and without allowing the private key itself to be exposed. There
are separate requests for the protocol 1 and protocol 2 private key
operations.
2.6.1 Protocol 1 private key challenge
The private key operation used in version 1 of the SSH protocol is
decrypting a challenge that has been encrypted with a public key.
It may be requested using this message:
byte SSH_AGENTC_RSA_CHALLENGE
uint32 ignored
mpint1 rsa_e
mpint1 rsa_n
mpint1 encrypted_challenge
byte[16] session_id
uint32 response_type /* must be 1 */
"rsa_e" and "rsa_n" are used to identify which private key to use.
"encrypted_challenge" is a challenge blob that has (presumably)
been encrypted with the public key and must be in the range
1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1
session ID (computed from the server host key, the server semi-ephemeral
key and the session cookie).
"ignored" and "response_type" exist for compatibility with legacy
implementations. "response_type" must be equal to 1; other response
types are not supported.
On receiving this request, the server decrypts the "encrypted_challenge"
using the private key matching the supplied (rsa_e, rsa_n) values. For
the response derivation, the decrypted challenge is represented as an
unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values
smaller than 2^248 will have leading 0 bytes).
The response value is then calculated as:
response = MD5(decrypted_challenge || session_id)
and returned in the following message
byte SSH_AGENT_RSA_RESPONSE
byte[16] response
If the agent cannot find the key specified by the supplied (rsa_e,
rsa_n) then it will return SSH_AGENT_FAILURE.
2.6.2 Protocol 2 private key signature request
A client may use the following message to request signing of data using
a protocol 2 key:
byte SSH2_AGENTC_SIGN_REQUEST
string key_blob
string data
uint32 flags
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
Algorithms" for any of the supported protocol 2 key types. "flags" is
a bit-mask, but at present only one possible value is defined (see below
for its meaning):
SSH_AGENT_OLD_SIGNATURE 1
Upon receiving this request, the agent will look up the private key that
corresponds to the public key contained in key_blob. It will use this
private key to sign the "data" and produce a signature blob using the
key type-specific method described in RFC 4253 section 6.6 "Public Key
Algorithms".
An exception to this is for "ssh-dss" keys where the "flags" word
contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy
signature encoding is used in lieu of the standard one. In this case,
the DSA signature blob is encoded as:
byte[40] signature
The signature will be returned in the response message:
byte SSH2_AGENT_SIGN_RESPONSE
string signature_blob
If the agent cannot find the key specified by the supplied key_blob then
it will return SSH_AGENT_FAILURE.
2.7 Locking or unlocking an agent
The agent supports temporary locking with a passphrase to suspend
processing of sensitive operations until it has been unlocked with the
same passphrase. To lock an agent, a client send the following request:
byte SSH_AGENTC_LOCK
string passphrase
Upon receipt of this message and if the agent is not already locked,
it will suspend processing requests and return a SSH_AGENT_SUCCESS
reply. If the agent is already locked, it will return SSH_AGENT_FAILURE.
While locked, the agent will refuse all requests except
SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and
SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are
treated specially by a locked agent: it will always return an empty list
of keys.
To unlock an agent, a client may request:
byte SSH_AGENTC_UNLOCK
string passphrase
If the passphrase matches and the agent is locked, then it will resume
processing all requests and return SSH_AGENT_SUCCESS. If the agent
is not locked or the passphrase does not match then it will return
SSH_AGENT_FAILURE.
Locking and unlocking affects both protocol 1 and protocol 2 keys.
3. Protocol message numbers
3.1 Requests from client to agent for protocol 1 key operations
SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
SSH_AGENTC_RSA_CHALLENGE 3
SSH_AGENTC_ADD_RSA_IDENTITY 7
SSH_AGENTC_REMOVE_RSA_IDENTITY 8
SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
3.2 Requests from client to agent for protocol 2 key operations
SSH2_AGENTC_REQUEST_IDENTITIES 11
SSH2_AGENTC_SIGN_REQUEST 13
SSH2_AGENTC_ADD_IDENTITY 17
SSH2_AGENTC_REMOVE_IDENTITY 18
SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
SSH2_AGENTC_ADD_ID_CONSTRAINED 25
3.3 Key-type independent requests from client to agent
SSH_AGENTC_ADD_SMARTCARD_KEY 20
SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
SSH_AGENTC_LOCK 22
SSH_AGENTC_UNLOCK 23
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
3.4 Generic replies from agent to client
SSH_AGENT_FAILURE 5
SSH_AGENT_SUCCESS 6
3.5 Replies from agent to client for protocol 1 key operations
SSH_AGENT_RSA_IDENTITIES_ANSWER 2
SSH_AGENT_RSA_RESPONSE 4
3.6 Replies from agent to client for protocol 2 key operations
SSH2_AGENT_IDENTITIES_ANSWER 12
SSH2_AGENT_SIGN_RESPONSE 14
3.7 Key constraint identifiers
SSH_AGENT_CONSTRAIN_LIFETIME 1
SSH_AGENT_CONSTRAIN_CONFIRM 2
$OpenBSD: PROTOCOL.agent,v 1.11 2016/05/19 07:45:32 djm Exp $
This file used to contain a description of the SSH agent protocol
implemented by OpenSSH. It has since been superseded by
https://tools.ietf.org/html/draft-miller-ssh-agent-00

View File

@ -224,6 +224,9 @@ option-specific information (see below). All options are
"critical", if an implementation does not recognise a option
then the validating party should refuse to accept the certificate.
Custom options should append the originating author or organisation's
domain name to the option name, e.g. "my-option@example.com".
No critical options are defined for host certificates at present. The
supported user certificate options and the contents and structure of
their data fields are:
@ -255,6 +258,9 @@ as is the requirement that each name appear only once.
If an implementation does not recognise an extension, then it should
ignore it.
Custom options should append the originating author or organisation's
domain name to the option name, e.g. "my-option@example.com".
No extensions are defined for host certificates at present. The
supported user certificate extensions and the contents and structure of
their data fields are:
@ -285,4 +291,4 @@ permit-user-rc empty Flag indicating that execution of
of this script will not be permitted if
this option is not present.
$OpenBSD: PROTOCOL.certkeys,v 1.11 2017/05/16 16:54:05 djm Exp $
$OpenBSD: PROTOCOL.certkeys,v 1.12 2017/05/31 04:29:44 djm Exp $

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth-options.c,v 1.72 2016/11/30 02:57:40 djm Exp $ */
/* $OpenBSD: auth-options.c,v 1.73 2017/05/31 10:54:00 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -119,7 +119,8 @@ match_flag(const char *opt, int allow_negate, char **optsp, const char *msg)
* side effect: sets key option flags
*/
int
auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
auth_parse_options(struct passwd *pw, char *opts, const char *file,
u_long linenum)
{
struct ssh *ssh = active_state; /* XXX */
const char *cp;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth-options.h,v 1.22 2016/11/30 02:57:40 djm Exp $ */
/* $OpenBSD: auth-options.h,v 1.23 2017/05/31 10:54:00 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -33,7 +33,7 @@ extern int forced_tun_device;
extern int key_is_cert_authority;
extern char *authorized_principals;
int auth_parse_options(struct passwd *, char *, char *, u_long);
int auth_parse_options(struct passwd *, char *, const char *, u_long);
void auth_clear_options(void);
int auth_cert_options(struct sshkey *, struct passwd *, const char **);

6
auth.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.120 2017/05/17 01:24:17 djm Exp $ */
/* $OpenBSD: auth.c,v 1.121 2017/05/30 08:52:19 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -429,7 +429,7 @@ authorized_principals_file(struct passwd *pw)
/* return ok if key exists in sysfile or userfile */
HostStatus
check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
const char *sysfile, const char *userfile)
{
char *user_hostfile;
@ -711,7 +711,7 @@ getpwnamallow(const char *user)
/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
int
auth_key_is_revoked(Key *key)
auth_key_is_revoked(struct sshkey *key)
{
char *fp = NULL;
int r;

35
auth.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.h,v 1.89 2016/08/13 17:47:41 markus Exp $ */
/* $OpenBSD: auth.h,v 1.91 2017/05/30 14:29:59 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -91,7 +91,7 @@ struct Authctxt {
struct Authmethod {
char *name;
int (*userauth)(Authctxt *authctxt);
int (*userauth)(struct ssh *);
int *enabled;
};
@ -117,9 +117,10 @@ auth_rhosts2(struct passwd *, const char *, const char *, const char *);
int auth_password(Authctxt *, const char *);
int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
int user_key_allowed(struct passwd *, Key *, int);
void pubkey_auth_info(Authctxt *, const Key *, const char *, ...)
int hostbased_key_allowed(struct passwd *, const char *, char *,
struct sshkey *);
int user_key_allowed(struct passwd *, struct sshkey *, int);
void pubkey_auth_info(Authctxt *, const struct sshkey *, const char *, ...)
__attribute__((__format__ (printf, 3, 4)));
void auth2_record_userkey(Authctxt *, struct sshkey *);
int auth2_userkey_already_used(Authctxt *, struct sshkey *);
@ -154,7 +155,7 @@ void auth_info(Authctxt *authctxt, const char *, ...)
__attribute__((__nonnull__ (2)));
void auth_log(Authctxt *, int, int, const char *, const char *);
void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn));
void userauth_finish(Authctxt *, int, const char *, const char *);
void userauth_finish(struct ssh *, int, const char *, const char *);
int auth_root_allowed(const char *);
void userauth_send_banner(const char *);
@ -167,8 +168,8 @@ int auth2_method_allowed(Authctxt *, const char *, const char *);
void privsep_challenge_enable(void);
int auth2_challenge(Authctxt *, char *);
void auth2_challenge_stop(Authctxt *);
int auth2_challenge(struct ssh *, char *);
void auth2_challenge_stop(struct ssh *);
int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
int bsdauth_respond(void *, u_int, char **);
int skey_query(void *, char **, char **, u_int *, char ***, u_int **);
@ -182,22 +183,22 @@ char *authorized_principals_file(struct passwd *);
FILE *auth_openkeyfile(const char *, struct passwd *, int);
FILE *auth_openprincipals(const char *, struct passwd *, int);
int auth_key_is_revoked(Key *);
int auth_key_is_revoked(struct sshkey *);
const char *auth_get_canonical_hostname(struct ssh *, int);
HostStatus
check_key_in_hostfiles(struct passwd *, Key *, const char *,
check_key_in_hostfiles(struct passwd *, struct sshkey *, const char *,
const char *, const char *);
/* hostkey handling */
Key *get_hostkey_by_index(int);
Key *get_hostkey_public_by_index(int, struct ssh *);
Key *get_hostkey_public_by_type(int, int, struct ssh *);
Key *get_hostkey_private_by_type(int, int, struct ssh *);
int get_hostkey_index(Key *, int, struct ssh *);
int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *,
const u_char *, size_t, const char *, u_int);
struct sshkey *get_hostkey_by_index(int);
struct sshkey *get_hostkey_public_by_index(int, struct ssh *);
struct sshkey *get_hostkey_public_by_type(int, int, struct ssh *);
struct sshkey *get_hostkey_private_by_type(int, int, struct ssh *);
int get_hostkey_index(struct sshkey *, int, struct ssh *);
int sshd_hostkey_sign(struct sshkey *, struct sshkey *, u_char **,
size_t *, const u_char *, size_t, const char *, u_int);
/* debug messages during authentication */
void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-chall.c,v 1.44 2016/05/02 08:49:03 djm Exp $ */
/* $OpenBSD: auth2-chall.c,v 1.48 2017/05/30 14:29:59 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Per Allansson. All rights reserved.
@ -47,9 +47,9 @@
/* import */
extern ServerOptions options;
static int auth2_challenge_start(Authctxt *);
static int auth2_challenge_start(struct ssh *);
static int send_userauth_info_request(Authctxt *);
static int input_userauth_info_response(int, u_int32_t, void *);
static int input_userauth_info_response(int, u_int32_t, struct ssh *);
#ifdef BSD_AUTH
extern KbdintDevice bsdauth_device;
@ -195,8 +195,9 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt)
* wait for the response.
*/
int
auth2_challenge(Authctxt *authctxt, char *devs)
auth2_challenge(struct ssh *ssh, char *devs)
{
Authctxt *authctxt = ssh->authctxt;
debug("auth2_challenge: user=%s devs=%s",
authctxt->user ? authctxt->user : "<nouser>",
devs ? devs : "<no devs>");
@ -205,15 +206,16 @@ auth2_challenge(Authctxt *authctxt, char *devs)
return 0;
if (authctxt->kbdintctxt == NULL)
authctxt->kbdintctxt = kbdint_alloc(devs);
return auth2_challenge_start(authctxt);
return auth2_challenge_start(ssh);
}
/* unregister kbd-int callbacks and context */
void
auth2_challenge_stop(Authctxt *authctxt)
auth2_challenge_stop(struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
/* unregister callback */
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
if (authctxt->kbdintctxt != NULL) {
kbdint_free(authctxt->kbdintctxt);
authctxt->kbdintctxt = NULL;
@ -222,29 +224,30 @@ auth2_challenge_stop(Authctxt *authctxt)
/* side effect: sets authctxt->postponed if a reply was sent*/
static int
auth2_challenge_start(Authctxt *authctxt)
auth2_challenge_start(struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt;
debug2("auth2_challenge_start: devices %s",
kbdintctxt->devices ? kbdintctxt->devices : "<empty>");
if (kbdint_next_device(authctxt, kbdintctxt) == 0) {
auth2_challenge_stop(authctxt);
auth2_challenge_stop(ssh);
return 0;
}
debug("auth2_challenge_start: trying authentication method '%s'",
kbdintctxt->device->name);
if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) {
auth2_challenge_stop(authctxt);
auth2_challenge_stop(ssh);
return 0;
}
if (send_userauth_info_request(authctxt) == 0) {
auth2_challenge_stop(authctxt);
auth2_challenge_stop(ssh);
return 0;
}
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE,
&input_userauth_info_response);
authctxt->postponed = 1;
@ -285,9 +288,9 @@ send_userauth_info_request(Authctxt *authctxt)
}
static int
input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
KbdintAuthctxt *kbdintctxt;
int authenticated = 0, res;
u_int i, nresp;
@ -340,14 +343,14 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
devicename = kbdintctxt->device->name;
if (!authctxt->postponed) {
if (authenticated) {
auth2_challenge_stop(authctxt);
auth2_challenge_stop(ssh);
} else {
/* start next device */
/* may set authctxt->postponed */
auth2_challenge_start(authctxt);
auth2_challenge_start(ssh);
}
}
userauth_finish(authctxt, authenticated, "keyboard-interactive",
userauth_finish(ssh, authenticated, "keyboard-interactive",
devicename);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-gss.c,v 1.22 2015/01/19 20:07:45 markus Exp $ */
/* $OpenBSD: auth2-gss.c,v 1.25 2017/05/30 14:29:59 markus Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@ -48,18 +48,19 @@
extern ServerOptions options;
static int input_gssapi_token(int type, u_int32_t plen, void *ctxt);
static int input_gssapi_mic(int type, u_int32_t plen, void *ctxt);
static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
static int input_gssapi_errtok(int, u_int32_t, void *);
static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh);
static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh);
static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh);
static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
/*
* We only support those mechanisms that we know about (ie ones that we know
* how to check local user kuserok and the like)
*/
static int
userauth_gssapi(Authctxt *authctxt)
userauth_gssapi(struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
gss_OID_desc goid = {0, NULL};
Gssctxt *ctxt = NULL;
int mechs;
@ -119,17 +120,17 @@ userauth_gssapi(Authctxt *authctxt)
packet_send();
free(doid);
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
authctxt->postponed = 1;
return (0);
}
static int
input_gssapi_token(int type, u_int32_t plen, void *ctxt)
input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
gss_buffer_desc recv_tok;
@ -157,8 +158,8 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
packet_send();
}
authctxt->postponed = 0;
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
userauth_finish(authctxt, 0, "gssapi-with-mic", NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
userauth_finish(ssh, 0, "gssapi-with-mic", NULL);
} else {
if (send_tok.length != 0) {
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
@ -166,12 +167,12 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
packet_send();
}
if (maj_status == GSS_S_COMPLETE) {
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
if (flags & GSS_C_INTEG_FLAG)
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC,
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC,
&input_gssapi_mic);
else
dispatch_set(
ssh_dispatch_set(ssh,
SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
&input_gssapi_exchange_complete);
}
@ -182,9 +183,9 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
}
static int
input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
gss_buffer_desc recv_tok;
@ -207,8 +208,8 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
free(recv_tok.value);
/* We can't return anything to the client, even if we wanted to */
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
/* The client will have already moved on to the next auth */
@ -223,9 +224,9 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
*/
static int
input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
int authenticated;
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
@ -241,18 +242,18 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
authctxt->postponed = 0;
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
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", NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
userauth_finish(ssh, authenticated, "gssapi-with-mic", NULL);
return 0;
}
static int
input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt;
int authenticated = 0;
Buffer b;
@ -282,11 +283,11 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
free(mic.value);
authctxt->postponed = 0;
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
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", NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
userauth_finish(ssh, authenticated, "gssapi-with-mic", NULL);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-hostbased.c,v 1.26 2016/03/07 19:02:43 djm Exp $ */
/* $OpenBSD: auth2-hostbased.c,v 1.30 2017/05/30 14:29:59 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -39,7 +39,7 @@
#include "misc.h"
#include "servconf.h"
#include "compat.h"
#include "key.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "canohost.h"
@ -48,6 +48,7 @@
#endif
#include "monitor_wrap.h"
#include "pathnames.h"
#include "ssherr.h"
#include "match.h"
/* import */
@ -56,54 +57,56 @@ extern u_char *session_id2;
extern u_int session_id2_len;
static int
userauth_hostbased(Authctxt *authctxt)
userauth_hostbased(struct ssh *ssh)
{
Buffer b;
Key *key = NULL;
Authctxt *authctxt = ssh->authctxt;
struct sshbuf *b;
struct sshkey *key = NULL;
char *pkalg, *cuser, *chost, *service;
u_char *pkblob, *sig;
u_int alen, blen, slen;
int pktype;
int authenticated = 0;
size_t alen, blen, slen;
int r, pktype, authenticated = 0;
if (!authctxt->valid) {
debug2("userauth_hostbased: disabled because of invalid user");
debug2("%s: disabled because of invalid user", __func__);
return 0;
}
pkalg = packet_get_string(&alen);
pkblob = packet_get_string(&blen);
chost = packet_get_string(NULL);
cuser = packet_get_string(NULL);
sig = packet_get_string(&slen);
/* XXX use sshkey_froms() */
if ((r = sshpkt_get_cstring(ssh, &pkalg, &alen)) != 0 ||
(r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
(r = sshpkt_get_cstring(ssh, &chost, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &cuser, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, &sig, &slen)) != 0)
fatal("%s: packet parsing: %s", __func__, ssh_err(r));
debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
debug("%s: cuser %s chost %s pkalg %s slen %zu", __func__,
cuser, chost, pkalg, slen);
#ifdef DEBUG_PK
debug("signature:");
buffer_init(&b);
buffer_append(&b, sig, slen);
buffer_dump(&b);
buffer_free(&b);
sshbuf_dump_data(sig, siglen, stderr);
#endif
pktype = key_type_from_name(pkalg);
pktype = sshkey_type_from_name(pkalg);
if (pktype == KEY_UNSPEC) {
/* this is perfectly legal */
logit("userauth_hostbased: unsupported "
"public key algorithm: %s", pkalg);
logit("%s: unsupported public key algorithm: %s",
__func__, pkalg);
goto done;
}
if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
error("%s: key_from_blob: %s", __func__, ssh_err(r));
goto done;
}
key = key_from_blob(pkblob, blen);
if (key == NULL) {
error("userauth_hostbased: cannot decode key: %s", pkalg);
error("%s: cannot decode key: %s", __func__, pkalg);
goto done;
}
if (key->type != pktype) {
error("userauth_hostbased: type mismatch for decoded key "
"(received %d, expected %d)", key->type, pktype);
error("%s: type mismatch for decoded key "
"(received %d, expected %d)", __func__, key->type, pktype);
goto done;
}
if (key_type_plain(key->type) == KEY_RSA &&
(datafellows & SSH_BUG_RSASIGMD5) != 0) {
if (sshkey_type_plain(key->type) == KEY_RSA &&
(ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
error("Refusing RSA key because peer uses unsafe "
"signature format");
goto done;
@ -115,21 +118,23 @@ userauth_hostbased(Authctxt *authctxt)
goto done;
}
service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
service = ssh->compat & SSH_BUG_HBSERVICE ? "ssh-userauth" :
authctxt->service;
buffer_init(&b);
buffer_put_string(&b, session_id2, session_id2_len);
if ((b = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
/* reconstruct packet */
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
buffer_put_cstring(&b, authctxt->user);
buffer_put_cstring(&b, service);
buffer_put_cstring(&b, "hostbased");
buffer_put_string(&b, pkalg, alen);
buffer_put_string(&b, pkblob, blen);
buffer_put_cstring(&b, chost);
buffer_put_cstring(&b, cuser);
if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 ||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
(r = sshbuf_put_cstring(b, authctxt->user)) != 0 ||
(r = sshbuf_put_cstring(b, service)) != 0 ||
(r = sshbuf_put_cstring(b, "hostbased")) != 0 ||
(r = sshbuf_put_string(b, pkalg, alen)) != 0 ||
(r = sshbuf_put_string(b, pkblob, blen)) != 0 ||
(r = sshbuf_put_cstring(b, chost)) != 0 ||
(r = sshbuf_put_cstring(b, cuser)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
#ifdef DEBUG_PK
buffer_dump(&b);
sshbuf_dump(b, stderr);
#endif
pubkey_auth_info(authctxt, key,
@ -138,15 +143,15 @@ userauth_hostbased(Authctxt *authctxt)
/* test for allowed key and correct signature */
authenticated = 0;
if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
buffer_len(&b))) == 1)
PRIVSEP(sshkey_verify(key, sig, slen,
sshbuf_ptr(b), sshbuf_len(b), ssh->compat)) == 0)
authenticated = 1;
buffer_free(&b);
sshbuf_free(b);
done:
debug2("userauth_hostbased: authenticated %d", authenticated);
debug2("%s: authenticated %d", __func__, authenticated);
if (key != NULL)
key_free(key);
sshkey_free(key);
free(pkalg);
free(pkblob);
free(cuser);
@ -158,7 +163,7 @@ done:
/* return 1 if given hostkey is allowed */
int
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
Key *key)
struct sshkey *key)
{
struct ssh *ssh = active_state; /* XXX */
const char *resolvedname, *ipaddr, *lookup, *reason;
@ -203,8 +208,8 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
}
debug2("%s: access allowed by auth_rhosts2", __func__);
if (key_is_cert(key) &&
key_cert_check_authority(key, 1, 0, lookup, &reason)) {
if (sshkey_is_cert(key) &&
sshkey_cert_check_authority(key, 1, 0, lookup, &reason)) {
error("%s", reason);
auth_debug_add("%s", reason);
return 0;
@ -223,20 +228,20 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
}
if (host_status == HOST_OK) {
if (key_is_cert(key)) {
if (sshkey_is_cert(key)) {
if ((fp = sshkey_fingerprint(key->cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
fatal("%s: sshkey_fingerprint fail", __func__);
verbose("Accepted certificate ID \"%s\" signed by "
"%s CA %s from %s@%s", key->cert->key_id,
key_type(key->cert->signature_key), fp,
sshkey_type(key->cert->signature_key), fp,
cuser, lookup);
} else {
if ((fp = sshkey_fingerprint(key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
fatal("%s: sshkey_fingerprint fail", __func__);
verbose("Accepted %s public key %s from %s@%s",
key_type(key), fp, cuser, lookup);
sshkey_type(key), fp, cuser, lookup);
}
free(fp);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-kbdint.c,v 1.7 2014/07/15 15:54:14 millert Exp $ */
/* $OpenBSD: auth2-kbdint.c,v 1.8 2017/05/30 14:29:59 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -43,7 +43,7 @@
extern ServerOptions options;
static int
userauth_kbdint(Authctxt *authctxt)
userauth_kbdint(struct ssh *ssh)
{
int authenticated = 0;
char *lang, *devs;
@ -55,7 +55,7 @@ userauth_kbdint(Authctxt *authctxt)
debug("keyboard-interactive devs %s", devs);
if (options.challenge_response_authentication)
authenticated = auth2_challenge(authctxt, devs);
authenticated = auth2_challenge(ssh, devs);
free(devs);
free(lang);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-none.c,v 1.18 2014/07/15 15:54:14 millert Exp $ */
/* $OpenBSD: auth2-none.c,v 1.20 2017/05/30 14:29:59 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -37,7 +37,7 @@
#include "atomicio.h"
#include "xmalloc.h"
#include "key.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "packet.h"
@ -47,6 +47,7 @@
#include "servconf.h"
#include "compat.h"
#include "ssh2.h"
#include "ssherr.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
@ -59,12 +60,15 @@ extern ServerOptions options;
static int none_enabled = 1;
static int
userauth_none(Authctxt *authctxt)
userauth_none(struct ssh *ssh)
{
int r;
none_enabled = 0;
packet_check_eom();
if ((r = sshpkt_get_end(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
if (options.permit_empty_passwd && options.password_authentication)
return (PRIVSEP(auth_password(authctxt, "")));
return (PRIVSEP(auth_password(ssh->authctxt, "")));
return (0);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-passwd.c,v 1.12 2014/07/15 15:54:14 millert Exp $ */
/* $OpenBSD: auth2-passwd.c,v 1.14 2017/05/30 14:29:59 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -30,10 +30,10 @@
#include <string.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "packet.h"
#include "ssherr.h"
#include "log.h"
#include "key.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "buffer.h"
@ -48,26 +48,22 @@
extern ServerOptions options;
static int
userauth_passwd(Authctxt *authctxt)
userauth_passwd(struct ssh *ssh)
{
char *password, *newpass;
int authenticated = 0;
int change;
u_int len, newlen;
char *password;
int authenticated = 0, r;
u_char change;
size_t len;
change = packet_get_char();
password = packet_get_string(&len);
if (change) {
/* discard new password from packet */
newpass = packet_get_string(&newlen);
explicit_bzero(newpass, newlen);
free(newpass);
}
packet_check_eom();
if ((r = sshpkt_get_u8(ssh, &change)) != 0 ||
(r = sshpkt_get_cstring(ssh, &password, &len)) != 0 ||
(change && (r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0) ||
(r = sshpkt_get_end(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
if (change)
logit("password change not supported");
else if (PRIVSEP(auth_password(authctxt, password)) == 1)
else if (PRIVSEP(auth_password(ssh->authctxt, password)) == 1)
authenticated = 1;
explicit_bzero(password, len);
free(password);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.62 2017/01/30 01:03:00 djm Exp $ */
/* $OpenBSD: auth2-pubkey.c,v 1.67 2017/05/31 10:54:00 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -52,7 +52,7 @@
#include "misc.h"
#include "servconf.h"
#include "compat.h"
#include "key.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "pathnames.h"
@ -76,42 +76,52 @@ extern u_char *session_id2;
extern u_int session_id2_len;
static int
userauth_pubkey(Authctxt *authctxt)
userauth_pubkey(struct ssh *ssh)
{
Buffer b;
Key *key = NULL;
char *pkalg, *userstyle, *fp = NULL;
u_char *pkblob, *sig;
u_int alen, blen, slen;
int have_sig, pktype;
Authctxt *authctxt = ssh->authctxt;
struct sshbuf *b;
struct sshkey *key = NULL;
char *pkalg, *userstyle = NULL, *fp = NULL;
u_char *pkblob, *sig, have_sig;
size_t blen, slen;
int r, pktype;
int authenticated = 0;
if (!authctxt->valid) {
debug2("%s: disabled because of invalid user", __func__);
return 0;
}
have_sig = packet_get_char();
if (datafellows & SSH_BUG_PKAUTH) {
if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0)
fatal("%s: sshpkt_get_u8 failed: %s", __func__, ssh_err(r));
if (ssh->compat & SSH_BUG_PKAUTH) {
debug2("%s: SSH_BUG_PKAUTH", __func__);
if ((b = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
/* no explicit pkalg given */
pkblob = packet_get_string(&blen);
buffer_init(&b);
buffer_append(&b, pkblob, blen);
/* so we have to extract the pkalg from the pkblob */
pkalg = buffer_get_string(&b, &alen);
buffer_free(&b);
/* XXX use sshbuf_from() */
if ((r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
(r = sshbuf_put(b, pkblob, blen)) != 0 ||
(r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0)
fatal("%s: failed: %s", __func__, ssh_err(r));
sshbuf_free(b);
} else {
pkalg = packet_get_string(&alen);
pkblob = packet_get_string(&blen);
if ((r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0)
fatal("%s: sshpkt_get_cstring failed: %s",
__func__, ssh_err(r));
}
pktype = key_type_from_name(pkalg);
pktype = sshkey_type_from_name(pkalg);
if (pktype == KEY_UNSPEC) {
/* this is perfectly legal */
logit("%s: unsupported public key algorithm: %s",
__func__, pkalg);
goto done;
}
key = key_from_blob(pkblob, blen);
if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
error("%s: could not parse key: %s", __func__, ssh_err(r));
goto done;
}
if (key == NULL) {
error("%s: cannot decode key: %s", __func__, pkalg);
goto done;
@ -121,15 +131,15 @@ userauth_pubkey(Authctxt *authctxt)
"(received %d, expected %d)", __func__, key->type, pktype);
goto done;
}
if (key_type_plain(key->type) == KEY_RSA &&
(datafellows & SSH_BUG_RSASIGMD5) != 0) {
if (sshkey_type_plain(key->type) == KEY_RSA &&
(ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
logit("Refusing RSA key because client uses unsafe "
"signature scheme");
goto done;
}
fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);
if (auth2_userkey_already_used(authctxt, key)) {
logit("refusing previously-used %s key", key_type(key));
logit("refusing previously-used %s key", sshkey_type(key));
goto done;
}
if (match_pattern_list(sshkey_ssh_name(key),
@ -142,35 +152,48 @@ userauth_pubkey(Authctxt *authctxt)
if (have_sig) {
debug3("%s: have signature for %s %s",
__func__, sshkey_type(key), fp);
sig = packet_get_string(&slen);
packet_check_eom();
buffer_init(&b);
if (datafellows & SSH_OLD_SESSIONID) {
buffer_append(&b, session_id2, session_id2_len);
if ((r = sshpkt_get_string(ssh, &sig, &slen)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
if ((b = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
if (ssh->compat & SSH_OLD_SESSIONID) {
if ((r = sshbuf_put(b, session_id2,
session_id2_len)) != 0)
fatal("%s: sshbuf_put session id: %s",
__func__, ssh_err(r));
} else {
buffer_put_string(&b, session_id2, session_id2_len);
if ((r = sshbuf_put_string(b, session_id2,
session_id2_len)) != 0)
fatal("%s: sshbuf_put_string session id: %s",
__func__, ssh_err(r));
}
/* reconstruct packet */
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
xasprintf(&userstyle, "%s%s%s", authctxt->user,
authctxt->style ? ":" : "",
authctxt->style ? authctxt->style : "");
buffer_put_cstring(&b, userstyle);
free(userstyle);
buffer_put_cstring(&b,
datafellows & SSH_BUG_PKSERVICE ?
"ssh-userauth" :
authctxt->service);
if (datafellows & SSH_BUG_PKAUTH) {
buffer_put_char(&b, have_sig);
if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
(r = sshbuf_put_cstring(b, userstyle)) != 0 ||
(r = sshbuf_put_cstring(b, ssh->compat & SSH_BUG_PKSERVICE ?
"ssh-userauth" : authctxt->service)) != 0)
fatal("%s: build packet failed: %s",
__func__, ssh_err(r));
if (ssh->compat & SSH_BUG_PKAUTH) {
if ((r = sshbuf_put_u8(b, have_sig)) != 0)
fatal("%s: build packet failed: %s",
__func__, ssh_err(r));
} else {
buffer_put_cstring(&b, "publickey");
buffer_put_char(&b, have_sig);
buffer_put_cstring(&b, pkalg);
if ((r = sshbuf_put_cstring(b, "publickey")) != 0 ||
(r = sshbuf_put_u8(b, have_sig)) != 0 ||
(r = sshbuf_put_cstring(b, pkalg) != 0))
fatal("%s: build packet failed: %s",
__func__, ssh_err(r));
}
buffer_put_string(&b, pkblob, blen);
if ((r = sshbuf_put_string(b, pkblob, blen)) != 0)
fatal("%s: build packet failed: %s",
__func__, ssh_err(r));
#ifdef DEBUG_PK
buffer_dump(&b);
sshbuf_dump(b, stderr);
#endif
pubkey_auth_info(authctxt, key, NULL);
@ -222,21 +245,22 @@ userauth_pubkey(Authctxt *authctxt)
#else /* !WINDOWS */
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
buffer_len(&b))) == 1) {
PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b),
sshbuf_len(b), ssh->compat)) == 0) {
authenticated = 1;
/* Record the successful key to prevent reuse */
auth2_record_userkey(authctxt, key);
key = NULL; /* Don't free below */
}
buffer_free(&b);
sshbuf_free(b);
free(sig);
#endif /* !WINDOWS */
} else {
debug("%s: test whether pkalg/pkblob are acceptable for %s %s",
__func__, sshkey_type(key), fp);
packet_check_eom();
if ((r = sshpkt_get_end(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
/* XXX fake reply and always send PK_OK ? */
/*
@ -247,11 +271,13 @@ userauth_pubkey(Authctxt *authctxt)
* issue? -markus
*/
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) {
packet_start(SSH2_MSG_USERAUTH_PK_OK);
packet_put_string(pkalg, alen);
packet_put_string(pkblob, blen);
packet_send();
packet_write_wait();
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_PK_OK))
!= 0 ||
(r = sshpkt_put_cstring(ssh, pkalg)) != 0 ||
(r = sshpkt_put_string(ssh, pkblob, blen)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
ssh_packet_write_wait(ssh);
authctxt->postponed = 1;
}
}
@ -260,7 +286,8 @@ userauth_pubkey(Authctxt *authctxt)
done:
debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg);
if (key != NULL)
key_free(key);
sshkey_free(key);
free(userstyle);
free(pkalg);
free(pkblob);
free(fp);
@ -268,7 +295,8 @@ done:
}
void
pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
pubkey_auth_info(Authctxt *authctxt, const struct sshkey *key,
const char *fmt, ...)
{
char *fp, *extra;
va_list ap;
@ -280,23 +308,23 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
i = vasprintf(&extra, fmt, ap);
va_end(ap);
if (i < 0 || extra == NULL)
fatal("%s: vasprintf failed", __func__);
fatal("%s: vasprintf failed", __func__);
}
if (key_is_cert(key)) {
if (sshkey_is_cert(key)) {
fp = sshkey_fingerprint(key->cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT);
auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s",
key_type(key), key->cert->key_id,
sshkey_type(key), key->cert->key_id,
(unsigned long long)key->cert->serial,
key_type(key->cert->signature_key),
sshkey_type(key->cert->signature_key),
fp == NULL ? "(null)" : fp,
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
free(fp);
} else {
fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT);
auth_info(authctxt, "%s %s%s%s", key_type(key),
auth_info(authctxt, "%s %s%s%s", sshkey_type(key),
fp == NULL ? "(null)" : fp,
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
free(fp);
@ -612,7 +640,7 @@ match_principals_option(const char *principal_list, struct sshkey_cert *cert)
}
static int
process_principals(FILE *f, char *file, struct passwd *pw,
process_principals(FILE *f, const char *file, struct passwd *pw,
const struct sshkey_cert *cert)
{
char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;
@ -650,8 +678,7 @@ process_principals(FILE *f, char *file, struct passwd *pw,
for (i = 0; i < cert->nprincipals; i++) {
if (strcmp(cp, cert->principals[i]) == 0) {
debug3("%s:%lu: matched principal \"%.100s\"",
file == NULL ? "(command)" : file,
linenum, cert->principals[i]);
file, linenum, cert->principals[i]);
if (auth_parse_options(pw, line_opts,
file, linenum) != 1)
continue;
@ -782,7 +809,7 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key)
uid_swapped = 1;
temporarily_use_uid(pw);
ok = process_principals(f, NULL, pw, cert);
ok = process_principals(f, "(command)", pw, cert);
fclose(f);
f = NULL;
@ -814,16 +841,13 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key)
* returns 1 if the key is allowed or 0 otherwise.
*/
static int
check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
check_authkeys_file(FILE *f, char *file, struct sshkey *key, struct passwd *pw)
{
char line[SSH_MAX_PUBKEY_BYTES];
int found_key = 0;
u_long linenum = 0;
Key *found;
struct sshkey *found = NULL;
found_key = 0;
found = NULL;
while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
char *cp, *key_options = NULL, *fp = NULL;
const char *reason = NULL;
@ -832,8 +856,10 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
if (found_key)
continue;
if (found != NULL)
key_free(found);
found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
sshkey_free(found);
found = sshkey_new(sshkey_is_cert(key) ? KEY_UNSPEC : key->type);
if (found == NULL)
goto done;
auth_clear_options();
/* Skip leading whitespace, empty and comment lines. */
@ -842,7 +868,7 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
if (!*cp || *cp == '\n' || *cp == '#')
continue;
if (key_read(found, &cp) != 1) {
if (sshkey_read(found, &cp) != 0) {
/* no key? check if there are options for this key */
int quoted = 0;
debug2("user_key_allowed: check options: '%s'", cp);
@ -856,14 +882,14 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
/* Skip remaining whitespace. */
for (; *cp == ' ' || *cp == '\t'; cp++)
;
if (key_read(found, &cp) != 1) {
if (sshkey_read(found, &cp) != 0) {
debug2("user_key_allowed: advance: '%s'", cp);
/* still no key? advance to next line*/
continue;
}
}
if (key_is_cert(key)) {
if (!key_equal(found, key->cert->signature_key))
if (sshkey_is_cert(key)) {
if (!sshkey_equal(found, key->cert->signature_key))
continue;
if (auth_parse_options(pw, key_options, file,
linenum) != 1)
@ -874,7 +900,7 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
continue;
debug("matching CA found: file %s, line %lu, %s %s",
file, linenum, key_type(found), fp);
file, linenum, sshkey_type(found), fp);
/*
* If the user has specified a list of principals as
* a key option, then prefer that list to matching
@ -891,7 +917,7 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
auth_debug_add("%s", reason);
continue;
}
if (key_cert_check_authority(key, 0, 0,
if (sshkey_cert_check_authority(key, 0, 0,
authorized_principals == NULL ? pw->pw_name : NULL,
&reason) != 0)
goto fail_reason;
@ -900,11 +926,11 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
verbose("Accepted certificate ID \"%s\" (serial %llu) "
"signed by %s CA %s via %s", key->cert->key_id,
(unsigned long long)key->cert->serial,
key_type(found), fp, file);
sshkey_type(found), fp, file);
free(fp);
found_key = 1;
break;
} else if (key_equal(found, key)) {
} else if (sshkey_equal(found, key)) {
if (auth_parse_options(pw, key_options, file,
linenum) != 1)
continue;
@ -914,14 +940,15 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
continue;
debug("matching key found: file %s, line %lu %s %s",
file, linenum, key_type(found), fp);
file, linenum, sshkey_type(found), fp);
free(fp);
found_key = 1;
continue;
}
}
done:
if (found != NULL)
key_free(found);
sshkey_free(found);
if (!found_key)
debug2("key not found");
return found_key;
@ -929,24 +956,24 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
/* Authenticate a certificate key against TrustedUserCAKeys */
static int
user_cert_trusted_ca(struct passwd *pw, Key *key)
user_cert_trusted_ca(struct passwd *pw, struct sshkey *key)
{
char *ca_fp, *principals_file = NULL;
const char *reason;
int ret = 0, found_principal = 0, use_authorized_principals;
int r, ret = 0, found_principal = 0, use_authorized_principals;
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
if (!sshkey_is_cert(key) || options.trusted_user_ca_keys == NULL)
return 0;
if ((ca_fp = sshkey_fingerprint(key->cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
return 0;
if (sshkey_in_file(key->cert->signature_key,
options.trusted_user_ca_keys, 1, 0) != 0) {
debug2("%s: CA %s %s is not listed in %s", __func__,
key_type(key->cert->signature_key), ca_fp,
options.trusted_user_ca_keys);
if ((r = sshkey_in_file(key->cert->signature_key,
options.trusted_user_ca_keys, 1, 0)) != 0) {
debug2("%s: CA %s %s is not listed in %s: %s", __func__,
sshkey_type(key->cert->signature_key), ca_fp,
options.trusted_user_ca_keys, ssh_err(r));
goto out;
}
/*
@ -971,7 +998,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
auth_debug_add("%s", reason);
goto out;
}
if (key_cert_check_authority(key, 0, 1,
if (sshkey_cert_check_authority(key, 0, 1,
use_authorized_principals ? NULL : pw->pw_name, &reason) != 0)
goto fail_reason;
if (auth_cert_options(key, pw, &reason) != 0)
@ -980,7 +1007,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
verbose("Accepted certificate ID \"%s\" (serial %llu) signed by "
"%s CA %s via %s", key->cert->key_id,
(unsigned long long)key->cert->serial,
key_type(key->cert->signature_key), ca_fp,
sshkey_type(key->cert->signature_key), ca_fp,
options.trusted_user_ca_keys);
ret = 1;
@ -995,7 +1022,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
* returns 1 if the key is allowed or 0 otherwise.
*/
static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
user_key_allowed2(struct passwd *pw, struct sshkey *key, char *file)
{
FILE *f;
int found_key = 0;
@ -1018,7 +1045,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
* returns 1 if the key is allowed or 0 otherwise.
*/
static int
user_key_command_allowed2(struct passwd *user_pw, Key *key)
user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key)
{
FILE *f = NULL;
int r, ok, found_key = 0;
@ -1141,14 +1168,15 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
* Check whether key authenticates and authorises the user.
*/
int
user_key_allowed(struct passwd *pw, Key *key, int auth_attempt)
user_key_allowed(struct passwd *pw, struct sshkey *key, int auth_attempt)
{
u_int success, i;
char *file;
if (auth_key_is_revoked(key))
return 0;
if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
if (sshkey_is_cert(key) &&
auth_key_is_revoked(key->cert->signature_key))
return 0;
success = user_cert_trusted_ca(pw, key);
@ -1180,9 +1208,10 @@ auth2_record_userkey(Authctxt *authctxt, struct sshkey *key)
struct sshkey **tmp;
if (authctxt->nprev_userkeys >= INT_MAX ||
(tmp = reallocarray(authctxt->prev_userkeys,
authctxt->nprev_userkeys + 1, sizeof(*tmp))) == NULL)
fatal("%s: reallocarray failed", __func__);
(tmp = recallocarray(authctxt->prev_userkeys,
authctxt->nprev_userkeys, authctxt->nprev_userkeys + 1,
sizeof(*tmp))) == NULL)
fatal("%s: recallocarray failed", __func__);
authctxt->prev_userkeys = tmp;
authctxt->prev_userkeys[authctxt->nprev_userkeys] = key;
authctxt->nprev_userkeys++;

42
auth2.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2.c,v 1.137 2017/02/03 23:05:57 djm Exp $ */
/* $OpenBSD: auth2.c,v 1.142 2017/05/31 07:00:13 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -87,8 +87,8 @@ Authmethod *authmethods[] = {
/* protocol */
static int input_service_request(int, u_int32_t, void *);
static int input_userauth_request(int, u_int32_t, void *);
static int input_service_request(int, u_int32_t, struct ssh *);
static int input_userauth_request(int, u_int32_t, struct ssh *);
/* helper */
static Authmethod *authmethod_lookup(Authctxt *, const char *);
@ -168,16 +168,19 @@ done:
void
do_authentication2(Authctxt *authctxt)
{
dispatch_init(&dispatch_protocol_error);
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
struct ssh *ssh = active_state; /* XXX */
ssh->authctxt = authctxt; /* XXX move to caller */
ssh_dispatch_init(ssh, &dispatch_protocol_error);
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request);
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success);
ssh->authctxt = NULL;
}
/*ARGSUSED*/
static int
input_service_request(int type, u_int32_t seq, void *ctxt)
input_service_request(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
u_int len;
int acceptit = 0;
char *service = packet_get_cstring(&len);
@ -190,7 +193,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
if (!authctxt->success) {
acceptit = 1;
/* now we can handle user-auth requests */
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
}
}
/* XXX all other service requests are denied */
@ -210,10 +213,9 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
/*ARGSUSED*/
static int
input_userauth_request(int type, u_int32_t seq, void *ctxt)
input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = active_state; /* XXX */
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
Authmethod *m = NULL;
char *user, *service, *method, *style = NULL;
int authenticated = 0;
@ -267,12 +269,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
authctxt->user, authctxt->service, user, service);
}
/* reset state */
auth2_challenge_stop(authctxt);
auth2_challenge_stop(ssh);
#ifdef GSSAPI
/* XXX move to auth2_gssapi_stop() */
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
#endif
authctxt->postponed = 0;
@ -282,9 +284,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
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);
authenticated = m->userauth(ssh);
}
userauth_finish(authctxt, authenticated, method, NULL);
userauth_finish(ssh, authenticated, method, NULL);
free(service);
free(user);
@ -293,10 +295,10 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
}
void
userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
userauth_finish(struct ssh *ssh, int authenticated, const char *method,
const char *submethod)
{
struct ssh *ssh = active_state; /* XXX */
Authctxt *authctxt = ssh->authctxt;
char *methods;
int partial = 0;
@ -352,7 +354,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
if (authenticated == 1) {
/* turn off userauth */
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
packet_start(SSH2_MSG_USERAUTH_SUCCESS);
packet_send();
packet_write_wait();

View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfile.c,v 1.124 2017/04/30 23:10:43 djm Exp $ */
/* $OpenBSD: authfile.c,v 1.126 2017/05/31 09:15:42 deraadt Exp $ */
/*
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
*
@ -101,25 +101,13 @@ sshkey_load_file(int fd, struct sshbuf *blob)
u_char buf[1024];
size_t len;
struct stat st;
int r, dontmax = 0;
int r;
if (fstat(fd, &st) < 0)
return SSH_ERR_SYSTEM_ERROR;
if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
st.st_size > MAX_KEY_FILE_SIZE)
return SSH_ERR_INVALID_FORMAT;
/*
* Pre-allocate the buffer used for the key contents and clamp its
* maximum size. This ensures that key contents are never leaked via
* implicit realloc() in the sshbuf code.
*/
if ((st.st_mode & S_IFREG) == 0 || st.st_size <= 0) {
st.st_size = 64*1024; /* 64k ought to be enough for anybody. :) */
dontmax = 1;
}
if ((r = sshbuf_allocate(blob, st.st_size)) != 0 ||
(dontmax && (r = sshbuf_set_max_size(blob, st.st_size)) != 0))
return r;
for (;;) {
if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
if (errno == EPIPE)
@ -326,50 +314,48 @@ sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
return SSH_ERR_INVALID_FORMAT;
}
/* load public key from ssh v1 private or any pubkey file */
/* load public key from any pubkey file */
int
sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
{
struct sshkey *pub = NULL;
char file[PATH_MAX];
int r, fd;
char *file = NULL;
int r;
if (keyp != NULL)
*keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
/* XXX should load file once and attempt to parse each format */
if ((fd = open(filename, O_RDONLY)) < 0)
goto skip;
close(fd);
/* try ssh2 public key */
if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
if (keyp != NULL)
if (keyp != NULL) {
*keyp = pub;
return 0;
pub = NULL;
}
r = 0;
goto out;
}
sshkey_free(pub);
skip:
/* try .pub suffix */
if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
if (asprintf(&file, "%s.pub", filename) == -1)
return SSH_ERR_ALLOC_FAIL;
r = SSH_ERR_ALLOC_FAIL; /* in case strlcpy or strlcat fail */
if ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&
(strlcat(file, ".pub", sizeof file) < sizeof(file)) &&
(r = sshkey_try_load_public(pub, file, commentp)) == 0) {
if (keyp != NULL)
*keyp = pub;
return 0;
if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = sshkey_try_load_public(pub, file, commentp)) == 0) {
if (keyp != NULL) {
*keyp = pub;
pub = NULL;
}
r = 0;
}
out:
free(file);
sshkey_free(pub);
return r;
}

View File

@ -87,10 +87,10 @@ reserve(struct bitmap *b, u_int n)
return -1; /* invalid */
nlen = (n / BITMAP_BITS) + 1;
if (b->len < nlen) {
if ((tmp = reallocarray(b->d, nlen, BITMAP_BYTES)) == NULL)
if ((tmp = recallocarray(b->d, b->len,
nlen, BITMAP_BYTES)) == NULL)
return -1;
b->d = tmp;
memset(b->d + b->len, 0, (nlen - b->len) * BITMAP_BYTES);
b->len = nlen;
}
return 0;
@ -189,7 +189,7 @@ bitmap_from_string(struct bitmap *b, const void *p, size_t l)
{
int r;
size_t i, offset, shift;
u_char *s = (u_char *)p;
const u_char *s = (const u_char *)p;
if (l > BITMAP_MAX / 8)
return -1;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.c,v 1.359 2017/04/30 23:28:41 djm Exp $ */
/* $OpenBSD: channels.c,v 1.365 2017/05/31 08:58:52 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -242,8 +242,6 @@ channel_lookup(int id)
case SSH_CHANNEL_DYNAMIC:
case SSH_CHANNEL_OPENING:
case SSH_CHANNEL_OPEN:
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
case SSH_CHANNEL_ABANDONED:
case SSH_CHANNEL_MUX_PROXY:
return (c);
@ -481,8 +479,6 @@ channel_free(Channel *c)
debug3("channel %d: status: %s", c->self, s);
free(s);
if (c->sock != -1)
shutdown(c->sock, SHUT_RDWR);
channel_close_fds(c);
buffer_free(&c->input);
buffer_free(&c->output);
@ -614,9 +610,6 @@ channel_still_open(void)
case SSH_CHANNEL_MUX_CLIENT:
case SSH_CHANNEL_MUX_PROXY:
return 1;
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
fatal("cannot happen: OUT_DRAIN");
default:
fatal("%s: bad channel type %d", __func__, c->type);
/* NOTREACHED */
@ -657,9 +650,6 @@ channel_find_open(void)
case SSH_CHANNEL_OPEN:
case SSH_CHANNEL_X11_OPEN:
return i;
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
fatal("cannot happen: OUT_DRAIN");
default:
fatal("%s: bad channel type %d", __func__, c->type);
/* NOTREACHED */
@ -706,8 +696,6 @@ channel_open_message(void)
case SSH_CHANNEL_DYNAMIC:
case SSH_CHANNEL_OPEN:
case SSH_CHANNEL_X11_OPEN:
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
case SSH_CHANNEL_MUX_PROXY:
case SSH_CHANNEL_MUX_CLIENT:
snprintf(buf, sizeof buf,
@ -1085,9 +1073,11 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
buffer_get(&c->input, (char *)&s4_req.dest_addr, 4);
have = buffer_len(&c->input);
p = (char *)buffer_ptr(&c->input);
if (memchr(p, '\0', have) == NULL)
fatal("channel %d: decode socks4: user not nul terminated",
if (memchr(p, '\0', have) == NULL) {
error("channel %d: decode socks4: user not nul terminated",
c->self);
return -1;
}
len = strlen(p);
debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
len++; /* trailing '\0' */
@ -1105,13 +1095,15 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
} else { /* SOCKS4A: two strings */
have = buffer_len(&c->input);
p = (char *)buffer_ptr(&c->input);
if (memchr(p, '\0', have) == NULL) {
error("channel %d: decode socks4a: host not nul "
"terminated", c->self);
return -1;
}
len = strlen(p);
debug2("channel %d: decode socks4a: host %s/%d",
c->self, p, len);
len++; /* trailing '\0' */
if (len > have)
fatal("channel %d: decode socks4a: len %d > have %d",
c->self, len, have);
if (len > NI_MAXHOST) {
error("channel %d: hostname \"%.100s\" too long",
c->self, p);
@ -2406,9 +2398,8 @@ channel_proxy_downstream(Channel *downstream)
* replaces local (proxy) channel ID with downstream channel ID.
*/
int
channel_proxy_upstream(Channel *c, int type, u_int32_t seq, void *ctxt)
channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = active_state;
struct sshbuf *b = NULL;
Channel *downstream;
const u_char *cp = NULL;
@ -2488,7 +2479,7 @@ channel_proxy_upstream(Channel *c, int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
channel_input_data(int type, u_int32_t seq, void *ctxt)
channel_input_data(int type, u_int32_t seq, struct ssh *ssh)
{
int id;
const u_char *data;
@ -2500,7 +2491,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
c = channel_lookup(id);
if (c == NULL)
packet_disconnect("Received data for nonexistent channel %d.", id);
if (channel_proxy_upstream(c, type, seq, ctxt))
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
/* Ignore any data for non-open channels (might happen on close) */
@ -2548,7 +2539,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh)
{
int id;
char *data;
@ -2561,7 +2552,7 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
if (c == NULL)
packet_disconnect("Received extended_data for bad channel %d.", id);
if (channel_proxy_upstream(c, type, seq, ctxt))
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if (c->type != SSH_CHANNEL_OPEN) {
logit("channel %d: ext data for non open", id);
@ -2598,7 +2589,7 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
channel_input_ieof(int type, u_int32_t seq, void *ctxt)
channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh)
{
int id;
Channel *c;
@ -2608,7 +2599,7 @@ channel_input_ieof(int type, u_int32_t seq, void *ctxt)
c = channel_lookup(id);
if (c == NULL)
packet_disconnect("Received ieof for nonexistent channel %d.", id);
if (channel_proxy_upstream(c, type, seq, ctxt))
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
chan_rcvd_ieof(c);
@ -2622,17 +2613,16 @@ channel_input_ieof(int type, u_int32_t seq, void *ctxt)
return 0;
}
/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
/* ARGSUSED */
int
channel_input_oclose(int type, u_int32_t seq, void *ctxt)
channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh)
{
int id = packet_get_int();
Channel *c = channel_lookup(id);
if (c == NULL)
packet_disconnect("Received oclose for nonexistent channel %d.", id);
if (channel_proxy_upstream(c, type, seq, ctxt))
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
packet_check_eom();
chan_rcvd_oclose(c);
@ -2641,27 +2631,7 @@ channel_input_oclose(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
{
int id = packet_get_int();
Channel *c = channel_lookup(id);
if (c == NULL)
packet_disconnect("Received close confirmation for "
"out-of-range channel %d.", id);
if (channel_proxy_upstream(c, type, seq, ctxt))
return 0;
packet_check_eom();
if (c->type != SSH_CHANNEL_CLOSED && c->type != SSH_CHANNEL_ABANDONED)
packet_disconnect("Received close confirmation for "
"non-closed channel %d (type %d).", id, c->type);
channel_free(c);
return 0;
}
/* ARGSUSED */
int
channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh)
{
int id, remote_id;
Channel *c;
@ -2672,7 +2642,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
if (c==NULL)
packet_disconnect("Received open confirmation for "
"unknown channel %d.", id);
if (channel_proxy_upstream(c, type, seq, ctxt))
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if (c->type != SSH_CHANNEL_OPENING)
packet_disconnect("Received open confirmation for "
@ -2713,7 +2683,7 @@ reason2txt(int reason)
/* ARGSUSED */
int
channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
channel_input_open_failure(int type, u_int32_t seq, struct ssh *ssh)
{
int id, reason;
char *msg = NULL, *lang = NULL;
@ -2725,7 +2695,7 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
if (c==NULL)
packet_disconnect("Received open failure for "
"unknown channel %d.", id);
if (channel_proxy_upstream(c, type, seq, ctxt))
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if (c->type != SSH_CHANNEL_OPENING)
packet_disconnect("Received open failure for "
@ -2752,7 +2722,7 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
channel_input_window_adjust(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c;
int id;
@ -2766,7 +2736,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
logit("Received window adjust for non-open channel %d.", id);
return 0;
}
if (channel_proxy_upstream(c, type, seq, ctxt))
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
adjust = packet_get_int();
packet_check_eom();
@ -2780,7 +2750,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
channel_input_status_confirm(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c;
struct channel_confirm *cc;
@ -2796,7 +2766,7 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
logit("channel_input_status_confirm: %d: unknown", id);
return 0;
}
if (channel_proxy_upstream(c, type, seq, ctxt))
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
packet_check_eom();
if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL)
@ -3224,7 +3194,7 @@ channel_cancel_lport_listener(struct Forward *fwd, int cport, struct ForwardOpti
return channel_cancel_lport_listener_tcpip(fwd->listen_host, fwd->listen_port, cport, fwd_opts);
}
/* protocol local port fwd, used by ssh (and sshd in v1) */
/* protocol local port fwd, used by ssh */
int
channel_setup_local_fwd_listener(struct Forward *fwd, struct ForwardOptions *fwd_opts)
{

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.h,v 1.123 2017/04/30 23:28:41 djm Exp $ */
/* $OpenBSD: channels.h,v 1.126 2017/05/30 14:23:52 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -46,8 +46,6 @@
#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */
#define SSH_CHANNEL_AUTH_SOCKET 6 /* authentication socket */
#define SSH_CHANNEL_X11_OPEN 7 /* reading first X11 packet */
#define SSH_CHANNEL_INPUT_DRAINING 8 /* sending remaining data to conn */
#define SSH_CHANNEL_OUTPUT_DRAINING 9 /* sending remaining data to app */
#define SSH_CHANNEL_LARVAL 10 /* larval session */
#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */
#define SSH_CHANNEL_CONNECTING 12
@ -63,6 +61,7 @@
#define CHANNEL_CANCEL_PORT_STATIC -1
struct ssh;
struct Channel;
typedef struct Channel Channel;
@ -234,19 +233,19 @@ void channel_send_window_changes(void);
/* mux proxy support */
int channel_proxy_downstream(Channel *mc);
int channel_proxy_upstream(Channel *, int, u_int32_t, void *);
int channel_proxy_upstream(Channel *, int, u_int32_t, struct ssh *);
/* protocol handler */
int channel_input_close_confirmation(int, u_int32_t, void *);
int channel_input_data(int, u_int32_t, void *);
int channel_input_extended_data(int, u_int32_t, void *);
int channel_input_ieof(int, u_int32_t, void *);
int channel_input_oclose(int, u_int32_t, void *);
int channel_input_open_confirmation(int, u_int32_t, void *);
int channel_input_open_failure(int, u_int32_t, void *);
int channel_input_window_adjust(int, u_int32_t, void *);
int channel_input_status_confirm(int, u_int32_t, void *);
int channel_input_data(int, u_int32_t, struct ssh *);
int channel_input_extended_data(int, u_int32_t, struct ssh *);
int channel_input_ieof(int, u_int32_t, struct ssh *);
int channel_input_oclose(int, u_int32_t, struct ssh *);
int channel_input_open_confirmation(int, u_int32_t, struct ssh *);
int channel_input_open_failure(int, u_int32_t, struct ssh *);
int channel_input_port_open(int, u_int32_t, struct ssh *);
int channel_input_window_adjust(int, u_int32_t, struct ssh *);
int channel_input_status_confirm(int, u_int32_t, struct ssh *);
/* file descriptor handling (read/write) */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.296 2017/05/03 21:08:09 naddy Exp $ */
/* $OpenBSD: clientloop.c,v 1.299 2017/05/31 09:15:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -459,7 +459,7 @@ client_check_window_change(void)
}
static int
client_global_request_reply(int type, u_int32_t seq, void *ctxt)
client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh)
{
struct global_confirm *gc;
@ -1171,7 +1171,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
static void
client_process_buffered_input_packets(void)
{
dispatch_run(DISPATCH_NONBLOCK, &quit_pending, active_state);
ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, &quit_pending);
}
/* scan buf[] for '~' before sending data to the peer */
@ -1646,7 +1646,7 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
/* XXXX move to generic input handler */
static int
client_input_channel_open(int type, u_int32_t seq, void *ctxt)
client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = NULL;
char *ctype;
@ -1702,7 +1702,7 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt)
}
static int
client_input_channel_req(int type, u_int32_t seq, void *ctxt)
client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = NULL;
int exitval, id, reply, success = 0;
@ -1710,7 +1710,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
id = packet_get_int();
c = channel_lookup(id);
if (channel_proxy_upstream(c, type, seq, ctxt))
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
rtype = packet_get_string(NULL);
reply = packet_get_char();
@ -1816,9 +1816,9 @@ hostkeys_find(struct hostkey_foreach_line *l, void *_ctx)
/* This line contained a key that not offered by the server */
debug3("%s: deprecated %s key at %s:%ld", __func__,
sshkey_ssh_name(l->key), l->path, l->linenum);
if ((tmp = reallocarray(ctx->old_keys, ctx->nold + 1,
if ((tmp = recallocarray(ctx->old_keys, ctx->nold, ctx->nold + 1,
sizeof(*ctx->old_keys))) == NULL)
fatal("%s: reallocarray failed nold = %zu",
fatal("%s: recallocarray failed nold = %zu",
__func__, ctx->nold);
ctx->old_keys = tmp;
ctx->old_keys[ctx->nold++] = l->key;
@ -2050,9 +2050,9 @@ client_input_hostkeys(void)
}
}
/* Key is good, record it */
if ((tmp = reallocarray(ctx->keys, ctx->nkeys + 1,
if ((tmp = recallocarray(ctx->keys, ctx->nkeys, ctx->nkeys + 1,
sizeof(*ctx->keys))) == NULL)
fatal("%s: reallocarray failed nkeys = %zu",
fatal("%s: recallocarray failed nkeys = %zu",
__func__, ctx->nkeys);
ctx->keys = tmp;
ctx->keys[ctx->nkeys++] = key;
@ -2140,7 +2140,7 @@ client_input_hostkeys(void)
}
static int
client_input_global_request(int type, u_int32_t seq, void *ctxt)
client_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
{
char *rtype;
int want_reply;

View File

@ -1678,6 +1678,7 @@ AC_CHECK_FUNCS([ \
getgrouplist \
getnameinfo \
getopt \
getpagesize \
getpeereid \
getpeerucred \
getpgid \
@ -1708,6 +1709,7 @@ AC_CHECK_FUNCS([ \
readpassphrase \
reallocarray \
recvmsg \
recallocarray \
rresvport_af \
sendmsg \
setdtablesize \
@ -3162,7 +3164,8 @@ AC_RUN_IFELSE(
select_works_with_rlimit=yes],
[AC_MSG_RESULT([no])
select_works_with_rlimit=no],
[AC_MSG_WARN([cross compiling: assuming yes])]
[AC_MSG_WARN([cross compiling: assuming yes])
select_works_with_rlimit=yes]
)
AC_MSG_CHECKING([if setrlimit(RLIMIT_NOFILE,{0,0}) works])
@ -3188,7 +3191,8 @@ AC_RUN_IFELSE(
rlimit_nofile_zero_works=yes],
[AC_MSG_RESULT([no])
rlimit_nofile_zero_works=no],
[AC_MSG_WARN([cross compiling: assuming yes])]
[AC_MSG_WARN([cross compiling: assuming yes])
rlimit_nofile_zero_works=yes]
)
AC_MSG_CHECKING([if setrlimit RLIMIT_FSIZE works])

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dispatch.c,v 1.29 2017/04/30 23:28:42 djm Exp $ */
/* $OpenBSD: dispatch.c,v 1.31 2017/05/31 07:00:13 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -38,9 +38,8 @@
#include "ssherr.h"
int
dispatch_protocol_error(int type, u_int32_t seq, void *ctx)
dispatch_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = active_state; /* XXX */
int r;
logit("dispatch_protocol_error: type %d seq %u", type, seq);
@ -53,7 +52,7 @@ dispatch_protocol_error(int type, u_int32_t seq, void *ctx)
}
int
dispatch_protocol_ignore(int type, u_int32_t seq, void *ssh)
dispatch_protocol_ignore(int type, u_int32_t seq, struct ssh *ssh)
{
logit("dispatch_protocol_ignore: type %d seq %u", type, seq);
return 0;
@ -86,8 +85,7 @@ ssh_dispatch_set(struct ssh *ssh, int type, dispatch_fn *fn)
}
int
ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done,
void *ctxt)
ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done)
{
int r;
u_char type;
@ -112,8 +110,7 @@ ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done,
ssh->dispatch_skip_packets--;
continue;
}
/* XXX 'ssh' will replace 'ctxt' later */
r = (*ssh->dispatch[type])(type, seqnr, ctxt);
r = (*ssh->dispatch[type])(type, seqnr, ssh);
if (r != 0)
return r;
} else {
@ -129,11 +126,10 @@ ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done,
}
void
ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done,
void *ctxt)
ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done)
{
int r;
if ((r = ssh_dispatch_run(ssh, mode, done, ctxt)) != 0)
if ((r = ssh_dispatch_run(ssh, mode, done)) != 0)
sshpkt_fatal(ssh, __func__, r);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dispatch.h,v 1.12 2015/01/19 20:07:45 markus Exp $ */
/* $OpenBSD: dispatch.h,v 1.14 2017/05/31 07:00:13 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -36,15 +36,15 @@ enum {
struct ssh;
typedef int dispatch_fn(int, u_int32_t, void *);
typedef int dispatch_fn(int, u_int32_t, struct ssh *);
int dispatch_protocol_error(int, u_int32_t, void *);
int dispatch_protocol_ignore(int, u_int32_t, void *);
int dispatch_protocol_error(int, u_int32_t, struct ssh *);
int dispatch_protocol_ignore(int, u_int32_t, struct ssh *);
void ssh_dispatch_init(struct ssh *, dispatch_fn *);
void ssh_dispatch_set(struct ssh *, int, dispatch_fn *);
void ssh_dispatch_range(struct ssh *, u_int, u_int, dispatch_fn *);
int ssh_dispatch_run(struct ssh *, int, volatile sig_atomic_t *, void *);
void ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *, void *);
int ssh_dispatch_run(struct ssh *, int, volatile sig_atomic_t *);
void ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *);
#define dispatch_init(dflt) \
ssh_dispatch_init(active_state, (dflt))
@ -52,7 +52,5 @@ void ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *, void *);
ssh_dispatch_range(active_state, (from), (to), (fn))
#define dispatch_set(type, fn) \
ssh_dispatch_set(active_state, (type), (fn))
#define dispatch_run(mode, done, ctxt) \
ssh_dispatch_run_fatal(active_state, (mode), (done), (ctxt))
#endif

View File

@ -1,4 +1,4 @@
/* $OpenBSD: hostfile.c,v 1.70 2017/04/30 23:18:44 djm Exp $ */
/* $OpenBSD: hostfile.c,v 1.71 2017/05/31 09:15:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -251,7 +251,7 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx)
l->marker == MRK_NONE ? "" :
(l->marker == MRK_CA ? "ca " : "revoked "),
sshkey_type(l->key), l->path, l->linenum);
if ((tmp = reallocarray(hostkeys->entries,
if ((tmp = recallocarray(hostkeys->entries, hostkeys->num_entries,
hostkeys->num_entries + 1, sizeof(*hostkeys->entries))) == NULL)
return SSH_ERR_ALLOC_FAIL;
hostkeys->entries = tmp;

16
kex.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.c,v 1.132 2017/04/30 23:10:43 djm Exp $ */
/* $OpenBSD: kex.c,v 1.133 2017/05/30 14:23:52 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@ -56,7 +56,7 @@
/* prototype */
static int kex_choose_conf(struct ssh *);
static int kex_input_newkeys(int, u_int32_t, void *);
static int kex_input_newkeys(int, u_int32_t, struct ssh *);
static const char *proposal_names[PROPOSAL_MAX] = {
"KEX algorithms",
@ -315,9 +315,8 @@ kex_prop_free(char **proposal)
/* ARGSUSED */
static int
kex_protocol_error(int type, u_int32_t seq, void *ctxt)
kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = active_state; /* XXX */
int r;
error("kex protocol error: type %d seq %u", type, seq);
@ -375,9 +374,8 @@ kex_send_newkeys(struct ssh *ssh)
}
int
kex_input_ext_info(int type, u_int32_t seq, void *ctxt)
kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
u_int32_t i, ninfo;
char *name, *val, *found;
@ -414,9 +412,8 @@ kex_input_ext_info(int type, u_int32_t seq, void *ctxt)
}
static int
kex_input_newkeys(int type, u_int32_t seq, void *ctxt)
kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
int r;
@ -467,9 +464,8 @@ kex_send_kexinit(struct ssh *ssh)
/* ARGSUSED */
int
kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
const u_char *ptr;
u_int i;

6
kex.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.h,v 1.82 2017/05/03 21:08:09 naddy Exp $ */
/* $OpenBSD: kex.h,v 1.83 2017/05/30 14:23:52 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -181,8 +181,8 @@ int kex_prop2buf(struct sshbuf *, char *proposal[PROPOSAL_MAX]);
void kex_prop_free(char **);
int kex_send_kexinit(struct ssh *);
int kex_input_kexinit(int, u_int32_t, void *);
int kex_input_ext_info(int, u_int32_t, void *);
int kex_input_kexinit(int, u_int32_t, struct ssh *);
int kex_input_ext_info(int, u_int32_t, struct ssh *);
int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *);
int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *);
int kex_send_newkeys(struct ssh *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexc25519c.c,v 1.7 2015/01/26 06:10:03 djm Exp $ */
/* $OpenBSD: kexc25519c.c,v 1.8 2017/05/31 04:17:12 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@ -44,7 +44,7 @@
#include "ssherr.h"
static int
input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt);
input_kex_c25519_reply(int type, u_int32_t seq, struct ssh *ssh);
int
kexc25519_client(struct ssh *ssh)
@ -69,9 +69,8 @@ kexc25519_client(struct ssh *ssh)
}
static int
input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt)
input_kex_c25519_reply(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
struct sshkey *server_host_key = NULL;
struct sshbuf *shared_secret = NULL;

View File

@ -41,7 +41,7 @@
#include "sshbuf.h"
#include "ssherr.h"
static int input_kex_c25519_init(int, u_int32_t, void *);
static int input_kex_c25519_init(int, u_int32_t, struct ssh *);
int
kexc25519_server(struct ssh *ssh)
@ -52,9 +52,8 @@ kexc25519_server(struct ssh *ssh)
}
static int
input_kex_c25519_init(int type, u_int32_t seq, void *ctxt)
input_kex_c25519_init(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
struct sshkey *server_host_private, *server_host_public;
struct sshbuf *shared_secret = NULL;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexdhc.c,v 1.19 2016/05/02 10:26:04 djm Exp $ */
/* $OpenBSD: kexdhc.c,v 1.20 2017/05/30 14:23:52 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -49,7 +49,7 @@
#include "ssherr.h"
#include "sshbuf.h"
static int input_kex_dh(int, u_int32_t, void *);
static int input_kex_dh(int, u_int32_t, struct ssh *);
int
kexdh_client(struct ssh *ssh)
@ -100,9 +100,8 @@ kexdh_client(struct ssh *ssh)
}
static int
input_kex_dh(int type, u_int32_t seq, void *ctxt)
input_kex_dh(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
struct sshkey *server_host_key = NULL;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexdhs.c,v 1.24 2016/05/02 10:26:04 djm Exp $ */
/* $OpenBSD: kexdhs.c,v 1.25 2017/05/30 14:23:52 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -49,7 +49,7 @@
#include "ssherr.h"
#include "sshbuf.h"
static int input_kex_dh_init(int, u_int32_t, void *);
static int input_kex_dh_init(int, u_int32_t, struct ssh *);
int
kexdh_server(struct ssh *ssh)
@ -91,9 +91,8 @@ kexdh_server(struct ssh *ssh)
}
int
input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
struct sshkey *server_host_public, *server_host_private;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexecdhc.c,v 1.10 2015/01/26 06:10:03 djm Exp $ */
/* $OpenBSD: kexecdhc.c,v 1.11 2017/05/30 14:23:52 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@ -49,7 +49,7 @@
#include "ssherr.h"
#include "sshbuf.h"
static int input_kex_ecdh_reply(int, u_int32_t, void *);
static int input_kex_ecdh_reply(int, u_int32_t, struct ssh *);
int
kexecdh_client(struct ssh *ssh)
@ -95,9 +95,8 @@ kexecdh_client(struct ssh *ssh)
}
static int
input_kex_ecdh_reply(int type, u_int32_t seq, void *ctxt)
input_kex_ecdh_reply(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
const EC_GROUP *group;
EC_POINT *server_public = NULL;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexecdhs.c,v 1.15 2015/12/04 16:41:28 markus Exp $ */
/* $OpenBSD: kexecdhs.c,v 1.16 2017/05/30 14:23:52 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@ -47,7 +47,7 @@
#include "ssherr.h"
#include "sshbuf.h"
static int input_kex_ecdh_init(int, u_int32_t, void *);
static int input_kex_ecdh_init(int, u_int32_t, struct ssh *);
int
kexecdh_server(struct ssh *ssh)
@ -58,9 +58,8 @@ kexecdh_server(struct ssh *ssh)
}
static int
input_kex_ecdh_init(int type, u_int32_t seq, void *ctxt)
input_kex_ecdh_init(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
EC_POINT *client_public;
EC_KEY *server_key = NULL;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexgexc.c,v 1.24 2017/05/16 16:56:15 djm Exp $ */
/* $OpenBSD: kexgexc.c,v 1.25 2017/05/30 14:23:52 markus Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -51,8 +51,8 @@
#include "sshbuf.h"
#include "misc.h"
static int input_kex_dh_gex_group(int, u_int32_t, void *);
static int input_kex_dh_gex_reply(int, u_int32_t, void *);
static int input_kex_dh_gex_group(int, u_int32_t, struct ssh *);
static int input_kex_dh_gex_reply(int, u_int32_t, struct ssh *);
int
kexgex_client(struct ssh *ssh)
@ -89,9 +89,8 @@ kexgex_client(struct ssh *ssh)
}
static int
input_kex_dh_gex_group(int type, u_int32_t seq, void *ctxt)
input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
BIGNUM *p = NULL, *g = NULL;
int r, bits;
@ -143,9 +142,8 @@ out:
}
static int
input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt)
input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
struct sshkey *server_host_key = NULL;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexgexs.c,v 1.30 2016/09/12 01:22:38 deraadt Exp $ */
/* $OpenBSD: kexgexs.c,v 1.31 2017/05/30 14:23:52 markus Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -54,8 +54,8 @@
#include "sshbuf.h"
#include "misc.h"
static int input_kex_dh_gex_request(int, u_int32_t, void *);
static int input_kex_dh_gex_init(int, u_int32_t, void *);
static int input_kex_dh_gex_request(int, u_int32_t, struct ssh *);
static int input_kex_dh_gex_init(int, u_int32_t, struct ssh *);
int
kexgex_server(struct ssh *ssh)
@ -67,9 +67,8 @@ kexgex_server(struct ssh *ssh)
}
static int
input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
input_kex_dh_gex_request(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
int r;
u_int min = 0, max = 0, nbits = 0;
@ -120,9 +119,8 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
}
static int
input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt)
input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh)
{
struct ssh *ssh = ctxt;
struct kex *kex = ssh->kex;
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
struct sshkey *server_host_public, *server_host_private;

177
key.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: key.c,v 1.130 2016/05/02 09:36:42 djm Exp $ */
/* $OpenBSD: key.c,v 1.131 2017/05/30 14:16:41 markus Exp $ */
/*
* placed in the public domain
*/
@ -20,68 +20,6 @@
#include "log.h"
#include "authfile.h"
void
key_add_private(Key *k)
{
int r;
if ((r = sshkey_add_private(k)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
Key *
key_new_private(int type)
{
Key *ret = NULL;
if ((ret = sshkey_new_private(type)) == NULL)
fatal("%s: failed", __func__);
return ret;
}
int
key_read(Key *ret, char **cpp)
{
return sshkey_read(ret, cpp) == 0 ? 1 : -1;
}
int
key_write(const Key *key, FILE *f)
{
return sshkey_write(key, f) == 0 ? 1 : 0;
}
Key *
key_generate(int type, u_int bits)
{
int r;
Key *ret = NULL;
if ((r = sshkey_generate(type, bits, &ret)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
return ret;
}
void
key_cert_copy(const Key *from_key, Key *to_key)
{
int r;
if ((r = sshkey_cert_copy(from_key, to_key)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
Key *
key_from_private(const Key *k)
{
int r;
Key *ret = NULL;
if ((r = sshkey_from_private(k, &ret)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
return ret;
}
static void
fatal_on_fatal_errors(int r, const char *func, int extra_fatal)
{
@ -183,19 +121,6 @@ key_demote(const Key *k)
return ret;
}
int
key_to_certified(Key *k)
{
int r;
if ((r = sshkey_to_certified(k)) != 0) {
fatal_on_fatal_errors(r, __func__, 0);
error("%s: %s", __func__, ssh_err(r));
return -1;
}
return 0;
}
int
key_drop_cert(Key *k)
{
@ -209,19 +134,6 @@ key_drop_cert(Key *k)
return 0;
}
int
key_certify(Key *k, Key *ca)
{
int r;
if ((r = sshkey_certify(k, ca, NULL)) != 0) {
fatal_on_fatal_errors(r, __func__, 0);
error("%s: %s", __func__, ssh_err(r));
return -1;
}
return 0;
}
int
key_cert_check_authority(const Key *k, int want_host, int require_principal,
const char *name, const char **reason)
@ -237,88 +149,8 @@ key_cert_check_authority(const Key *k, int want_host, int require_principal,
return 0;
}
#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
int
key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
{
int r;
if ((r = sshkey_ec_validate_public(group, public)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
error("%s: %s", __func__, ssh_err(r));
return -1;
}
return 0;
}
int
key_ec_validate_private(const EC_KEY *key)
{
int r;
if ((r = sshkey_ec_validate_private(key)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
error("%s: %s", __func__, ssh_err(r));
return -1;
}
return 0;
}
#endif /* WITH_OPENSSL */
void
key_private_serialize(const Key *key, struct sshbuf *b)
{
int r;
if ((r = sshkey_private_serialize(key, b)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
Key *
key_private_deserialize(struct sshbuf *blob)
{
int r;
Key *ret = NULL;
if ((r = sshkey_private_deserialize(blob, &ret)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
error("%s: %s", __func__, ssh_err(r));
return NULL;
}
return ret;
}
/* authfile.c */
int
key_save_private(Key *key, const char *filename, const char *passphrase,
const char *comment, int force_new_format, const char *new_format_cipher,
int new_format_rounds)
{
int r;
if ((r = sshkey_save_private(key, filename, passphrase, comment,
force_new_format, new_format_cipher, new_format_rounds)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
error("%s: %s", __func__, ssh_err(r));
return 0;
}
return 1;
}
int
key_load_file(int fd, const char *filename, struct sshbuf *blob)
{
int r;
if ((r = sshkey_load_file(fd, blob)) != 0) {
fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
error("%s: %s", __func__, ssh_err(r));
return 0;
}
return 1;
}
Key *
key_load_cert(const char *filename)
{
@ -417,10 +249,3 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
}
return ret;
}
int
key_perm_ok(int fd, const char *filename)
{
return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0;
}

36
key.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: key.h,v 1.50 2016/09/12 23:31:27 djm Exp $ */
/* $OpenBSD: key.h,v 1.51 2017/05/30 14:16:41 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -35,51 +35,24 @@ typedef struct sshkey Key;
#define fp_rep sshkey_fp_rep
#ifndef SSH_KEY_NO_DEFINE
#define key_new sshkey_new
#define key_free sshkey_free
#define key_equal_public sshkey_equal_public
#define key_equal sshkey_equal
#define key_type sshkey_type
#define key_cert_type sshkey_cert_type
#define key_ssh_name sshkey_ssh_name
#define key_ssh_name_plain sshkey_ssh_name_plain
#define key_type_from_name sshkey_type_from_name
#define key_ecdsa_nid_from_name sshkey_ecdsa_nid_from_name
#define key_type_is_cert sshkey_type_is_cert
#define key_size sshkey_size
#define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid
#define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid
#define key_is_cert sshkey_is_cert
#define key_type_plain sshkey_type_plain
#define key_curve_name_to_nid sshkey_curve_name_to_nid
#define key_curve_nid_to_bits sshkey_curve_nid_to_bits
#define key_curve_nid_to_name sshkey_curve_nid_to_name
#define key_ec_nid_to_hash_alg sshkey_ec_nid_to_hash_alg
#define key_dump_ec_point sshkey_dump_ec_point
#define key_dump_ec_key sshkey_dump_ec_key
#endif
void key_add_private(Key *);
Key *key_new_private(int);
void key_free(Key *);
Key *key_demote(const Key *);
int key_write(const Key *, FILE *);
int key_read(Key *, char **);
Key *key_generate(int, u_int);
Key *key_from_private(const Key *);
int key_to_certified(Key *);
int key_drop_cert(Key *);
int key_certify(Key *, Key *);
void key_cert_copy(const Key *, Key *);
int key_cert_check_authority(const Key *, int, int, const char *,
const char **);
#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
int key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
int key_ec_validate_private(const EC_KEY *);
#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */
Key *key_from_blob(const u_char *, u_int);
int key_to_blob(const Key *, u_char **, u_int *);
@ -87,18 +60,11 @@ int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int,
const char *);
int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
void key_private_serialize(const Key *, struct sshbuf *);
Key *key_private_deserialize(struct sshbuf *);
/* authfile.c */
int key_save_private(Key *, const char *, const char *, const char *,
int, const char *, int);
int key_load_file(int, const char *, struct sshbuf *);
Key *key_load_cert(const char *);
Key *key_load_public(const char *, char **);
Key *key_load_private(const char *, const char *, char **);
Key *key_load_private_cert(int, const char *, const char *, int *);
Key *key_load_private_type(int, const char *, const char *, char **, int *);
int key_perm_ok(int, const char *);
#endif

4
krl.c
View File

@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $OpenBSD: krl.c,v 1.39 2017/03/10 07:18:32 dtucker Exp $ */
/* $OpenBSD: krl.c,v 1.40 2017/05/31 09:15:42 deraadt Exp $ */
#include "includes.h"
@ -1026,7 +1026,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
}
}
/* Record keys used to sign the KRL */
tmp_ca_used = reallocarray(ca_used, nca_used + 1,
tmp_ca_used = recallocarray(ca_used, nca_used, nca_used + 1,
sizeof(*ca_used));
if (tmp_ca_used == NULL) {
r = SSH_ERR_ALLOC_FAIL;

4
misc.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.109 2017/03/14 00:55:37 dtucker Exp $ */
/* $OpenBSD: misc.c,v 1.110 2017/05/31 09:15:42 deraadt Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@ -554,7 +554,7 @@ addargs(arglist *args, char *fmt, ...)
} else if (args->num+2 >= nalloc)
nalloc *= 2;
args->list = xreallocarray(args->list, nalloc, sizeof(char *));
args->list = xrecallocarray(args->list, args->nalloc, nalloc, sizeof(char *));
args->nalloc = nalloc;
args->list[args->num++] = cp;
args->list[args->num] = NULL;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.167 2017/02/03 23:05:57 djm Exp $ */
/* $OpenBSD: monitor.c,v 1.171 2017/05/31 10:04:29 markus Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -1119,7 +1119,7 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
int
mm_answer_keyallowed(int sock, Buffer *m)
{
Key *key;
struct sshkey *key;
char *cuser, *chost;
u_char *blob;
u_int bloblen, pubkey_auth_attempt;
@ -1330,25 +1330,25 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
}
int
mm_answer_keyverify(int sock, Buffer *m)
mm_answer_keyverify(int sock, struct sshbuf *m)
{
Key *key;
struct sshkey *key;
u_char *signature, *data, *blob;
u_int signaturelen, datalen, bloblen;
int verified = 0;
int valid_data = 0;
size_t signaturelen, datalen, bloblen;
int r, ret, valid_data = 0, encoded_ret;
blob = buffer_get_string(m, &bloblen);
signature = buffer_get_string(m, &signaturelen);
data = buffer_get_string(m, &datalen);
if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 ||
(r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 ||
(r = sshbuf_get_string(m, &data, &datalen)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (hostbased_cuser == NULL || hostbased_chost == NULL ||
!monitor_allowed_key(blob, bloblen))
fatal("%s: bad key, not previously allowed", __func__);
key = key_from_blob(blob, bloblen);
if (key == NULL)
fatal("%s: bad public key blob", __func__);
/* XXX use sshkey_froms here; need to change key_blob, etc. */
if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0)
fatal("%s: bad public key blob: %s", __func__, ssh_err(r));
switch (key_blobtype) {
case MM_USERKEY:
@ -1365,15 +1365,16 @@ mm_answer_keyverify(int sock, Buffer *m)
if (!valid_data)
fatal("%s: bad signature data blob", __func__);
verified = key_verify(key, signature, signaturelen, data, datalen);
ret = sshkey_verify(key, signature, signaturelen, data, datalen,
active_state->compat);
debug3("%s: key %p signature %s",
__func__, key, (verified == 1) ? "verified" : "unverified");
__func__, key, (ret == 0) ? "verified" : "unverified");
/* If auth was successful then record key to ensure it isn't reused */
if (verified == 1 && key_blobtype == MM_USERKEY)
if (ret == 0 && key_blobtype == MM_USERKEY)
auth2_record_userkey(authctxt, key);
else
key_free(key);
sshkey_free(key);
free(blob);
free(signature);
@ -1383,11 +1384,15 @@ mm_answer_keyverify(int sock, Buffer *m)
monitor_reset_key_state();
buffer_clear(m);
buffer_put_int(m, verified);
sshbuf_reset(m);
/* encode ret != 0 as positive integer, since we're sending u32 */
encoded_ret = (ret != 0);
if ((r = sshbuf_put_u32(m, encoded_ret)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
return (verified == 1);
return ret == 0;
}
static void
@ -1578,6 +1583,17 @@ mm_answer_audit_command(int socket, Buffer *m)
}
#endif /* SSH_AUDIT_EVENTS */
void
monitor_clear_keystate(struct monitor *pmonitor)
{
struct ssh *ssh = active_state; /* XXX */
ssh_clear_newkeys(ssh, MODE_IN);
ssh_clear_newkeys(ssh, MODE_OUT);
sshbuf_free(child_state);
child_state = NULL;
}
void
monitor_apply_keystate(struct monitor *pmonitor)
{
@ -1639,9 +1655,18 @@ static void
monitor_openfds(struct monitor *mon, int do_logfds)
{
int pair[2];
#ifdef SO_ZEROIZE
int on = 1;
#endif
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
fatal("%s: socketpair: %s", __func__, strerror(errno));
#ifdef SO_ZEROIZE
if (setsockopt(pair[0], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
error("setsockopt SO_ZEROIZE(0): %.100s", strerror(errno));
if (setsockopt(pair[1], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
error("setsockopt SO_ZEROIZE(1): %.100s", strerror(errno));
#endif
FD_CLOSEONEXEC(pair[0]);
FD_CLOSEONEXEC(pair[1]);
mon->m_recvfd = pair[0];

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.c,v 1.90 2017/05/17 01:24:17 djm Exp $ */
/* $OpenBSD: monitor_wrap.c,v 1.92 2017/05/30 14:10:53 markus Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -216,7 +216,7 @@ mm_choose_dh(int min, int nbits, int max)
#endif
int
mm_key_sign(Key *key, u_char **sigp, u_int *lenp,
mm_key_sign(struct sshkey *key, u_char **sigp, u_int *lenp,
const u_char *data, u_int datalen, const char *hostkey_alg)
{
struct kex *kex = *pmonitor->m_pkex;
@ -375,7 +375,8 @@ mm_auth_password(Authctxt *authctxt, char *password)
}
int
mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt)
mm_user_key_allowed(struct passwd *pw, struct sshkey *key,
int pubkey_auth_attempt)
{
return (mm_key_allowed(MM_USERKEY, NULL, NULL, key,
pubkey_auth_attempt));
@ -383,14 +384,14 @@ mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt)
int
mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host,
Key *key)
struct sshkey *key)
{
return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0));
}
int
mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
Key *key, int pubkey_auth_attempt)
struct sshkey *key, int pubkey_auth_attempt)
{
Buffer m;
u_char *blob;
@ -435,12 +436,13 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
*/
int
mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
const u_char *data, size_t datalen, u_int compat)
{
Buffer m;
u_char *blob;
u_int len;
int verified = 0;
u_int encoded_ret = 0;
debug3("%s entering", __func__);
@ -459,11 +461,13 @@ mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
verified = buffer_get_int(&m);
encoded_ret = buffer_get_int(&m);
buffer_free(&m);
return (verified);
if (encoded_ret != 0)
return SSH_ERR_SIGNATURE_INVALID;
return 0;
}
void

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.h,v 1.32 2016/09/28 16:33:07 djm Exp $ */
/* $OpenBSD: monitor_wrap.h,v 1.35 2017/05/31 08:09:45 markus Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -34,22 +34,24 @@ extern int use_privsep;
enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY };
struct monitor;
struct mm_master;
struct Authctxt;
void mm_log_handler(LogLevel, const char *, void *);
int mm_is_monitor(void);
DH *mm_choose_dh(int, int, int);
int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *);
int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int,
const char *);
void mm_inform_authserv(char *, char *);
struct passwd *mm_getpwnamallow(const char *);
char *mm_auth2_read_banner(void);
int mm_auth_password(struct Authctxt *, char *);
int mm_key_allowed(enum mm_keytype, const char *, const char *, Key *, int);
int mm_user_key_allowed(struct passwd *, Key *, int);
int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *,
int);
int mm_user_key_allowed(struct passwd *, struct sshkey *, int);
int mm_hostbased_key_allowed(struct passwd *, const char *,
const char *, Key *);
int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);
const char *, struct sshkey *);
int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
const u_char *, size_t, u_int);
#ifdef GSSAPI
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
@ -83,6 +85,7 @@ void mm_session_pty_cleanup2(struct Session *);
struct newkeys *mm_newkeys_from_blob(u_char *, int);
int mm_newkeys_to_blob(int, u_char **, u_int *);
void monitor_clear_keystate(struct monitor *);
void monitor_apply_keystate(struct monitor *);
void mm_get_keystate(struct monitor *);
void mm_send_keystate(struct monitor*);

View File

@ -149,5 +149,7 @@ void packet_disconnect(const char *, ...)
ssh_packet_set_mux(active_state)
#define packet_get_mux() \
ssh_packet_get_mux(active_state)
#define packet_clear_keys() \
ssh_packet_clear_keys(active_state)
#endif /* _OPACKET_H */

View File

@ -16,9 +16,9 @@ RANLIB=@RANLIB@
INSTALL=@INSTALL@
LDFLAGS=-L. @LDFLAGS@
OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strcasestr.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o
OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o recallocarray.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strcasestr.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o
COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o
COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o
PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o

View File

@ -0,0 +1,23 @@
/* Placed in the public domain */
#ifndef HAVE_GETPAGESIZE
#include <unistd.h>
#include <limits.h>
int
getpagesize(void)
{
#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
long r = sysconf(_SC_PAGESIZE);
if (r > 0 && r < INT_MAX)
return (int)r;
#endif
/*
* This is at the lower end of common values and appropriate for
* our current use of getpagesize() in recallocarray().
*/
return 4096;
}
#endif /* HAVE_GETPAGESIZE */

View File

@ -60,6 +60,10 @@ int bindresvport_sa(int sd, struct sockaddr *sa);
void closefrom(int);
#endif
#ifndef HAVE_GETPAGESIZE
int getpagesize(void);
#endif
#ifndef HAVE_GETCWD
char *getcwd(char *pt, size_t size);
#endif
@ -68,6 +72,10 @@ char *getcwd(char *pt, size_t size);
void *reallocarray(void *, size_t, size_t);
#endif
#ifndef HAVE_RECALLOCARRAY
void *recallocarray(void *, size_t, size_t, size_t);
#endif
#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
/*
* glibc's FORTIFY_SOURCE can redefine this and prevent us picking up the

View File

@ -0,0 +1,88 @@
/* $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $ */
/*
* Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
*
* 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 ORIGINAL: lib/libc/stdlib/recallocarray.c */
#include "includes.h"
#ifndef HAVE_RECALLOCARRAY
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
/*
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
*/
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
void *
recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
{
size_t oldsize, newsize;
void *newptr;
if (ptr == NULL)
return calloc(newnmemb, size);
if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
newnmemb > 0 && SIZE_MAX / newnmemb < size) {
errno = ENOMEM;
return NULL;
}
newsize = newnmemb * size;
if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
errno = EINVAL;
return NULL;
}
oldsize = oldnmemb * size;
/*
* Don't bother too much if we're shrinking just a bit,
* we do not shrink for series of small steps, oh well.
*/
if (newsize <= oldsize) {
size_t d = oldsize - newsize;
if (d < oldsize / 2 && d < (size_t)getpagesize()) {
memset((char *)ptr + newsize, 0, d);
return ptr;
}
}
newptr = malloc(newsize);
if (newptr == NULL)
return NULL;
if (newsize > oldsize) {
memcpy(newptr, ptr, oldsize);
memset((char *)newptr + oldsize, 0, newsize - oldsize);
} else
memcpy(newptr, ptr, newsize);
explicit_bzero(ptr, oldsize);
free(ptr);
return newptr;
}
/* DEF_WEAK(recallocarray); */
#endif /* HAVE_RECALLOCARRAY */

101
packet.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.256 2017/05/08 06:03:39 djm Exp $ */
/* $OpenBSD: packet.c,v 1.260 2017/06/06 09:12:17 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -559,8 +559,8 @@ ssh_local_port(struct ssh *ssh)
/* Closes the connection and clears and frees internal data structures. */
void
ssh_packet_close(struct ssh *ssh)
static void
ssh_packet_close_internal(struct ssh *ssh, int do_close)
{
struct session_state *state = ssh->state;
u_int mode;
@ -568,20 +568,25 @@ ssh_packet_close(struct ssh *ssh)
if (!state->initialized)
return;
state->initialized = 0;
if (state->connection_in == state->connection_out) {
shutdown(state->connection_out, SHUT_RDWR);
close(state->connection_out);
} else {
close(state->connection_in);
close(state->connection_out);
if (do_close) {
if (state->connection_in == state->connection_out) {
close(state->connection_out);
} else {
close(state->connection_in);
close(state->connection_out);
}
}
sshbuf_free(state->input);
sshbuf_free(state->output);
sshbuf_free(state->outgoing_packet);
sshbuf_free(state->incoming_packet);
for (mode = 0; mode < MODE_MAX; mode++)
kex_free_newkeys(state->newkeys[mode]);
if (state->compression_buffer) {
for (mode = 0; mode < MODE_MAX; mode++) {
kex_free_newkeys(state->newkeys[mode]); /* current keys */
state->newkeys[mode] = NULL;
ssh_clear_newkeys(ssh, mode); /* next keys */
}
/* comression state is in shared mem, so we can only release it once */
if (do_close && state->compression_buffer) {
sshbuf_free(state->compression_buffer);
if (state->compression_out_started) {
z_streamp stream = &state->compression_out_stream;
@ -595,7 +600,7 @@ ssh_packet_close(struct ssh *ssh)
deflateEnd(stream);
}
if (state->compression_in_started) {
z_streamp stream = &state->compression_out_stream;
z_streamp stream = &state->compression_in_stream;
debug("compress incoming: "
"raw data %llu, compressed %llu, factor %.2f",
(unsigned long long)stream->total_out,
@ -609,10 +614,24 @@ ssh_packet_close(struct ssh *ssh)
cipher_free(state->send_context);
cipher_free(state->receive_context);
state->send_context = state->receive_context = NULL;
free(ssh->remote_ipaddr);
ssh->remote_ipaddr = NULL;
free(ssh->state);
ssh->state = NULL;
if (do_close) {
free(ssh->remote_ipaddr);
ssh->remote_ipaddr = NULL;
free(ssh->state);
ssh->state = NULL;
}
}
void
ssh_packet_close(struct ssh *ssh)
{
ssh_packet_close_internal(ssh, 1);
}
void
ssh_packet_clear_keys(struct ssh *ssh)
{
ssh_packet_close_internal(ssh, 0);
}
/* Sets remote side protocol flags. */
@ -791,6 +810,15 @@ uncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out)
/* NOTREACHED */
}
void
ssh_clear_newkeys(struct ssh *ssh, int mode)
{
if (ssh->kex && ssh->kex->newkeys[mode]) {
kex_free_newkeys(ssh->kex->newkeys[mode]);
ssh->kex->newkeys[mode] = NULL;
}
}
int
ssh_set_newkeys(struct ssh *ssh, int mode)
{
@ -801,45 +829,33 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
struct sshcipher_ctx **ccp;
struct packet_state *ps;
u_int64_t *max_blocks;
const char *wmsg, *dir;
const char *wmsg;
int r, crypt_type;
debug2("set_newkeys: mode %d", mode);
if (mode == MODE_OUT) {
dir = "output";
ccp = &state->send_context;
crypt_type = CIPHER_ENCRYPT;
ps = &state->p_send;
max_blocks = &state->max_blocks_out;
} else {
dir = "input";
ccp = &state->receive_context;
crypt_type = CIPHER_DECRYPT;
ps = &state->p_read;
max_blocks = &state->max_blocks_in;
}
if (state->newkeys[mode] != NULL) {
debug("%s: rekeying after %llu %s blocks"
" (%llu bytes total)", __func__,
(unsigned long long)ps->blocks, dir,
(unsigned long long)ps->bytes);
debug("set_newkeys: rekeying, input %llu bytes %llu blocks, "
"output %llu bytes %llu blocks",
(unsigned long long)state->p_read.bytes,
(unsigned long long)state->p_read.blocks,
(unsigned long long)state->p_send.bytes,
(unsigned long long)state->p_send.blocks);
cipher_free(*ccp);
*ccp = NULL;
enc = &state->newkeys[mode]->enc;
mac = &state->newkeys[mode]->mac;
comp = &state->newkeys[mode]->comp;
mac_clear(mac);
explicit_bzero(enc->iv, enc->iv_len);
explicit_bzero(enc->key, enc->key_len);
explicit_bzero(mac->key, mac->key_len);
free(enc->name);
free(enc->iv);
free(enc->key);
free(mac->name);
free(mac->key);
free(comp->name);
free(state->newkeys[mode]);
kex_free_newkeys(state->newkeys[mode]);
state->newkeys[mode] = NULL;
}
/* note that both bytes and the seqnr are not reset */
ps->packets = ps->blocks = 0;
@ -1784,15 +1800,20 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
switch (r) {
case SSH_ERR_CONN_CLOSED:
ssh_packet_clear_keys(ssh);
logdie("Connection closed by %s", remote_id);
case SSH_ERR_CONN_TIMEOUT:
ssh_packet_clear_keys(ssh);
logdie("Connection %s %s timed out",
ssh->state->server_side ? "from" : "to", remote_id);
case SSH_ERR_DISCONNECTED:
ssh_packet_clear_keys(ssh);
logdie("Disconnected from %s", remote_id);
case SSH_ERR_SYSTEM_ERROR:
if (errno == ECONNRESET)
if (errno == ECONNRESET) {
ssh_packet_clear_keys(ssh);
logdie("Connection reset by %s", remote_id);
}
/* FALLTHROUGH */
case SSH_ERR_NO_CIPHER_ALG_MATCH:
case SSH_ERR_NO_MAC_ALG_MATCH:
@ -1800,12 +1821,14 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
case SSH_ERR_NO_KEX_ALG_MATCH:
case SSH_ERR_NO_HOSTKEY_ALG_MATCH:
if (ssh && ssh->kex && ssh->kex->failed_choice) {
ssh_packet_clear_keys(ssh);
logdie("Unable to negotiate with %s: %s. "
"Their offer: %s", remote_id, ssh_err(r),
ssh->kex->failed_choice);
}
/* FALLTHROUGH */
default:
ssh_packet_clear_keys(ssh);
logdie("%s%sConnection %s %s: %s",
tag != NULL ? tag : "", tag != NULL ? ": " : "",
ssh->state->server_side ? "from" : "to",

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.h,v 1.79 2017/05/03 21:08:09 naddy Exp $ */
/* $OpenBSD: packet.h,v 1.81 2017/05/31 08:09:45 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -77,6 +77,9 @@ struct ssh {
TAILQ_HEAD(, key_entry) private_keys;
TAILQ_HEAD(, key_entry) public_keys;
/* Client/Server authentication context */
void *authctxt;
/* APP data */
void *app_data;
};
@ -94,6 +97,8 @@ int ssh_packet_get_connection_in(struct ssh *);
int ssh_packet_get_connection_out(struct ssh *);
void ssh_packet_close(struct ssh *);
void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *);
void ssh_packet_clear_keys(struct ssh *);
void ssh_clear_newkeys(struct ssh *, int);
int ssh_packet_is_rekeying(struct ssh *);
void ssh_packet_set_protocol_flags(struct ssh *, u_int);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.275 2017/04/30 23:18:22 djm Exp $ */
/* $OpenBSD: readconf.c,v 1.277 2017/05/30 18:58:37 bluhm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -164,7 +164,8 @@ typedef enum {
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
oSendEnv, oControlPath, oControlMaster, oControlPersist,
oHashKnownHosts,
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
oTunnel, oTunnelDevice,
oLocalCommand, oPermitLocalCommand, oRemoteCommand,
oVisualHostKey,
oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
@ -285,6 +286,7 @@ static struct {
{ "tunneldevice", oTunnelDevice },
{ "localcommand", oLocalCommand },
{ "permitlocalcommand", oPermitLocalCommand },
{ "remotecommand", oRemoteCommand },
{ "visualhostkey", oVisualHostKey },
{ "kexalgorithms", oKexAlgorithms },
{ "ipqos", oIPQoS },
@ -439,8 +441,8 @@ add_identity_file(Options *options, const char *dir, const char *filename,
if (dir == NULL) /* no dir, filename is absolute */
path = xstrdup(filename);
else
(void)xasprintf(&path, "%.100s%.100s", dir, filename);
else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
fatal("Identity file path %s too long", path);
/* Avoid registering duplicates */
for (i = 0; i < options->num_identity_files; i++) {
@ -1446,6 +1448,10 @@ parse_keytypes:
intptr = &options->permit_local_command;
goto parse_flag;
case oRemoteCommand:
charptr = &options->remote_command;
goto parse_command;
case oVisualHostKey:
intptr = &options->visual_host_key;
goto parse_flag;
@ -1845,6 +1851,7 @@ initialize_options(Options * options)
options->tun_remote = -1;
options->local_command = NULL;
options->permit_local_command = -1;
options->remote_command = NULL;
options->add_keys_to_agent = -1;
options->identity_agent = NULL;
options->visual_host_key = -1;
@ -2049,6 +2056,7 @@ fill_default_options(Options * options)
} \
} while(0)
CLEAR_ON_NONE(options->local_command);
CLEAR_ON_NONE(options->remote_command);
CLEAR_ON_NONE(options->proxy_command);
CLEAR_ON_NONE(options->control_path);
CLEAR_ON_NONE(options->revoked_host_keys);
@ -2526,6 +2534,7 @@ dump_client_config(Options *o, const char *host)
dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
dump_cfg_string(oLocalCommand, o->local_command);
dump_cfg_string(oRemoteCommand, o->remote_command);
dump_cfg_string(oLogLevel, log_level_name(o->log_level));
dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
#ifdef ENABLE_PKCS11

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.h,v 1.121 2017/04/30 23:18:22 djm Exp $ */
/* $OpenBSD: readconf.h,v 1.122 2017/05/30 18:58:37 bluhm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -134,6 +134,7 @@ typedef struct {
char *local_command;
int permit_local_command;
char *remote_command;
int visual_host_key;
int request_tty;

View File

@ -1,4 +1,4 @@
# $OpenBSD: proto-version.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
# $OpenBSD: proto-version.sh,v 1.7 2017/06/07 01:48:15 djm Exp $
# Placed in the Public Domain.
tid="sshd version with different protocol combinations"
@ -6,7 +6,7 @@ tid="sshd version with different protocol combinations"
# we just start sshd in inetd mode and check the banner
check_version ()
{
expect=$2
expect=$1
banner=`printf '' | ${SSHD} -i -f ${OBJ}/sshd_proxy`
case ${banner} in
SSH-1.99-*)

8
scp.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: scp.c,v 1.191 2017/05/02 08:06:33 jmc Exp $ */
/* $OpenBSD: scp.c,v 1.192 2017/05/31 09:15:42 deraadt Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@ -1475,11 +1475,7 @@ allocbuf(BUF *bp, int fd, int blksize)
#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
if (bp->cnt >= size)
return (bp);
if (bp->buf == NULL)
bp->buf = xmalloc(size);
else
bp->buf = xreallocarray(bp->buf, 1, size);
memset(bp->buf, 0, size);
bp->buf = xrecallocarray(bp->buf, bp->cnt, size, 1);
bp->cnt = size;
return (bp);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: serverloop.c,v 1.191 2017/02/01 02:59:09 dtucker Exp $ */
/* $OpenBSD: serverloop.c,v 1.193 2017/05/31 07:00:13 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -323,7 +323,7 @@ process_output(fd_set *writeset, int connection_out)
static void
process_buffered_input_packets(void)
{
dispatch_run(DISPATCH_NONBLOCK, NULL, active_state);
ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, NULL);
}
static void
@ -417,7 +417,7 @@ server_loop2(Authctxt *authctxt)
}
static int
server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh)
{
debug("Got %d/%u for keepalive", type, seq);
/*
@ -579,7 +579,7 @@ server_request_session(void)
}
static int
server_input_channel_open(int type, u_int32_t seq, void *ctxt)
server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = NULL;
char *ctype;
@ -703,7 +703,7 @@ server_input_hostkeys_prove(struct sshbuf **respp)
}
static int
server_input_global_request(int type, u_int32_t seq, void *ctxt)
server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
{
char *rtype;
int want_reply;
@ -810,7 +810,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
}
static int
server_input_channel_req(int type, u_int32_t seq, void *ctxt)
server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c;
int id, reply, success = 0;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: session.c,v 1.286 2016/11/30 03:00:05 djm Exp $ */
/* $OpenBSD: session.c,v 1.288 2017/05/31 09:15:42 deraadt Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -1740,6 +1740,7 @@ do_child(Session *s, const char *command)
/* remove hostkey from the child's memory */
destroy_sensitive_data();
packet_clear_keys();
/* Force a password change */
if (s->authctxt->force_pwchange) {
@ -1965,8 +1966,8 @@ session_new(void)
return NULL;
debug2("%s: allocate (allocated %d max %d)",
__func__, sessions_nalloc, options.max_sessions);
tmp = xreallocarray(sessions, sessions_nalloc + 1,
sizeof(*sessions));
tmp = xrecallocarray(sessions, sessions_nalloc,
sessions_nalloc + 1, sizeof(*sessions));
if (tmp == NULL) {
error("%s: cannot allocate %d sessions",
__func__, sessions_nalloc + 1);
@ -2290,8 +2291,8 @@ session_env_req(Session *s)
for (i = 0; i < options.num_accept_env; i++) {
if (match_pattern(name, options.accept_env[i])) {
debug2("Setting env %d: %s=%s", s->num_env, name, val);
s->env = xreallocarray(s->env, s->num_env + 1,
sizeof(*s->env));
s->env = xrecallocarray(s->env, s->num_env,
s->num_env + 1, sizeof(*s->env));
s->env[s->num_env].name = name;
s->env[s->num_env].val = val;
s->num_env++;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-add.c,v 1.131 2017/05/05 10:42:49 naddy Exp $ */
/* $OpenBSD: ssh-add.c,v 1.132 2017/05/30 14:16:41 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -306,7 +306,7 @@ add_file(int agent_fd, const char *filename, int key_only)
goto out;
}
if ((r = sshkey_cert_copy(cert, private)) != 0) {
error("%s: key_cert_copy: %s", __func__, ssh_err(r));
error("%s: sshkey_cert_copy: %s", __func__, ssh_err(r));
sshkey_free(cert);
goto out;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.303 2017/05/07 23:15:59 djm Exp $ */
/* $OpenBSD: ssh-keygen.c,v 1.304 2017/05/30 14:16:41 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -493,7 +493,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
return NULL;
}
if ((key = sshkey_new_private(ktype)) == NULL)
fatal("key_new_private failed");
fatal("sshkey_new_private failed");
free(type);
switch (key->type) {
@ -775,7 +775,7 @@ do_print_public(struct passwd *pw)
fatal("%s: %s", identity_file, strerror(errno));
prv = load_identity(identity_file);
if ((r = sshkey_write(prv, stdout)) != 0)
error("key_write failed: %s", ssh_err(r));
error("sshkey_write failed: %s", ssh_err(r));
sshkey_free(prv);
fprintf(stdout, "\n");
exit(0);
@ -1024,7 +1024,7 @@ do_gen_all_hostkeys(struct passwd *pw)
bits = 0;
type_bits_valid(type, NULL, &bits);
if ((r = sshkey_generate(type, bits, &private)) != 0) {
error("key_generate failed: %s", ssh_err(r));
error("sshkey_generate failed: %s", ssh_err(r));
first = 0;
continue;
}
@ -1492,7 +1492,7 @@ do_change_comment(struct passwd *pw)
explicit_bzero(passphrase, strlen(passphrase));
free(passphrase);
if ((r = sshkey_from_private(private, &public)) != 0)
fatal("key_from_private failed: %s", ssh_err(r));
fatal("sshkey_from_private failed: %s", ssh_err(r));
sshkey_free(private);
strlcat(identity_file, ".pub", sizeof(identity_file));
@ -1680,7 +1680,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
OPTIONS_EXTENSIONS);
if ((r = sshkey_from_private(ca,
&public->cert->signature_key)) != 0)
fatal("key_from_private (ca key): %s", ssh_err(r));
fatal("sshkey_from_private (ca key): %s", ssh_err(r));
if ((r = sshkey_certify(public, ca, key_type_name)) != 0)
fatal("Couldn't certify key %s: %s", tmp, ssh_err(r));
@ -1998,7 +1998,7 @@ do_show_cert(struct passwd *pw)
if (*cp == '#' || *cp == '\0')
continue;
if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("key_new");
fatal("sshkey_new");
if ((r = sshkey_read(key, &cp)) != 0) {
error("%s:%lu: invalid key: %s", path,
lnum, ssh_err(r));
@ -2144,7 +2144,7 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
*/
}
if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("key_new");
fatal("sshkey_new");
if ((r = sshkey_read(key, &cp)) != 0)
fatal("%s:%lu: invalid key: %s",
path, lnum, ssh_err(r));
@ -2685,9 +2685,9 @@ main(int argc, char **argv)
printf("Generating public/private %s key pair.\n",
key_type_name);
if ((r = sshkey_generate(type, bits, &private)) != 0)
fatal("key_generate failed");
fatal("sshkey_generate failed");
if ((r = sshkey_from_private(private, &public)) != 0)
fatal("key_from_private failed: %s\n", ssh_err(r));
fatal("sshkey_from_private failed: %s\n", ssh_err(r));
if (!have_identity)
ask_filename(pw, "Enter file in which to save the key");

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keyscan.c,v 1.113 2017/04/30 23:28:42 djm Exp $ */
/* $OpenBSD: ssh-keyscan.c,v 1.114 2017/05/31 07:00:13 markus Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@ -276,7 +276,7 @@ keygrab_ssh2(con *c)
* do the key-exchange until an error occurs or until
* the key_print_wrapper() callback sets c_done.
*/
ssh_dispatch_run(c->c_ssh, DISPATCH_BLOCK, &c->c_done, c->c_ssh);
ssh_dispatch_run(c->c_ssh, DISPATCH_BLOCK, &c->c_done);
}
static void

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-pkcs11-client.c,v 1.6 2015/12/11 00:20:04 mmcc Exp $ */
/* $OpenBSD: ssh-pkcs11-client.c,v 1.7 2017/05/30 08:52:19 markus Exp $ */
/*
* Copyright (c) 2010 Markus Friedl. All rights reserved.
*
@ -106,7 +106,7 @@ static int
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
int padding)
{
Key key;
struct sshkey key; /* XXX */
u_char *blob, *signature = NULL;
u_int blen, slen = 0;
int ret = -1;
@ -186,7 +186,7 @@ pkcs11_start_helper(void)
int
pkcs11_add_provider(char *name, char *pin, Key ***keysp)
{
Key *k;
struct sshkey *k;
int i, nkeys;
u_char *blob;
u_int blen;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-pkcs11-helper.c,v 1.12 2016/02/15 09:47:49 dtucker Exp $ */
/* $OpenBSD: ssh-pkcs11-helper.c,v 1.13 2017/05/30 08:52:19 markus Exp $ */
/*
* Copyright (c) 2010 Markus Friedl. All rights reserved.
*
@ -42,7 +42,7 @@
/* borrows code from sftp-server and ssh-agent */
struct pkcs11_keyinfo {
Key *key;
struct sshkey *key;
char *providername;
TAILQ_ENTRY(pkcs11_keyinfo) next;
};
@ -60,7 +60,7 @@ Buffer iqueue;
Buffer oqueue;
static void
add_key(Key *k, char *name)
add_key(struct sshkey *k, char *name)
{
struct pkcs11_keyinfo *ki;
@ -87,8 +87,8 @@ del_keys_by_name(char *name)
}
/* lookup matching 'private' key */
static Key *
lookup_key(Key *k)
static struct sshkey *
lookup_key(struct sshkey *k)
{
struct pkcs11_keyinfo *ki;
@ -114,7 +114,7 @@ static void
process_add(void)
{
char *name, *pin;
Key **keys;
struct sshkey **keys;
int i, nkeys;
u_char *blob;
u_int blen;
@ -170,7 +170,7 @@ process_sign(void)
u_char *blob, *data, *signature = NULL;
u_int blen, dlen, slen = 0;
int ok = -1;
Key *key, *found;
struct sshkey *key, *found;
Buffer msg;
blob = get_string(&blen);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-pkcs11.c,v 1.23 2016/10/28 03:33:52 djm Exp $ */
/* $OpenBSD: ssh-pkcs11.c,v 1.25 2017/05/31 09:15:42 deraadt Exp $ */
/*
* Copyright (c) 2010 Markus Friedl. All rights reserved.
*
@ -537,7 +537,8 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
}
if (rsa && rsa->n && rsa->e &&
pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
key = sshkey_new(KEY_UNSPEC);
if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed");
key->rsa = rsa;
key->type = KEY_RSA;
key->flags |= SSHKEY_FLAG_EXT;
@ -545,8 +546,8 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
sshkey_free(key);
} else {
/* expand key array and add key */
*keysp = xreallocarray(*keysp, *nkeys + 1,
sizeof(struct sshkey *));
*keysp = xrecallocarray(*keysp, *nkeys,
*nkeys + 1, sizeof(struct sshkey *));
(*keysp)[*nkeys] = key;
*nkeys = *nkeys + 1;
debug("have %d keys", *nkeys);

5
ssh.1
View File

@ -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.381 2017/05/05 10:41:58 naddy Exp $
.Dd $Mdocdate: May 5 2017 $
.\" $OpenBSD: ssh.1,v 1.382 2017/05/30 18:58:37 bluhm Exp $
.Dd $Mdocdate: May 30 2017 $
.Dt SSH 1
.Os
.Sh NAME
@ -518,6 +518,7 @@ For full details of the options listed below, and their possible values, see
.It PubkeyAcceptedKeyTypes
.It PubkeyAuthentication
.It RekeyLimit
.It RemoteCommand
.It RemoteForward
.It RequestTTY
.It SendEnv

48
ssh.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh.c,v 1.459 2017/05/02 08:06:33 jmc Exp $ */
/* $OpenBSD: ssh.c,v 1.461 2017/05/30 18:58:37 bluhm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -973,12 +973,6 @@ main(int ac, char **av)
}
}
/* Cannot fork to background if no command. */
if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
!no_shell_flag)
fatal("Cannot fork into background without a command "
"to execute.");
/*
* Initialize "log" output. Since we are the client all output
* goes to stderr unless otherwise specified by -y or -E.
@ -1133,6 +1127,15 @@ main(int ac, char **av)
options.use_privileged_port = 0;
#endif
if (buffer_len(&command) != 0 && options.remote_command != NULL)
fatal("Cannot execute command-line and remote command.");
/* Cannot fork to background if no command. */
if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
options.remote_command == NULL && !no_shell_flag)
fatal("Cannot fork into background without a command "
"to execute.");
/* reinit */
log_init(argv0, options.log_level, options.log_facility, !use_syslog);
@ -1141,7 +1144,7 @@ main(int ac, char **av)
tty_flag = 1;
/* Allocate a tty by default if no command specified. */
if (buffer_len(&command) == 0)
if (buffer_len(&command) == 0 && options.remote_command == NULL)
tty_flag = options.request_tty != REQUEST_TTY_NO;
/* Force no tty */
@ -1197,6 +1200,27 @@ main(int ac, char **av)
free(cp);
}
if (options.remote_command != NULL) {
debug3("expanding RemoteCommand: %s", options.remote_command);
cp = options.remote_command;
options.remote_command = percent_expand(cp,
"C", conn_hash_hex,
"L", shorthost,
"d", pw->pw_dir,
"h", host,
"l", thishost,
"n", host_arg,
"p", portstr,
"r", options.user,
"u", pw->pw_name,
(char *)NULL);
debug3("expanded RemoteCommand: %s", options.remote_command);
free(cp);
buffer_append(&command, options.remote_command,
strlen(options.remote_command));
}
if (options.control_path != NULL) {
cp = tilde_expand_filename(options.control_path,
original_real_uid);
@ -1278,7 +1302,7 @@ main(int ac, char **av)
if (options.hostbased_authentication) {
sensitive_data.nkeys = 9;
sensitive_data.keys = xcalloc(sensitive_data.nkeys,
sizeof(Key));
sizeof(struct sshkey)); /* XXX */
for (i = 0; i < sensitive_data.nkeys; i++)
sensitive_data.keys[i] = NULL;
@ -1858,16 +1882,16 @@ load_public_identity_files(void)
{
char *filename, *cp, thishost[NI_MAXHOST];
char *pwdir = NULL, *pwname = NULL;
Key *public;
struct sshkey *public;
struct passwd *pw;
int i;
u_int n_ids, n_certs;
char *identity_files[SSH_MAX_IDENTITY_FILES];
Key *identity_keys[SSH_MAX_IDENTITY_FILES];
struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES];
char *certificate_files[SSH_MAX_CERTIFICATE_FILES];
struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
#ifdef ENABLE_PKCS11
Key **keys;
struct sshkey **keys;
int nkeys;
#endif /* PKCS11 */

View File

@ -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.248 2017/05/07 23:12:57 djm Exp $
.Dd $Mdocdate: May 7 2017 $
.\" $OpenBSD: ssh_config.5,v 1.250 2017/05/30 19:38:17 jmc Exp $
.Dd $Mdocdate: May 30 2017 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@ -1287,6 +1287,16 @@ is
.Cm default none ,
which means that rekeying is performed after the cipher's default amount
of data has been sent or received and no time based rekeying is done.
.It Cm RemoteCommand
Specifies a command to execute on the remote machine after successfully
connecting to the server.
The command string extends to the end of the line, and is executed with
the user's shell.
Arguments to
.Cm RemoteCommand
accept the tokens described in the
.Sx TOKENS
section.
.It Cm RemoteForward
Specifies that a TCP port on the remote machine be forwarded over
the secure channel to the specified host and port from the local machine.
@ -1702,6 +1712,9 @@ accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, and %u.
.Pp
.Cm ProxyCommand
accepts the tokens %%, %h, %p, and %r.
.Pp
.Cm RemoteCommand
accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, and %u.
.Sh FILES
.Bl -tag -width Ds
.It Pa ~/.ssh/config

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshbuf-getput-basic.c,v 1.6 2016/06/16 11:00:17 dtucker Exp $ */
/* $OpenBSD: sshbuf-getput-basic.c,v 1.7 2017/06/01 04:51:58 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@ -365,7 +365,7 @@ sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len)
int
sshbuf_put_cstring(struct sshbuf *buf, const char *v)
{
return sshbuf_put_string(buf, (u_char *)v, v == NULL ? 0 : strlen(v));
return sshbuf_put_string(buf, v, v == NULL ? 0 : strlen(v));
}
int

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshbuf.c,v 1.8 2016/11/25 23:22:04 djm Exp $ */
/* $OpenBSD: sshbuf.c,v 1.11 2017/06/01 06:58:25 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@ -193,15 +193,16 @@ sshbuf_reset(struct sshbuf *buf)
buf->off = buf->size;
return;
}
if (sshbuf_check_sanity(buf) == 0)
explicit_bzero(buf->d, buf->alloc);
(void) sshbuf_check_sanity(buf);
buf->off = buf->size = 0;
if (buf->alloc != SSHBUF_SIZE_INIT) {
if ((d = realloc(buf->d, SSHBUF_SIZE_INIT)) != NULL) {
if ((d = recallocarray(buf->d, buf->alloc, SSHBUF_SIZE_INIT,
1)) != NULL) {
buf->cd = buf->d = d;
buf->alloc = SSHBUF_SIZE_INIT;
}
}
explicit_bzero(buf->d, SSHBUF_SIZE_INIT);
}
size_t
@ -253,9 +254,8 @@ sshbuf_set_max_size(struct sshbuf *buf, size_t max_size)
rlen = ROUNDUP(buf->size, SSHBUF_SIZE_INC);
if (rlen > max_size)
rlen = max_size;
explicit_bzero(buf->d + buf->size, buf->alloc - buf->size);
SSHBUF_DBG(("new alloc = %zu", rlen));
if ((dp = realloc(buf->d, rlen)) == NULL)
if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
buf->cd = buf->d = dp;
buf->alloc = rlen;
@ -344,7 +344,7 @@ sshbuf_allocate(struct sshbuf *buf, size_t len)
if (rlen > buf->max_size)
rlen = buf->alloc + need;
SSHBUF_DBG(("adjusted rlen %zu", rlen));
if ((dp = realloc(buf->d, rlen)) == NULL) {
if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL) {
SSHBUF_DBG(("realloc fail"));
return SSH_ERR_ALLOC_FAIL;
}
@ -391,6 +391,9 @@ sshbuf_consume(struct sshbuf *buf, size_t len)
if (len > sshbuf_len(buf))
return SSH_ERR_MESSAGE_INCOMPLETE;
buf->off += len;
/* deal with empty buffer */
if (buf->off == buf->size)
buf->off = buf->size = 0;
SSHBUF_TELL("done");
return 0;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.278 2017/05/01 02:27:11 djm Exp $ */
/* $OpenBSD: sshconnect.c,v 1.280 2017/05/30 14:13:40 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -67,7 +67,7 @@
char *client_version_string = NULL;
char *server_version_string = NULL;
Key *previous_host_key = NULL;
struct sshkey *previous_host_key = NULL;
static int matching_host_key_dns = 0;
@ -79,8 +79,8 @@ extern char *__progname;
extern uid_t original_real_uid;
extern uid_t original_effective_uid;
static int show_other_keys(struct hostkeys *, Key *);
static void warn_changed_key(Key *);
static int show_other_keys(struct hostkeys *, struct sshkey *);
static void warn_changed_key(struct sshkey *);
/* Expand a proxy command */
static char *
@ -687,7 +687,7 @@ confirm(const char *prompt)
}
static int
check_host_cert(const char *host, const Key *host_key)
check_host_cert(const char *host, const struct sshkey *host_key)
{
const char *reason;
@ -785,13 +785,13 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
#define ROQUIET 2
static int
check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
Key *host_key, int readonly,
struct sshkey *host_key, int readonly,
char **user_hostfiles, u_int num_user_hostfiles,
char **system_hostfiles, u_int num_system_hostfiles)
{
HostStatus host_status;
HostStatus ip_status;
Key *raw_key = NULL;
struct sshkey *raw_key = NULL;
char *ip = NULL, *host = NULL;
char hostline[1000], *hostp, *fp, *ra;
char msg[1024];
@ -799,7 +799,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
const struct hostkey_entry *host_found, *ip_found;
int len, cancelled_forwarding = 0;
int local = sockaddr_is_local(hostaddr);
int r, want_cert = key_is_cert(host_key), host_ip_differ = 0;
int r, want_cert = sshkey_is_cert(host_key), host_ip_differ = 0;
int hostkey_trusted = 0; /* Known or explicitly accepted by user */
struct hostkeys *host_hostkeys, *ip_hostkeys;
u_int i;
@ -850,8 +850,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
retry:
/* Reload these as they may have changed on cert->key downgrade */
want_cert = key_is_cert(host_key);
type = key_type(host_key);
want_cert = sshkey_is_cert(host_key);
type = sshkey_type(host_key);
/*
* Check if the host key is present in the user's list of known
@ -871,7 +871,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
if (host_status == HOST_CHANGED &&
(ip_status != HOST_CHANGED ||
(ip_found != NULL &&
!key_equal(ip_found->key, host_found->key))))
!sshkey_equal(ip_found->key, host_found->key))))
host_ip_differ = 1;
} else
ip_status = host_status;
@ -1068,7 +1068,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
warn_changed_key(host_key);
error("Add correct host key in %.100s to get rid of this message.",
user_hostfiles[0]);
error("Offending %s key in %s:%lu", key_type(host_found->key),
error("Offending %s key in %s:%lu",
sshkey_type(host_found->key),
host_found->file, host_found->line);
/*
@ -1197,14 +1198,16 @@ fail:
* search normally.
*/
debug("No matching CA found. Retry with plain key");
raw_key = key_from_private(host_key);
if (key_drop_cert(raw_key) != 0)
fatal("Couldn't drop certificate");
if ((r = sshkey_from_private(host_key, &raw_key)) != 0)
fatal("%s: sshkey_from_private: %s",
__func__, ssh_err(r));
if ((r = sshkey_drop_cert(raw_key)) != 0)
fatal("Couldn't drop certificate: %s", ssh_err(r));
host_key = raw_key;
goto retry;
}
if (raw_key != NULL)
key_free(raw_key);
sshkey_free(raw_key);
free(ip);
free(host);
if (host_hostkeys != NULL)
@ -1216,7 +1219,7 @@ fail:
/* returns 0 if key verifies or -1 if key does NOT verify */
int
verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key)
{
u_int i;
int r = -1, flags = 0;
@ -1320,8 +1323,8 @@ out:
free(fp);
free(cafp);
if (r == 0 && host_key != NULL) {
key_free(previous_host_key);
previous_host_key = key_from_private(host_key);
sshkey_free(previous_host_key);
r = sshkey_from_private(host_key, &previous_host_key);
}
return r;
@ -1382,7 +1385,7 @@ ssh_put_password(char *password)
/* print all known host keys for a given host, but skip keys of given type */
static int
show_other_keys(struct hostkeys *hostkeys, Key *key)
show_other_keys(struct hostkeys *hostkeys, struct sshkey *key)
{
int type[] = {
KEY_RSA,
@ -1422,7 +1425,7 @@ show_other_keys(struct hostkeys *hostkeys, Key *key)
}
static void
warn_changed_key(Key *host_key)
warn_changed_key(struct sshkey *host_key)
{
char *fp;
@ -1490,7 +1493,7 @@ ssh_local_cmd(const char *args)
}
void
maybe_add_key_to_agent(char *authfile, Key *private, char *comment,
maybe_add_key_to_agent(char *authfile, struct sshkey *private, char *comment,
char *passphrase)
{
int auth_sock = -1, r;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.h,v 1.29 2015/11/15 22:26:49 jcs Exp $ */
/* $OpenBSD: sshconnect.h,v 1.30 2017/05/30 08:52:19 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -26,9 +26,9 @@
typedef struct Sensitive Sensitive;
struct Sensitive {
Key **keys;
int nkeys;
int external_keysign;
struct sshkey **keys;
int nkeys;
int external_keysign;
};
struct addrinfo;
@ -41,7 +41,7 @@ void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short,
void ssh_exchange_identification(int);
int verify_host_key(char *, struct sockaddr *, Key *);
int verify_host_key(char *, struct sockaddr *, struct sshkey *);
void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short,
char **, char **);
@ -55,7 +55,7 @@ void ssh_userauth2(const char *, const char *, char *, Sensitive *);
void ssh_put_password(char *);
int ssh_local_cmd(const char *);
void maybe_add_key_to_agent(char *, Key *, char *, char *);
void maybe_add_key_to_agent(char *, struct sshkey *, char *, char *);
/*
* Macros to raise/lower permissions.

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect2.c,v 1.258 2017/05/05 10:42:49 naddy Exp $ */
/* $OpenBSD: sshconnect2.c,v 1.263 2017/05/31 07:00:13 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@ -93,7 +93,7 @@ char *xxx_host;
struct sockaddr *xxx_hostaddr;
static int
verify_host_key_callback(Key *hostkey, struct ssh *ssh)
verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
{
if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
fatal("Host key verification failed.");
@ -222,7 +222,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
kex->server_version_string=server_version_string;
kex->verify_host_key=&verify_host_key_callback;
dispatch_run(DISPATCH_BLOCK, &kex->done, active_state);
ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done);
/* remove ext-info from the KEX proposals for rekeying */
myproposal[PROPOSAL_KEX_ALGS] =
@ -292,16 +292,16 @@ struct cauthmethod {
int *batch_flag; /* flag in option struct that disables method */
};
int input_userauth_service_accept(int, u_int32_t, void *);
int input_userauth_ext_info(int, u_int32_t, void *);
int input_userauth_success(int, u_int32_t, void *);
int input_userauth_success_unexpected(int, u_int32_t, void *);
int input_userauth_failure(int, u_int32_t, void *);
int input_userauth_banner(int, u_int32_t, void *);
int input_userauth_error(int, u_int32_t, void *);
int input_userauth_info_req(int, u_int32_t, void *);
int input_userauth_pk_ok(int, u_int32_t, void *);
int input_userauth_passwd_changereq(int, u_int32_t, void *);
int input_userauth_service_accept(int, u_int32_t, struct ssh *);
int input_userauth_ext_info(int, u_int32_t, struct ssh *);
int input_userauth_success(int, u_int32_t, struct ssh *);
int input_userauth_success_unexpected(int, u_int32_t, struct ssh *);
int input_userauth_failure(int, u_int32_t, struct ssh *);
int input_userauth_banner(int, u_int32_t, struct ssh *);
int input_userauth_error(int, u_int32_t, struct ssh *);
int input_userauth_info_req(int, u_int32_t, struct ssh *);
int input_userauth_pk_ok(int, u_int32_t, struct ssh *);
int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *);
int userauth_none(Authctxt *);
int userauth_pubkey(Authctxt *);
@ -311,11 +311,11 @@ int userauth_hostbased(Authctxt *);
#ifdef GSSAPI
int userauth_gssapi(Authctxt *authctxt);
int input_gssapi_response(int type, u_int32_t, void *);
int input_gssapi_token(int type, u_int32_t, void *);
int input_gssapi_hash(int type, u_int32_t, void *);
int input_gssapi_error(int, u_int32_t, void *);
int input_gssapi_errtok(int, u_int32_t, void *);
int input_gssapi_response(int type, u_int32_t, struct ssh *);
int input_gssapi_token(int type, u_int32_t, struct ssh *);
int input_gssapi_hash(int type, u_int32_t, struct ssh *);
int input_gssapi_error(int, u_int32_t, struct ssh *);
int input_gssapi_errtok(int, u_int32_t, struct ssh *);
#endif
void userauth(Authctxt *, char *);
@ -324,7 +324,7 @@ static int sign_and_send_pubkey(Authctxt *, Identity *);
static void pubkey_prepare(Authctxt *);
static void pubkey_cleanup(Authctxt *);
static void pubkey_reset(Authctxt *);
static Key *load_identity_file(Identity *);
static struct sshkey *load_identity_file(Identity *);
static Authmethod *authmethod_get(char *authlist);
static Authmethod *authmethod_lookup(const char *name);
@ -402,10 +402,12 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
(r = sshpkt_send(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
ssh->authctxt = &authctxt;
ssh_dispatch_init(ssh, &input_userauth_error);
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info);
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept);
ssh_dispatch_run(ssh, DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */
ssh->authctxt = NULL;
pubkey_cleanup(&authctxt);
ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
@ -417,10 +419,9 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
/* ARGSUSED */
int
input_userauth_service_accept(int type, u_int32_t seqnr, void *ctxt)
input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
struct ssh *ssh = active_state;
Authctxt *authctxt = ssh->authctxt;
int r;
if (ssh_packet_remaining(ssh) > 0) {
@ -451,9 +452,9 @@ input_userauth_service_accept(int type, u_int32_t seqnr, void *ctxt)
/* ARGSUSED */
int
input_userauth_ext_info(int type, u_int32_t seqnr, void *ctxt)
input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh)
{
return kex_input_ext_info(type, seqnr, active_state);
return kex_input_ext_info(type, seqnr, ssh);
}
void
@ -493,7 +494,7 @@ userauth(Authctxt *authctxt, char *authlist)
/* ARGSUSED */
int
input_userauth_error(int type, u_int32_t seq, void *ctxt)
input_userauth_error(int type, u_int32_t seq, struct ssh *ssh)
{
fatal("input_userauth_error: bad message during authentication: "
"type %d", type);
@ -502,7 +503,7 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
input_userauth_banner(int type, u_int32_t seq, void *ctxt)
input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh)
{
char *msg, *lang;
u_int len;
@ -519,9 +520,9 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
input_userauth_success(int type, u_int32_t seq, void *ctxt)
input_userauth_success(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
if (authctxt == NULL)
fatal("input_userauth_success: no authentication context");
@ -536,9 +537,9 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
}
int
input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)
input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
if (authctxt == NULL)
fatal("%s: no authentication context", __func__);
@ -550,9 +551,9 @@ input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
input_userauth_failure(int type, u_int32_t seq, void *ctxt)
input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
char *authlist = NULL;
int partial;
@ -576,10 +577,10 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
/* ARGSUSED */
int
input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Key *key = NULL;
Authctxt *authctxt = ssh->authctxt;
struct sshkey *key = NULL;
Identity *id = NULL;
Buffer b;
int pktype, sent = 0;
@ -707,9 +708,9 @@ userauth_gssapi(Authctxt *authctxt)
}
static OM_uint32
process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt = authctxt->methoddata;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
@ -762,9 +763,9 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
/* ARGSUSED */
int
input_gssapi_response(int type, u_int32_t plen, void *ctxt)
input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt;
int oidlen;
char *oidv;
@ -792,7 +793,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
free(oidv);
if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) {
if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) {
/* Start again with next method on list */
debug("Trying to start again");
userauth(authctxt, NULL);
@ -803,9 +804,9 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
/* ARGSUSED */
int
input_gssapi_token(int type, u_int32_t plen, void *ctxt)
input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
gss_buffer_desc recv_tok;
OM_uint32 status;
u_int slen;
@ -818,7 +819,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
packet_check_eom();
status = process_gssapi_token(ctxt, &recv_tok);
status = process_gssapi_token(ssh, &recv_tok);
free(recv_tok.value);
@ -832,9 +833,9 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
/* ARGSUSED */
int
input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
Gssctxt *gssctxt;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
gss_buffer_desc recv_tok;
@ -863,7 +864,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
/* ARGSUSED */
int
input_gssapi_error(int type, u_int32_t plen, void *ctxt)
input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
{
char *msg;
char *lang;
@ -934,9 +935,9 @@ userauth_passwd(Authctxt *authctxt)
*/
/* ARGSUSED */
int
input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
char *info, *lang, *password = NULL, *retype = NULL;
char prompt[150];
const char *host;
@ -1020,7 +1021,7 @@ static int
identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat)
{
Key *prv;
struct sshkey *prv;
int ret;
/* the agent supports this key */
@ -1230,10 +1231,10 @@ send_pubkey_test(Authctxt *authctxt, Identity *id)
return 1;
}
static Key *
static struct sshkey *
load_identity_file(Identity *id)
{
Key *private = NULL;
struct sshkey *private = NULL;
char prompt[300], *passphrase, *comment;
int r, perm_ok = 0, quit = 0, i;
struct stat st;
@ -1564,9 +1565,9 @@ userauth_kbdint(Authctxt *authctxt)
* parse INFO_REQUEST, prompt user and send INFO_RESPONSE
*/
int
input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
char *name, *inst, *lang, *prompt, *response;
u_int num_prompts, i;
int echo = 0;

47
sshd.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.487 2017/04/30 23:18:44 djm Exp $ */
/* $OpenBSD: sshd.c,v 1.490 2017/05/31 08:09:45 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -200,10 +200,10 @@ int have_agent = 0;
* not very useful. Currently, memory locking is not implemented.
*/
struct {
Key **host_keys; /* all private host keys */
Key **host_pubkeys; /* all public host keys */
Key **host_certificates; /* all public host certificates */
int have_ssh2_key;
struct sshkey **host_keys; /* all private host keys */
struct sshkey **host_pubkeys; /* all public host keys */
struct sshkey **host_certificates; /* all public host certificates */
int have_ssh2_key;
} sensitive_data;
/* This is set to true when a signal is received. */
@ -504,7 +504,7 @@ destroy_sensitive_data(void)
void
demote_sensitive_data(void)
{
Key *tmp;
struct sshkey *tmp;
int i;
for (i = 0; i < options.num_host_key_files; i++) {
@ -690,6 +690,7 @@ privsep_postauth(Authctxt *authctxt)
else if (pmonitor->m_pid != 0) {
verbose("User child is on pid %ld", (long)pmonitor->m_pid);
buffer_clear(&loginmsg);
monitor_clear_keystate(pmonitor);
monitor_child_postauth(pmonitor);
/* NEVERREACHED */
@ -729,7 +730,7 @@ list_hostkey_types(void)
const char *p;
char *ret;
int i;
Key *key;
struct sshkey *key;
buffer_init(&b);
for (i = 0; i < options.num_host_key_files; i++) {
@ -785,11 +786,11 @@ list_hostkey_types(void)
return ret;
}
static Key *
static struct sshkey *
get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
{
int i;
Key *key;
struct sshkey *key;
for (i = 0; i < options.num_host_key_files; i++) {
switch (type) {
@ -813,19 +814,19 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
return NULL;
}
Key *
struct sshkey *
get_hostkey_public_by_type(int type, int nid, struct ssh *ssh)
{
return get_hostkey_by_type(type, nid, 0, ssh);
}
Key *
struct sshkey *
get_hostkey_private_by_type(int type, int nid, struct ssh *ssh)
{
return get_hostkey_by_type(type, nid, 1, ssh);
}
Key *
struct sshkey *
get_hostkey_by_index(int ind)
{
if (ind < 0 || ind >= options.num_host_key_files)
@ -833,7 +834,7 @@ get_hostkey_by_index(int ind)
return (sensitive_data.host_keys[ind]);
}
Key *
struct sshkey *
get_hostkey_public_by_index(int ind, struct ssh *ssh)
{
if (ind < 0 || ind >= options.num_host_key_files)
@ -842,7 +843,7 @@ get_hostkey_public_by_index(int ind, struct ssh *ssh)
}
int
get_hostkey_index(Key *key, int compare, struct ssh *ssh)
get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh)
{
int i;
@ -1450,8 +1451,8 @@ main(int ac, char **av)
u_int n;
u_int64_t ibytes, obytes;
mode_t new_umask;
Key *key;
Key *pubkey;
struct sshkey *key;
struct sshkey *pubkey;
int keytype;
Authctxt *authctxt;
struct connection_info *connection_info = get_connection_info(0, 0);
@ -1750,9 +1751,9 @@ main(int ac, char **av)
/* load host keys */
sensitive_data.host_keys = xcalloc(options.num_host_key_files,
sizeof(Key *));
sizeof(struct sshkey *));
sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files,
sizeof(Key *));
sizeof(struct sshkey *));
if (options.host_key_agent) {
if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME))
@ -1818,7 +1819,7 @@ main(int ac, char **av)
* indices to the public keys that they relate to.
*/
sensitive_data.host_certificates = xcalloc(options.num_host_key_files,
sizeof(Key *));
sizeof(struct sshkey *));
for (i = 0; i < options.num_host_key_files; i++)
sensitive_data.host_certificates[i] = NULL;
@ -2154,6 +2155,7 @@ main(int ac, char **av)
*/
if (use_privsep) {
mm_send_keystate(pmonitor);
packet_clear_keys();
exit(0);
}
@ -2231,8 +2233,9 @@ main(int ac, char **av)
}
int
sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen,
const u_char *data, size_t dlen, const char *alg, u_int flag)
sshd_hostkey_sign(struct sshkey *privkey, struct sshkey *pubkey,
u_char **signature, size_t *slen, const u_char *data, size_t dlen,
const char *alg, u_int flag)
{
int r;
u_int xxx_slen, xxx_dlen = dlen;
@ -2312,7 +2315,7 @@ do_ssh2_kex(void)
kex->host_key_index=&get_hostkey_index;
kex->sign = sshd_hostkey_sign;
dispatch_run(DISPATCH_BLOCK, &kex->done, active_state);
ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done);
session_id2 = kex->session_id;
session_id2_len = kex->session_id_len;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshkey.c,v 1.50 2017/05/08 06:11:06 djm Exp $ */
/* $OpenBSD: sshkey.c,v 1.51 2017/05/31 09:15:42 deraadt Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@ -1764,8 +1764,9 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
goto out;
}
oprincipals = key->cert->principals;
key->cert->principals = reallocarray(key->cert->principals,
key->cert->nprincipals + 1, sizeof(*key->cert->principals));
key->cert->principals = recallocarray(key->cert->principals,
key->cert->nprincipals, key->cert->nprincipals + 1,
sizeof(*key->cert->principals));
if (key->cert->principals == NULL) {
free(principal);
key->cert->principals = oprincipals;

8
umac.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: umac.c,v 1.11 2014/07/22 07:13:42 guenther Exp $ */
/* $OpenBSD: umac.c,v 1.12 2017/05/31 08:09:45 markus Exp $ */
/* -----------------------------------------------------------------------
*
* umac.c -- C Implementation UMAC Message Authentication
@ -203,6 +203,8 @@ static void kdf(void *bufp, aes_int_key key, UINT8 ndx, int nbytes)
aes_encryption(in_buf, out_buf, key);
memcpy(dst_buf,out_buf,nbytes);
}
explicit_bzero(in_buf, sizeof(in_buf));
explicit_bzero(out_buf, sizeof(out_buf));
}
/* The final UHASH result is XOR'd with the output of a pseudorandom
@ -227,6 +229,7 @@ static void pdf_init(pdf_ctx *pc, aes_int_key prf_key)
/* Initialize pdf and cache */
memset(pc->nonce, 0, sizeof(pc->nonce));
aes_encryption(pc->nonce, pc->cache, pc->prf_key);
explicit_bzero(buf, sizeof(buf));
}
static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8])
@ -991,6 +994,7 @@ static void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key)
kdf(ahc->ip_trans, prf_key, 4, STREAMS * sizeof(UINT32));
endian_convert_if_le(ahc->ip_trans, sizeof(UINT32),
STREAMS * sizeof(UINT32));
explicit_bzero(buf, sizeof(buf));
}
/* ---------------------------------------------------------------------- */
@ -1200,6 +1204,7 @@ int umac_delete(struct umac_ctx *ctx)
if (ctx) {
if (ALLOC_BOUNDARY)
ctx = (struct umac_ctx *)ctx->free_ptr;
explicit_bzero(ctx, sizeof(*ctx) + ALLOC_BOUNDARY);
free(ctx);
}
return (1);
@ -1227,6 +1232,7 @@ struct umac_ctx *umac_new(const u_char key[])
aes_key_setup(key, prf_key);
pdf_init(&ctx->pdf, prf_key);
uhash_init(&ctx->hash, prf_key);
explicit_bzero(prf_key, sizeof(prf_key));
}
return (ctx);

4
utf8.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: utf8.c,v 1.6 2017/04/17 14:31:23 schwarze Exp $ */
/* $OpenBSD: utf8.c,v 1.7 2017/05/31 09:15:42 deraadt Exp $ */
/*
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
*
@ -76,7 +76,7 @@ grow_dst(char **dst, size_t *sz, size_t maxsz, char **dp, size_t need)
tsz = *sz + 128;
if (tsz > maxsz)
tsz = maxsz;
if ((tp = realloc(*dst, tsz)) == NULL)
if ((tp = recallocarray(*dst, *sz, tsz, 1)) == NULL)
return -1;
*dp = tp + (*dp - *dst);
*dst = tp;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: xmalloc.c,v 1.33 2016/02/15 09:47:49 dtucker Exp $ */
/* $OpenBSD: xmalloc.c,v 1.34 2017/05/31 09:15:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -77,6 +77,18 @@ xreallocarray(void *ptr, size_t nmemb, size_t size)
return new_ptr;
}
void *
xrecallocarray(void *ptr, size_t onmemb, size_t nmemb, size_t size)
{
void *new_ptr;
new_ptr = recallocarray(ptr, onmemb, nmemb, size);
if (new_ptr == NULL)
fatal("xrecallocarray: out of memory (%zu elements of %zu bytes)",
nmemb, size);
return new_ptr;
}
char *
xstrdup(const char *str)
{

View File

@ -1,4 +1,4 @@
/* $OpenBSD: xmalloc.h,v 1.16 2016/02/15 09:47:49 dtucker Exp $ */
/* $OpenBSD: xmalloc.h,v 1.17 2017/05/31 09:15:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -20,6 +20,7 @@ void ssh_malloc_init(void);
void *xmalloc(size_t);
void *xcalloc(size_t, size_t);
void *xreallocarray(void *, size_t, size_t);
void *xrecallocarray(void *, size_t, size_t, size_t);
char *xstrdup(const char *);
int xasprintf(char **, const char *, ...)
__attribute__((__format__ (printf, 2, 3)))