Merge remote-tracking branch 'openssh/master' into latestw
This commit is contained in:
commit
f7e6475b96
|
@ -10,6 +10,7 @@ openbsd-compat/regress/Makefile
|
|||
openssh.xml
|
||||
opensshd.init
|
||||
survey.sh
|
||||
**/*.0
|
||||
**/*.o
|
||||
**/*.out
|
||||
**/*.a
|
||||
|
|
|
@ -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
|
||||
|
|
6
PROTOCOL
6
PROTOCOL
|
@ -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 $
|
||||
|
|
585
PROTOCOL.agent
585
PROTOCOL.agent
|
@ -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
|
||||
|
|
|
@ -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 $
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
6
auth.c
|
@ -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
35
auth.h
|
@ -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)));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
67
auth2-gss.c
67
auth2-gss.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
14
auth2-none.c
14
auth2-none.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
223
auth2-pubkey.c
223
auth2-pubkey.c
|
@ -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
42
auth2.c
|
@ -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();
|
||||
|
|
60
authfile.c
60
authfile.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
6
bitmap.c
6
bitmap.c
|
@ -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;
|
||||
|
|
86
channels.c
86
channels.c
|
@ -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)
|
||||
{
|
||||
|
|
25
channels.h
25
channels.h
|
@ -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) */
|
||||
|
||||
|
|
22
clientloop.c
22
clientloop.c
|
@ -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;
|
||||
|
|
|
@ -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])
|
||||
|
|
18
dispatch.c
18
dispatch.c
|
@ -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);
|
||||
}
|
||||
|
|
14
dispatch.h
14
dispatch.h
|
@ -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
|
||||
|
|
|
@ -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
16
kex.c
|
@ -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
6
kex.h
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
7
kexdhc.c
7
kexdhc.c
|
@ -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;
|
||||
|
|
7
kexdhs.c
7
kexdhs.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
12
kexgexc.c
12
kexgexc.c
|
@ -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;
|
||||
|
|
12
kexgexs.c
12
kexgexs.c
|
@ -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
177
key.c
|
@ -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
36
key.h
|
@ -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
4
krl.c
|
@ -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
4
misc.c
|
@ -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;
|
||||
|
|
65
monitor.c
65
monitor.c
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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
101
packet.c
|
@ -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",
|
||||
|
|
7
packet.h
7
packet.h
|
@ -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);
|
||||
|
|
17
readconf.c
17
readconf.c
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
8
scp.c
|
@ -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);
|
||||
}
|
||||
|
|
12
serverloop.c
12
serverloop.c
|
@ -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;
|
||||
|
|
11
session.c
11
session.c
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
20
ssh-keygen.c
20
ssh-keygen.c
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
5
ssh.1
|
@ -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
48
ssh.c
|
@ -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 */
|
||||
|
||||
|
|
17
ssh_config.5
17
ssh_config.5
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
17
sshbuf.c
17
sshbuf.c
|
@ -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;
|
||||
}
|
||||
|
|
47
sshconnect.c
47
sshconnect.c
|
@ -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;
|
||||
|
|
12
sshconnect.h
12
sshconnect.h
|
@ -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.
|
||||
|
|
109
sshconnect2.c
109
sshconnect2.c
|
@ -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
47
sshd.c
|
@ -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;
|
||||
|
|
7
sshkey.c
7
sshkey.c
|
@ -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
8
umac.c
|
@ -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
4
utf8.c
|
@ -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;
|
||||
|
|
14
xmalloc.c
14
xmalloc.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)))
|
||||
|
|
Loading…
Reference in New Issue