Upgrade to OpenSSH 5.8p2.
This commit is contained in:
commit
ee2afa8165
File diff suppressed because it is too large
Load Diff
@ -206,6 +206,7 @@ OpenSSH contains no GPL code.
|
||||
Sun Microsystems
|
||||
The SCO Group
|
||||
Daniel Walsh
|
||||
Red Hat, Inc
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -12,7 +12,9 @@ are individually implemented as extensions described below.
|
||||
The protocol used by OpenSSH's ssh-agent is described in the file
|
||||
PROTOCOL.agent
|
||||
|
||||
1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
|
||||
1. Transport protocol changes
|
||||
|
||||
1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
|
||||
|
||||
This is a new transport-layer MAC method using the UMAC algorithm
|
||||
(rfc4418). This method is identical to the "umac-64" method documented
|
||||
@ -20,7 +22,7 @@ in:
|
||||
|
||||
http://www.openssh.com/txt/draft-miller-secsh-umac-01.txt
|
||||
|
||||
2. transport: Protocol 2 compression algorithm "zlib@openssh.com"
|
||||
1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com"
|
||||
|
||||
This transport-layer compression method uses the zlib compression
|
||||
algorithm (identical to the "zlib" method in rfc4253), but delays the
|
||||
@ -31,14 +33,27 @@ The method is documented in:
|
||||
|
||||
http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
|
||||
|
||||
3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com" and
|
||||
"ssh-dsa-cert-v00@openssh.com"
|
||||
1.3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com",
|
||||
"ssh-dsa-cert-v00@openssh.com",
|
||||
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com" and
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com"
|
||||
|
||||
OpenSSH introduces two new public key algorithms to support certificate
|
||||
OpenSSH introduces new public key algorithms to support certificate
|
||||
authentication for users and hostkeys. These methods are documented in
|
||||
the file PROTOCOL.certkeys
|
||||
|
||||
4. connection: Channel write close extension "eow@openssh.com"
|
||||
1.4. transport: Elliptic Curve cryptography
|
||||
|
||||
OpenSSH supports ECC key exchange and public key authentication as
|
||||
specified in RFC5656. Only the ecdsa-sha2-nistp256, ecdsa-sha2-nistp384
|
||||
and ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic
|
||||
curve points encoded using point compression are NOT accepted or
|
||||
generated.
|
||||
|
||||
2. Connection protocol changes
|
||||
|
||||
2.1. connection: Channel write close extension "eow@openssh.com"
|
||||
|
||||
The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF
|
||||
message to allow an endpoint to signal its peer that it will send no
|
||||
@ -77,8 +92,8 @@ message is only sent to OpenSSH peers (identified by banner).
|
||||
Other SSH implementations may be whitelisted to receive this message
|
||||
upon request.
|
||||
|
||||
5. connection: disallow additional sessions extension
|
||||
"no-more-sessions@openssh.com"
|
||||
2.2. connection: disallow additional sessions extension
|
||||
"no-more-sessions@openssh.com"
|
||||
|
||||
Most SSH connections will only ever request a single session, but a
|
||||
attacker may abuse a running ssh client to surreptitiously open
|
||||
@ -105,7 +120,7 @@ of this message, the no-more-sessions request is only sent to OpenSSH
|
||||
servers (identified by banner). Other SSH implementations may be
|
||||
whitelisted to receive this message upon request.
|
||||
|
||||
6. connection: Tunnel forward extension "tun@openssh.com"
|
||||
2.3. connection: Tunnel forward extension "tun@openssh.com"
|
||||
|
||||
OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
|
||||
channel type. This channel type supports forwarding of network packets
|
||||
@ -166,7 +181,9 @@ The contents of the "data" field for layer 2 packets is:
|
||||
The "frame" field contains an IEEE 802.3 Ethernet frame, including
|
||||
header.
|
||||
|
||||
7. sftp: Reversal of arguments to SSH_FXP_SYMLINK
|
||||
3. SFTP protocol changes
|
||||
|
||||
3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK
|
||||
|
||||
When OpenSSH's sftp-server was implemented, the order of the arguments
|
||||
to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
|
||||
@ -179,7 +196,7 @@ SSH_FXP_SYMLINK as follows:
|
||||
string targetpath
|
||||
string linkpath
|
||||
|
||||
8. sftp: Server extension announcement in SSH_FXP_VERSION
|
||||
3.2. sftp: Server extension announcement in SSH_FXP_VERSION
|
||||
|
||||
OpenSSH's sftp-server lists the extensions it supports using the
|
||||
standard extension announcement mechanism in the SSH_FXP_VERSION server
|
||||
@ -200,7 +217,7 @@ ever changed in an incompatible way. The server MAY advertise the same
|
||||
extension with multiple versions (though this is unlikely). Clients MUST
|
||||
check the version number before attempting to use the extension.
|
||||
|
||||
9. sftp: Extension request "posix-rename@openssh.com"
|
||||
3.3. sftp: Extension request "posix-rename@openssh.com"
|
||||
|
||||
This operation provides a rename operation with POSIX semantics, which
|
||||
are different to those provided by the standard SSH_FXP_RENAME in
|
||||
@ -217,7 +234,7 @@ rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
10. sftp: Extension requests "statvfs@openssh.com" and
|
||||
3.4. sftp: Extension requests "statvfs@openssh.com" and
|
||||
"fstatvfs@openssh.com"
|
||||
|
||||
These requests correspond to the statvfs and fstatvfs POSIX system
|
||||
@ -258,4 +275,20 @@ The values of the f_flag bitmask are as follows:
|
||||
Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
|
||||
advertised in the SSH_FXP_VERSION hello with version "2".
|
||||
|
||||
$OpenBSD: PROTOCOL,v 1.15 2010/02/26 20:29:54 djm Exp $
|
||||
10. sftp: Extension request "hardlink@openssh.com"
|
||||
|
||||
This request is for creating a hard link to a regular file. This
|
||||
request is implemented as a SSH_FXP_EXTENDED request with the
|
||||
following format:
|
||||
|
||||
uint32 id
|
||||
string "hardlink@openssh.com"
|
||||
string oldpath
|
||||
string newpath
|
||||
|
||||
On receiving this request the server will perform the operation
|
||||
link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
$OpenBSD: PROTOCOL,v 1.17 2010/12/04 00:18:01 djm Exp $
|
||||
|
@ -159,8 +159,8 @@ successfully added or a SSH_AGENT_FAILURE if an error occurred.
|
||||
|
||||
2.2.3 Add protocol 2 key
|
||||
|
||||
The OpenSSH agent supports DSA and RSA keys for protocol 2. DSA keys may
|
||||
be added using the following request
|
||||
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
|
||||
@ -182,6 +182,30 @@ DSA certificates may be added with:
|
||||
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
|
||||
|
||||
RSA keys may be added with this request:
|
||||
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
@ -214,7 +238,7 @@ 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 both DSA and RSA key add requests, "key_constraints" may only be
|
||||
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
|
||||
@ -294,8 +318,7 @@ Protocol 2 keys may be removed with the following request:
|
||||
string key_blob
|
||||
|
||||
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
|
||||
Algorithms" for either of the supported key types: "ssh-dss" or
|
||||
"ssh-rsa".
|
||||
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
|
||||
@ -364,8 +387,7 @@ Followed by zero or more consecutive keys, encoded as:
|
||||
string key_comment
|
||||
|
||||
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
|
||||
Algorithms" for either of the supported key types: "ssh-dss" or
|
||||
"ssh-rsa".
|
||||
Algorithms" for any of the supported protocol 2 key types.
|
||||
|
||||
2.6 Private key operations
|
||||
|
||||
@ -429,9 +451,9 @@ a protocol 2 key:
|
||||
uint32 flags
|
||||
|
||||
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
|
||||
Algorithms" for either of the supported key types: "ssh-dss" or
|
||||
"ssh-rsa". "flags" is a bit-mask, but at present only one possible value
|
||||
is defined (see below for its meaning):
|
||||
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
|
||||
|
||||
@ -535,4 +557,4 @@ Locking and unlocking affects both protocol 1 and protocol 2 keys.
|
||||
SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
|
||||
$OpenBSD: PROTOCOL.agent,v 1.5 2010/02/26 20:29:54 djm Exp $
|
||||
$OpenBSD: PROTOCOL.agent,v 1.6 2010/08/31 11:54:45 djm Exp $
|
||||
|
@ -5,31 +5,37 @@ Background
|
||||
----------
|
||||
|
||||
The SSH protocol currently supports a simple public key authentication
|
||||
mechanism. Unlike other public key implementations, SSH eschews the
|
||||
use of X.509 certificates and uses raw keys. This approach has some
|
||||
benefits relating to simplicity of configuration and minimisation
|
||||
of attack surface, but it does not support the important use-cases
|
||||
of centrally managed, passwordless authentication and centrally
|
||||
certified host keys.
|
||||
mechanism. Unlike other public key implementations, SSH eschews the use
|
||||
of X.509 certificates and uses raw keys. This approach has some benefits
|
||||
relating to simplicity of configuration and minimisation of attack
|
||||
surface, but it does not support the important use-cases of centrally
|
||||
managed, passwordless authentication and centrally certified host keys.
|
||||
|
||||
These protocol extensions build on the simple public key authentication
|
||||
system already in SSH to allow certificate-based authentication.
|
||||
The certificates used are not traditional X.509 certificates, with
|
||||
numerous options and complex encoding rules, but something rather
|
||||
more minimal: a key, some identity information and usage options
|
||||
that have been signed with some other trusted key.
|
||||
system already in SSH to allow certificate-based authentication. The
|
||||
certificates used are not traditional X.509 certificates, with numerous
|
||||
options and complex encoding rules, but something rather more minimal: a
|
||||
key, some identity information and usage options that have been signed
|
||||
with some other trusted key.
|
||||
|
||||
A sshd server may be configured to allow authentication via certified
|
||||
keys, by extending the existing ~/.ssh/authorized_keys mechanism
|
||||
to allow specification of certification authority keys in addition
|
||||
to raw user keys. The ssh client will support automatic verification
|
||||
of acceptance of certified host keys, by adding a similar ability
|
||||
to specify CA keys in ~/.ssh/known_hosts.
|
||||
keys, by extending the existing ~/.ssh/authorized_keys mechanism to
|
||||
allow specification of certification authority keys in addition to
|
||||
raw user keys. The ssh client will support automatic verification of
|
||||
acceptance of certified host keys, by adding a similar ability to
|
||||
specify CA keys in ~/.ssh/known_hosts.
|
||||
|
||||
Certified keys are represented using two new key types:
|
||||
ssh-rsa-cert-v01@openssh.com and ssh-dss-cert-v01@openssh.com that
|
||||
include certification information along with the public key that is used
|
||||
to sign challenges. ssh-keygen performs the CA signing operation.
|
||||
Certified keys are represented using new key types:
|
||||
|
||||
ssh-rsa-cert-v01@openssh.com
|
||||
ssh-dss-cert-v01@openssh.com
|
||||
ecdsa-sha2-nistp256-cert-v01@openssh.com
|
||||
ecdsa-sha2-nistp384-cert-v01@openssh.com
|
||||
ecdsa-sha2-nistp521-cert-v01@openssh.com
|
||||
|
||||
These include certification information along with the public key
|
||||
that is used to sign challenges. ssh-keygen performs the CA signing
|
||||
operation.
|
||||
|
||||
Protocol extensions
|
||||
-------------------
|
||||
@ -47,10 +53,9 @@ in RFC4252 section 7.
|
||||
New public key formats
|
||||
----------------------
|
||||
|
||||
The ssh-rsa-cert-v01@openssh.com and ssh-dss-cert-v01@openssh.com key
|
||||
types take a similar high-level format (note: data types and
|
||||
encoding are as per RFC4251 section 5). The serialised wire encoding of
|
||||
these certificates is also used for storing them on disk.
|
||||
The certificate key types take a similar high-level format (note: data
|
||||
types and encoding are as per RFC4251 section 5). The serialised wire
|
||||
encoding of these certificates is also used for storing them on disk.
|
||||
|
||||
#define SSH_CERT_TYPE_USER 1
|
||||
#define SSH_CERT_TYPE_HOST 2
|
||||
@ -93,6 +98,26 @@ DSA certificate
|
||||
string signature key
|
||||
string signature
|
||||
|
||||
ECDSA certificate
|
||||
|
||||
string "ecdsa-sha2-nistp256@openssh.com" |
|
||||
"ecdsa-sha2-nistp384@openssh.com" |
|
||||
"ecdsa-sha2-nistp521@openssh.com"
|
||||
string nonce
|
||||
string curve
|
||||
string public_key
|
||||
uint64 serial
|
||||
uint32 type
|
||||
string key id
|
||||
string valid principals
|
||||
uint64 valid after
|
||||
uint64 valid before
|
||||
string critical options
|
||||
string extensions
|
||||
string reserved
|
||||
string signature key
|
||||
string signature
|
||||
|
||||
The nonce field is a CA-provided random bitstring of arbitrary length
|
||||
(but typically 16 or 32 bytes) included to make attacks that depend on
|
||||
inducing collisions in the signature hash infeasible.
|
||||
@ -101,6 +126,9 @@ e and n are the RSA exponent and public modulus respectively.
|
||||
|
||||
p, q, g, y are the DSA parameters as described in FIPS-186-2.
|
||||
|
||||
curve and public key are respectively the ECDSA "[identifier]" and "Q"
|
||||
defined in section 3.1 of RFC5656.
|
||||
|
||||
serial is an optional certificate serial number set by the CA to
|
||||
provide an abbreviated way to refer to certificates from that CA.
|
||||
If a CA does not wish to number its certificates it must set this
|
||||
@ -123,7 +151,8 @@ any principal of the specified type. XXX DNS wildcards?
|
||||
"valid after" and "valid before" specify a validity period for the
|
||||
certificate. Each represents a time in seconds since 1970-01-01
|
||||
00:00:00. A certificate is considered valid if:
|
||||
valid after <= current time < valid before
|
||||
|
||||
valid after <= current time < valid before
|
||||
|
||||
criticial options is a set of zero or more key options encoded as
|
||||
below. All such options are "critical" in the sense that an implementation
|
||||
@ -137,15 +166,17 @@ The reserved field is currently unused and is ignored in this version of
|
||||
the protocol.
|
||||
|
||||
signature key contains the CA key used to sign the certificate.
|
||||
The valid key types for CA keys are ssh-rsa and ssh-dss. "Chained"
|
||||
The valid key types for CA keys are ssh-rsa, ssh-dss and the ECDSA types
|
||||
ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained"
|
||||
certificates, where the signature key type is a certificate type itself
|
||||
are NOT supported. Note that it is possible for a RSA certificate key to
|
||||
be signed by a DSS CA key and vice-versa.
|
||||
be signed by a DSS or ECDSA CA key and vice-versa.
|
||||
|
||||
signature is computed over all preceding fields from the initial string
|
||||
up to, and including the signature key. Signatures are computed and
|
||||
encoded according to the rules defined for the CA's public key algorithm
|
||||
(RFC4253 section 6.6 for ssh-rsa and ssh-dss).
|
||||
(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA
|
||||
types).
|
||||
|
||||
Critical options
|
||||
----------------
|
||||
@ -222,4 +253,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.7 2010/08/04 05:40:39 djm Exp $
|
||||
$OpenBSD: PROTOCOL.certkeys,v 1.8 2010/08/31 11:54:45 djm Exp $
|
||||
|
@ -28,7 +28,7 @@ defined.
|
||||
To open a new multiplexed session, a client may send the following
|
||||
request:
|
||||
|
||||
uint32 MUX_C_MSG_NEW_SESSION
|
||||
uint32 MUX_C_NEW_SESSION
|
||||
uint32 request id
|
||||
string reserved
|
||||
bool want tty flag
|
||||
@ -99,7 +99,7 @@ The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED.
|
||||
|
||||
A client may request the master to establish a port forward:
|
||||
|
||||
uint32 MUX_C_OPEN_FORWARD
|
||||
uint32 MUX_C_OPEN_FWD
|
||||
uint32 request id
|
||||
uint32 forwarding type
|
||||
string listen host
|
||||
@ -118,24 +118,23 @@ For dynamically allocated listen port the server replies with
|
||||
uint32 client request id
|
||||
uint32 allocated remote listen port
|
||||
|
||||
5. Requesting closure of port forwards
|
||||
6. Requesting closure of port forwards
|
||||
|
||||
A client may request the master to establish a port forward:
|
||||
Note: currently unimplemented (server will always reply with MUX_S_FAILURE).
|
||||
|
||||
uint32 MUX_C_OPEN_FORWARD
|
||||
A client may request the master to close a port forward:
|
||||
|
||||
uint32 MUX_C_CLOSE_FWD
|
||||
uint32 request id
|
||||
uint32 forwarding type
|
||||
string listen host
|
||||
string listen port
|
||||
string connect host
|
||||
string connect port
|
||||
|
||||
forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC.
|
||||
|
||||
A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
|
||||
MUX_S_FAILURE.
|
||||
|
||||
6. Requesting stdio forwarding
|
||||
7. Requesting stdio forwarding
|
||||
|
||||
A client may request the master to establish a stdio forwarding:
|
||||
|
||||
@ -153,7 +152,7 @@ The contents of "reserved" are currently ignored.
|
||||
A server may reply with a MUX_S_SESSION_OPEED, a MUX_S_PERMISSION_DENIED
|
||||
or a MUX_S_FAILURE.
|
||||
|
||||
7. Status messages
|
||||
8. Status messages
|
||||
|
||||
The MUX_S_OK message is empty:
|
||||
|
||||
@ -170,14 +169,15 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
|
||||
uint32 client request id
|
||||
string reason
|
||||
|
||||
7. Protocol numbers
|
||||
9. Protocol numbers
|
||||
|
||||
#define MUX_MSG_HELLO 0x00000001
|
||||
#define MUX_C_NEW_SESSION 0x10000002
|
||||
#define MUX_C_ALIVE_CHECK 0x10000004
|
||||
#define MUX_C_TERMINATE 0x10000005
|
||||
#define MUX_C_OPEN_FORWARD 0x10000006
|
||||
#define MUX_C_CLOSE_FORWARD 0x10000007
|
||||
#define MUX_C_OPEN_FWD 0x10000006
|
||||
#define MUX_C_CLOSE_FWD 0x10000007
|
||||
#define MUX_C_NEW_STDIO_FWD 0x10000008
|
||||
#define MUX_S_OK 0x80000001
|
||||
#define MUX_S_PERMISSION_DENIED 0x80000002
|
||||
#define MUX_S_FAILURE 0x80000003
|
||||
@ -200,4 +200,4 @@ XXX server->client error/warning notifications
|
||||
XXX port0 rfwd (need custom response message)
|
||||
XXX send signals via mux
|
||||
|
||||
$OpenBSD: PROTOCOL.mux,v 1.2 2010/05/16 12:55:51 markus Exp $
|
||||
$OpenBSD: PROTOCOL.mux,v 1.4 2011/01/31 21:42:15 djm Exp $
|
||||
|
@ -1,4 +1,4 @@
|
||||
See http://www.openssh.com/txt/release-5.6 for the release notes.
|
||||
See http://www.openssh.com/txt/release-5.8p2 for the release notes.
|
||||
|
||||
- A Japanese translation of this document and of the OpenSSH FAQ is
|
||||
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
|
||||
@ -62,4 +62,4 @@ References -
|
||||
[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
|
||||
[7] http://www.openssh.com/faq.html
|
||||
|
||||
$Id: README,v 1.74 2010/08/08 16:32:06 djm Exp $
|
||||
$Id: README,v 1.75.4.2 2011/05/03 00:04:21 djm Exp $
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: atomicio.c,v 1.25 2007/06/25 12:02:27 dtucker Exp $ */
|
||||
/* $OpenBSD: atomicio.c,v 1.26 2010/09/22 22:58:51 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
|
||||
@ -48,7 +48,8 @@
|
||||
* ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t
|
||||
atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
|
||||
atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
|
||||
int (*cb)(void *, size_t), void *cb_arg)
|
||||
{
|
||||
char *s = _s;
|
||||
size_t pos = 0;
|
||||
@ -73,17 +74,28 @@ atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
|
||||
return pos;
|
||||
default:
|
||||
pos += (size_t)res;
|
||||
if (cb != NULL && cb(cb_arg, (size_t)res) == -1) {
|
||||
errno = EINTR;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t
|
||||
atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
|
||||
{
|
||||
return atomicio6(f, fd, _s, n, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==readv || f==writev
|
||||
*/
|
||||
size_t
|
||||
atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt)
|
||||
atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt,
|
||||
int (*cb)(void *, size_t), void *cb_arg)
|
||||
{
|
||||
size_t pos = 0, rem;
|
||||
ssize_t res;
|
||||
@ -137,6 +149,17 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
iov[0].iov_base = ((char *)iov[0].iov_base) + rem;
|
||||
iov[0].iov_len -= rem;
|
||||
}
|
||||
if (cb != NULL && cb(cb_arg, (size_t)res) == -1) {
|
||||
errno = EINTR;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t
|
||||
atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt)
|
||||
{
|
||||
return atomiciov6(f, fd, _iov, iovcnt, NULL, NULL);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: atomicio.h,v 1.10 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/* $OpenBSD: atomicio.h,v 1.11 2010/09/22 22:58:51 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
@ -32,6 +32,9 @@
|
||||
/*
|
||||
* Ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t
|
||||
atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
|
||||
int (*cb)(void *, size_t), void *);
|
||||
size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
|
||||
#define vwrite (ssize_t (*)(int, void *, size_t))write
|
||||
@ -39,6 +42,9 @@ size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==readv || f==writev
|
||||
*/
|
||||
size_t
|
||||
atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt, int (*cb)(void *, size_t), void *);
|
||||
size_t atomiciov(ssize_t (*)(int, const struct iovec *, int),
|
||||
int, const struct iovec *, int);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: audit-bsm.c,v 1.6 2008/02/25 10:05:04 dtucker Exp $ */
|
||||
/* $Id: audit-bsm.c,v 1.7 2011/01/17 10:15:29 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* TODO
|
||||
@ -305,13 +305,13 @@ audit_run_command(const char *command)
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_open(const char *ttyn)
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_close(const char *ttyn)
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
126
crypto/openssh/audit-linux.c
Normal file
126
crypto/openssh/audit-linux.c
Normal file
@ -0,0 +1,126 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright 2010 Red Hat, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Red Hat author: Jan F. Chadima <jchadima@redhat.com>
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#if defined(USE_LINUX_AUDIT)
|
||||
#include <libaudit.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "audit.h"
|
||||
#include "canohost.h"
|
||||
|
||||
const char* audit_username(void);
|
||||
|
||||
int
|
||||
linux_audit_record_event(int uid, const char *username,
|
||||
const char *hostname, const char *ip, const char *ttyn, int success)
|
||||
{
|
||||
int audit_fd, rc, saved_errno;
|
||||
|
||||
audit_fd = audit_open();
|
||||
if (audit_fd < 0) {
|
||||
if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
errno == EAFNOSUPPORT)
|
||||
return 1; /* No audit support in kernel */
|
||||
else
|
||||
return 0; /* Must prevent login */
|
||||
}
|
||||
rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN,
|
||||
NULL, "login", username ? username : "(unknown)",
|
||||
username == NULL ? uid : -1, hostname, ip, ttyn, success);
|
||||
saved_errno = errno;
|
||||
close(audit_fd);
|
||||
/*
|
||||
* Do not report error if the error is EPERM and sshd is run as non
|
||||
* root user.
|
||||
*/
|
||||
if ((rc == -EPERM) && (geteuid() != 0))
|
||||
rc = 0;
|
||||
errno = saved_errno;
|
||||
return (rc >= 0);
|
||||
}
|
||||
|
||||
/* Below is the sshd audit API code */
|
||||
|
||||
void
|
||||
audit_connection_from(const char *host, int port)
|
||||
{
|
||||
}
|
||||
/* not implemented */
|
||||
|
||||
void
|
||||
audit_run_command(const char *command)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
if (linux_audit_record_event(li->uid, NULL, li->hostname,
|
||||
NULL, li->line, 1) == 0)
|
||||
fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_event(ssh_audit_event_t event)
|
||||
{
|
||||
switch(event) {
|
||||
case SSH_AUTH_SUCCESS:
|
||||
case SSH_CONNECTION_CLOSE:
|
||||
case SSH_NOLOGIN:
|
||||
case SSH_LOGIN_EXCEED_MAXTRIES:
|
||||
case SSH_LOGIN_ROOT_DENIED:
|
||||
break;
|
||||
|
||||
case SSH_AUTH_FAIL_NONE:
|
||||
case SSH_AUTH_FAIL_PASSWD:
|
||||
case SSH_AUTH_FAIL_KBDINT:
|
||||
case SSH_AUTH_FAIL_PUBKEY:
|
||||
case SSH_AUTH_FAIL_HOSTBASED:
|
||||
case SSH_AUTH_FAIL_GSSAPI:
|
||||
case SSH_INVALID_USER:
|
||||
linux_audit_record_event(-1, audit_username(), NULL,
|
||||
get_remote_ipaddr(), "sshd", 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
debug("%s: unhandled event %d", __func__, event);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_LINUX_AUDIT */
|
@ -1,4 +1,4 @@
|
||||
/* $Id: audit.c,v 1.5 2006/09/01 05:38:36 djm Exp $ */
|
||||
/* $Id: audit.c,v 1.6 2011/01/17 10:15:30 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Darren Tucker. All rights reserved.
|
||||
@ -147,9 +147,9 @@ audit_event(ssh_audit_event_t event)
|
||||
* within a single connection.
|
||||
*/
|
||||
void
|
||||
audit_session_open(const char *ttyn)
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
const char *t = ttyn ? ttyn : "(no tty)";
|
||||
const char *t = li->line ? li->line : "(no tty)";
|
||||
|
||||
debug("audit session open euid %d user %s tty name %s", geteuid(),
|
||||
audit_username(), t);
|
||||
@ -163,9 +163,9 @@ audit_session_open(const char *ttyn)
|
||||
* within a single connection.
|
||||
*/
|
||||
void
|
||||
audit_session_close(const char *ttyn)
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
const char *t = ttyn ? ttyn : "(no tty)";
|
||||
const char *t = li->line ? li->line : "(no tty)";
|
||||
|
||||
debug("audit session close euid %d user %s tty name %s", geteuid(),
|
||||
audit_username(), t);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: audit.h,v 1.3 2006/08/05 14:05:10 dtucker Exp $ */
|
||||
/* $Id: audit.h,v 1.4 2011/01/17 10:15:30 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Darren Tucker. All rights reserved.
|
||||
@ -26,6 +26,9 @@
|
||||
|
||||
#ifndef _SSH_AUDIT_H
|
||||
# define _SSH_AUDIT_H
|
||||
|
||||
#include "loginrec.h"
|
||||
|
||||
enum ssh_audit_event_type {
|
||||
SSH_LOGIN_EXCEED_MAXTRIES,
|
||||
SSH_LOGIN_ROOT_DENIED,
|
||||
@ -46,8 +49,8 @@ typedef enum ssh_audit_event_type ssh_audit_event_t;
|
||||
|
||||
void audit_connection_from(const char *, int);
|
||||
void audit_event(ssh_audit_event_t);
|
||||
void audit_session_open(const char *);
|
||||
void audit_session_close(const char *);
|
||||
void audit_session_open(struct logininfo *);
|
||||
void audit_session_close(struct logininfo *);
|
||||
void audit_run_command(const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth-options.c,v 1.52 2010/05/20 23:46:02 djm Exp $ */
|
||||
/* $OpenBSD: auth-options.c,v 1.54 2010/12/24 21:41:48 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -172,7 +172,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
goto bad_option;
|
||||
}
|
||||
forced_command[i] = '\0';
|
||||
auth_debug_add("Forced command: %.900s", forced_command);
|
||||
auth_debug_add("Forced command.");
|
||||
opts++;
|
||||
goto next_option;
|
||||
}
|
||||
@ -444,7 +444,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
|
||||
buffer_append(&c, optblob, optblob_len);
|
||||
|
||||
while (buffer_len(&c) > 0) {
|
||||
if ((name = buffer_get_string_ret(&c, &nlen)) == NULL ||
|
||||
if ((name = buffer_get_cstring_ret(&c, &nlen)) == NULL ||
|
||||
(data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
|
||||
error("Certificate options corrupt");
|
||||
goto out;
|
||||
@ -479,7 +479,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
|
||||
}
|
||||
if (!found && (which & OPTIONS_CRITICAL) != 0) {
|
||||
if (strcmp(name, "force-command") == 0) {
|
||||
if ((command = buffer_get_string_ret(&data,
|
||||
if ((command = buffer_get_cstring_ret(&data,
|
||||
&clen)) == NULL) {
|
||||
error("Certificate constraint \"%s\" "
|
||||
"corrupt", name);
|
||||
@ -500,7 +500,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
|
||||
found = 1;
|
||||
}
|
||||
if (strcmp(name, "source-address") == 0) {
|
||||
if ((allowed = buffer_get_string_ret(&data,
|
||||
if ((allowed = buffer_get_cstring_ret(&data,
|
||||
&clen)) == NULL) {
|
||||
error("Certificate constraint "
|
||||
"\"%s\" corrupt", name);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth-rsa.c,v 1.78 2010/07/13 23:13:16 djm Exp $ */
|
||||
/* $OpenBSD: auth-rsa.c,v 1.79 2010/12/03 23:55:27 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -94,9 +94,6 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
|
||||
MD5_CTX md;
|
||||
int len;
|
||||
|
||||
if (auth_key_is_revoked(key))
|
||||
return 0;
|
||||
|
||||
/* don't allow short keys */
|
||||
if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
|
||||
error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits",
|
||||
@ -249,6 +246,10 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
|
||||
"actual %d vs. announced %d.",
|
||||
file, linenum, BN_num_bits(key->rsa->n), bits);
|
||||
|
||||
/* Never accept a revoked key */
|
||||
if (auth_key_is_revoked(key))
|
||||
break;
|
||||
|
||||
/* We have found the desired key. */
|
||||
/*
|
||||
* If our options do not allow this key to be used,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth.c,v 1.89 2010/08/04 05:42:47 djm Exp $ */
|
||||
/* $OpenBSD: auth.c,v 1.91 2010/11/29 23:45:51 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -380,16 +380,15 @@ HostStatus
|
||||
check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
|
||||
const char *sysfile, const char *userfile)
|
||||
{
|
||||
Key *found;
|
||||
char *user_hostfile;
|
||||
struct stat st;
|
||||
HostStatus host_status;
|
||||
struct hostkeys *hostkeys;
|
||||
const struct hostkey_entry *found;
|
||||
|
||||
/* Check if we know the host and its host key. */
|
||||
found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
|
||||
host_status = check_host_in_hostfile(sysfile, host, key, found, NULL);
|
||||
|
||||
if (host_status != HOST_OK && userfile != NULL) {
|
||||
hostkeys = init_hostkeys();
|
||||
load_hostkeys(hostkeys, host, sysfile);
|
||||
if (userfile != NULL) {
|
||||
user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
|
||||
if (options.strict_modes &&
|
||||
(stat(user_hostfile, &st) == 0) &&
|
||||
@ -402,16 +401,23 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
|
||||
user_hostfile);
|
||||
} else {
|
||||
temporarily_use_uid(pw);
|
||||
host_status = check_host_in_hostfile(user_hostfile,
|
||||
host, key, found, NULL);
|
||||
load_hostkeys(hostkeys, host, user_hostfile);
|
||||
restore_uid();
|
||||
}
|
||||
xfree(user_hostfile);
|
||||
}
|
||||
key_free(found);
|
||||
host_status = check_key_in_hostkeys(hostkeys, key, &found);
|
||||
if (host_status == HOST_REVOKED)
|
||||
error("WARNING: revoked key for %s attempted authentication",
|
||||
found->host);
|
||||
else if (host_status == HOST_OK)
|
||||
debug("%s: key for %s found at %s:%ld", __func__,
|
||||
found->host, found->file, found->line);
|
||||
else
|
||||
debug("%s: key for host %s not found", __func__, host);
|
||||
|
||||
free_hostkeys(hostkeys);
|
||||
|
||||
debug2("check_key_in_hostfiles: key %s for %s", host_status == HOST_OK ?
|
||||
"ok" : "not found", host);
|
||||
return host_status;
|
||||
}
|
||||
|
||||
@ -519,7 +525,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (options.strict_modes &&
|
||||
if (strict_modes &&
|
||||
secure_filename(f, file, pw, line, sizeof(line)) != 0) {
|
||||
fclose(f);
|
||||
logit("Authentication refused: %s", line);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth1.c,v 1.74 2010/06/25 08:46:17 djm Exp $ */
|
||||
/* $OpenBSD: auth1.c,v 1.75 2010/08/31 09:58:37 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -167,7 +167,7 @@ auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen)
|
||||
* trust the client; root on the client machine can
|
||||
* claim to be any user.
|
||||
*/
|
||||
client_user = packet_get_string(&ulen);
|
||||
client_user = packet_get_cstring(&ulen);
|
||||
|
||||
/* Get the client host key. */
|
||||
client_host_key = key_new(KEY_RSA1);
|
||||
@ -389,7 +389,7 @@ do_authentication(Authctxt *authctxt)
|
||||
packet_read_expect(SSH_CMSG_USER);
|
||||
|
||||
/* Get the user name. */
|
||||
user = packet_get_string(&ulen);
|
||||
user = packet_get_cstring(&ulen);
|
||||
packet_check_eom();
|
||||
|
||||
if ((style = strchr(user, ':')) != NULL)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2-jpake.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
|
||||
/* $OpenBSD: auth2-jpake.c,v 1.4 2010/08/31 11:54:45 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
*
|
||||
@ -162,6 +162,11 @@ derive_rawsalt(const char *username, u_char *rawsalt, u_int len)
|
||||
fatal("%s: DSA key missing priv_key", __func__);
|
||||
buffer_put_bignum2(&b, k->dsa->priv_key);
|
||||
break;
|
||||
case KEY_ECDSA:
|
||||
if (EC_KEY_get0_private_key(k->ecdsa) == NULL)
|
||||
fatal("%s: ECDSA key missing priv_key", __func__);
|
||||
buffer_put_bignum2(&b, EC_KEY_get0_private_key(k->ecdsa));
|
||||
break;
|
||||
default:
|
||||
fatal("%s: unknown key type %d", __func__, k->type);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.26 2010/06/29 23:16:46 djm Exp $ */
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.27 2010/11/20 05:12:38 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -232,7 +232,7 @@ match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert)
|
||||
if ((ep = strrchr(cp, ' ')) != NULL ||
|
||||
(ep = strrchr(cp, '\t')) != NULL) {
|
||||
for (; *ep == ' ' || *ep == '\t'; ep++)
|
||||
;;
|
||||
;
|
||||
line_opts = cp;
|
||||
cp = ep;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2.c,v 1.121 2009/06/22 05:39:28 dtucker Exp $ */
|
||||
/* $OpenBSD: auth2.c,v 1.122 2010/08/31 09:58:37 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -184,7 +184,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
|
||||
Authctxt *authctxt = ctxt;
|
||||
u_int len;
|
||||
int acceptit = 0;
|
||||
char *service = packet_get_string(&len);
|
||||
char *service = packet_get_cstring(&len);
|
||||
packet_check_eom();
|
||||
|
||||
if (authctxt == NULL)
|
||||
@ -230,9 +230,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_request: no authctxt");
|
||||
|
||||
user = packet_get_string(NULL);
|
||||
service = packet_get_string(NULL);
|
||||
method = packet_get_string(NULL);
|
||||
user = packet_get_cstring(NULL);
|
||||
service = packet_get_cstring(NULL);
|
||||
method = packet_get_cstring(NULL);
|
||||
debug("userauth-request for user %s service %s method %s", user, service, method);
|
||||
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfd.c,v 1.83 2010/04/16 01:47:26 djm Exp $ */
|
||||
/* $OpenBSD: authfd.c,v 1.84 2010/08/31 11:54:45 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -509,6 +509,21 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
|
||||
buffer_len(&key->cert->certblob));
|
||||
buffer_put_bignum2(b, key->dsa->priv_key);
|
||||
break;
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
case KEY_ECDSA:
|
||||
buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid));
|
||||
buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
|
||||
EC_KEY_get0_public_key(key->ecdsa));
|
||||
buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
|
||||
break;
|
||||
case KEY_ECDSA_CERT:
|
||||
if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
|
||||
fatal("%s: no cert/certblob", __func__);
|
||||
buffer_put_string(b, buffer_ptr(&key->cert->certblob),
|
||||
buffer_len(&key->cert->certblob));
|
||||
buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
buffer_put_cstring(b, comment);
|
||||
}
|
||||
@ -541,6 +556,8 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
|
||||
case KEY_DSA:
|
||||
case KEY_DSA_CERT:
|
||||
case KEY_DSA_CERT_V00:
|
||||
case KEY_ECDSA:
|
||||
case KEY_ECDSA_CERT:
|
||||
type = constrained ?
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED :
|
||||
SSH2_AGENTC_ADD_IDENTITY;
|
||||
@ -589,7 +606,8 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key)
|
||||
buffer_put_bignum(&msg, key->rsa->e);
|
||||
buffer_put_bignum(&msg, key->rsa->n);
|
||||
} else if (key_type_plain(key->type) == KEY_DSA ||
|
||||
key_type_plain(key->type) == KEY_RSA) {
|
||||
key_type_plain(key->type) == KEY_RSA ||
|
||||
key_type_plain(key->type) == KEY_ECDSA) {
|
||||
key_to_blob(key, &blob, &blen);
|
||||
buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
|
||||
buffer_put_string(&msg, blob, blen);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfile.c,v 1.82 2010/08/04 05:49:22 djm Exp $ */
|
||||
/* $OpenBSD: authfile.c,v 1.87 2010/11/29 18:57:04 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -74,19 +74,18 @@ static const char authfile_id_string[] =
|
||||
"SSH PRIVATE KEY FILE FORMAT 1.1\n";
|
||||
|
||||
/*
|
||||
* Saves the authentication (private) key in a file, encrypting it with
|
||||
* passphrase. The identification of the file (lowest 64 bits of n) will
|
||||
* Serialises the authentication (private) key to a blob, encrypting it with
|
||||
* passphrase. The identification of the blob (lowest 64 bits of n) will
|
||||
* precede the key to provide identification of the key without needing a
|
||||
* passphrase.
|
||||
*/
|
||||
|
||||
static int
|
||||
key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
|
||||
key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
|
||||
const char *comment)
|
||||
{
|
||||
Buffer buffer, encrypted;
|
||||
u_char buf[100], *cp;
|
||||
int fd, i, cipher_num;
|
||||
int i, cipher_num;
|
||||
CipherContext ciphercontext;
|
||||
Cipher *cipher;
|
||||
u_int32_t rnd;
|
||||
@ -157,88 +156,200 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
|
||||
memset(buf, 0, sizeof(buf));
|
||||
buffer_free(&buffer);
|
||||
|
||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0) {
|
||||
error("open %s failed: %s.", filename, strerror(errno));
|
||||
buffer_free(&encrypted);
|
||||
return 0;
|
||||
}
|
||||
if (atomicio(vwrite, fd, buffer_ptr(&encrypted),
|
||||
buffer_len(&encrypted)) != buffer_len(&encrypted)) {
|
||||
error("write to key file %s failed: %s", filename,
|
||||
strerror(errno));
|
||||
buffer_free(&encrypted);
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted));
|
||||
buffer_free(&encrypted);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* save SSH v2 key in OpenSSL PEM format */
|
||||
/* convert SSH v2 key in OpenSSL PEM format */
|
||||
static int
|
||||
key_save_private_pem(Key *key, const char *filename, const char *_passphrase,
|
||||
key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase,
|
||||
const char *comment)
|
||||
{
|
||||
FILE *fp;
|
||||
int fd;
|
||||
int success = 0;
|
||||
int len = strlen(_passphrase);
|
||||
int blen, len = strlen(_passphrase);
|
||||
u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
|
||||
const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
|
||||
#else
|
||||
const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
|
||||
#endif
|
||||
const u_char *bptr;
|
||||
BIO *bio;
|
||||
|
||||
if (len > 0 && len <= 4) {
|
||||
error("passphrase too short: have %d bytes, need > 4", len);
|
||||
return 0;
|
||||
}
|
||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0) {
|
||||
error("open %s failed: %s.", filename, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
fp = fdopen(fd, "w");
|
||||
if (fp == NULL) {
|
||||
error("fdopen %s failed: %s.", filename, strerror(errno));
|
||||
close(fd);
|
||||
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
|
||||
error("%s: BIO_new failed", __func__);
|
||||
return 0;
|
||||
}
|
||||
switch (key->type) {
|
||||
case KEY_DSA:
|
||||
success = PEM_write_DSAPrivateKey(fp, key->dsa,
|
||||
success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
|
||||
cipher, passphrase, len, NULL, NULL);
|
||||
break;
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
case KEY_ECDSA:
|
||||
success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
|
||||
cipher, passphrase, len, NULL, NULL);
|
||||
break;
|
||||
#endif
|
||||
case KEY_RSA:
|
||||
success = PEM_write_RSAPrivateKey(fp, key->rsa,
|
||||
success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
|
||||
cipher, passphrase, len, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
if (success) {
|
||||
if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0)
|
||||
success = 0;
|
||||
else
|
||||
buffer_append(blob, bptr, blen);
|
||||
}
|
||||
BIO_free(bio);
|
||||
return success;
|
||||
}
|
||||
|
||||
/* Save a key blob to a file */
|
||||
static int
|
||||
key_save_private_blob(Buffer *keybuf, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) {
|
||||
error("open %s failed: %s.", filename, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (atomicio(vwrite, fd, buffer_ptr(keybuf),
|
||||
buffer_len(keybuf)) != buffer_len(keybuf)) {
|
||||
error("write to key file %s failed: %s", filename,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Serialise "key" to buffer "blob" */
|
||||
static int
|
||||
key_private_to_blob(Key *key, Buffer *blob, const char *passphrase,
|
||||
const char *comment)
|
||||
{
|
||||
switch (key->type) {
|
||||
case KEY_RSA1:
|
||||
return key_private_rsa1_to_blob(key, blob, passphrase, comment);
|
||||
case KEY_DSA:
|
||||
case KEY_ECDSA:
|
||||
case KEY_RSA:
|
||||
return key_private_pem_to_blob(key, blob, passphrase, comment);
|
||||
default:
|
||||
error("%s: cannot save key type %d", __func__, key->type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
key_save_private(Key *key, const char *filename, const char *passphrase,
|
||||
const char *comment)
|
||||
{
|
||||
switch (key->type) {
|
||||
case KEY_RSA1:
|
||||
return key_save_private_rsa1(key, filename, passphrase,
|
||||
comment);
|
||||
case KEY_DSA:
|
||||
case KEY_RSA:
|
||||
return key_save_private_pem(key, filename, passphrase,
|
||||
comment);
|
||||
default:
|
||||
break;
|
||||
Buffer keyblob;
|
||||
int success = 0;
|
||||
|
||||
buffer_init(&keyblob);
|
||||
if (!key_private_to_blob(key, &keyblob, passphrase, comment))
|
||||
goto out;
|
||||
if (!key_save_private_blob(&keyblob, filename))
|
||||
goto out;
|
||||
success = 1;
|
||||
out:
|
||||
buffer_free(&keyblob);
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the public, unencrypted portion of a RSA1 key.
|
||||
*/
|
||||
static Key *
|
||||
key_parse_public_rsa1(Buffer *blob, char **commentp)
|
||||
{
|
||||
Key *pub;
|
||||
|
||||
/* Check that it is at least big enough to contain the ID string. */
|
||||
if (buffer_len(blob) < sizeof(authfile_id_string)) {
|
||||
debug3("Truncated RSA1 identifier");
|
||||
return NULL;
|
||||
}
|
||||
error("key_save_private: cannot save key type %d", key->type);
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Make sure it begins with the id string. Consume the id string
|
||||
* from the buffer.
|
||||
*/
|
||||
if (memcmp(buffer_ptr(blob), authfile_id_string,
|
||||
sizeof(authfile_id_string)) != 0) {
|
||||
debug3("Incorrect RSA1 identifier");
|
||||
return NULL;
|
||||
}
|
||||
buffer_consume(blob, sizeof(authfile_id_string));
|
||||
|
||||
/* Skip cipher type and reserved data. */
|
||||
(void) buffer_get_char(blob); /* cipher type */
|
||||
(void) buffer_get_int(blob); /* reserved */
|
||||
|
||||
/* Read the public key from the buffer. */
|
||||
(void) buffer_get_int(blob);
|
||||
pub = key_new(KEY_RSA1);
|
||||
buffer_get_bignum(blob, pub->rsa->n);
|
||||
buffer_get_bignum(blob, pub->rsa->e);
|
||||
if (commentp)
|
||||
*commentp = buffer_get_string(blob, NULL);
|
||||
/* The encrypted private part is not parsed by this function. */
|
||||
buffer_clear(blob);
|
||||
|
||||
return pub;
|
||||
}
|
||||
|
||||
/* Load the contents of a key file into a buffer */
|
||||
static int
|
||||
key_load_file(int fd, const char *filename, Buffer *blob)
|
||||
{
|
||||
size_t len;
|
||||
u_char *cp;
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
error("%s: fstat of key file %.200s%sfailed: %.100s", __func__,
|
||||
filename == NULL ? "" : filename,
|
||||
filename == NULL ? "" : " ",
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (st.st_size > 1*1024*1024) {
|
||||
error("%s: key file %.200s%stoo large", __func__,
|
||||
filename == NULL ? "" : filename,
|
||||
filename == NULL ? "" : " ");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
len = (size_t)st.st_size; /* truncated */
|
||||
|
||||
buffer_init(blob);
|
||||
cp = buffer_append_space(blob, len);
|
||||
|
||||
if (atomicio(read, fd, cp, len) != len) {
|
||||
debug("%s: read from key file %.200s%sfailed: %.100s", __func__,
|
||||
filename == NULL ? "" : filename,
|
||||
filename == NULL ? "" : " ",
|
||||
strerror(errno));
|
||||
buffer_clear(blob);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -246,67 +357,21 @@ key_save_private(Key *key, const char *filename, const char *passphrase,
|
||||
* encountered (the file does not exist or is not readable), and the key
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
static Key *
|
||||
key_load_public_rsa1(int fd, const char *filename, char **commentp)
|
||||
{
|
||||
Buffer buffer;
|
||||
Key *pub;
|
||||
struct stat st;
|
||||
char *cp;
|
||||
u_int i;
|
||||
size_t len;
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
error("fstat for key file %.200s failed: %.100s",
|
||||
filename, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if (st.st_size > 1*1024*1024) {
|
||||
error("key file %.200s too large", filename);
|
||||
return NULL;
|
||||
}
|
||||
len = (size_t)st.st_size; /* truncated */
|
||||
|
||||
buffer_init(&buffer);
|
||||
cp = buffer_append_space(&buffer, len);
|
||||
|
||||
if (atomicio(read, fd, cp, len) != len) {
|
||||
debug("Read from key file %.200s failed: %.100s", filename,
|
||||
strerror(errno));
|
||||
if (!key_load_file(fd, filename, &buffer)) {
|
||||
buffer_free(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check that it is at least big enough to contain the ID string. */
|
||||
if (len < sizeof(authfile_id_string)) {
|
||||
debug3("Not a RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* Make sure it begins with the id string. Consume the id string
|
||||
* from the buffer.
|
||||
*/
|
||||
for (i = 0; i < sizeof(authfile_id_string); i++)
|
||||
if (buffer_get_char(&buffer) != authfile_id_string[i]) {
|
||||
debug3("Not a RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
/* Skip cipher type and reserved data. */
|
||||
(void) buffer_get_char(&buffer); /* cipher type */
|
||||
(void) buffer_get_int(&buffer); /* reserved */
|
||||
|
||||
/* Read the public key from the buffer. */
|
||||
(void) buffer_get_int(&buffer);
|
||||
pub = key_new(KEY_RSA1);
|
||||
buffer_get_bignum(&buffer, pub->rsa->n);
|
||||
buffer_get_bignum(&buffer, pub->rsa->e);
|
||||
if (commentp)
|
||||
*commentp = buffer_get_string(&buffer, NULL);
|
||||
/* The encrypted private part is not parsed by this function. */
|
||||
|
||||
pub = key_parse_public_rsa1(&buffer, commentp);
|
||||
if (pub == NULL)
|
||||
debug3("Could not load \"%s\" as a RSA1 public key", filename);
|
||||
buffer_free(&buffer);
|
||||
return pub;
|
||||
}
|
||||
@ -329,113 +394,73 @@ key_load_public_type(int type, const char *filename, char **commentp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the private key from the file. Returns 0 if an error is encountered
|
||||
* (file does not exist or is not readable, or passphrase is bad). This
|
||||
* initializes the private key.
|
||||
* Assumes we are called under uid of the owner of the file.
|
||||
*/
|
||||
|
||||
static Key *
|
||||
key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
|
||||
char **commentp)
|
||||
key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
|
||||
{
|
||||
u_int i;
|
||||
int check1, check2, cipher_type;
|
||||
size_t len;
|
||||
Buffer buffer, decrypted;
|
||||
Buffer decrypted;
|
||||
u_char *cp;
|
||||
CipherContext ciphercontext;
|
||||
Cipher *cipher;
|
||||
Key *prv = NULL;
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
error("fstat for key file %.200s failed: %.100s",
|
||||
filename, strerror(errno));
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (st.st_size > 1*1024*1024) {
|
||||
error("key file %.200s too large", filename);
|
||||
close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
len = (size_t)st.st_size; /* truncated */
|
||||
|
||||
buffer_init(&buffer);
|
||||
cp = buffer_append_space(&buffer, len);
|
||||
|
||||
if (atomicio(read, fd, cp, len) != len) {
|
||||
debug("Read from key file %.200s failed: %.100s", filename,
|
||||
strerror(errno));
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check that it is at least big enough to contain the ID string. */
|
||||
if (len < sizeof(authfile_id_string)) {
|
||||
debug3("Not a RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
if (buffer_len(blob) < sizeof(authfile_id_string)) {
|
||||
debug3("Truncated RSA1 identifier");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure it begins with the id string. Consume the id string
|
||||
* from the buffer.
|
||||
*/
|
||||
for (i = 0; i < sizeof(authfile_id_string); i++)
|
||||
if (buffer_get_char(&buffer) != authfile_id_string[i]) {
|
||||
debug3("Not a RSA1 key file %.200s.", filename);
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (memcmp(buffer_ptr(blob), authfile_id_string,
|
||||
sizeof(authfile_id_string)) != 0) {
|
||||
debug3("Incorrect RSA1 identifier");
|
||||
return NULL;
|
||||
}
|
||||
buffer_consume(blob, sizeof(authfile_id_string));
|
||||
|
||||
/* Read cipher type. */
|
||||
cipher_type = buffer_get_char(&buffer);
|
||||
(void) buffer_get_int(&buffer); /* Reserved data. */
|
||||
cipher_type = buffer_get_char(blob);
|
||||
(void) buffer_get_int(blob); /* Reserved data. */
|
||||
|
||||
/* Read the public key from the buffer. */
|
||||
(void) buffer_get_int(&buffer);
|
||||
(void) buffer_get_int(blob);
|
||||
prv = key_new_private(KEY_RSA1);
|
||||
|
||||
buffer_get_bignum(&buffer, prv->rsa->n);
|
||||
buffer_get_bignum(&buffer, prv->rsa->e);
|
||||
buffer_get_bignum(blob, prv->rsa->n);
|
||||
buffer_get_bignum(blob, prv->rsa->e);
|
||||
if (commentp)
|
||||
*commentp = buffer_get_string(&buffer, NULL);
|
||||
*commentp = buffer_get_string(blob, NULL);
|
||||
else
|
||||
xfree(buffer_get_string(&buffer, NULL));
|
||||
(void)buffer_get_string_ptr(blob, NULL);
|
||||
|
||||
/* Check that it is a supported cipher. */
|
||||
cipher = cipher_by_number(cipher_type);
|
||||
if (cipher == NULL) {
|
||||
debug("Unsupported cipher %d used in key file %.200s.",
|
||||
cipher_type, filename);
|
||||
buffer_free(&buffer);
|
||||
debug("Unsupported RSA1 cipher %d", cipher_type);
|
||||
goto fail;
|
||||
}
|
||||
/* Initialize space for decrypted data. */
|
||||
buffer_init(&decrypted);
|
||||
cp = buffer_append_space(&decrypted, buffer_len(&buffer));
|
||||
cp = buffer_append_space(&decrypted, buffer_len(blob));
|
||||
|
||||
/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
|
||||
cipher_set_key_string(&ciphercontext, cipher, passphrase,
|
||||
CIPHER_DECRYPT);
|
||||
cipher_crypt(&ciphercontext, cp,
|
||||
buffer_ptr(&buffer), buffer_len(&buffer));
|
||||
buffer_ptr(blob), buffer_len(blob));
|
||||
cipher_cleanup(&ciphercontext);
|
||||
memset(&ciphercontext, 0, sizeof(ciphercontext));
|
||||
buffer_free(&buffer);
|
||||
buffer_clear(blob);
|
||||
|
||||
check1 = buffer_get_char(&decrypted);
|
||||
check2 = buffer_get_char(&decrypted);
|
||||
if (check1 != buffer_get_char(&decrypted) ||
|
||||
check2 != buffer_get_char(&decrypted)) {
|
||||
if (strcmp(passphrase, "") != 0)
|
||||
debug("Bad passphrase supplied for key file %.200s.",
|
||||
filename);
|
||||
debug("Bad passphrase supplied for RSA1 key");
|
||||
/* Bad passphrase. */
|
||||
buffer_free(&decrypted);
|
||||
goto fail;
|
||||
@ -454,38 +479,37 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
|
||||
|
||||
/* enable blinding */
|
||||
if (RSA_blinding_on(prv->rsa, NULL) != 1) {
|
||||
error("key_load_private_rsa1: RSA_blinding_on failed");
|
||||
error("%s: RSA_blinding_on failed", __func__);
|
||||
goto fail;
|
||||
}
|
||||
close(fd);
|
||||
return prv;
|
||||
|
||||
fail:
|
||||
if (commentp)
|
||||
xfree(*commentp);
|
||||
close(fd);
|
||||
key_free(prv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Key *
|
||||
key_load_private_pem(int fd, int type, const char *passphrase,
|
||||
static Key *
|
||||
key_parse_private_pem(Buffer *blob, int type, const char *passphrase,
|
||||
char **commentp)
|
||||
{
|
||||
FILE *fp;
|
||||
EVP_PKEY *pk = NULL;
|
||||
Key *prv = NULL;
|
||||
char *name = "<no key>";
|
||||
BIO *bio;
|
||||
|
||||
fp = fdopen(fd, "r");
|
||||
if (fp == NULL) {
|
||||
error("fdopen failed: %s", strerror(errno));
|
||||
close(fd);
|
||||
if ((bio = BIO_new_mem_buf(buffer_ptr(blob),
|
||||
buffer_len(blob))) == NULL) {
|
||||
error("%s: BIO_new_mem_buf failed", __func__);
|
||||
return NULL;
|
||||
}
|
||||
pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase);
|
||||
|
||||
pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase);
|
||||
BIO_free(bio);
|
||||
if (pk == NULL) {
|
||||
debug("PEM_read_PrivateKey failed");
|
||||
debug("%s: PEM_read_PrivateKey failed", __func__);
|
||||
(void)ERR_get_error();
|
||||
} else if (pk->type == EVP_PKEY_RSA &&
|
||||
(type == KEY_UNSPEC||type==KEY_RSA)) {
|
||||
@ -497,7 +521,7 @@ key_load_private_pem(int fd, int type, const char *passphrase,
|
||||
RSA_print_fp(stderr, prv->rsa, 8);
|
||||
#endif
|
||||
if (RSA_blinding_on(prv->rsa, NULL) != 1) {
|
||||
error("key_load_private_pem: RSA_blinding_on failed");
|
||||
error("%s: RSA_blinding_on failed", __func__);
|
||||
key_free(prv);
|
||||
prv = NULL;
|
||||
}
|
||||
@ -510,11 +534,31 @@ key_load_private_pem(int fd, int type, const char *passphrase,
|
||||
#ifdef DEBUG_PK
|
||||
DSA_print_fp(stderr, prv->dsa, 8);
|
||||
#endif
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
} else if (pk->type == EVP_PKEY_EC &&
|
||||
(type == KEY_UNSPEC||type==KEY_ECDSA)) {
|
||||
prv = key_new(KEY_UNSPEC);
|
||||
prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
|
||||
prv->type = KEY_ECDSA;
|
||||
if ((prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa)) == -1 ||
|
||||
key_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
|
||||
key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
|
||||
EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
|
||||
key_ec_validate_private(prv->ecdsa) != 0) {
|
||||
error("%s: bad ECDSA key", __func__);
|
||||
key_free(prv);
|
||||
prv = NULL;
|
||||
}
|
||||
name = "ecdsa w/o comment";
|
||||
#ifdef DEBUG_PK
|
||||
if (prv != NULL && prv->ecdsa != NULL)
|
||||
key_dump_ec_key(prv->ecdsa);
|
||||
#endif
|
||||
#endif /* OPENSSL_HAS_ECC */
|
||||
} else {
|
||||
error("PEM_read_PrivateKey: mismatch or "
|
||||
"unknown EVP_PKEY save_type %d", pk->save_type);
|
||||
error("%s: PEM_read_PrivateKey: mismatch or "
|
||||
"unknown EVP_PKEY save_type %d", __func__, pk->save_type);
|
||||
}
|
||||
fclose(fp);
|
||||
if (pk != NULL)
|
||||
EVP_PKEY_free(pk);
|
||||
if (prv != NULL && commentp)
|
||||
@ -524,6 +568,23 @@ key_load_private_pem(int fd, int type, const char *passphrase,
|
||||
return prv;
|
||||
}
|
||||
|
||||
Key *
|
||||
key_load_private_pem(int fd, int type, const char *passphrase,
|
||||
char **commentp)
|
||||
{
|
||||
Buffer buffer;
|
||||
Key *prv;
|
||||
|
||||
buffer_init(&buffer);
|
||||
if (!key_load_file(fd, NULL, &buffer)) {
|
||||
buffer_free(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
prv = key_parse_private_pem(&buffer, type, passphrase, commentp);
|
||||
buffer_free(&buffer);
|
||||
return prv;
|
||||
}
|
||||
|
||||
int
|
||||
key_perm_ok(int fd, const char *filename)
|
||||
{
|
||||
@ -552,11 +613,31 @@ key_perm_ok(int fd, const char *filename)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Key *
|
||||
key_parse_private_type(Buffer *blob, int type, const char *passphrase,
|
||||
char **commentp)
|
||||
{
|
||||
switch (type) {
|
||||
case KEY_RSA1:
|
||||
return key_parse_private_rsa1(blob, passphrase, commentp);
|
||||
case KEY_DSA:
|
||||
case KEY_ECDSA:
|
||||
case KEY_RSA:
|
||||
case KEY_UNSPEC:
|
||||
return key_parse_private_pem(blob, type, passphrase, commentp);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Key *
|
||||
key_load_private_type(int type, const char *filename, const char *passphrase,
|
||||
char **commentp, int *perm_ok)
|
||||
{
|
||||
int fd;
|
||||
Key *ret;
|
||||
Buffer buffer;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
@ -575,21 +656,17 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
|
||||
}
|
||||
if (perm_ok != NULL)
|
||||
*perm_ok = 1;
|
||||
switch (type) {
|
||||
case KEY_RSA1:
|
||||
return key_load_private_rsa1(fd, filename, passphrase,
|
||||
commentp);
|
||||
/* closes fd */
|
||||
case KEY_DSA:
|
||||
case KEY_RSA:
|
||||
case KEY_UNSPEC:
|
||||
return key_load_private_pem(fd, type, passphrase, commentp);
|
||||
/* closes fd */
|
||||
default:
|
||||
|
||||
buffer_init(&buffer);
|
||||
if (!key_load_file(fd, filename, &buffer)) {
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
break;
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
close(fd);
|
||||
ret = key_parse_private_type(&buffer, type, passphrase, commentp);
|
||||
buffer_free(&buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Key *
|
||||
@ -597,6 +674,7 @@ key_load_private(const char *filename, const char *passphrase,
|
||||
char **commentp)
|
||||
{
|
||||
Key *pub, *prv;
|
||||
Buffer buffer, pubcopy;
|
||||
int fd;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
@ -610,20 +688,33 @@ key_load_private(const char *filename, const char *passphrase,
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
pub = key_load_public_rsa1(fd, filename, commentp);
|
||||
lseek(fd, (off_t) 0, SEEK_SET); /* rewind */
|
||||
|
||||
buffer_init(&buffer);
|
||||
if (!key_load_file(fd, filename, &buffer)) {
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
buffer_init(&pubcopy);
|
||||
buffer_append(&pubcopy, buffer_ptr(&buffer), buffer_len(&buffer));
|
||||
/* it's a SSH v1 key if the public key part is readable */
|
||||
pub = key_parse_public_rsa1(&pubcopy, commentp);
|
||||
buffer_free(&pubcopy);
|
||||
if (pub == NULL) {
|
||||
/* closes fd */
|
||||
prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL);
|
||||
prv = key_parse_private_type(&buffer, KEY_UNSPEC,
|
||||
passphrase, NULL);
|
||||
/* use the filename as a comment for PEM */
|
||||
if (commentp && prv)
|
||||
*commentp = xstrdup(filename);
|
||||
} else {
|
||||
/* it's a SSH v1 key if the public key part is readable */
|
||||
key_free(pub);
|
||||
/* closes fd */
|
||||
prv = key_load_private_rsa1(fd, filename, passphrase, NULL);
|
||||
/* key_parse_public_rsa1() has already loaded the comment */
|
||||
prv = key_parse_private_type(&buffer, KEY_RSA1, passphrase,
|
||||
NULL);
|
||||
}
|
||||
buffer_free(&buffer);
|
||||
return prv;
|
||||
}
|
||||
|
||||
@ -721,6 +812,7 @@ key_load_private_cert(int type, const char *filename, const char *passphrase,
|
||||
switch (type) {
|
||||
case KEY_RSA:
|
||||
case KEY_DSA:
|
||||
case KEY_ECDSA:
|
||||
break;
|
||||
default:
|
||||
error("%s: unsupported key type", __func__);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: bufaux.c,v 1.49 2010/03/26 03:13:17 djm Exp $ */
|
||||
/* $OpenBSD: bufaux.c,v 1.50 2010/08/31 09:58:37 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -202,6 +202,39 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
char *
|
||||
buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr)
|
||||
{
|
||||
u_int length;
|
||||
char *cp, *ret = buffer_get_string_ret(buffer, &length);
|
||||
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
if ((cp = memchr(ret, '\0', length)) != NULL) {
|
||||
/* XXX allow \0 at end-of-string for a while, remove later */
|
||||
if (cp == ret + length - 1)
|
||||
error("buffer_get_cstring_ret: string contains \\0");
|
||||
else {
|
||||
bzero(ret, length);
|
||||
xfree(ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (length_ptr != NULL)
|
||||
*length_ptr = length;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
buffer_get_cstring(Buffer *buffer, u_int *length_ptr)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL)
|
||||
fatal("buffer_get_cstring: buffer error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr)
|
||||
{
|
||||
|
146
crypto/openssh/bufec.c
Normal file
146
crypto/openssh/bufec.c
Normal file
@ -0,0 +1,146 @@
|
||||
/* $OpenBSD: bufec.c,v 1.1 2010/08/31 11:54:45 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
|
||||
/*
|
||||
* Maximum supported EC GFp field length is 528 bits. SEC1 uncompressed
|
||||
* encoding represents this as two bitstring points that should each
|
||||
* be no longer than the field length, SEC1 specifies a 1 byte
|
||||
* point type header.
|
||||
* Being paranoid here may insulate us to parsing problems in
|
||||
* EC_POINT_oct2point.
|
||||
*/
|
||||
#define BUFFER_MAX_ECPOINT_LEN ((528*2 / 8) + 1)
|
||||
|
||||
/*
|
||||
* Append an EC_POINT to the buffer as a string containing a SEC1 encoded
|
||||
* uncompressed point. Fortunately OpenSSL handles the gory details for us.
|
||||
*/
|
||||
int
|
||||
buffer_put_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve,
|
||||
const EC_POINT *point)
|
||||
{
|
||||
u_char *buf = NULL;
|
||||
size_t len;
|
||||
BN_CTX *bnctx;
|
||||
int ret = -1;
|
||||
|
||||
/* Determine length */
|
||||
if ((bnctx = BN_CTX_new()) == NULL)
|
||||
fatal("%s: BN_CTX_new failed", __func__);
|
||||
len = EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED,
|
||||
NULL, 0, bnctx);
|
||||
if (len > BUFFER_MAX_ECPOINT_LEN) {
|
||||
error("%s: giant EC point: len = %lu (max %u)",
|
||||
__func__, (u_long)len, BUFFER_MAX_ECPOINT_LEN);
|
||||
goto out;
|
||||
}
|
||||
/* Convert */
|
||||
buf = xmalloc(len);
|
||||
if (EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED,
|
||||
buf, len, bnctx) != len) {
|
||||
error("%s: EC_POINT_point2oct length mismatch", __func__);
|
||||
goto out;
|
||||
}
|
||||
/* Append */
|
||||
buffer_put_string(buffer, buf, len);
|
||||
ret = 0;
|
||||
out:
|
||||
if (buf != NULL) {
|
||||
bzero(buf, len);
|
||||
xfree(buf);
|
||||
}
|
||||
BN_CTX_free(bnctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_put_ecpoint(Buffer *buffer, const EC_GROUP *curve,
|
||||
const EC_POINT *point)
|
||||
{
|
||||
if (buffer_put_ecpoint_ret(buffer, curve, point) == -1)
|
||||
fatal("%s: buffer error", __func__);
|
||||
}
|
||||
|
||||
int
|
||||
buffer_get_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve,
|
||||
EC_POINT *point)
|
||||
{
|
||||
u_char *buf;
|
||||
u_int len;
|
||||
BN_CTX *bnctx;
|
||||
int ret = -1;
|
||||
|
||||
if ((buf = buffer_get_string_ret(buffer, &len)) == NULL) {
|
||||
error("%s: invalid point", __func__);
|
||||
return -1;
|
||||
}
|
||||
if ((bnctx = BN_CTX_new()) == NULL)
|
||||
fatal("%s: BN_CTX_new failed", __func__);
|
||||
if (len > BUFFER_MAX_ECPOINT_LEN) {
|
||||
error("%s: EC_POINT too long: %u > max %u", __func__,
|
||||
len, BUFFER_MAX_ECPOINT_LEN);
|
||||
goto out;
|
||||
}
|
||||
if (len == 0) {
|
||||
error("%s: EC_POINT buffer is empty", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (buf[0] != POINT_CONVERSION_UNCOMPRESSED) {
|
||||
error("%s: EC_POINT is in an incorrect form: "
|
||||
"0x%02x (want 0x%02x)", __func__, buf[0],
|
||||
POINT_CONVERSION_UNCOMPRESSED);
|
||||
goto out;
|
||||
}
|
||||
if (EC_POINT_oct2point(curve, point, buf, len, bnctx) != 1) {
|
||||
error("buffer_get_bignum2_ret: BN_bin2bn failed");
|
||||
goto out;
|
||||
}
|
||||
/* EC_POINT_oct2point verifies that the point is on the curve for us */
|
||||
ret = 0;
|
||||
out:
|
||||
BN_CTX_free(bnctx);
|
||||
bzero(buf, len);
|
||||
xfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_get_ecpoint(Buffer *buffer, const EC_GROUP *curve,
|
||||
EC_POINT *point)
|
||||
{
|
||||
if (buffer_get_ecpoint_ret(buffer, curve, point) == -1)
|
||||
fatal("%s: buffer error", __func__);
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_HAS_ECC */
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: buffer.h,v 1.19 2010/02/09 03:56:28 djm Exp $ */
|
||||
/* $OpenBSD: buffer.h,v 1.21 2010/08/31 11:54:45 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -68,6 +68,7 @@ void buffer_put_char(Buffer *, int);
|
||||
void *buffer_get_string(Buffer *, u_int *);
|
||||
void *buffer_get_string_ptr(Buffer *, u_int *);
|
||||
void buffer_put_string(Buffer *, const void *, u_int);
|
||||
char *buffer_get_cstring(Buffer *, u_int *);
|
||||
void buffer_put_cstring(Buffer *, const char *);
|
||||
|
||||
#define buffer_skip_string(b) \
|
||||
@ -81,7 +82,17 @@ int buffer_get_short_ret(u_short *, Buffer *);
|
||||
int buffer_get_int_ret(u_int *, Buffer *);
|
||||
int buffer_get_int64_ret(u_int64_t *, Buffer *);
|
||||
void *buffer_get_string_ret(Buffer *, u_int *);
|
||||
char *buffer_get_cstring_ret(Buffer *, u_int *);
|
||||
void *buffer_get_string_ptr_ret(Buffer *, u_int *);
|
||||
int buffer_get_char_ret(char *, Buffer *);
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
#include <openssl/ec.h>
|
||||
|
||||
int buffer_put_ecpoint_ret(Buffer *, const EC_GROUP *, const EC_POINT *);
|
||||
void buffer_put_ecpoint(Buffer *, const EC_GROUP *, const EC_POINT *);
|
||||
int buffer_get_ecpoint_ret(Buffer *, const EC_GROUP *, EC_POINT *);
|
||||
void buffer_get_ecpoint(Buffer *, const EC_GROUP *, EC_POINT *);
|
||||
#endif
|
||||
|
||||
#endif /* BUFFER_H */
|
||||
|
@ -199,7 +199,7 @@ ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
|
||||
memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
|
||||
port = a6->sin6_port;
|
||||
|
||||
memset(addr, 0, sizeof(*a4));
|
||||
bzero(a4, sizeof(*a4));
|
||||
|
||||
a4->sin_family = AF_INET;
|
||||
*len = sizeof(*a4);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: channels.c,v 1.309 2010/08/05 13:08:42 djm Exp $ */
|
||||
/* $OpenBSD: channels.c,v 1.310 2010/11/24 01:24:14 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -373,9 +373,6 @@ channel_close_fd(int *fdp)
|
||||
static void
|
||||
channel_close_fds(Channel *c)
|
||||
{
|
||||
debug3("channel %d: close_fds r %d w %d e %d",
|
||||
c->self, c->rfd, c->wfd, c->efd);
|
||||
|
||||
channel_close_fd(&c->sock);
|
||||
channel_close_fd(&c->rfd);
|
||||
channel_close_fd(&c->wfd);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cipher-3des1.c,v 1.6 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/* $OpenBSD: cipher-3des1.c,v 1.7 2010/10/01 23:05:32 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -103,7 +103,8 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
}
|
||||
|
||||
static int
|
||||
ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
|
||||
ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
|
||||
LIBCRYPTO_EVP_INL_TYPE len)
|
||||
{
|
||||
struct ssh1_3des_ctx *c;
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00907000L)
|
||||
|
||||
#include "acss.h"
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
#define data(ctx) ((EVP_ACSS_KEY *)(ctx)->cipher_data)
|
||||
|
||||
@ -43,7 +44,7 @@ acss_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
|
||||
static int
|
||||
acss_ciph(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
|
||||
unsigned int inl)
|
||||
LIBCRYPTO_EVP_INL_TYPE inl)
|
||||
{
|
||||
acss(&data(ctx)->ks,inl,in,out);
|
||||
return 1;
|
||||
|
@ -72,7 +72,7 @@ ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
|
||||
static int
|
||||
ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
|
||||
u_int len)
|
||||
LIBCRYPTO_EVP_INL_TYPE len)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
u_char buf[RIJNDAEL_BLOCKSIZE];
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cipher-bf1.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/* $OpenBSD: cipher-bf1.c,v 1.6 2010/10/01 23:05:32 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -76,10 +76,12 @@ static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
|
||||
static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *,
|
||||
const u_char *, LIBCRYPTO_EVP_INL_TYPE) = NULL;
|
||||
|
||||
static int
|
||||
bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
|
||||
bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in,
|
||||
LIBCRYPTO_EVP_INL_TYPE len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cipher-ctr.c,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/* $OpenBSD: cipher-ctr.c,v 1.11 2010/10/01 23:05:32 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
|
||||
*
|
||||
@ -34,7 +34,7 @@
|
||||
#endif
|
||||
|
||||
const EVP_CIPHER *evp_aes_128_ctr(void);
|
||||
void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
|
||||
void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t);
|
||||
|
||||
struct ssh_aes_ctr_ctx
|
||||
{
|
||||
@ -48,7 +48,7 @@ struct ssh_aes_ctr_ctx
|
||||
* (LSB at ctr[len-1], MSB at ctr[0])
|
||||
*/
|
||||
static void
|
||||
ssh_ctr_inc(u_char *ctr, u_int len)
|
||||
ssh_ctr_inc(u_char *ctr, size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -59,10 +59,10 @@ ssh_ctr_inc(u_char *ctr, u_int len)
|
||||
|
||||
static int
|
||||
ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
|
||||
u_int len)
|
||||
LIBCRYPTO_EVP_INL_TYPE len)
|
||||
{
|
||||
struct ssh_aes_ctr_ctx *c;
|
||||
u_int n = 0;
|
||||
size_t n = 0;
|
||||
u_char buf[AES_BLOCK_SIZE];
|
||||
|
||||
if (len == 0)
|
||||
@ -113,7 +113,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
}
|
||||
|
||||
void
|
||||
ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len)
|
||||
ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, size_t len)
|
||||
{
|
||||
struct ssh_aes_ctr_ctx *c;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: clientloop.c,v 1.222 2010/07/19 09:15:12 djm Exp $ */
|
||||
/* $OpenBSD: clientloop.c,v 1.231 2011/01/16 12:05:59 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -325,7 +325,7 @@ client_x11_get_proto(const char *display, const char *xauth_path,
|
||||
if (trusted == 0) {
|
||||
xauthdir = xmalloc(MAXPATHLEN);
|
||||
xauthfile = xmalloc(MAXPATHLEN);
|
||||
strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
|
||||
mktemp_proto(xauthdir, MAXPATHLEN);
|
||||
if (mkdtemp(xauthdir) != NULL) {
|
||||
do_unlink = 1;
|
||||
snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
|
||||
@ -544,7 +544,7 @@ static void
|
||||
server_alive_check(void)
|
||||
{
|
||||
if (packet_inc_alive_timeouts() > options.server_alive_count_max) {
|
||||
logit("Timeout, server not responding.");
|
||||
logit("Timeout, server %s not responding.", host);
|
||||
cleanup_exit(255);
|
||||
}
|
||||
packet_start(SSH2_MSG_GLOBAL_REQUEST);
|
||||
@ -1590,25 +1590,23 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
||||
}
|
||||
|
||||
/* Output any buffered data for stdout. */
|
||||
while (buffer_len(&stdout_buffer) > 0) {
|
||||
len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
|
||||
buffer_len(&stdout_buffer));
|
||||
if (len <= 0) {
|
||||
if (buffer_len(&stdout_buffer) > 0) {
|
||||
len = atomicio(vwrite, fileno(stdout),
|
||||
buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer));
|
||||
if (len < 0 || (u_int)len != buffer_len(&stdout_buffer))
|
||||
error("Write failed flushing stdout buffer.");
|
||||
break;
|
||||
}
|
||||
buffer_consume(&stdout_buffer, len);
|
||||
else
|
||||
buffer_consume(&stdout_buffer, len);
|
||||
}
|
||||
|
||||
/* Output any buffered data for stderr. */
|
||||
while (buffer_len(&stderr_buffer) > 0) {
|
||||
len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
|
||||
buffer_len(&stderr_buffer));
|
||||
if (len <= 0) {
|
||||
if (buffer_len(&stderr_buffer) > 0) {
|
||||
len = atomicio(vwrite, fileno(stderr),
|
||||
buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer));
|
||||
if (len < 0 || (u_int)len != buffer_len(&stderr_buffer))
|
||||
error("Write failed flushing stderr buffer.");
|
||||
break;
|
||||
}
|
||||
buffer_consume(&stderr_buffer, len);
|
||||
else
|
||||
buffer_consume(&stderr_buffer, len);
|
||||
}
|
||||
|
||||
/* Clear and free any buffers. */
|
||||
@ -1622,7 +1620,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
||||
packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
|
||||
packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
|
||||
verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds",
|
||||
obytes, ibytes, total_time);
|
||||
(unsigned long long)obytes, (unsigned long long)ibytes, total_time);
|
||||
if (total_time > 0)
|
||||
verbose("Bytes per second: sent %.1f, received %.1f",
|
||||
obytes / total_time, ibytes / total_time);
|
||||
@ -1933,7 +1931,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
|
||||
}
|
||||
packet_check_eom();
|
||||
}
|
||||
if (reply) {
|
||||
if (reply && c != NULL) {
|
||||
packet_start(success ?
|
||||
SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
|
||||
packet_put_int(c->remote_id);
|
||||
@ -1973,6 +1971,9 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
|
||||
if ((c = channel_lookup(id)) == NULL)
|
||||
fatal("client_session2_setup: channel %d: unknown channel", id);
|
||||
|
||||
packet_set_interactive(want_tty,
|
||||
options.ip_qos_interactive, options.ip_qos_bulk);
|
||||
|
||||
if (want_tty) {
|
||||
struct winsize ws;
|
||||
|
||||
@ -2129,5 +2130,6 @@ cleanup_exit(int i)
|
||||
leave_non_blocking();
|
||||
if (options.control_path != NULL && muxserver_sock != -1)
|
||||
unlink(options.control_path);
|
||||
ssh_kill_proxy_command();
|
||||
_exit(i);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: compress.c,v 1.25 2006/08/06 01:13:32 stevesk Exp $ */
|
||||
/* $OpenBSD: compress.c,v 1.26 2010/09/08 04:13:31 deraadt Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -17,12 +17,13 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "compress.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
z_stream incoming_stream;
|
||||
z_stream outgoing_stream;
|
||||
static int compress_init_send_called = 0;
|
||||
|
@ -1,6 +1,9 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address
|
||||
*/
|
||||
/* #undef AIX_GETNAMEINFO_HACK */
|
||||
@ -81,9 +84,6 @@
|
||||
/* Define if you want to specify the path to your lastlog file */
|
||||
/* #undef CONF_LASTLOG_FILE */
|
||||
|
||||
/* Define if you want to specify the path to your utmpx file */
|
||||
/* #undef CONF_UTMPX_FILE */
|
||||
|
||||
/* Define if you want to specify the path to your utmp file */
|
||||
/* #undef CONF_UTMP_FILE */
|
||||
|
||||
@ -129,6 +129,9 @@
|
||||
/* Builtin PRNG command timeout */
|
||||
#define ENTROPY_TIMEOUT_MSEC 200
|
||||
|
||||
/* File names may not contain backslash characters */
|
||||
/* #undef FILESYSTEM_NO_BACKSLASH */
|
||||
|
||||
/* fsid_t has member val */
|
||||
/* #undef FSID_HAS_VAL */
|
||||
|
||||
@ -147,6 +150,9 @@
|
||||
/* Define if your system glob() function has gl_matchc options in glob_t */
|
||||
#define GLOB_HAS_GL_MATCHC 1
|
||||
|
||||
/* Define if your system glob() function has gl_statv options in glob_t */
|
||||
/* #undef GLOB_HAS_GL_STATV */
|
||||
|
||||
/* Define this if you want GSSAPI support in the version 2 protocol */
|
||||
/* #undef GSSAPI */
|
||||
|
||||
@ -207,6 +213,9 @@
|
||||
/* Define to 1 if you have the `bindresvport_sa' function. */
|
||||
#define HAVE_BINDRESVPORT_SA 1
|
||||
|
||||
/* Define to 1 if you have the `BN_is_prime_ex' function. */
|
||||
#define HAVE_BN_IS_PRIME_EX 1
|
||||
|
||||
/* Define to 1 if you have the <bsm/audit.h> header file. */
|
||||
/* #undef HAVE_BSM_AUDIT_H */
|
||||
|
||||
@ -315,6 +324,9 @@
|
||||
/* Define to 1 if you have the `dirname' function. */
|
||||
#define HAVE_DIRNAME 1
|
||||
|
||||
/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */
|
||||
#define HAVE_DSA_GENERATE_PARAMETERS_EX 1
|
||||
|
||||
/* Define to 1 if you have the <endian.h> header file. */
|
||||
/* #undef HAVE_ENDIAN_H */
|
||||
|
||||
@ -537,9 +549,15 @@
|
||||
/* Define to 1 if the system has the type `in_port_t'. */
|
||||
#define HAVE_IN_PORT_T 1
|
||||
|
||||
/* Define if you have isblank(3C). */
|
||||
#define HAVE_ISBLANK 1
|
||||
|
||||
/* Define to 1 if you have the <lastlog.h> header file. */
|
||||
/* #undef HAVE_LASTLOG_H */
|
||||
|
||||
/* Define to 1 if you have the <libaudit.h> header file. */
|
||||
/* #undef HAVE_LIBAUDIT_H */
|
||||
|
||||
/* Define to 1 if you have the `bsm' library (-lbsm). */
|
||||
/* #undef HAVE_LIBBSM */
|
||||
|
||||
@ -742,6 +760,12 @@
|
||||
/* Define to 1 if you have the `rresvport_af' function. */
|
||||
#define HAVE_RRESVPORT_AF 1
|
||||
|
||||
/* Define to 1 if you have the `RSA_generate_key_ex' function. */
|
||||
#define HAVE_RSA_GENERATE_KEY_EX 1
|
||||
|
||||
/* Define to 1 if you have the `RSA_get_default_method' function. */
|
||||
#define HAVE_RSA_GET_DEFAULT_METHOD 1
|
||||
|
||||
/* define if you have sa_family_t data type */
|
||||
#define HAVE_SA_FAMILY_T 1
|
||||
|
||||
@ -928,13 +952,13 @@
|
||||
/* define if you have struct sockaddr_in6 data type */
|
||||
#define HAVE_STRUCT_SOCKADDR_IN6 1
|
||||
|
||||
/* Define to 1 if `sin6_scope_id' is member of `struct sockaddr_in6'. */
|
||||
/* Define to 1 if `sin6_scope_id' is a member of `struct sockaddr_in6'. */
|
||||
#define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||
|
||||
/* define if you have struct sockaddr_storage data type */
|
||||
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
|
||||
/* Define to 1 if `st_blksize' is member of `struct stat'. */
|
||||
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct timespec'. */
|
||||
@ -1048,6 +1072,9 @@
|
||||
/* Define if you have ut_time in utmpx.h */
|
||||
/* #undef HAVE_TIME_IN_UTMPX */
|
||||
|
||||
/* Define to 1 if you have the `timingsafe_bcmp' function. */
|
||||
/* #undef HAVE_TIMINGSAFE_BCMP */
|
||||
|
||||
/* Define to 1 if you have the <tmpdir.h> header file. */
|
||||
/* #undef HAVE_TMPDIR_H */
|
||||
|
||||
@ -1263,6 +1290,9 @@
|
||||
/* Define if EVP_DigestUpdate returns void */
|
||||
/* #undef OPENSSL_EVP_DIGESTUPDATE_VOID */
|
||||
|
||||
/* libcrypto includes complete ECC support */
|
||||
#define OPENSSL_HAS_ECC 1
|
||||
|
||||
/* libcrypto is missing AES 192 and 256 bit functions */
|
||||
/* #undef OPENSSL_LOBOTOMISED_AES */
|
||||
|
||||
@ -1281,6 +1311,9 @@
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "openssh"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "Portable"
|
||||
|
||||
@ -1394,6 +1427,9 @@
|
||||
/* Use libedit for sftp */
|
||||
#define USE_LIBEDIT 1
|
||||
|
||||
/* Use Linux audit module */
|
||||
/* #undef USE_LINUX_AUDIT */
|
||||
|
||||
/* Enable OpenSSL engine support */
|
||||
#define USE_OPENSSL_ENGINE 1
|
||||
|
||||
@ -1406,6 +1442,9 @@
|
||||
/* Define if you have Solaris process contracts */
|
||||
/* #undef USE_SOLARIS_PROCESS_CONTRACTS */
|
||||
|
||||
/* Define if you have Solaris projects */
|
||||
/* #undef USE_SOLARIS_PROJECTS */
|
||||
|
||||
/* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */
|
||||
/* #undef WITH_ABBREV_NO_TTY */
|
||||
|
||||
@ -1429,7 +1468,7 @@
|
||||
/* #undef WITH_SELINUX */
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
#elif ! defined __LITTLE_ENDIAN__
|
||||
|
@ -125,6 +125,9 @@
|
||||
/* Builtin PRNG command timeout */
|
||||
#undef ENTROPY_TIMEOUT_MSEC
|
||||
|
||||
/* File names may not contain backslash characters */
|
||||
#undef FILESYSTEM_NO_BACKSLASH
|
||||
|
||||
/* fsid_t has member val */
|
||||
#undef FSID_HAS_VAL
|
||||
|
||||
@ -143,6 +146,9 @@
|
||||
/* Define if your system glob() function has gl_matchc options in glob_t */
|
||||
#undef GLOB_HAS_GL_MATCHC
|
||||
|
||||
/* Define if your system glob() function has gl_statv options in glob_t */
|
||||
#undef GLOB_HAS_GL_STATV
|
||||
|
||||
/* Define this if you want GSSAPI support in the version 2 protocol */
|
||||
#undef GSSAPI
|
||||
|
||||
@ -203,6 +209,9 @@
|
||||
/* Define to 1 if you have the `bindresvport_sa' function. */
|
||||
#undef HAVE_BINDRESVPORT_SA
|
||||
|
||||
/* Define to 1 if you have the `BN_is_prime_ex' function. */
|
||||
#undef HAVE_BN_IS_PRIME_EX
|
||||
|
||||
/* Define to 1 if you have the <bsm/audit.h> header file. */
|
||||
#undef HAVE_BSM_AUDIT_H
|
||||
|
||||
@ -311,6 +320,9 @@
|
||||
/* Define to 1 if you have the `dirname' function. */
|
||||
#undef HAVE_DIRNAME
|
||||
|
||||
/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */
|
||||
#undef HAVE_DSA_GENERATE_PARAMETERS_EX
|
||||
|
||||
/* Define to 1 if you have the <endian.h> header file. */
|
||||
#undef HAVE_ENDIAN_H
|
||||
|
||||
@ -533,9 +545,15 @@
|
||||
/* Define to 1 if the system has the type `in_port_t'. */
|
||||
#undef HAVE_IN_PORT_T
|
||||
|
||||
/* Define if you have isblank(3C). */
|
||||
#undef HAVE_ISBLANK
|
||||
|
||||
/* Define to 1 if you have the <lastlog.h> header file. */
|
||||
#undef HAVE_LASTLOG_H
|
||||
|
||||
/* Define to 1 if you have the <libaudit.h> header file. */
|
||||
#undef HAVE_LIBAUDIT_H
|
||||
|
||||
/* Define to 1 if you have the `bsm' library (-lbsm). */
|
||||
#undef HAVE_LIBBSM
|
||||
|
||||
@ -738,6 +756,12 @@
|
||||
/* Define to 1 if you have the `rresvport_af' function. */
|
||||
#undef HAVE_RRESVPORT_AF
|
||||
|
||||
/* Define to 1 if you have the `RSA_generate_key_ex' function. */
|
||||
#undef HAVE_RSA_GENERATE_KEY_EX
|
||||
|
||||
/* Define to 1 if you have the `RSA_get_default_method' function. */
|
||||
#undef HAVE_RSA_GET_DEFAULT_METHOD
|
||||
|
||||
/* define if you have sa_family_t data type */
|
||||
#undef HAVE_SA_FAMILY_T
|
||||
|
||||
@ -1044,6 +1068,9 @@
|
||||
/* Define if you have ut_time in utmpx.h */
|
||||
#undef HAVE_TIME_IN_UTMPX
|
||||
|
||||
/* Define to 1 if you have the `timingsafe_bcmp' function. */
|
||||
#undef HAVE_TIMINGSAFE_BCMP
|
||||
|
||||
/* Define to 1 if you have the <tmpdir.h> header file. */
|
||||
#undef HAVE_TMPDIR_H
|
||||
|
||||
@ -1259,6 +1286,9 @@
|
||||
/* Define if EVP_DigestUpdate returns void */
|
||||
#undef OPENSSL_EVP_DIGESTUPDATE_VOID
|
||||
|
||||
/* libcrypto includes complete ECC support */
|
||||
#undef OPENSSL_HAS_ECC
|
||||
|
||||
/* libcrypto is missing AES 192 and 256 bit functions */
|
||||
#undef OPENSSL_LOBOTOMISED_AES
|
||||
|
||||
@ -1390,6 +1420,9 @@
|
||||
/* Use libedit for sftp */
|
||||
#undef USE_LIBEDIT
|
||||
|
||||
/* Use Linux audit module */
|
||||
#undef USE_LINUX_AUDIT
|
||||
|
||||
/* Enable OpenSSL engine support */
|
||||
#undef USE_OPENSSL_ENGINE
|
||||
|
||||
@ -1402,6 +1435,9 @@
|
||||
/* Define if you have Solaris process contracts */
|
||||
#undef USE_SOLARIS_PROCESS_CONTRACTS
|
||||
|
||||
/* Define if you have Solaris projects */
|
||||
#undef USE_SOLARIS_PROJECTS
|
||||
|
||||
/* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */
|
||||
#undef WITH_ABBREV_NO_TTY
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#ifndef _DEFINES_H
|
||||
#define _DEFINES_H
|
||||
|
||||
/* $Id: defines.h,v 1.160 2010/04/09 08:13:27 dtucker Exp $ */
|
||||
/* $Id: defines.h,v 1.164 2011/01/17 10:15:31 dtucker Exp $ */
|
||||
|
||||
|
||||
/* Constants */
|
||||
@ -42,6 +42,10 @@ enum
|
||||
# define SHUT_RDWR SHUT_RDWR
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definitions for IP type of service (ip_tos)
|
||||
*/
|
||||
#include <netinet/ip.h>
|
||||
#ifndef IPTOS_LOWDELAY
|
||||
# define IPTOS_LOWDELAY 0x10
|
||||
# define IPTOS_THROUGHPUT 0x08
|
||||
@ -50,6 +54,39 @@ enum
|
||||
# define IPTOS_MINCOST IPTOS_LOWCOST
|
||||
#endif /* IPTOS_LOWDELAY */
|
||||
|
||||
/*
|
||||
* Definitions for DiffServ Codepoints as per RFC2474
|
||||
*/
|
||||
#include <netinet/in_systm.h>
|
||||
#ifndef IPTOS_DSCP_AF11
|
||||
# define IPTOS_DSCP_AF11 0x28
|
||||
# define IPTOS_DSCP_AF12 0x30
|
||||
# define IPTOS_DSCP_AF13 0x38
|
||||
# define IPTOS_DSCP_AF21 0x48
|
||||
# define IPTOS_DSCP_AF22 0x50
|
||||
# define IPTOS_DSCP_AF23 0x58
|
||||
# define IPTOS_DSCP_AF31 0x68
|
||||
# define IPTOS_DSCP_AF32 0x70
|
||||
# define IPTOS_DSCP_AF33 0x78
|
||||
# define IPTOS_DSCP_AF41 0x88
|
||||
# define IPTOS_DSCP_AF42 0x90
|
||||
# define IPTOS_DSCP_AF43 0x98
|
||||
# define IPTOS_DSCP_EF 0xb8
|
||||
#endif /* IPTOS_DSCP_AF11 */
|
||||
#ifndef IPTOS_DSCP_CS0
|
||||
# define IPTOS_DSCP_CS0 0x00
|
||||
# define IPTOS_DSCP_CS1 0x20
|
||||
# define IPTOS_DSCP_CS2 0x40
|
||||
# define IPTOS_DSCP_CS3 0x60
|
||||
# define IPTOS_DSCP_CS4 0x80
|
||||
# define IPTOS_DSCP_CS5 0xa0
|
||||
# define IPTOS_DSCP_CS6 0xc0
|
||||
# define IPTOS_DSCP_CS7 0xe0
|
||||
#endif /* IPTOS_DSCP_CS0 */
|
||||
#ifndef IPTOS_DSCP_EF
|
||||
# define IPTOS_DSCP_EF 0xb8
|
||||
#endif /* IPTOS_DSCP_EF */
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# ifdef PATH_MAX
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
@ -256,6 +293,10 @@ typedef unsigned int size_t;
|
||||
# define SIZE_T_MAX UINT_MAX
|
||||
#endif /* HAVE_SIZE_T */
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX SIZE_T_MAX
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SSIZE_T
|
||||
typedef int ssize_t;
|
||||
# define HAVE_SSIZE_T
|
||||
@ -566,6 +607,11 @@ struct winsize {
|
||||
# define CUSTOM_SSH_AUDIT_EVENTS
|
||||
#endif
|
||||
|
||||
#ifdef USE_LINUX_AUDIT
|
||||
# define SSH_AUDIT_EVENTS
|
||||
# define CUSTOM_SSH_AUDIT_EVENTS
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE___func__) && defined(HAVE___FUNCTION__)
|
||||
# define __func__ __FUNCTION__
|
||||
#elif !defined(HAVE___func__)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: dns.c,v 1.26 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: dns.c,v 1.27 2010/08/31 11:54:45 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
|
||||
@ -86,6 +86,7 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
|
||||
case KEY_DSA:
|
||||
*algorithm = SSHFP_KEY_DSA;
|
||||
break;
|
||||
/* XXX KEY_ECDSA */
|
||||
default:
|
||||
*algorithm = SSHFP_KEY_RESERVED; /* 0 */
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ seed_rng(void)
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
close(devnull);
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
if (original_uid != original_euid &&
|
||||
( seteuid(getuid()) == -1 ||
|
||||
@ -157,7 +158,7 @@ init_rng(void)
|
||||
*/
|
||||
if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L)
|
||||
fatal("OpenSSL version mismatch. Built against %lx, you "
|
||||
"have %lx", OPENSSL_VERSION_NUMBER, SSLeay());
|
||||
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
|
||||
|
||||
#ifndef OPENSSL_PRNG_ONLY
|
||||
original_uid = getuid();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: hostfile.c,v 1.48 2010/03/04 10:36:03 djm Exp $ */
|
||||
/* $OpenBSD: hostfile.c,v 1.50 2010/12/04 13:31:37 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -56,6 +56,12 @@
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
|
||||
struct hostkeys {
|
||||
struct hostkey_entry *entries;
|
||||
u_int num_entries;
|
||||
};
|
||||
|
||||
static int
|
||||
extract_salt(const char *s, u_int l, char *salt, size_t salt_len)
|
||||
@ -164,26 +170,28 @@ hostfile_read_key(char **cpp, u_int *bitsp, Key *ret)
|
||||
|
||||
/* Return results. */
|
||||
*cpp = cp;
|
||||
*bitsp = key_size(ret);
|
||||
if (bitsp != NULL)
|
||||
*bitsp = key_size(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
hostfile_check_key(int bits, const Key *key, const char *host, const char *filename, int linenum)
|
||||
hostfile_check_key(int bits, const Key *key, const char *host,
|
||||
const char *filename, u_long linenum)
|
||||
{
|
||||
if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL)
|
||||
return 1;
|
||||
if (bits != BN_num_bits(key->rsa->n)) {
|
||||
logit("Warning: %s, line %d: keysize mismatch for host %s: "
|
||||
logit("Warning: %s, line %lu: keysize mismatch for host %s: "
|
||||
"actual %d vs. announced %d.",
|
||||
filename, linenum, host, BN_num_bits(key->rsa->n), bits);
|
||||
logit("Warning: replace %d with %d in %s, line %d.",
|
||||
logit("Warning: replace %d with %d in %s, line %lu.",
|
||||
bits, BN_num_bits(key->rsa->n), filename, linenum);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static enum { MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA }
|
||||
static HostkeyMarker
|
||||
check_markers(char **cpp)
|
||||
{
|
||||
char marker[32], *sp, *cp = *cpp;
|
||||
@ -218,49 +226,32 @@ check_markers(char **cpp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether the given host (which must be in all lowercase) is already
|
||||
* in the list of our known hosts. Returns HOST_OK if the host is known and
|
||||
* has the specified key, HOST_NEW if the host is not known, and HOST_CHANGED
|
||||
* if the host is known but used to have a different host key.
|
||||
*
|
||||
* If no 'key' has been specified and a key of type 'keytype' is known
|
||||
* for the specified host, then HOST_FOUND is returned.
|
||||
*/
|
||||
struct hostkeys *
|
||||
init_hostkeys(void)
|
||||
{
|
||||
struct hostkeys *ret = xcalloc(1, sizeof(*ret));
|
||||
|
||||
static HostStatus
|
||||
check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
const char *host, const Key *key, int keytype, Key *found,
|
||||
int want_revocation, int *numret)
|
||||
ret->entries = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path)
|
||||
{
|
||||
FILE *f;
|
||||
char line[8192];
|
||||
int want, have, linenum = 0, want_cert = key_is_cert(key);
|
||||
u_int kbits;
|
||||
u_long linenum = 0, num_loaded = 0;
|
||||
char *cp, *cp2, *hashed_host;
|
||||
HostStatus end_return;
|
||||
HostkeyMarker marker;
|
||||
Key *key;
|
||||
int kbits;
|
||||
|
||||
debug3("check_host_in_hostfile: host %s filename %s", host, filename);
|
||||
|
||||
if (want_revocation && (key == NULL || keytype != 0 || found != NULL))
|
||||
fatal("%s: invalid arguments", __func__);
|
||||
|
||||
/* Open the file containing the list of known hosts. */
|
||||
f = fopen(filename, "r");
|
||||
if (!f)
|
||||
return HOST_NEW;
|
||||
|
||||
/*
|
||||
* Return value when the loop terminates. This is set to
|
||||
* HOST_CHANGED if we have seen a different key for the host and have
|
||||
* not found the proper one.
|
||||
*/
|
||||
end_return = HOST_NEW;
|
||||
|
||||
/* Go through the file. */
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
if ((f = fopen(path, "r")) == NULL)
|
||||
return;
|
||||
debug3("%s: loading entries for host \"%.100s\" from file \"%s\"",
|
||||
__func__, host, path);
|
||||
while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) {
|
||||
cp = line;
|
||||
linenum++;
|
||||
|
||||
/* Skip any leading whitespace, comments and empty lines. */
|
||||
for (; *cp == ' ' || *cp == '\t'; cp++)
|
||||
@ -268,19 +259,11 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
if (!*cp || *cp == '#' || *cp == '\n')
|
||||
continue;
|
||||
|
||||
if (want_revocation)
|
||||
want = MRK_REVOKE;
|
||||
else if (want_cert)
|
||||
want = MRK_CA;
|
||||
else
|
||||
want = MRK_NONE;
|
||||
|
||||
if ((have = check_markers(&cp)) == MRK_ERROR) {
|
||||
verbose("%s: invalid marker at %s:%d",
|
||||
__func__, filename, linenum);
|
||||
continue;
|
||||
} else if (want != have)
|
||||
if ((marker = check_markers(&cp)) == MRK_ERROR) {
|
||||
verbose("%s: invalid marker at %s:%lu",
|
||||
__func__, path, linenum);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find the end of the host name portion. */
|
||||
for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++)
|
||||
@ -292,8 +275,8 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
continue;
|
||||
hashed_host = host_hash(host, cp, (u_int) (cp2 - cp));
|
||||
if (hashed_host == NULL) {
|
||||
debug("Invalid hashed host line %d of %s",
|
||||
linenum, filename);
|
||||
debug("Invalid hashed host line %lu of %s",
|
||||
linenum, path);
|
||||
continue;
|
||||
}
|
||||
if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0)
|
||||
@ -303,98 +286,167 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
/* Got a match. Skip host name. */
|
||||
cp = cp2;
|
||||
|
||||
if (want_revocation)
|
||||
found = key_new(KEY_UNSPEC);
|
||||
|
||||
/*
|
||||
* Extract the key from the line. This will skip any leading
|
||||
* whitespace. Ignore badly formatted lines.
|
||||
*/
|
||||
if (!hostfile_read_key(&cp, &kbits, found))
|
||||
continue;
|
||||
|
||||
if (numret != NULL)
|
||||
*numret = linenum;
|
||||
|
||||
if (key == NULL) {
|
||||
/* we found a key of the requested type */
|
||||
if (found->type == keytype) {
|
||||
fclose(f);
|
||||
return HOST_FOUND;
|
||||
key = key_new(KEY_UNSPEC);
|
||||
if (!hostfile_read_key(&cp, &kbits, key)) {
|
||||
key_free(key);
|
||||
key = key_new(KEY_RSA1);
|
||||
if (!hostfile_read_key(&cp, &kbits, key)) {
|
||||
key_free(key);
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hostfile_check_key(kbits, found, host, filename, linenum))
|
||||
if (!hostfile_check_key(kbits, key, host, path, linenum))
|
||||
continue;
|
||||
|
||||
if (want_revocation) {
|
||||
if (key_is_cert(key) &&
|
||||
key_equal_public(key->cert->signature_key, found)) {
|
||||
verbose("check_host_in_hostfile: revoked CA "
|
||||
"line %d", linenum);
|
||||
key_free(found);
|
||||
return HOST_REVOKED;
|
||||
}
|
||||
if (key_equal_public(key, found)) {
|
||||
verbose("check_host_in_hostfile: revoked key "
|
||||
"line %d", linenum);
|
||||
key_free(found);
|
||||
return HOST_REVOKED;
|
||||
}
|
||||
key_free(found);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if the current key is the same as the given key. */
|
||||
if (want_cert && key_equal(key->cert->signature_key, found)) {
|
||||
/* Found CA cert for key */
|
||||
debug3("check_host_in_hostfile: CA match line %d",
|
||||
linenum);
|
||||
fclose(f);
|
||||
return HOST_OK;
|
||||
} else if (!want_cert && key_equal(key, found)) {
|
||||
/* Found identical key */
|
||||
debug3("check_host_in_hostfile: match line %d", linenum);
|
||||
fclose(f);
|
||||
return HOST_OK;
|
||||
}
|
||||
/*
|
||||
* They do not match. We will continue to go through the
|
||||
* file; however, we note that we will not return that it is
|
||||
* new.
|
||||
*/
|
||||
end_return = HOST_CHANGED;
|
||||
debug3("%s: found %skey type %s in file %s:%lu", __func__,
|
||||
marker == MRK_NONE ? "" :
|
||||
(marker == MRK_CA ? "ca " : "revoked "),
|
||||
key_type(key), path, linenum);
|
||||
hostkeys->entries = xrealloc(hostkeys->entries,
|
||||
hostkeys->num_entries + 1, sizeof(*hostkeys->entries));
|
||||
hostkeys->entries[hostkeys->num_entries].host = xstrdup(host);
|
||||
hostkeys->entries[hostkeys->num_entries].file = xstrdup(path);
|
||||
hostkeys->entries[hostkeys->num_entries].line = linenum;
|
||||
hostkeys->entries[hostkeys->num_entries].key = key;
|
||||
hostkeys->entries[hostkeys->num_entries].marker = marker;
|
||||
hostkeys->num_entries++;
|
||||
num_loaded++;
|
||||
}
|
||||
/* Clear variables and close the file. */
|
||||
debug3("%s: loaded %lu keys", __func__, num_loaded);
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return either HOST_NEW or HOST_CHANGED, depending on whether we
|
||||
* saw a different key for the host.
|
||||
*/
|
||||
return end_return;
|
||||
void
|
||||
free_hostkeys(struct hostkeys *hostkeys)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < hostkeys->num_entries; i++) {
|
||||
xfree(hostkeys->entries[i].host);
|
||||
xfree(hostkeys->entries[i].file);
|
||||
key_free(hostkeys->entries[i].key);
|
||||
bzero(hostkeys->entries + i, sizeof(*hostkeys->entries));
|
||||
}
|
||||
if (hostkeys->entries != NULL)
|
||||
xfree(hostkeys->entries);
|
||||
hostkeys->entries = NULL;
|
||||
hostkeys->num_entries = 0;
|
||||
xfree(hostkeys);
|
||||
}
|
||||
|
||||
static int
|
||||
check_key_not_revoked(struct hostkeys *hostkeys, Key *k)
|
||||
{
|
||||
int is_cert = key_is_cert(k);
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < hostkeys->num_entries; i++) {
|
||||
if (hostkeys->entries[i].marker != MRK_REVOKE)
|
||||
continue;
|
||||
if (key_equal_public(k, hostkeys->entries[i].key))
|
||||
return -1;
|
||||
if (is_cert &&
|
||||
key_equal_public(k->cert->signature_key,
|
||||
hostkeys->entries[i].key))
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Match keys against a specified key, or look one up by key type.
|
||||
*
|
||||
* If looking for a keytype (key == NULL) and one is found then return
|
||||
* HOST_FOUND, otherwise HOST_NEW.
|
||||
*
|
||||
* If looking for a key (key != NULL):
|
||||
* 1. If the key is a cert and a matching CA is found, return HOST_OK
|
||||
* 2. If the key is not a cert and a matching key is found, return HOST_OK
|
||||
* 3. If no key matches but a key with a different type is found, then
|
||||
* return HOST_CHANGED
|
||||
* 4. If no matching keys are found, then return HOST_NEW.
|
||||
*
|
||||
* Finally, check any found key is not revoked.
|
||||
*/
|
||||
static HostStatus
|
||||
check_hostkeys_by_key_or_type(struct hostkeys *hostkeys,
|
||||
Key *k, int keytype, const struct hostkey_entry **found)
|
||||
{
|
||||
u_int i;
|
||||
HostStatus end_return = HOST_NEW;
|
||||
int want_cert = key_is_cert(k);
|
||||
HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE;
|
||||
int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2;
|
||||
|
||||
if (found != NULL)
|
||||
*found = NULL;
|
||||
|
||||
for (i = 0; i < hostkeys->num_entries; i++) {
|
||||
if (proto == 1 && hostkeys->entries[i].key->type != KEY_RSA1)
|
||||
continue;
|
||||
if (proto == 2 && hostkeys->entries[i].key->type == KEY_RSA1)
|
||||
continue;
|
||||
if (hostkeys->entries[i].marker != want_marker)
|
||||
continue;
|
||||
if (k == NULL) {
|
||||
if (hostkeys->entries[i].key->type != keytype)
|
||||
continue;
|
||||
end_return = HOST_FOUND;
|
||||
if (found != NULL)
|
||||
*found = hostkeys->entries + i;
|
||||
k = hostkeys->entries[i].key;
|
||||
break;
|
||||
}
|
||||
if (want_cert) {
|
||||
if (key_equal_public(k->cert->signature_key,
|
||||
hostkeys->entries[i].key)) {
|
||||
/* A matching CA exists */
|
||||
end_return = HOST_OK;
|
||||
if (found != NULL)
|
||||
*found = hostkeys->entries + i;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (key_equal(k, hostkeys->entries[i].key)) {
|
||||
end_return = HOST_OK;
|
||||
if (found != NULL)
|
||||
*found = hostkeys->entries + i;
|
||||
break;
|
||||
}
|
||||
/* A non-maching key exists */
|
||||
end_return = HOST_CHANGED;
|
||||
if (found != NULL)
|
||||
*found = hostkeys->entries + i;
|
||||
}
|
||||
}
|
||||
if (check_key_not_revoked(hostkeys, k) != 0) {
|
||||
end_return = HOST_REVOKED;
|
||||
if (found != NULL)
|
||||
*found = NULL;
|
||||
}
|
||||
return end_return;
|
||||
}
|
||||
|
||||
HostStatus
|
||||
check_host_in_hostfile(const char *filename, const char *host, const Key *key,
|
||||
Key *found, int *numret)
|
||||
check_key_in_hostkeys(struct hostkeys *hostkeys, Key *key,
|
||||
const struct hostkey_entry **found)
|
||||
{
|
||||
if (key == NULL)
|
||||
fatal("no key to look up");
|
||||
if (check_host_in_hostfile_by_key_or_type(filename, host,
|
||||
key, 0, NULL, 1, NULL) == HOST_REVOKED)
|
||||
return HOST_REVOKED;
|
||||
return check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
|
||||
found, 0, numret);
|
||||
return check_hostkeys_by_key_or_type(hostkeys, key, 0, found);
|
||||
}
|
||||
|
||||
int
|
||||
lookup_key_in_hostfile_by_type(const char *filename, const char *host,
|
||||
int keytype, Key *found, int *numret)
|
||||
lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype,
|
||||
const struct hostkey_entry **found)
|
||||
{
|
||||
return (check_host_in_hostfile_by_key_or_type(filename, host, NULL,
|
||||
keytype, found, 0, numret) == HOST_FOUND);
|
||||
return (check_hostkeys_by_key_or_type(hostkeys, NULL, keytype,
|
||||
found) == HOST_FOUND);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: hostfile.h,v 1.18 2010/03/04 10:36:03 djm Exp $ */
|
||||
/* $OpenBSD: hostfile.h,v 1.19 2010/11/29 23:45:51 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -18,12 +18,30 @@ typedef enum {
|
||||
HOST_OK, HOST_NEW, HOST_CHANGED, HOST_REVOKED, HOST_FOUND
|
||||
} HostStatus;
|
||||
|
||||
typedef enum {
|
||||
MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA
|
||||
} HostkeyMarker;
|
||||
|
||||
struct hostkey_entry {
|
||||
char *host;
|
||||
char *file;
|
||||
u_long line;
|
||||
Key *key;
|
||||
HostkeyMarker marker;
|
||||
};
|
||||
struct hostkeys;
|
||||
|
||||
struct hostkeys *init_hostkeys(void);
|
||||
void load_hostkeys(struct hostkeys *, const char *, const char *);
|
||||
void free_hostkeys(struct hostkeys *);
|
||||
|
||||
HostStatus check_key_in_hostkeys(struct hostkeys *, Key *,
|
||||
const struct hostkey_entry **);
|
||||
int lookup_key_in_hostkeys_by_type(struct hostkeys *, int,
|
||||
const struct hostkey_entry **);
|
||||
|
||||
int hostfile_read_key(char **, u_int *, Key *);
|
||||
HostStatus check_host_in_hostfile(const char *, const char *,
|
||||
const Key *, Key *, int *);
|
||||
int add_host_to_hostfile(const char *, const char *, const Key *, int);
|
||||
int lookup_key_in_hostfile_by_type(const char *, const char *,
|
||||
int, Key *, int *);
|
||||
int add_host_to_hostfile(const char *, const char *, const Key *, int);
|
||||
|
||||
#define HASH_MAGIC "|1|"
|
||||
#define HASH_DELIM '|'
|
||||
|
@ -30,7 +30,7 @@
|
||||
# include <bstring.h>
|
||||
#endif
|
||||
#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \
|
||||
defined(GLOB_HAS_GL_MATCHC) && \
|
||||
defined(GLOB_HAS_GL_MATCHC) && defined(GLOB_HAS_GL_STATV) && \
|
||||
defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0 && \
|
||||
!defined(BROKEN_GLOB)
|
||||
# include <glob.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: jpake.c,v 1.4 2010/07/13 23:13:16 djm Exp $ */
|
||||
/* $OpenBSD: jpake.c,v 1.6 2010/09/20 04:54:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
*
|
||||
@ -45,6 +45,7 @@
|
||||
#include "packet.h"
|
||||
#include "dispatch.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "jpake.h"
|
||||
#include "schnorr.h"
|
||||
@ -257,8 +258,12 @@ jpake_step2(struct modp_group *grp, BIGNUM *s,
|
||||
/* Validate peer's step 1 values */
|
||||
if (BN_cmp(theirpub1, BN_value_one()) <= 0)
|
||||
fatal("%s: theirpub1 <= 1", __func__);
|
||||
if (BN_cmp(theirpub1, grp->p) >= 0)
|
||||
fatal("%s: theirpub1 >= p", __func__);
|
||||
if (BN_cmp(theirpub2, BN_value_one()) <= 0)
|
||||
fatal("%s: theirpub2 <= 1", __func__);
|
||||
if (BN_cmp(theirpub2, grp->p) >= 0)
|
||||
fatal("%s: theirpub2 >= p", __func__);
|
||||
|
||||
if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub1,
|
||||
theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1)
|
||||
@ -363,6 +368,8 @@ jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
|
||||
/* Validate step 2 values */
|
||||
if (BN_cmp(step2_val, BN_value_one()) <= 0)
|
||||
fatal("%s: step2_val <= 1", __func__);
|
||||
if (BN_cmp(step2_val, grp->p) >= 0)
|
||||
fatal("%s: step2_val >= p", __func__);
|
||||
|
||||
/*
|
||||
* theirpriv2_s_proof is calculated with a different generator:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.c,v 1.82 2009/10/24 11:13:54 andreas Exp $ */
|
||||
/* $OpenBSD: kex.c,v 1.86 2010/09/22 05:01:29 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -62,6 +62,34 @@ extern const EVP_MD *evp_ssh_sha256(void);
|
||||
static void kex_kexinit_finish(Kex *);
|
||||
static void kex_choose_conf(Kex *);
|
||||
|
||||
/* Validate KEX method name list */
|
||||
int
|
||||
kex_names_valid(const char *names)
|
||||
{
|
||||
char *s, *cp, *p;
|
||||
|
||||
if (names == NULL || strcmp(names, "") == 0)
|
||||
return 0;
|
||||
s = cp = xstrdup(names);
|
||||
for ((p = strsep(&cp, ",")); p && *p != '\0';
|
||||
(p = strsep(&cp, ","))) {
|
||||
if (strcmp(p, KEX_DHGEX_SHA256) != 0 &&
|
||||
strcmp(p, KEX_DHGEX_SHA1) != 0 &&
|
||||
strcmp(p, KEX_DH14) != 0 &&
|
||||
strcmp(p, KEX_DH1) != 0 &&
|
||||
(strncmp(p, KEX_ECDH_SHA2_STEM,
|
||||
sizeof(KEX_ECDH_SHA2_STEM) - 1) != 0 ||
|
||||
kex_ecdh_name_to_nid(p) == -1)) {
|
||||
error("Unsupported KEX algorithm \"%.100s\"", p);
|
||||
xfree(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
debug3("kex names ok: [%s]", names);
|
||||
xfree(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* put algorithm proposal into buffer */
|
||||
static void
|
||||
kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
|
||||
@ -98,7 +126,7 @@ kex_buf2prop(Buffer *raw, int *first_kex_follows)
|
||||
buffer_get_char(&b);
|
||||
/* extract kex init proposal strings */
|
||||
for (i = 0; i < PROPOSAL_MAX; i++) {
|
||||
proposal[i] = buffer_get_string(&b,NULL);
|
||||
proposal[i] = buffer_get_cstring(&b,NULL);
|
||||
debug2("kex_parse_kexinit: %s", proposal[i]);
|
||||
}
|
||||
/* first kex follows / reserved */
|
||||
@ -325,6 +353,10 @@ choose_kex(Kex *k, char *client, char *server)
|
||||
} else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) {
|
||||
k->kex_type = KEX_DH_GEX_SHA256;
|
||||
k->evp_md = evp_ssh_sha256();
|
||||
} else if (strncmp(k->name, KEX_ECDH_SHA2_STEM,
|
||||
sizeof(KEX_ECDH_SHA2_STEM) - 1) == 0) {
|
||||
k->kex_type = KEX_ECDH_SHA2;
|
||||
k->evp_md = kex_ecdh_name_to_evpmd(k->name);
|
||||
#endif
|
||||
} else
|
||||
fatal("bad kex alg %s", k->name);
|
||||
@ -559,11 +591,11 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
|
||||
memset(&md, 0, sizeof(md));
|
||||
}
|
||||
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
|
||||
void
|
||||
dump_digest(char *msg, u_char *digest, int len)
|
||||
{
|
||||
u_int i;
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
for (i = 0; i < len; i++) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.h,v 1.49 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: kex.h,v 1.52 2010/09/22 05:01:29 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -29,6 +29,9 @@
|
||||
#include <signal.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
#include <openssl/ec.h>
|
||||
#endif
|
||||
|
||||
#define KEX_COOKIE_LEN 16
|
||||
|
||||
@ -37,6 +40,8 @@
|
||||
#define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1"
|
||||
#define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256"
|
||||
#define KEX_RESUME "resume@appgate.com"
|
||||
/* The following represents the family of ECDH methods */
|
||||
#define KEX_ECDH_SHA2_STEM "ecdh-sha2-"
|
||||
|
||||
#define COMP_NONE 0
|
||||
#define COMP_ZLIB 1
|
||||
@ -67,6 +72,7 @@ enum kex_exchange {
|
||||
KEX_DH_GRP14_SHA1,
|
||||
KEX_DH_GEX_SHA1,
|
||||
KEX_DH_GEX_SHA256,
|
||||
KEX_ECDH_SHA2,
|
||||
KEX_MAX
|
||||
};
|
||||
|
||||
@ -132,6 +138,8 @@ struct Kex {
|
||||
void (*kex[KEX_MAX])(Kex *);
|
||||
};
|
||||
|
||||
int kex_names_valid(const char *);
|
||||
|
||||
Kex *kex_setup(char *[PROPOSAL_MAX]);
|
||||
void kex_finish(Kex *);
|
||||
|
||||
@ -145,6 +153,8 @@ void kexdh_client(Kex *);
|
||||
void kexdh_server(Kex *);
|
||||
void kexgex_client(Kex *);
|
||||
void kexgex_server(Kex *);
|
||||
void kexecdh_client(Kex *);
|
||||
void kexecdh_server(Kex *);
|
||||
|
||||
void
|
||||
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
|
||||
@ -153,11 +163,22 @@ void
|
||||
kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *,
|
||||
int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *,
|
||||
BIGNUM *, BIGNUM *, u_char **, u_int *);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void
|
||||
kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int,
|
||||
char *, int, u_char *, int, const EC_POINT *, const EC_POINT *,
|
||||
const BIGNUM *, u_char **, u_int *);
|
||||
int kex_ecdh_name_to_nid(const char *);
|
||||
const EVP_MD *kex_ecdh_name_to_evpmd(const char *);
|
||||
#else
|
||||
# define kex_ecdh_name_to_nid(x) (-1)
|
||||
# define kex_ecdh_name_to_evpmd(x) (NULL)
|
||||
#endif
|
||||
|
||||
void
|
||||
derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
|
||||
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
|
||||
void dump_digest(char *, u_char *, int);
|
||||
#endif
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexdhc.c,v 1.11 2006/11/06 21:25:28 markus Exp $ */
|
||||
/* $OpenBSD: kexdhc.c,v 1.12 2010/11/10 01:33:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -27,6 +27,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexdhs.c,v 1.11 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: kexdhs.c,v 1.12 2010/11/10 01:33:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -31,6 +31,8 @@
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "key.h"
|
||||
|
117
crypto/openssh/kexecdh.c
Normal file
117
crypto/openssh/kexecdh.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* $OpenBSD: kexecdh.c,v 1.3 2010/09/22 05:01:29 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdh.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "ssh2.h"
|
||||
#include "key.h"
|
||||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "log.h"
|
||||
|
||||
int
|
||||
kex_ecdh_name_to_nid(const char *kexname)
|
||||
{
|
||||
if (strlen(kexname) < sizeof(KEX_ECDH_SHA2_STEM) - 1)
|
||||
fatal("%s: kexname too short \"%s\"", __func__, kexname);
|
||||
return key_curve_name_to_nid(kexname + sizeof(KEX_ECDH_SHA2_STEM) - 1);
|
||||
}
|
||||
|
||||
const EVP_MD *
|
||||
kex_ecdh_name_to_evpmd(const char *kexname)
|
||||
{
|
||||
int nid = kex_ecdh_name_to_nid(kexname);
|
||||
|
||||
if (nid == -1)
|
||||
fatal("%s: unsupported ECDH curve \"%s\"", __func__, kexname);
|
||||
return key_ec_nid_to_evpmd(nid);
|
||||
}
|
||||
|
||||
void
|
||||
kex_ecdh_hash(
|
||||
const EVP_MD *evp_md,
|
||||
const EC_GROUP *ec_group,
|
||||
char *client_version_string,
|
||||
char *server_version_string,
|
||||
char *ckexinit, int ckexinitlen,
|
||||
char *skexinit, int skexinitlen,
|
||||
u_char *serverhostkeyblob, int sbloblen,
|
||||
const EC_POINT *client_dh_pub,
|
||||
const EC_POINT *server_dh_pub,
|
||||
const BIGNUM *shared_secret,
|
||||
u_char **hash, u_int *hashlen)
|
||||
{
|
||||
Buffer b;
|
||||
EVP_MD_CTX md;
|
||||
static u_char digest[EVP_MAX_MD_SIZE];
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, client_version_string);
|
||||
buffer_put_cstring(&b, server_version_string);
|
||||
|
||||
/* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
|
||||
buffer_put_int(&b, ckexinitlen+1);
|
||||
buffer_put_char(&b, SSH2_MSG_KEXINIT);
|
||||
buffer_append(&b, ckexinit, ckexinitlen);
|
||||
buffer_put_int(&b, skexinitlen+1);
|
||||
buffer_put_char(&b, SSH2_MSG_KEXINIT);
|
||||
buffer_append(&b, skexinit, skexinitlen);
|
||||
|
||||
buffer_put_string(&b, serverhostkeyblob, sbloblen);
|
||||
buffer_put_ecpoint(&b, ec_group, client_dh_pub);
|
||||
buffer_put_ecpoint(&b, ec_group, server_dh_pub);
|
||||
buffer_put_bignum2(&b, shared_secret);
|
||||
|
||||
#ifdef DEBUG_KEX
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
|
||||
buffer_free(&b);
|
||||
|
||||
#ifdef DEBUG_KEX
|
||||
dump_digest("hash", digest, EVP_MD_size(evp_md));
|
||||
#endif
|
||||
*hash = digest;
|
||||
*hashlen = EVP_MD_size(evp_md);
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_HAS_ECC */
|
168
crypto/openssh/kexecdhc.c
Normal file
168
crypto/openssh/kexecdhc.c
Normal file
@ -0,0 +1,168 @@
|
||||
/* $OpenBSD: kexecdhc.c,v 1.2 2010/09/22 05:01:29 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "key.h"
|
||||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "log.h"
|
||||
#include "packet.h"
|
||||
#include "dh.h"
|
||||
#include "ssh2.h"
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
|
||||
#include <openssl/ecdh.h>
|
||||
|
||||
void
|
||||
kexecdh_client(Kex *kex)
|
||||
{
|
||||
EC_KEY *client_key;
|
||||
EC_POINT *server_public;
|
||||
const EC_GROUP *group;
|
||||
BIGNUM *shared_secret;
|
||||
Key *server_host_key;
|
||||
u_char *server_host_key_blob = NULL, *signature = NULL;
|
||||
u_char *kbuf, *hash;
|
||||
u_int klen, slen, sbloblen, hashlen;
|
||||
int curve_nid;
|
||||
|
||||
if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1)
|
||||
fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name);
|
||||
if ((client_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL)
|
||||
fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
|
||||
if (EC_KEY_generate_key(client_key) != 1)
|
||||
fatal("%s: EC_KEY_generate_key failed", __func__);
|
||||
group = EC_KEY_get0_group(client_key);
|
||||
|
||||
packet_start(SSH2_MSG_KEX_ECDH_INIT);
|
||||
packet_put_ecpoint(group, EC_KEY_get0_public_key(client_key));
|
||||
packet_send();
|
||||
debug("sending SSH2_MSG_KEX_ECDH_INIT");
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
fputs("client private key:\n", stderr);
|
||||
key_dump_ec_key(client_key);
|
||||
#endif
|
||||
|
||||
debug("expecting SSH2_MSG_KEX_ECDH_REPLY");
|
||||
packet_read_expect(SSH2_MSG_KEX_ECDH_REPLY);
|
||||
|
||||
/* hostkey */
|
||||
server_host_key_blob = packet_get_string(&sbloblen);
|
||||
server_host_key = key_from_blob(server_host_key_blob, sbloblen);
|
||||
if (server_host_key == NULL)
|
||||
fatal("cannot decode server_host_key_blob");
|
||||
if (server_host_key->type != kex->hostkey_type)
|
||||
fatal("type mismatch for decoded server_host_key_blob");
|
||||
if (kex->verify_host_key == NULL)
|
||||
fatal("cannot verify server_host_key");
|
||||
if (kex->verify_host_key(server_host_key) == -1)
|
||||
fatal("server_host_key verification failed");
|
||||
|
||||
/* Q_S, server public key */
|
||||
if ((server_public = EC_POINT_new(group)) == NULL)
|
||||
fatal("%s: EC_POINT_new failed", __func__);
|
||||
packet_get_ecpoint(group, server_public);
|
||||
|
||||
if (key_ec_validate_public(group, server_public) != 0)
|
||||
fatal("%s: invalid server public key", __func__);
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
fputs("server public key:\n", stderr);
|
||||
key_dump_ec_point(group, server_public);
|
||||
#endif
|
||||
|
||||
/* signed H */
|
||||
signature = packet_get_string(&slen);
|
||||
packet_check_eom();
|
||||
|
||||
klen = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
kbuf = xmalloc(klen);
|
||||
if (ECDH_compute_key(kbuf, klen, server_public,
|
||||
client_key, NULL) != (int)klen)
|
||||
fatal("%s: ECDH_compute_key failed", __func__);
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
dump_digest("shared secret", kbuf, klen);
|
||||
#endif
|
||||
if ((shared_secret = BN_new()) == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
if (BN_bin2bn(kbuf, klen, shared_secret) == NULL)
|
||||
fatal("%s: BN_bin2bn failed", __func__);
|
||||
memset(kbuf, 0, klen);
|
||||
xfree(kbuf);
|
||||
|
||||
/* calc and verify H */
|
||||
kex_ecdh_hash(
|
||||
kex->evp_md,
|
||||
group,
|
||||
kex->client_version_string,
|
||||
kex->server_version_string,
|
||||
buffer_ptr(&kex->my), buffer_len(&kex->my),
|
||||
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
|
||||
server_host_key_blob, sbloblen,
|
||||
EC_KEY_get0_public_key(client_key),
|
||||
server_public,
|
||||
shared_secret,
|
||||
&hash, &hashlen
|
||||
);
|
||||
xfree(server_host_key_blob);
|
||||
EC_POINT_clear_free(server_public);
|
||||
EC_KEY_free(client_key);
|
||||
|
||||
if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1)
|
||||
fatal("key_verify failed for server_host_key");
|
||||
key_free(server_host_key);
|
||||
xfree(signature);
|
||||
|
||||
/* save session id */
|
||||
if (kex->session_id == NULL) {
|
||||
kex->session_id_len = hashlen;
|
||||
kex->session_id = xmalloc(kex->session_id_len);
|
||||
memcpy(kex->session_id, hash, kex->session_id_len);
|
||||
}
|
||||
|
||||
kex_derive_keys(kex, hash, hashlen, shared_secret);
|
||||
BN_clear_free(shared_secret);
|
||||
kex_finish(kex);
|
||||
}
|
||||
#else /* OPENSSL_HAS_ECC */
|
||||
void
|
||||
kexecdh_client(Kex *kex)
|
||||
{
|
||||
fatal("ECC support is not enabled");
|
||||
}
|
||||
#endif /* OPENSSL_HAS_ECC */
|
173
crypto/openssh/kexecdhs.c
Normal file
173
crypto/openssh/kexecdhs.c
Normal file
@ -0,0 +1,173 @@
|
||||
/* $OpenBSD: kexecdhs.c,v 1.2 2010/09/22 05:01:29 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "key.h"
|
||||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "log.h"
|
||||
#include "packet.h"
|
||||
#include "dh.h"
|
||||
#include "ssh2.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
|
||||
#include <openssl/ecdh.h>
|
||||
|
||||
void
|
||||
kexecdh_server(Kex *kex)
|
||||
{
|
||||
EC_POINT *client_public;
|
||||
EC_KEY *server_key;
|
||||
const EC_GROUP *group;
|
||||
BIGNUM *shared_secret;
|
||||
Key *server_host_private, *server_host_public;
|
||||
u_char *server_host_key_blob = NULL, *signature = NULL;
|
||||
u_char *kbuf, *hash;
|
||||
u_int klen, slen, sbloblen, hashlen;
|
||||
int curve_nid;
|
||||
|
||||
if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1)
|
||||
fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name);
|
||||
if ((server_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL)
|
||||
fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
|
||||
if (EC_KEY_generate_key(server_key) != 1)
|
||||
fatal("%s: EC_KEY_generate_key failed", __func__);
|
||||
group = EC_KEY_get0_group(server_key);
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
fputs("server private key:\n", stderr);
|
||||
key_dump_ec_key(server_key);
|
||||
#endif
|
||||
|
||||
if (kex->load_host_public_key == NULL ||
|
||||
kex->load_host_private_key == NULL)
|
||||
fatal("Cannot load hostkey");
|
||||
server_host_public = kex->load_host_public_key(kex->hostkey_type);
|
||||
if (server_host_public == NULL)
|
||||
fatal("Unsupported hostkey type %d", kex->hostkey_type);
|
||||
server_host_private = kex->load_host_private_key(kex->hostkey_type);
|
||||
if (server_host_private == NULL)
|
||||
fatal("Missing private key for hostkey type %d",
|
||||
kex->hostkey_type);
|
||||
|
||||
debug("expecting SSH2_MSG_KEX_ECDH_INIT");
|
||||
packet_read_expect(SSH2_MSG_KEX_ECDH_INIT);
|
||||
if ((client_public = EC_POINT_new(group)) == NULL)
|
||||
fatal("%s: EC_POINT_new failed", __func__);
|
||||
packet_get_ecpoint(group, client_public);
|
||||
packet_check_eom();
|
||||
|
||||
if (key_ec_validate_public(group, client_public) != 0)
|
||||
fatal("%s: invalid client public key", __func__);
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
fputs("client public key:\n", stderr);
|
||||
key_dump_ec_point(group, client_public);
|
||||
#endif
|
||||
|
||||
/* Calculate shared_secret */
|
||||
klen = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
kbuf = xmalloc(klen);
|
||||
if (ECDH_compute_key(kbuf, klen, client_public,
|
||||
server_key, NULL) != (int)klen)
|
||||
fatal("%s: ECDH_compute_key failed", __func__);
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
dump_digest("shared secret", kbuf, klen);
|
||||
#endif
|
||||
if ((shared_secret = BN_new()) == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
if (BN_bin2bn(kbuf, klen, shared_secret) == NULL)
|
||||
fatal("%s: BN_bin2bn failed", __func__);
|
||||
memset(kbuf, 0, klen);
|
||||
xfree(kbuf);
|
||||
|
||||
/* calc H */
|
||||
key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
|
||||
kex_ecdh_hash(
|
||||
kex->evp_md,
|
||||
group,
|
||||
kex->client_version_string,
|
||||
kex->server_version_string,
|
||||
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
|
||||
buffer_ptr(&kex->my), buffer_len(&kex->my),
|
||||
server_host_key_blob, sbloblen,
|
||||
client_public,
|
||||
EC_KEY_get0_public_key(server_key),
|
||||
shared_secret,
|
||||
&hash, &hashlen
|
||||
);
|
||||
EC_POINT_clear_free(client_public);
|
||||
|
||||
/* save session id := H */
|
||||
if (kex->session_id == NULL) {
|
||||
kex->session_id_len = hashlen;
|
||||
kex->session_id = xmalloc(kex->session_id_len);
|
||||
memcpy(kex->session_id, hash, kex->session_id_len);
|
||||
}
|
||||
|
||||
/* sign H */
|
||||
if (PRIVSEP(key_sign(server_host_private, &signature, &slen,
|
||||
hash, hashlen)) < 0)
|
||||
fatal("kexdh_server: key_sign failed");
|
||||
|
||||
/* destroy_sensitive_data(); */
|
||||
|
||||
/* send server hostkey, ECDH pubkey 'Q_S' and signed H */
|
||||
packet_start(SSH2_MSG_KEX_ECDH_REPLY);
|
||||
packet_put_string(server_host_key_blob, sbloblen);
|
||||
packet_put_ecpoint(group, EC_KEY_get0_public_key(server_key));
|
||||
packet_put_string(signature, slen);
|
||||
packet_send();
|
||||
|
||||
xfree(signature);
|
||||
xfree(server_host_key_blob);
|
||||
/* have keys, free server key */
|
||||
EC_KEY_free(server_key);
|
||||
|
||||
kex_derive_keys(kex, hash, hashlen, shared_secret);
|
||||
BN_clear_free(shared_secret);
|
||||
kex_finish(kex);
|
||||
}
|
||||
#else /* OPENSSL_HAS_ECC */
|
||||
void
|
||||
kexecdh_server(Kex *kex)
|
||||
{
|
||||
fatal("ECC support is not enabled");
|
||||
}
|
||||
#endif /* OPENSSL_HAS_ECC */
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexgexc.c,v 1.11 2006/11/06 21:25:28 markus Exp $ */
|
||||
/* $OpenBSD: kexgexc.c,v 1.12 2010/11/10 01:33:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
@ -28,6 +28,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexgexs.c,v 1.13 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: kexgexs.c,v 1.14 2010/11/10 01:33:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
@ -33,6 +33,8 @@
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "key.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: key.h,v 1.30 2010/04/16 01:47:26 djm Exp $ */
|
||||
/* $OpenBSD: key.h,v 1.33 2010/10/28 11:22:09 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -29,14 +29,19 @@
|
||||
#include "buffer.h"
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
#include <openssl/ec.h>
|
||||
#endif
|
||||
|
||||
typedef struct Key Key;
|
||||
enum types {
|
||||
KEY_RSA1,
|
||||
KEY_RSA,
|
||||
KEY_DSA,
|
||||
KEY_ECDSA,
|
||||
KEY_RSA_CERT,
|
||||
KEY_DSA_CERT,
|
||||
KEY_ECDSA_CERT,
|
||||
KEY_RSA_CERT_V00,
|
||||
KEY_DSA_CERT_V00,
|
||||
KEY_UNSPEC
|
||||
@ -73,6 +78,12 @@ struct Key {
|
||||
int flags;
|
||||
RSA *rsa;
|
||||
DSA *dsa;
|
||||
int ecdsa_nid; /* NID of curve */
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
EC_KEY *ecdsa;
|
||||
#else
|
||||
void *ecdsa;
|
||||
#endif
|
||||
struct KeyCert *cert;
|
||||
};
|
||||
|
||||
@ -104,9 +115,22 @@ int key_cert_check_authority(const Key *, int, int, const char *,
|
||||
const char **);
|
||||
int key_cert_is_legacy(Key *);
|
||||
|
||||
int key_ecdsa_nid_from_name(const char *);
|
||||
int key_curve_name_to_nid(const char *);
|
||||
const char * key_curve_nid_to_name(int);
|
||||
u_int key_curve_nid_to_bits(int);
|
||||
int key_ecdsa_bits_to_nid(int);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
int key_ecdsa_key_to_nid(EC_KEY *);
|
||||
const EVP_MD * key_ec_nid_to_evpmd(int nid);
|
||||
int key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
|
||||
int key_ec_validate_private(const EC_KEY *);
|
||||
#endif
|
||||
|
||||
Key *key_from_blob(const u_char *, u_int);
|
||||
int key_to_blob(const Key *, u_char **, u_int *);
|
||||
const char *key_ssh_name(const Key *);
|
||||
const char *key_ssh_name_plain(const Key *);
|
||||
int key_names_valid2(const char *);
|
||||
|
||||
int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
|
||||
@ -114,7 +138,14 @@ int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
int ssh_dss_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
|
||||
int ssh_dss_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
int ssh_ecdsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
|
||||
int ssh_ecdsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
int ssh_rsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
|
||||
int ssh_rsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
#if defined(OPENSSL_HAS_ECC) && (defined(DEBUG_KEXECDH) || defined(DEBUG_PK))
|
||||
void key_dump_ec_point(const EC_GROUP *, const EC_POINT *);
|
||||
void key_dump_ec_key(const EC_KEY *);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -274,7 +274,7 @@ login_logout(struct logininfo *li)
|
||||
* try to retrieve lastlog information from wtmp/wtmpx.
|
||||
*/
|
||||
unsigned int
|
||||
login_get_lastlog_time(const int uid)
|
||||
login_get_lastlog_time(const uid_t uid)
|
||||
{
|
||||
struct logininfo li;
|
||||
|
||||
@ -298,7 +298,7 @@ login_get_lastlog_time(const int uid)
|
||||
* 0 on failure (will use OpenSSH's logging facilities for diagnostics)
|
||||
*/
|
||||
struct logininfo *
|
||||
login_get_lastlog(struct logininfo *li, const int uid)
|
||||
login_get_lastlog(struct logininfo *li, const uid_t uid)
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
@ -312,7 +312,8 @@ login_get_lastlog(struct logininfo *li, const int uid)
|
||||
*/
|
||||
pw = getpwuid(uid);
|
||||
if (pw == NULL)
|
||||
fatal("%s: Cannot find account for uid %i", __func__, uid);
|
||||
fatal("%s: Cannot find account for uid %ld", __func__,
|
||||
(long)uid);
|
||||
|
||||
/* No MIN_SIZEOF here - we absolutely *must not* truncate the
|
||||
* username (XXX - so check for trunc!) */
|
||||
@ -336,7 +337,7 @@ login_get_lastlog(struct logininfo *li, const int uid)
|
||||
* allocation fails, the program halts.
|
||||
*/
|
||||
struct
|
||||
logininfo *login_alloc_entry(int pid, const char *username,
|
||||
logininfo *login_alloc_entry(pid_t pid, const char *username,
|
||||
const char *hostname, const char *line)
|
||||
{
|
||||
struct logininfo *newli;
|
||||
@ -364,7 +365,7 @@ login_free_entry(struct logininfo *li)
|
||||
* Returns: 1
|
||||
*/
|
||||
int
|
||||
login_init_entry(struct logininfo *li, int pid, const char *username,
|
||||
login_init_entry(struct logininfo *li, pid_t pid, const char *username,
|
||||
const char *hostname, const char *line)
|
||||
{
|
||||
struct passwd *pw;
|
||||
@ -469,9 +470,9 @@ login_write(struct logininfo *li)
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
if (li->type == LTYPE_LOGIN)
|
||||
audit_session_open(li->line);
|
||||
audit_session_open(li);
|
||||
else if (li->type == LTYPE_LOGOUT)
|
||||
audit_session_close(li->line);
|
||||
audit_session_close(li);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
@ -877,11 +878,13 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut)
|
||||
pos = (off_t)tty * sizeof(struct utmp);
|
||||
if ((ret = lseek(fd, pos, SEEK_SET)) == -1) {
|
||||
logit("%s: lseek: %s", __func__, strerror(errno));
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
if (ret != pos) {
|
||||
logit("%s: Couldn't seek to tty %d slot in %s",
|
||||
__func__, tty, UTMP_FILE);
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
@ -897,16 +900,20 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut)
|
||||
|
||||
if ((ret = lseek(fd, pos, SEEK_SET)) == -1) {
|
||||
logit("%s: lseek: %s", __func__, strerror(errno));
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
if (ret != pos) {
|
||||
logit("%s: Couldn't seek to tty %d slot in %s",
|
||||
__func__, tty, UTMP_FILE);
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) {
|
||||
logit("%s: error writing %s: %s", __func__,
|
||||
UTMP_FILE, strerror(errno));
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
@ -1210,7 +1217,7 @@ wtmp_get_entry(struct logininfo *li)
|
||||
close (fd);
|
||||
return (0);
|
||||
}
|
||||
if ( wtmp_islogin(li, &ut) ) {
|
||||
if (wtmp_islogin(li, &ut) ) {
|
||||
found = 1;
|
||||
/*
|
||||
* We've already checked for a time in struct
|
||||
@ -1501,11 +1508,12 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode)
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
/* find this uid's offset in the lastlog file */
|
||||
offset = (off_t) ((long)li->uid * sizeof(struct lastlog));
|
||||
offset = (off_t) ((u_long)li->uid * sizeof(struct lastlog));
|
||||
|
||||
if (lseek(*fd, offset, SEEK_SET) != offset) {
|
||||
logit("%s: %s->lseek(): %s", __func__,
|
||||
lastlog_file, strerror(errno));
|
||||
close(*fd);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -1677,7 +1685,7 @@ record_failed_login(const char *username, const char *hostname,
|
||||
strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
if((fst.st_mode & (S_IRWXG | S_IRWXO)) || (fst.st_uid != 0)){
|
||||
if((fst.st_mode & (S_IXGRP | S_IRWXO)) || (fst.st_uid != 0)){
|
||||
logit("Excess permission or bad ownership on file %s",
|
||||
_PATH_BTMP);
|
||||
goto out;
|
||||
|
@ -63,8 +63,8 @@ struct logininfo {
|
||||
char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */
|
||||
int progname_null;
|
||||
short int type; /* type of login (LTYPE_*) */
|
||||
int pid; /* PID of login process */
|
||||
int uid; /* UID of this user */
|
||||
pid_t pid; /* PID of login process */
|
||||
uid_t uid; /* UID of this user */
|
||||
char line[LINFO_LINESIZE]; /* tty/pty name */
|
||||
char username[LINFO_NAMESIZE]; /* login username */
|
||||
char hostname[LINFO_HOSTSIZE]; /* remote hostname */
|
||||
@ -86,12 +86,12 @@ struct logininfo {
|
||||
/** 'public' functions */
|
||||
|
||||
/* construct a new login entry */
|
||||
struct logininfo *login_alloc_entry(int pid, const char *username,
|
||||
struct logininfo *login_alloc_entry(pid_t pid, const char *username,
|
||||
const char *hostname, const char *line);
|
||||
/* free a structure */
|
||||
void login_free_entry(struct logininfo *li);
|
||||
/* fill out a pre-allocated structure with useful information */
|
||||
int login_init_entry(struct logininfo *li, int pid, const char *username,
|
||||
int login_init_entry(struct logininfo *li, pid_t pid, const char *username,
|
||||
const char *hostname, const char *line);
|
||||
/* place the current time in a logininfo struct */
|
||||
void login_set_current_time(struct logininfo *li);
|
||||
@ -117,9 +117,9 @@ void login_set_addr(struct logininfo *li, const struct sockaddr *sa,
|
||||
* lastlog retrieval functions
|
||||
*/
|
||||
/* lastlog *entry* functions fill out a logininfo */
|
||||
struct logininfo *login_get_lastlog(struct logininfo *li, const int uid);
|
||||
struct logininfo *login_get_lastlog(struct logininfo *li, const uid_t uid);
|
||||
/* lastlog *time* functions return time_t equivalent (uint) */
|
||||
unsigned int login_get_lastlog_time(const int uid);
|
||||
unsigned int login_get_lastlog_time(const uid_t uid);
|
||||
|
||||
/* produce various forms of the line filename */
|
||||
char *line_fullname(char *dst, const char *src, u_int dstsize);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: misc.c,v 1.80 2010/07/21 02:10:58 djm Exp $ */
|
||||
/* $OpenBSD: misc.c,v 1.84 2010/11/21 01:01:13 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
|
||||
@ -35,9 +35,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include <errno.h>
|
||||
@ -850,16 +853,138 @@ ms_to_timeval(struct timeval *tv, int ms)
|
||||
tv->tv_usec = (ms % 1000) * 1000;
|
||||
}
|
||||
|
||||
int
|
||||
timingsafe_bcmp(const void *b1, const void *b2, size_t n)
|
||||
void
|
||||
bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
|
||||
{
|
||||
const unsigned char *p1 = b1, *p2 = b2;
|
||||
int ret = 0;
|
||||
bw->buflen = buflen;
|
||||
bw->rate = kbps;
|
||||
bw->thresh = bw->rate;
|
||||
bw->lamt = 0;
|
||||
timerclear(&bw->bwstart);
|
||||
timerclear(&bw->bwend);
|
||||
}
|
||||
|
||||
for (; n > 0; n--)
|
||||
ret |= *p1++ ^ *p2++;
|
||||
return (ret != 0);
|
||||
/* Callback from read/write loop to insert bandwidth-limiting delays */
|
||||
void
|
||||
bandwidth_limit(struct bwlimit *bw, size_t read_len)
|
||||
{
|
||||
u_int64_t waitlen;
|
||||
struct timespec ts, rm;
|
||||
|
||||
if (!timerisset(&bw->bwstart)) {
|
||||
gettimeofday(&bw->bwstart, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
bw->lamt += read_len;
|
||||
if (bw->lamt < bw->thresh)
|
||||
return;
|
||||
|
||||
gettimeofday(&bw->bwend, NULL);
|
||||
timersub(&bw->bwend, &bw->bwstart, &bw->bwend);
|
||||
if (!timerisset(&bw->bwend))
|
||||
return;
|
||||
|
||||
bw->lamt *= 8;
|
||||
waitlen = (double)1000000L * bw->lamt / bw->rate;
|
||||
|
||||
bw->bwstart.tv_sec = waitlen / 1000000L;
|
||||
bw->bwstart.tv_usec = waitlen % 1000000L;
|
||||
|
||||
if (timercmp(&bw->bwstart, &bw->bwend, >)) {
|
||||
timersub(&bw->bwstart, &bw->bwend, &bw->bwend);
|
||||
|
||||
/* Adjust the wait time */
|
||||
if (bw->bwend.tv_sec) {
|
||||
bw->thresh /= 2;
|
||||
if (bw->thresh < bw->buflen / 4)
|
||||
bw->thresh = bw->buflen / 4;
|
||||
} else if (bw->bwend.tv_usec < 10000) {
|
||||
bw->thresh *= 2;
|
||||
if (bw->thresh > bw->buflen * 8)
|
||||
bw->thresh = bw->buflen * 8;
|
||||
}
|
||||
|
||||
TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts);
|
||||
while (nanosleep(&ts, &rm) == -1) {
|
||||
if (errno != EINTR)
|
||||
break;
|
||||
ts = rm;
|
||||
}
|
||||
}
|
||||
|
||||
bw->lamt = 0;
|
||||
gettimeofday(&bw->bwstart, NULL);
|
||||
}
|
||||
|
||||
/* Make a template filename for mk[sd]temp() */
|
||||
void
|
||||
mktemp_proto(char *s, size_t len)
|
||||
{
|
||||
const char *tmpdir;
|
||||
int r;
|
||||
|
||||
if ((tmpdir = getenv("TMPDIR")) != NULL) {
|
||||
r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir);
|
||||
if (r > 0 && (size_t)r < len)
|
||||
return;
|
||||
}
|
||||
r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX");
|
||||
if (r < 0 || (size_t)r >= len)
|
||||
fatal("%s: template string too short", __func__);
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
int value;
|
||||
} ipqos[] = {
|
||||
{ "af11", IPTOS_DSCP_AF11 },
|
||||
{ "af12", IPTOS_DSCP_AF12 },
|
||||
{ "af13", IPTOS_DSCP_AF13 },
|
||||
{ "af14", IPTOS_DSCP_AF21 },
|
||||
{ "af22", IPTOS_DSCP_AF22 },
|
||||
{ "af23", IPTOS_DSCP_AF23 },
|
||||
{ "af31", IPTOS_DSCP_AF31 },
|
||||
{ "af32", IPTOS_DSCP_AF32 },
|
||||
{ "af33", IPTOS_DSCP_AF33 },
|
||||
{ "af41", IPTOS_DSCP_AF41 },
|
||||
{ "af42", IPTOS_DSCP_AF42 },
|
||||
{ "af43", IPTOS_DSCP_AF43 },
|
||||
{ "cs0", IPTOS_DSCP_CS0 },
|
||||
{ "cs1", IPTOS_DSCP_CS1 },
|
||||
{ "cs2", IPTOS_DSCP_CS2 },
|
||||
{ "cs3", IPTOS_DSCP_CS3 },
|
||||
{ "cs4", IPTOS_DSCP_CS4 },
|
||||
{ "cs5", IPTOS_DSCP_CS5 },
|
||||
{ "cs6", IPTOS_DSCP_CS6 },
|
||||
{ "cs7", IPTOS_DSCP_CS7 },
|
||||
{ "ef", IPTOS_DSCP_EF },
|
||||
{ "lowdelay", IPTOS_LOWDELAY },
|
||||
{ "throughput", IPTOS_THROUGHPUT },
|
||||
{ "reliability", IPTOS_RELIABILITY },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
|
||||
int
|
||||
parse_ipqos(const char *cp)
|
||||
{
|
||||
u_int i;
|
||||
char *ep;
|
||||
long val;
|
||||
|
||||
if (cp == NULL)
|
||||
return -1;
|
||||
for (i = 0; ipqos[i].name != NULL; i++) {
|
||||
if (strcasecmp(cp, ipqos[i].name) == 0)
|
||||
return ipqos[i].value;
|
||||
}
|
||||
/* Try parsing as an integer */
|
||||
val = strtol(cp, &ep, 0);
|
||||
if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255)
|
||||
return -1;
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
sock_set_v6only(int s)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: misc.h,v 1.43 2010/07/13 23:13:16 djm Exp $ */
|
||||
/* $OpenBSD: misc.h,v 1.47 2010/11/21 01:01:13 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -36,7 +36,6 @@ void sanitise_stdfd(void);
|
||||
void ms_subtract_diff(struct timeval *, int *);
|
||||
void ms_to_timeval(struct timeval *, int);
|
||||
void sock_set_v6only(int);
|
||||
int timingsafe_bcmp(const void *, const void *, size_t);
|
||||
|
||||
struct passwd *pwcopy(struct passwd *);
|
||||
const char *ssh_gai_strerror(int);
|
||||
@ -80,6 +79,17 @@ void put_u32(void *, u_int32_t)
|
||||
void put_u16(void *, u_int16_t)
|
||||
__attribute__((__bounded__( __minbytes__, 1, 2)));
|
||||
|
||||
struct bwlimit {
|
||||
size_t buflen;
|
||||
u_int64_t rate, thresh, lamt;
|
||||
struct timeval bwstart, bwend;
|
||||
};
|
||||
|
||||
void bandwidth_limit_init(struct bwlimit *, u_int64_t, size_t);
|
||||
void bandwidth_limit(struct bwlimit *, size_t);
|
||||
|
||||
int parse_ipqos(const char *);
|
||||
void mktemp_proto(char *, size_t);
|
||||
|
||||
/* readpass.c */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: moduli.c,v 1.21 2008/06/26 09:19:40 djm Exp $ */
|
||||
/* $OpenBSD: moduli.c,v 1.22 2010/11/10 01:33:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright 1994 Phil Karn <karn@qualcomm.com>
|
||||
* Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
|
||||
@ -54,6 +54,8 @@
|
||||
#include "dh.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
/*
|
||||
* File output defines
|
||||
*/
|
||||
@ -600,7 +602,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
|
||||
* that p is also prime. A single pass will weed out the
|
||||
* vast majority of composite q's.
|
||||
*/
|
||||
if (BN_is_prime(q, 1, NULL, ctx, NULL) <= 0) {
|
||||
if (BN_is_prime_ex(q, 1, ctx, NULL) <= 0) {
|
||||
debug("%10u: q failed first possible prime test",
|
||||
count_in);
|
||||
continue;
|
||||
@ -613,14 +615,14 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
|
||||
* will show up on the first Rabin-Miller iteration so it
|
||||
* doesn't hurt to specify a high iteration count.
|
||||
*/
|
||||
if (!BN_is_prime(p, trials, NULL, ctx, NULL)) {
|
||||
if (!BN_is_prime_ex(p, trials, ctx, NULL)) {
|
||||
debug("%10u: p is not prime", count_in);
|
||||
continue;
|
||||
}
|
||||
debug("%10u: p is almost certainly prime", count_in);
|
||||
|
||||
/* recheck q more rigorously */
|
||||
if (!BN_is_prime(q, trials - 1, NULL, ctx, NULL)) {
|
||||
if (!BN_is_prime_ex(q, trials - 1, ctx, NULL)) {
|
||||
debug("%10u: q is not prime", count_in);
|
||||
continue;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor.c,v 1.108 2010/07/13 23:13:16 djm Exp $ */
|
||||
/* $OpenBSD: monitor.c,v 1.110 2010/09/09 10:45:45 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
@ -590,10 +590,10 @@ mm_answer_sign(int sock, Buffer *m)
|
||||
p = buffer_get_string(m, &datlen);
|
||||
|
||||
/*
|
||||
* Supported KEX types will only return SHA1 (20 byte) or
|
||||
* SHA256 (32 byte) hashes
|
||||
* Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes),
|
||||
* SHA384 (48 bytes) and SHA512 (64 bytes).
|
||||
*/
|
||||
if (datlen != 20 && datlen != 32)
|
||||
if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64)
|
||||
fatal("%s: data length incorrect: %u", __func__, datlen);
|
||||
|
||||
/* save session id, it will be passed on the first call */
|
||||
@ -1691,6 +1691,7 @@ mm_get_kex(Buffer *m)
|
||||
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
|
||||
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
|
||||
kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
|
||||
kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
|
||||
kex->server = 1;
|
||||
kex->hostkey_type = buffer_get_int(m);
|
||||
kex->kex_type = buffer_get_int(m);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.69 2010/03/07 11:57:13 dtucker Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.70 2010/08/31 11:54:45 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
@ -73,6 +73,7 @@
|
||||
#include "misc.h"
|
||||
#include "schnorr.h"
|
||||
#include "jpake.h"
|
||||
#include "uuencode.h"
|
||||
|
||||
#include "channels.h"
|
||||
#include "session.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mux.c,v 1.21 2010/06/25 23:15:36 djm Exp $ */
|
||||
/* $OpenBSD: mux.c,v 1.24 2011/01/13 21:54:53 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
@ -879,7 +879,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
|
||||
if (options.control_master == SSHCTL_MASTER_ASK ||
|
||||
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
|
||||
if (!ask_permission("Allow forward to to %s:%u? ",
|
||||
if (!ask_permission("Allow forward to %s:%u? ",
|
||||
chost, cport)) {
|
||||
debug2("%s: stdio fwd refused by user", __func__);
|
||||
/* prepare reply */
|
||||
@ -1026,6 +1026,9 @@ muxserver_listen(void)
|
||||
struct sockaddr_un addr;
|
||||
socklen_t sun_len;
|
||||
mode_t old_umask;
|
||||
char *orig_control_path = options.control_path;
|
||||
char rbuf[16+1];
|
||||
u_int i, r;
|
||||
|
||||
if (options.control_path == NULL ||
|
||||
options.control_master == SSHCTL_MASTER_NO)
|
||||
@ -1033,6 +1036,23 @@ muxserver_listen(void)
|
||||
|
||||
debug("setting up multiplex master socket");
|
||||
|
||||
/*
|
||||
* Use a temporary path before listen so we can pseudo-atomically
|
||||
* establish the listening socket in its final location to avoid
|
||||
* other processes racing in between bind() and listen() and hitting
|
||||
* an unready socket.
|
||||
*/
|
||||
for (i = 0; i < sizeof(rbuf) - 1; i++) {
|
||||
r = arc4random_uniform(26+26+10);
|
||||
rbuf[i] = (r < 26) ? 'a' + r :
|
||||
(r < 26*2) ? 'A' + r - 26 :
|
||||
'0' + r - 26 - 26;
|
||||
}
|
||||
rbuf[sizeof(rbuf) - 1] = '\0';
|
||||
options.control_path = NULL;
|
||||
xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf);
|
||||
debug3("%s: temporary control path %s", __func__, options.control_path);
|
||||
|
||||
memset(&addr, '\0', sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
sun_len = offsetof(struct sockaddr_un, sun_path) +
|
||||
@ -1051,6 +1071,7 @@ muxserver_listen(void)
|
||||
if (errno == EINVAL || errno == EADDRINUSE) {
|
||||
error("ControlSocket %s already exists, "
|
||||
"disabling multiplexing", options.control_path);
|
||||
disable_mux_master:
|
||||
close(muxserver_sock);
|
||||
muxserver_sock = -1;
|
||||
xfree(options.control_path);
|
||||
@ -1065,12 +1086,29 @@ muxserver_listen(void)
|
||||
if (listen(muxserver_sock, 64) == -1)
|
||||
fatal("%s listen(): %s", __func__, strerror(errno));
|
||||
|
||||
/* Now atomically "move" the mux socket into position */
|
||||
if (link(options.control_path, orig_control_path) != 0) {
|
||||
if (errno != EEXIST) {
|
||||
fatal("%s: link mux listener %s => %s: %s", __func__,
|
||||
options.control_path, orig_control_path,
|
||||
strerror(errno));
|
||||
}
|
||||
error("ControlSocket %s already exists, disabling multiplexing",
|
||||
orig_control_path);
|
||||
xfree(orig_control_path);
|
||||
unlink(options.control_path);
|
||||
goto disable_mux_master;
|
||||
}
|
||||
unlink(options.control_path);
|
||||
xfree(options.control_path);
|
||||
options.control_path = orig_control_path;
|
||||
|
||||
set_nonblock(muxserver_sock);
|
||||
|
||||
mux_listener_channel = channel_new("mux listener",
|
||||
SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,
|
||||
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
|
||||
0, addr.sun_path, 1);
|
||||
0, options.control_path, 1);
|
||||
mux_listener_channel->mux_rcb = mux_master_read_cb;
|
||||
debug3("%s: mux listener channel %d fd %d", __func__,
|
||||
mux_listener_channel->self, mux_listener_channel->sock);
|
||||
@ -1492,7 +1530,7 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
|
||||
case MUX_S_FAILURE:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
error("%s: session request failed: %s", __func__, e);
|
||||
error("%s: forwarding request failed: %s", __func__, e);
|
||||
return -1;
|
||||
default:
|
||||
fatal("%s: unexpected response from master 0x%08x",
|
||||
@ -1611,12 +1649,12 @@ mux_client_request_session(int fd)
|
||||
case MUX_S_PERMISSION_DENIED:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
error("Master refused forwarding request: %s", e);
|
||||
error("Master refused session request: %s", e);
|
||||
return -1;
|
||||
case MUX_S_FAILURE:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
error("%s: forwarding request failed: %s", __func__, e);
|
||||
error("%s: session request failed: %s", __func__, e);
|
||||
return -1;
|
||||
default:
|
||||
buffer_free(&m);
|
||||
@ -1743,7 +1781,7 @@ mux_client_request_stdio_fwd(int fd)
|
||||
case MUX_S_PERMISSION_DENIED:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
fatal("Master refused forwarding request: %s", e);
|
||||
fatal("Master refused stdio forwarding request: %s", e);
|
||||
case MUX_S_FAILURE:
|
||||
e = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
@ -1823,9 +1861,13 @@ muxclient(const char *path)
|
||||
fatal("Control socket connect(%.100s): %s", path,
|
||||
strerror(errno));
|
||||
}
|
||||
if (errno == ENOENT)
|
||||
if (errno == ECONNREFUSED &&
|
||||
options.control_master != SSHCTL_MASTER_NO) {
|
||||
debug("Stale control socket %.100s, unlinking", path);
|
||||
unlink(path);
|
||||
} else if (errno == ENOENT) {
|
||||
debug("Control socket \"%.100s\" does not exist", path);
|
||||
else {
|
||||
} else {
|
||||
error("Control socket connect(%.100s): %s", path,
|
||||
strerror(errno));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: myproposal.h,v 1.25 2010/04/16 01:47:26 djm Exp $ */
|
||||
/* $OpenBSD: myproposal.h,v 1.27 2010/09/01 22:42:13 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -26,26 +26,49 @@
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
# define KEX_DEFAULT_KEX \
|
||||
"diffie-hellman-group-exchange-sha1," \
|
||||
"diffie-hellman-group14-sha1," \
|
||||
"diffie-hellman-group1-sha1"
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
# define KEX_ECDH_METHODS \
|
||||
"ecdh-sha2-nistp256," \
|
||||
"ecdh-sha2-nistp384," \
|
||||
"ecdh-sha2-nistp521,"
|
||||
# define HOSTKEY_ECDSA_CERT_METHODS \
|
||||
"ecdsa-sha2-nistp256-cert-v01@openssh.com," \
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com," \
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com,"
|
||||
# define HOSTKEY_ECDSA_METHODS \
|
||||
"ecdsa-sha2-nistp256," \
|
||||
"ecdsa-sha2-nistp384," \
|
||||
"ecdsa-sha2-nistp521,"
|
||||
#else
|
||||
# define KEX_DEFAULT_KEX \
|
||||
"diffie-hellman-group-exchange-sha256," \
|
||||
"diffie-hellman-group-exchange-sha1," \
|
||||
"diffie-hellman-group14-sha1," \
|
||||
"diffie-hellman-group1-sha1"
|
||||
# define KEX_ECDH_METHODS
|
||||
# define HOSTKEY_ECDSA_CERT_METHODS
|
||||
# define HOSTKEY_ECDSA_METHODS
|
||||
#endif
|
||||
|
||||
/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
|
||||
# define KEX_SHA256_METHODS \
|
||||
"diffie-hellman-group-exchange-sha256,"
|
||||
#else
|
||||
# define KEX_SHA256_METHODS
|
||||
#endif
|
||||
|
||||
# define KEX_DEFAULT_KEX \
|
||||
KEX_ECDH_METHODS \
|
||||
KEX_SHA256_METHODS \
|
||||
"diffie-hellman-group-exchange-sha1," \
|
||||
"diffie-hellman-group14-sha1," \
|
||||
"diffie-hellman-group1-sha1"
|
||||
|
||||
#define KEX_DEFAULT_PK_ALG \
|
||||
"ssh-rsa-cert-v01@openssh.com," \
|
||||
"ssh-dss-cert-v01@openssh.com," \
|
||||
"ssh-rsa-cert-v00@openssh.com," \
|
||||
"ssh-dss-cert-v00@openssh.com," \
|
||||
"ssh-rsa,ssh-dss"
|
||||
HOSTKEY_ECDSA_CERT_METHODS \
|
||||
"ssh-rsa-cert-v01@openssh.com," \
|
||||
"ssh-dss-cert-v01@openssh.com," \
|
||||
"ssh-rsa-cert-v00@openssh.com," \
|
||||
"ssh-dss-cert-v00@openssh.com," \
|
||||
HOSTKEY_ECDSA_METHODS \
|
||||
"ssh-rsa," \
|
||||
"ssh-dss"
|
||||
|
||||
#define KEX_DEFAULT_ENCRYPT \
|
||||
"aes128-ctr,aes192-ctr,aes256-ctr," \
|
||||
|
@ -89,7 +89,7 @@ bindresvport_sa(int sd, struct sockaddr *sa)
|
||||
|
||||
port = ntohs(*portp);
|
||||
if (port == 0)
|
||||
port = (arc4random() % NPORTS) + STARTPORT;
|
||||
port = arc4random_uniform(NPORTS) + STARTPORT;
|
||||
|
||||
/* Avoid warning */
|
||||
error = -1;
|
||||
|
@ -240,3 +240,10 @@ strdup(const char *str)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ISBLANK
|
||||
int isblank(int c)
|
||||
{
|
||||
return (c == ' ' || c == '\t');
|
||||
}
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: bsd-misc.h,v 1.18 2005/02/25 23:07:38 dtucker Exp $ */
|
||||
/* $Id: bsd-misc.h,v 1.19 2010/11/08 22:26:23 tim Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org>
|
||||
@ -95,4 +95,8 @@ mysig_t mysignal(int sig, mysig_t act);
|
||||
|
||||
#define signal(a,b) mysignal(a,b)
|
||||
|
||||
#ifndef HAVE_ISBLANK
|
||||
int isblank(int);
|
||||
#endif
|
||||
|
||||
#endif /* _BSD_MISC_H */
|
||||
|
31
crypto/openssh/openbsd-compat/charclass.h
Normal file
31
crypto/openssh/openbsd-compat/charclass.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Public domain, 2008, Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* $OpenBSD: charclass.h,v 1.1 2008/10/01 23:04:13 millert Exp $
|
||||
*/
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/gen/charclass.h */
|
||||
|
||||
/*
|
||||
* POSIX character class support for fnmatch() and glob().
|
||||
*/
|
||||
static struct cclass {
|
||||
const char *name;
|
||||
int (*isctype)(int);
|
||||
} cclasses[] = {
|
||||
{ "alnum", isalnum },
|
||||
{ "alpha", isalpha },
|
||||
{ "blank", isblank },
|
||||
{ "cntrl", iscntrl },
|
||||
{ "digit", isdigit },
|
||||
{ "graph", isgraph },
|
||||
{ "lower", islower },
|
||||
{ "print", isprint },
|
||||
{ "punct", ispunct },
|
||||
{ "space", isspace },
|
||||
{ "upper", isupper },
|
||||
{ "xdigit", isxdigit },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#define NCCLASSES (sizeof(cclasses) / sizeof(cclasses[0]) - 1)
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: glob.c,v 1.26 2005/11/28 17:50:12 deraadt Exp $ */
|
||||
/* $OpenBSD: glob.c,v 1.35 2011/01/12 01:53:14 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -33,36 +33,6 @@
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/gen/glob.c */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \
|
||||
!defined(GLOB_HAS_GL_MATCHC) || \
|
||||
!defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
|
||||
defined(BROKEN_GLOB)
|
||||
|
||||
static long
|
||||
get_arg_max(void)
|
||||
{
|
||||
#ifdef ARG_MAX
|
||||
return(ARG_MAX);
|
||||
#elif defined(HAVE_SYSCONF) && defined(_SC_ARG_MAX)
|
||||
return(sysconf(_SC_ARG_MAX));
|
||||
#else
|
||||
return(256); /* XXX: arbitrary */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* glob(3) -- a superset of the one defined in POSIX 1003.2.
|
||||
*
|
||||
@ -88,6 +58,25 @@ get_arg_max(void)
|
||||
* Number of matches in the current invocation of glob.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \
|
||||
!defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \
|
||||
!defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
|
||||
defined(BROKEN_GLOB)
|
||||
|
||||
#include "charclass.h"
|
||||
|
||||
#define DOLLAR '$'
|
||||
#define DOT '.'
|
||||
@ -100,7 +89,6 @@ get_arg_max(void)
|
||||
#define RBRACKET ']'
|
||||
#define SEP '/'
|
||||
#define STAR '*'
|
||||
#undef TILDE /* Some platforms may already define it */
|
||||
#define TILDE '~'
|
||||
#define UNDERSCORE '_'
|
||||
#define LBRACE '{'
|
||||
@ -137,26 +125,39 @@ typedef char Char;
|
||||
#define M_ONE META('?')
|
||||
#define M_RNG META('-')
|
||||
#define M_SET META('[')
|
||||
#define M_CLASS META(':')
|
||||
#define ismeta(c) (((c)&M_QUOTE) != 0)
|
||||
|
||||
#define GLOB_LIMIT_MALLOC 65536
|
||||
#define GLOB_LIMIT_STAT 128
|
||||
#define GLOB_LIMIT_READDIR 16384
|
||||
|
||||
struct glob_lim {
|
||||
size_t glim_malloc;
|
||||
size_t glim_stat;
|
||||
size_t glim_readdir;
|
||||
};
|
||||
|
||||
static int compare(const void *, const void *);
|
||||
static int g_Ctoc(const Char *, char *, u_int);
|
||||
static int g_lstat(Char *, struct stat *, glob_t *);
|
||||
static DIR *g_opendir(Char *, glob_t *);
|
||||
static Char *g_strchr(Char *, int);
|
||||
static Char *g_strchr(const Char *, int);
|
||||
static int g_strncmp(const Char *, const char *, size_t);
|
||||
static int g_stat(Char *, struct stat *, glob_t *);
|
||||
static int glob0(const Char *, glob_t *);
|
||||
static int glob1(Char *, Char *, glob_t *, size_t *);
|
||||
static int glob0(const Char *, glob_t *, struct glob_lim *);
|
||||
static int glob1(Char *, Char *, glob_t *, struct glob_lim *);
|
||||
static int glob2(Char *, Char *, Char *, Char *, Char *, Char *,
|
||||
glob_t *, size_t *);
|
||||
glob_t *, struct glob_lim *);
|
||||
static int glob3(Char *, Char *, Char *, Char *, Char *,
|
||||
Char *, Char *, glob_t *, size_t *);
|
||||
static int globextend(const Char *, glob_t *, size_t *);
|
||||
Char *, Char *, glob_t *, struct glob_lim *);
|
||||
static int globextend(const Char *, glob_t *, struct glob_lim *,
|
||||
struct stat *);
|
||||
static const Char *
|
||||
globtilde(const Char *, Char *, size_t, glob_t *);
|
||||
static int globexp1(const Char *, glob_t *);
|
||||
static int globexp2(const Char *, const Char *, glob_t *, int *);
|
||||
static int globexp1(const Char *, glob_t *, struct glob_lim *);
|
||||
static int globexp2(const Char *, const Char *, glob_t *,
|
||||
struct glob_lim *);
|
||||
static int match(Char *, Char *, Char *);
|
||||
#ifdef DEBUG
|
||||
static void qprintf(const char *, Char *);
|
||||
@ -169,11 +170,13 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
|
||||
const u_char *patnext;
|
||||
int c;
|
||||
Char *bufnext, *bufend, patbuf[MAXPATHLEN];
|
||||
struct glob_lim limit = { 0, 0, 0 };
|
||||
|
||||
patnext = (u_char *) pattern;
|
||||
if (!(flags & GLOB_APPEND)) {
|
||||
pglob->gl_pathc = 0;
|
||||
pglob->gl_pathv = NULL;
|
||||
pglob->gl_statv = NULL;
|
||||
if (!(flags & GLOB_DOOFFS))
|
||||
pglob->gl_offs = 0;
|
||||
}
|
||||
@ -181,6 +184,11 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
|
||||
pglob->gl_errfunc = errfunc;
|
||||
pglob->gl_matchc = 0;
|
||||
|
||||
if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 ||
|
||||
pglob->gl_offs >= INT_MAX || pglob->gl_pathc >= INT_MAX ||
|
||||
pglob->gl_pathc >= INT_MAX - pglob->gl_offs - 1)
|
||||
return GLOB_NOSPACE;
|
||||
|
||||
bufnext = patbuf;
|
||||
bufend = bufnext + MAXPATHLEN - 1;
|
||||
if (flags & GLOB_NOESCAPE)
|
||||
@ -201,9 +209,9 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
|
||||
*bufnext = EOS;
|
||||
|
||||
if (flags & GLOB_BRACE)
|
||||
return globexp1(patbuf, pglob);
|
||||
return globexp1(patbuf, pglob, &limit);
|
||||
else
|
||||
return glob0(patbuf, pglob);
|
||||
return glob0(patbuf, pglob, &limit);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -212,20 +220,18 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
|
||||
* characters
|
||||
*/
|
||||
static int
|
||||
globexp1(const Char *pattern, glob_t *pglob)
|
||||
globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
|
||||
{
|
||||
const Char* ptr = pattern;
|
||||
int rv;
|
||||
|
||||
/* Protect a single {}, for find(1), like csh */
|
||||
if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
|
||||
return glob0(pattern, pglob);
|
||||
return glob0(pattern, pglob, limitp);
|
||||
|
||||
while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
|
||||
if (!globexp2(ptr, pattern, pglob, &rv))
|
||||
return rv;
|
||||
if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)
|
||||
return globexp2(ptr, pattern, pglob, limitp);
|
||||
|
||||
return glob0(pattern, pglob);
|
||||
return glob0(pattern, pglob, limitp);
|
||||
}
|
||||
|
||||
|
||||
@ -235,9 +241,10 @@ globexp1(const Char *pattern, glob_t *pglob)
|
||||
* If it fails then it tries to glob the rest of the pattern and returns.
|
||||
*/
|
||||
static int
|
||||
globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
|
||||
globexp2(const Char *ptr, const Char *pattern, glob_t *pglob,
|
||||
struct glob_lim *limitp)
|
||||
{
|
||||
int i;
|
||||
int i, rv;
|
||||
Char *lm, *ls;
|
||||
const Char *pe, *pm, *pl;
|
||||
Char patbuf[MAXPATHLEN];
|
||||
@ -270,10 +277,8 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
|
||||
}
|
||||
|
||||
/* Non matching braces; just glob the pattern */
|
||||
if (i != 0 || *pe == EOS) {
|
||||
*rv = glob0(patbuf, pglob);
|
||||
return 0;
|
||||
}
|
||||
if (i != 0 || *pe == EOS)
|
||||
return glob0(patbuf, pglob, limitp);
|
||||
|
||||
for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
|
||||
switch (*pm) {
|
||||
@ -319,7 +324,9 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
|
||||
#ifdef DEBUG
|
||||
qprintf("globexp2:", patbuf);
|
||||
#endif
|
||||
*rv = globexp1(patbuf, pglob);
|
||||
rv = globexp1(patbuf, pglob, limitp);
|
||||
if (rv && rv != GLOB_NOMATCH)
|
||||
return rv;
|
||||
|
||||
/* move after the comma, to the next string */
|
||||
pl = pm + 1;
|
||||
@ -330,7 +337,6 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
*rv = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -399,6 +405,47 @@ globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
|
||||
return patbuf;
|
||||
}
|
||||
|
||||
static int
|
||||
g_strncmp(const Char *s1, const char *s2, size_t n)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
while (n--) {
|
||||
rv = *(Char *)s1 - *(const unsigned char *)s2++;
|
||||
if (rv)
|
||||
break;
|
||||
if (*s1++ == '\0')
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int
|
||||
g_charclass(const Char **patternp, Char **bufnextp)
|
||||
{
|
||||
const Char *pattern = *patternp + 1;
|
||||
Char *bufnext = *bufnextp;
|
||||
const Char *colon;
|
||||
struct cclass *cc;
|
||||
size_t len;
|
||||
|
||||
if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']')
|
||||
return 1; /* not a character class */
|
||||
|
||||
len = (size_t)(colon - pattern);
|
||||
for (cc = cclasses; cc->name != NULL; cc++) {
|
||||
if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0')
|
||||
break;
|
||||
}
|
||||
if (cc->name == NULL)
|
||||
return -1; /* invalid character class */
|
||||
*bufnext++ = M_CLASS;
|
||||
*bufnext++ = (Char)(cc - &cclasses[0]);
|
||||
*bufnextp = bufnext;
|
||||
*patternp += len + 3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The main glob() routine: compiles the pattern (optionally processing
|
||||
@ -408,12 +455,11 @@ globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
|
||||
* to find no matches.
|
||||
*/
|
||||
static int
|
||||
glob0(const Char *pattern, glob_t *pglob)
|
||||
glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
|
||||
{
|
||||
const Char *qpatnext;
|
||||
int c, err, oldpathc;
|
||||
Char *bufnext, patbuf[MAXPATHLEN];
|
||||
size_t limit = 0;
|
||||
|
||||
qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
|
||||
oldpathc = pglob->gl_pathc;
|
||||
@ -427,7 +473,7 @@ glob0(const Char *pattern, glob_t *pglob)
|
||||
if (c == NOT)
|
||||
++qpatnext;
|
||||
if (*qpatnext == EOS ||
|
||||
g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
|
||||
g_strchr(qpatnext+1, RBRACKET) == NULL) {
|
||||
*bufnext++ = LBRACKET;
|
||||
if (c == NOT)
|
||||
--qpatnext;
|
||||
@ -438,6 +484,20 @@ glob0(const Char *pattern, glob_t *pglob)
|
||||
*bufnext++ = M_NOT;
|
||||
c = *qpatnext++;
|
||||
do {
|
||||
if (c == LBRACKET && *qpatnext == ':') {
|
||||
do {
|
||||
err = g_charclass(&qpatnext,
|
||||
&bufnext);
|
||||
if (err)
|
||||
break;
|
||||
c = *qpatnext++;
|
||||
} while (c == LBRACKET && *qpatnext == ':');
|
||||
if (err == -1 &&
|
||||
!(pglob->gl_flags & GLOB_NOCHECK))
|
||||
return GLOB_NOMATCH;
|
||||
if (c == RBRACKET)
|
||||
break;
|
||||
}
|
||||
*bufnext++ = CHAR(c);
|
||||
if (*qpatnext == RANGE &&
|
||||
(c = qpatnext[1]) != RBRACKET) {
|
||||
@ -471,7 +531,7 @@ glob0(const Char *pattern, glob_t *pglob)
|
||||
qprintf("glob0:", patbuf);
|
||||
#endif
|
||||
|
||||
if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0)
|
||||
if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0)
|
||||
return(err);
|
||||
|
||||
/*
|
||||
@ -484,7 +544,7 @@ glob0(const Char *pattern, glob_t *pglob)
|
||||
if ((pglob->gl_flags & GLOB_NOCHECK) ||
|
||||
((pglob->gl_flags & GLOB_NOMAGIC) &&
|
||||
!(pglob->gl_flags & GLOB_MAGCHAR)))
|
||||
return(globextend(pattern, pglob, &limit));
|
||||
return(globextend(pattern, pglob, limitp, NULL));
|
||||
else
|
||||
return(GLOB_NOMATCH);
|
||||
}
|
||||
@ -501,7 +561,7 @@ compare(const void *p, const void *q)
|
||||
}
|
||||
|
||||
static int
|
||||
glob1(Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp)
|
||||
glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
|
||||
{
|
||||
Char pathbuf[MAXPATHLEN];
|
||||
|
||||
@ -520,7 +580,7 @@ glob1(Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp)
|
||||
*/
|
||||
static int
|
||||
glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp)
|
||||
Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
|
||||
{
|
||||
struct stat sb;
|
||||
Char *p, *q;
|
||||
@ -536,6 +596,14 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
if (g_lstat(pathbuf, &sb, pglob))
|
||||
return(0);
|
||||
|
||||
if ((pglob->gl_flags & GLOB_LIMIT) &&
|
||||
limitp->glim_stat++ >= GLOB_LIMIT_STAT) {
|
||||
errno = 0;
|
||||
*pathend++ = SEP;
|
||||
*pathend = EOS;
|
||||
return(GLOB_NOSPACE);
|
||||
}
|
||||
|
||||
if (((pglob->gl_flags & GLOB_MARK) &&
|
||||
pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ||
|
||||
(S_ISLNK(sb.st_mode) &&
|
||||
@ -547,7 +615,7 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
*pathend = EOS;
|
||||
}
|
||||
++pglob->gl_matchc;
|
||||
return(globextend(pathbuf, pglob, limitp));
|
||||
return(globextend(pathbuf, pglob, limitp, &sb));
|
||||
}
|
||||
|
||||
/* Find end of next segment, copy tentatively to pathend. */
|
||||
@ -581,7 +649,7 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
static int
|
||||
glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob,
|
||||
size_t *limitp)
|
||||
struct glob_lim *limitp)
|
||||
{
|
||||
struct dirent *dp;
|
||||
DIR *dirp;
|
||||
@ -624,6 +692,14 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
u_char *sc;
|
||||
Char *dc;
|
||||
|
||||
if ((pglob->gl_flags & GLOB_LIMIT) &&
|
||||
limitp->glim_readdir++ >= GLOB_LIMIT_READDIR) {
|
||||
errno = 0;
|
||||
*pathend++ = SEP;
|
||||
*pathend = EOS;
|
||||
return(GLOB_NOSPACE);
|
||||
}
|
||||
|
||||
/* Initial DOT must be matched literally. */
|
||||
if (dp->d_name[0] == DOT && *pattern != DOT)
|
||||
continue;
|
||||
@ -670,25 +746,44 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
|
||||
* gl_pathv points to (gl_offs + gl_pathc + 1) items.
|
||||
*/
|
||||
static int
|
||||
globextend(const Char *path, glob_t *pglob, size_t *limitp)
|
||||
globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp,
|
||||
struct stat *sb)
|
||||
{
|
||||
char **pathv;
|
||||
int i;
|
||||
u_int newsize, len;
|
||||
char *copy;
|
||||
ssize_t i;
|
||||
size_t newn, len;
|
||||
char *copy = NULL;
|
||||
const Char *p;
|
||||
struct stat **statv;
|
||||
|
||||
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
|
||||
pathv = pglob->gl_pathv ? realloc((char *)pglob->gl_pathv, newsize) :
|
||||
malloc(newsize);
|
||||
if (pathv == NULL) {
|
||||
newn = 2 + pglob->gl_pathc + pglob->gl_offs;
|
||||
if (pglob->gl_offs >= INT_MAX ||
|
||||
pglob->gl_pathc >= INT_MAX ||
|
||||
newn >= INT_MAX ||
|
||||
SIZE_MAX / sizeof(*pathv) <= newn ||
|
||||
SIZE_MAX / sizeof(*statv) <= newn) {
|
||||
nospace:
|
||||
for (i = pglob->gl_offs; i < (ssize_t)(newn - 2); i++) {
|
||||
if (pglob->gl_pathv && pglob->gl_pathv[i])
|
||||
free(pglob->gl_pathv[i]);
|
||||
if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 &&
|
||||
pglob->gl_pathv && pglob->gl_pathv[i])
|
||||
free(pglob->gl_statv[i]);
|
||||
}
|
||||
if (pglob->gl_pathv) {
|
||||
free(pglob->gl_pathv);
|
||||
pglob->gl_pathv = NULL;
|
||||
}
|
||||
if (pglob->gl_statv) {
|
||||
free(pglob->gl_statv);
|
||||
pglob->gl_statv = NULL;
|
||||
}
|
||||
return(GLOB_NOSPACE);
|
||||
}
|
||||
|
||||
pathv = realloc(pglob->gl_pathv, newn * sizeof(*pathv));
|
||||
if (pathv == NULL)
|
||||
goto nospace;
|
||||
if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
|
||||
/* first time around -- clear initial gl_offs items */
|
||||
pathv += pglob->gl_offs;
|
||||
@ -697,10 +792,39 @@ globextend(const Char *path, glob_t *pglob, size_t *limitp)
|
||||
}
|
||||
pglob->gl_pathv = pathv;
|
||||
|
||||
if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0) {
|
||||
statv = realloc(pglob->gl_statv, newn * sizeof(*statv));
|
||||
if (statv == NULL)
|
||||
goto nospace;
|
||||
if (pglob->gl_statv == NULL && pglob->gl_offs > 0) {
|
||||
/* first time around -- clear initial gl_offs items */
|
||||
statv += pglob->gl_offs;
|
||||
for (i = pglob->gl_offs; --i >= 0; )
|
||||
*--statv = NULL;
|
||||
}
|
||||
pglob->gl_statv = statv;
|
||||
if (sb == NULL)
|
||||
statv[pglob->gl_offs + pglob->gl_pathc] = NULL;
|
||||
else {
|
||||
limitp->glim_malloc += sizeof(**statv);
|
||||
if ((pglob->gl_flags & GLOB_LIMIT) &&
|
||||
limitp->glim_malloc >= GLOB_LIMIT_MALLOC) {
|
||||
errno = 0;
|
||||
return(GLOB_NOSPACE);
|
||||
}
|
||||
if ((statv[pglob->gl_offs + pglob->gl_pathc] =
|
||||
malloc(sizeof(**statv))) == NULL)
|
||||
goto copy_error;
|
||||
memcpy(statv[pglob->gl_offs + pglob->gl_pathc], sb,
|
||||
sizeof(*sb));
|
||||
}
|
||||
statv[pglob->gl_offs + pglob->gl_pathc + 1] = NULL;
|
||||
}
|
||||
|
||||
for (p = path; *p++;)
|
||||
;
|
||||
len = (size_t)(p - path);
|
||||
*limitp += len;
|
||||
limitp->glim_malloc += len;
|
||||
if ((copy = malloc(len)) != NULL) {
|
||||
if (g_Ctoc(path, copy, len)) {
|
||||
free(copy);
|
||||
@ -711,11 +835,12 @@ globextend(const Char *path, glob_t *pglob, size_t *limitp)
|
||||
pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
|
||||
|
||||
if ((pglob->gl_flags & GLOB_LIMIT) &&
|
||||
newsize + *limitp >= (u_int) get_arg_max()) {
|
||||
(newn * sizeof(*pathv)) + limitp->glim_malloc >
|
||||
GLOB_LIMIT_MALLOC) {
|
||||
errno = 0;
|
||||
return(GLOB_NOSPACE);
|
||||
}
|
||||
|
||||
copy_error:
|
||||
return(copy == NULL ? GLOB_NOSPACE : 0);
|
||||
}
|
||||
|
||||
@ -751,13 +876,21 @@ match(Char *name, Char *pat, Char *patend)
|
||||
return(0);
|
||||
if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
|
||||
++pat;
|
||||
while (((c = *pat++) & M_MASK) != M_END)
|
||||
while (((c = *pat++) & M_MASK) != M_END) {
|
||||
if ((c & M_MASK) == M_CLASS) {
|
||||
Char idx = *pat & M_MASK;
|
||||
if (idx < NCCLASSES &&
|
||||
cclasses[idx].isctype(k))
|
||||
ok = 1;
|
||||
++pat;
|
||||
}
|
||||
if ((*pat & M_MASK) == M_RNG) {
|
||||
if (c <= k && k <= pat[1])
|
||||
ok = 1;
|
||||
pat += 2;
|
||||
} else if (c == k)
|
||||
ok = 1;
|
||||
}
|
||||
if (ok == negate_range)
|
||||
return(0);
|
||||
break;
|
||||
@ -785,6 +918,14 @@ globfree(glob_t *pglob)
|
||||
free(pglob->gl_pathv);
|
||||
pglob->gl_pathv = NULL;
|
||||
}
|
||||
if (pglob->gl_statv != NULL) {
|
||||
for (i = 0; i < pglob->gl_pathc; i++) {
|
||||
if (pglob->gl_statv[i] != NULL)
|
||||
free(pglob->gl_statv[i]);
|
||||
}
|
||||
free(pglob->gl_statv);
|
||||
pglob->gl_statv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static DIR *
|
||||
@ -830,11 +971,11 @@ g_stat(Char *fn, struct stat *sb, glob_t *pglob)
|
||||
}
|
||||
|
||||
static Char *
|
||||
g_strchr(Char *str, int ch)
|
||||
g_strchr(const Char *str, int ch)
|
||||
{
|
||||
do {
|
||||
if (*str == ch)
|
||||
return (str);
|
||||
return ((Char *)str);
|
||||
} while (*str++);
|
||||
return (NULL);
|
||||
}
|
||||
@ -870,5 +1011,4 @@ qprintf(const char *str, Char *s)
|
||||
#endif
|
||||
|
||||
#endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) ||
|
||||
!defined(GLOB_HAS_GL_MATCHC) */
|
||||
|
||||
!defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: glob.h,v 1.10 2005/12/13 00:35:22 millert Exp $ */
|
||||
/* $OpenBSD: glob.h,v 1.11 2010/09/24 13:32:55 djm Exp $ */
|
||||
/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */
|
||||
|
||||
/*
|
||||
@ -38,13 +38,15 @@
|
||||
/* OPENBSD ORIGINAL: include/glob.h */
|
||||
|
||||
#if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || \
|
||||
!defined(GLOB_HAS_GL_MATCHC) || \
|
||||
!defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \
|
||||
!defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
|
||||
defined(BROKEN_GLOB)
|
||||
|
||||
#ifndef _GLOB_H_
|
||||
#define _GLOB_H_
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
struct stat;
|
||||
typedef struct {
|
||||
int gl_pathc; /* Count of total paths so far. */
|
||||
@ -52,6 +54,7 @@ typedef struct {
|
||||
int gl_offs; /* Reserved at beginning of gl_pathv. */
|
||||
int gl_flags; /* Copy of flags parameter to glob. */
|
||||
char **gl_pathv; /* List of paths matching pattern. */
|
||||
struct stat **gl_statv; /* Stat entries corresponding to gl_pathv */
|
||||
/* Copy of errfunc parameter to glob. */
|
||||
int (*gl_errfunc)(const char *, int);
|
||||
|
||||
@ -75,12 +78,10 @@ typedef struct {
|
||||
#define GLOB_NOSORT 0x0020 /* Don't sort. */
|
||||
#define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */
|
||||
|
||||
/* Error values returned by glob(3) */
|
||||
#define GLOB_NOSPACE (-1) /* Malloc call failed. */
|
||||
#define GLOB_ABORTED (-2) /* Unignored error. */
|
||||
#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */
|
||||
#define GLOB_NOSYS (-4) /* Function not supported. */
|
||||
#define GLOB_ABEND GLOB_ABORTED
|
||||
|
||||
#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
|
||||
#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
|
||||
@ -89,6 +90,8 @@ typedef struct {
|
||||
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
|
||||
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
|
||||
#define GLOB_LIMIT 0x2000 /* Limit pattern match output to ARG_MAX */
|
||||
#define GLOB_KEEPSTAT 0x4000 /* Retain stat data for paths in gl_statv. */
|
||||
#define GLOB_ABEND GLOB_ABORTED /* backward compatibility */
|
||||
|
||||
int glob(const char *, int, int (*)(const char *, int), glob_t *);
|
||||
void globfree(glob_t *);
|
||||
@ -96,5 +99,5 @@ void globfree(glob_t *);
|
||||
#endif /* !_GLOB_H_ */
|
||||
|
||||
#endif /* !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) ||
|
||||
!defined(GLOB_HAS_GL_MATCHC */
|
||||
!defined(GLOB_HAS_GL_MATCHC) || !defined(GLOH_HAS_GL_STATV) */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: openbsd-compat.h,v 1.50 2010/08/16 03:15:23 dtucker Exp $ */
|
||||
/* $Id: openbsd-compat.h,v 1.51 2010/10/07 10:25:29 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
|
||||
@ -213,6 +213,10 @@ char *user_from_uid(uid_t, int);
|
||||
char *group_from_gid(gid_t, int);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_TIMINGSAFE_BCMP
|
||||
int timingsafe_bcmp(const void *, const void *, size_t);
|
||||
#endif
|
||||
|
||||
void *xmmap(size_t size);
|
||||
char *xcrypt(const char *password, const char *salt);
|
||||
char *shadow_pw(struct passwd *pw);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: openssl-compat.c,v 1.9 2010/01/28 23:54:11 dtucker Exp $ */
|
||||
/* $Id: openssl-compat.c,v 1.13 2011/01/21 22:37:06 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
|
||||
@ -18,10 +18,20 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_OPENSSL_ENGINE
|
||||
# include <openssl/engine.h>
|
||||
# include <openssl/conf.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RSA_GET_DEFAULT_METHOD
|
||||
# include <openssl/rsa.h>
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#define SSH_DONT_OVERLOAD_OPENSSL_FUNCS
|
||||
#include "openssl-compat.h"
|
||||
|
||||
@ -58,6 +68,70 @@ ssh_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BN_IS_PRIME_EX
|
||||
int
|
||||
BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, void *cb)
|
||||
{
|
||||
if (cb != NULL)
|
||||
fatal("%s: callback args not supported", __func__);
|
||||
return BN_is_prime(p, nchecks, NULL, ctx, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RSA_GENERATE_KEY_EX
|
||||
int
|
||||
RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *bn_e, void *cb)
|
||||
{
|
||||
RSA *new_rsa, tmp_rsa;
|
||||
unsigned long e;
|
||||
|
||||
if (cb != NULL)
|
||||
fatal("%s: callback args not supported", __func__);
|
||||
e = BN_get_word(bn_e);
|
||||
if (e == 0xffffffffL)
|
||||
fatal("%s: value of e too large", __func__);
|
||||
new_rsa = RSA_generate_key(bits, e, NULL, NULL);
|
||||
if (new_rsa == NULL)
|
||||
return 0;
|
||||
/* swap rsa/new_rsa then free new_rsa */
|
||||
tmp_rsa = *rsa;
|
||||
*rsa = *new_rsa;
|
||||
*new_rsa = tmp_rsa;
|
||||
RSA_free(new_rsa);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DSA_GENERATE_PARAMETERS_EX
|
||||
int
|
||||
DSA_generate_parameters_ex(DSA *dsa, int bits, const unsigned char *seed,
|
||||
int seed_len, int *counter_ret, unsigned long *h_ret, void *cb)
|
||||
{
|
||||
DSA *new_dsa, tmp_dsa;
|
||||
|
||||
if (cb != NULL)
|
||||
fatal("%s: callback args not supported", __func__);
|
||||
new_dsa = DSA_generate_parameters(bits, (unsigned char *)seed, seed_len,
|
||||
counter_ret, h_ret, NULL, NULL);
|
||||
if (new_dsa == NULL)
|
||||
return 0;
|
||||
/* swap dsa/new_dsa then free new_dsa */
|
||||
tmp_dsa = *dsa;
|
||||
*dsa = *new_dsa;
|
||||
*new_dsa = tmp_dsa;
|
||||
DSA_free(new_dsa);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RSA_GET_DEFAULT_METHOD
|
||||
RSA_METHOD *
|
||||
RSA_get_default_method(void)
|
||||
{
|
||||
return RSA_PKCS1_SSLeay();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENSSL_ENGINE
|
||||
void
|
||||
ssh_SSLeay_add_all_algorithms(void)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: openssl-compat.h,v 1.15 2010/05/12 07:50:02 djm Exp $ */
|
||||
/* $Id: openssl-compat.h,v 1.18 2011/01/21 22:37:06 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
|
||||
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
@ -39,6 +40,12 @@
|
||||
# define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x1000000fL
|
||||
# define LIBCRYPTO_EVP_INL_TYPE unsigned int
|
||||
#else
|
||||
# define LIBCRYPTO_EVP_INL_TYPE size_t
|
||||
#endif
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x00907000L) || defined(OPENSSL_LOBOTOMISED_AES)
|
||||
# define USE_BUILTIN_RIJNDAEL
|
||||
#endif
|
||||
@ -71,6 +78,10 @@ extern const EVP_CIPHER *evp_acss(void);
|
||||
# define EVP_CIPHER_CTX_key_length(c) ((c)->key_len)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RSA_GET_DEFAULT_METHOD
|
||||
RSA_METHOD *RSA_get_default_method(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We overload some of the OpenSSL crypto functions with ssh_* equivalents
|
||||
* which cater for older and/or less featureful OpenSSL version.
|
||||
@ -101,6 +112,19 @@ extern const EVP_CIPHER *evp_acss(void);
|
||||
# define SSLeay_add_all_algorithms() ssh_SSLeay_add_all_algorithms()
|
||||
# endif
|
||||
|
||||
# ifndef HAVE_BN_IS_PRIME_EX
|
||||
int BN_is_prime_ex(const BIGNUM *, int, BN_CTX *, void *);
|
||||
# endif
|
||||
|
||||
# ifndef HAVE_DSA_GENERATE_PARAMETERS_EX
|
||||
int DSA_generate_parameters_ex(DSA *, int, const unsigned char *, int, int *,
|
||||
unsigned long *, void *);
|
||||
# endif
|
||||
|
||||
# ifndef HAVE_RSA_GENERATE_KEY_EX
|
||||
int RSA_generate_key_ex(RSA *, int, BIGNUM *, void *);
|
||||
# endif
|
||||
|
||||
int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *,
|
||||
unsigned char *, int);
|
||||
int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: port-linux.c,v 1.8 2010/03/01 04:52:50 dtucker Exp $ */
|
||||
/* $Id: port-linux.c,v 1.11.4.3 2011/02/06 02:24:17 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
|
||||
@ -45,7 +45,7 @@ ssh_selinux_enabled(void)
|
||||
static int enabled = -1;
|
||||
|
||||
if (enabled == -1) {
|
||||
enabled = is_selinux_enabled();
|
||||
enabled = (is_selinux_enabled() == 1);
|
||||
debug("SELinux support %s", enabled ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
@ -205,17 +205,41 @@ ssh_selinux_change_context(const char *newname)
|
||||
xfree(oldctx);
|
||||
xfree(newctx);
|
||||
}
|
||||
|
||||
void
|
||||
ssh_selinux_setfscreatecon(const char *path)
|
||||
{
|
||||
security_context_t context;
|
||||
|
||||
if (!ssh_selinux_enabled())
|
||||
return;
|
||||
if (path == NULL) {
|
||||
setfscreatecon(NULL);
|
||||
return;
|
||||
}
|
||||
if (matchpathcon(path, 0700, &context) == 0)
|
||||
setfscreatecon(context);
|
||||
}
|
||||
|
||||
#endif /* WITH_SELINUX */
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
#define OOM_ADJ_PATH "/proc/self/oom_adj"
|
||||
/*
|
||||
* The magic "don't kill me", as documented in eg:
|
||||
* The magic "don't kill me" values, old and new, as documented in eg:
|
||||
* http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt
|
||||
* http://lxr.linux.no/#linux+v2.6.36/Documentation/filesystems/proc.txt
|
||||
*/
|
||||
#define OOM_ADJ_NOKILL -17
|
||||
|
||||
static int oom_adj_save = INT_MIN;
|
||||
static char *oom_adj_path = NULL;
|
||||
struct {
|
||||
char *path;
|
||||
int value;
|
||||
} oom_adjust[] = {
|
||||
{"/proc/self/oom_score_adj", -1000}, /* kernels >= 2.6.36 */
|
||||
{"/proc/self/oom_adj", -17}, /* kernels <= 2.6.35 */
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
/*
|
||||
* Tell the kernel's out-of-memory killer to avoid sshd.
|
||||
@ -224,23 +248,31 @@ static int oom_adj_save = INT_MIN;
|
||||
void
|
||||
oom_adjust_setup(void)
|
||||
{
|
||||
int i, value;
|
||||
FILE *fp;
|
||||
|
||||
debug3("%s", __func__);
|
||||
if ((fp = fopen(OOM_ADJ_PATH, "r+")) != NULL) {
|
||||
if (fscanf(fp, "%d", &oom_adj_save) != 1)
|
||||
verbose("error reading %s: %s", OOM_ADJ_PATH, strerror(errno));
|
||||
else {
|
||||
rewind(fp);
|
||||
if (fprintf(fp, "%d\n", OOM_ADJ_NOKILL) <= 0)
|
||||
verbose("error writing %s: %s",
|
||||
OOM_ADJ_PATH, strerror(errno));
|
||||
else
|
||||
verbose("Set %s from %d to %d",
|
||||
OOM_ADJ_PATH, oom_adj_save, OOM_ADJ_NOKILL);
|
||||
for (i = 0; oom_adjust[i].path != NULL; i++) {
|
||||
oom_adj_path = oom_adjust[i].path;
|
||||
value = oom_adjust[i].value;
|
||||
if ((fp = fopen(oom_adj_path, "r+")) != NULL) {
|
||||
if (fscanf(fp, "%d", &oom_adj_save) != 1)
|
||||
verbose("error reading %s: %s", oom_adj_path,
|
||||
strerror(errno));
|
||||
else {
|
||||
rewind(fp);
|
||||
if (fprintf(fp, "%d\n", value) <= 0)
|
||||
verbose("error writing %s: %s",
|
||||
oom_adj_path, strerror(errno));
|
||||
else
|
||||
verbose("Set %s from %d to %d",
|
||||
oom_adj_path, oom_adj_save, value);
|
||||
}
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
oom_adj_path = NULL;
|
||||
}
|
||||
|
||||
/* Restore the saved OOM adjustment */
|
||||
@ -250,13 +282,14 @@ oom_adjust_restore(void)
|
||||
FILE *fp;
|
||||
|
||||
debug3("%s", __func__);
|
||||
if (oom_adj_save == INT_MIN || (fp = fopen(OOM_ADJ_PATH, "w")) == NULL)
|
||||
if (oom_adj_save == INT_MIN || oom_adj_path == NULL ||
|
||||
(fp = fopen(oom_adj_path, "w")) == NULL)
|
||||
return;
|
||||
|
||||
if (fprintf(fp, "%d\n", oom_adj_save) <= 0)
|
||||
verbose("error writing %s: %s", OOM_ADJ_PATH, strerror(errno));
|
||||
verbose("error writing %s: %s", oom_adj_path, strerror(errno));
|
||||
else
|
||||
verbose("Set %s to %d", OOM_ADJ_PATH, oom_adj_save);
|
||||
verbose("Set %s to %d", oom_adj_path, oom_adj_save);
|
||||
|
||||
fclose(fp);
|
||||
return;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: port-linux.h,v 1.4 2009/12/08 02:39:48 dtucker Exp $ */
|
||||
/* $Id: port-linux.h,v 1.4.10.1 2011/02/04 00:42:21 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller <djm@openbsd.org>
|
||||
@ -24,6 +24,7 @@ int ssh_selinux_enabled(void);
|
||||
void ssh_selinux_setup_pty(char *, const char *);
|
||||
void ssh_selinux_setup_exec_context(char *);
|
||||
void ssh_selinux_change_context(const char *);
|
||||
void ssh_selinux_setfscreatecon(const char *);
|
||||
#endif
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: port-solaris.c,v 1.3 2006/10/31 23:28:49 dtucker Exp $ */
|
||||
/* $Id: port-solaris.c,v 1.4 2010/11/05 01:03:05 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Chad Mynhier.
|
||||
@ -197,3 +197,33 @@ solaris_contract_post_fork_parent(pid_t pid)
|
||||
close(ctl_fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SOLARIS_PROJECTS
|
||||
#include <sys/task.h>
|
||||
#include <project.h>
|
||||
|
||||
/*
|
||||
* Get/set solaris default project.
|
||||
* If we fail, just run along gracefully.
|
||||
*/
|
||||
void
|
||||
solaris_set_default_project(struct passwd *pw)
|
||||
{
|
||||
struct project *defaultproject;
|
||||
struct project tempproject;
|
||||
char buf[1024];
|
||||
|
||||
/* get default project, if we fail just return gracefully */
|
||||
if ((defaultproject = getdefaultproj(pw->pw_name, &tempproject, &buf,
|
||||
sizeof(buf))) > 0) {
|
||||
/* set default project */
|
||||
if (setproject(defaultproject->pj_name, pw->pw_name,
|
||||
TASK_NORMAL) != 0)
|
||||
debug("setproject(%s): %s", defaultproject->pj_name,
|
||||
strerror(errno));
|
||||
} else {
|
||||
/* debug on getdefaultproj() error */
|
||||
debug("getdefaultproj(%s): %s", pw->pw_name, strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif /* USE_SOLARIS_PROJECTS */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: port-solaris.h,v 1.1 2006/08/30 17:24:42 djm Exp $ */
|
||||
/* $Id: port-solaris.h,v 1.2 2010/11/05 01:03:05 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Chad Mynhier.
|
||||
@ -20,8 +20,11 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
void solaris_contract_pre_fork(void);
|
||||
void solaris_contract_post_fork_child(void);
|
||||
void solaris_contract_post_fork_parent(pid_t pid);
|
||||
void solaris_set_default_project(struct passwd *);
|
||||
|
||||
#endif
|
||||
|
34
crypto/openssh/openbsd-compat/timingsafe_bcmp.c
Normal file
34
crypto/openssh/openbsd-compat/timingsafe_bcmp.c
Normal file
@ -0,0 +1,34 @@
|
||||
/* $OpenBSD: timingsafe_bcmp.c,v 1.1 2010/09/24 13:33:00 matthew Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
*
|
||||
* 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/string/timingsafe_bcmp.c */
|
||||
|
||||
#include "includes.h"
|
||||
#ifndef HAVE_TIMINGSAFE_BCMP
|
||||
|
||||
int
|
||||
timingsafe_bcmp(const void *b1, const void *b2, size_t n)
|
||||
{
|
||||
const unsigned char *p1 = b1, *p2 = b2;
|
||||
int ret = 0;
|
||||
|
||||
for (; n > 0; n--)
|
||||
ret |= *p1++ ^ *p2++;
|
||||
return (ret != 0);
|
||||
}
|
||||
|
||||
#endif /* TIMINGSAFE_BCMP */
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: packet.c,v 1.168 2010/07/13 23:13:16 djm Exp $ */
|
||||
/* $OpenBSD: packet.c,v 1.172 2010/11/13 23:27:50 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -199,13 +199,13 @@ static struct session_state *active_state, *backup_state;
|
||||
static struct session_state *
|
||||
alloc_session_state(void)
|
||||
{
|
||||
struct session_state *s = xcalloc(1, sizeof(*s));
|
||||
struct session_state *s = xcalloc(1, sizeof(*s));
|
||||
|
||||
s->connection_in = -1;
|
||||
s->connection_out = -1;
|
||||
s->max_packet_size = 32768;
|
||||
s->packet_timeout_ms = -1;
|
||||
return s;
|
||||
s->connection_in = -1;
|
||||
s->connection_out = -1;
|
||||
s->max_packet_size = 32768;
|
||||
s->packet_timeout_ms = -1;
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -391,8 +391,8 @@ packet_get_ssh1_cipher(void)
|
||||
}
|
||||
|
||||
void
|
||||
packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets,
|
||||
u_int64_t *bytes)
|
||||
packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks,
|
||||
u_int32_t *packets, u_int64_t *bytes)
|
||||
{
|
||||
struct packet_state *state;
|
||||
|
||||
@ -547,8 +547,7 @@ packet_start_compression(int level)
|
||||
*/
|
||||
|
||||
void
|
||||
packet_set_encryption_key(const u_char *key, u_int keylen,
|
||||
int number)
|
||||
packet_set_encryption_key(const u_char *key, u_int keylen, int number)
|
||||
{
|
||||
Cipher *cipher = cipher_by_number(number);
|
||||
|
||||
@ -641,6 +640,14 @@ packet_put_bignum2(BIGNUM * value)
|
||||
buffer_put_bignum2(&active_state->outgoing_packet, value);
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void
|
||||
packet_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point)
|
||||
{
|
||||
buffer_put_ecpoint(&active_state->outgoing_packet, curve, point);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Finalizes and sends the packet. If the encryption key has been set,
|
||||
* encrypts the packet before sending.
|
||||
@ -1511,6 +1518,14 @@ packet_get_bignum2(BIGNUM * value)
|
||||
buffer_get_bignum2(&active_state->incoming_packet, value);
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void
|
||||
packet_get_ecpoint(const EC_GROUP *curve, EC_POINT *point)
|
||||
{
|
||||
buffer_get_ecpoint(&active_state->incoming_packet, curve, point);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *
|
||||
packet_get_raw(u_int *length_ptr)
|
||||
{
|
||||
@ -1546,6 +1561,13 @@ packet_get_string_ptr(u_int *length_ptr)
|
||||
return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
|
||||
}
|
||||
|
||||
/* Ensures the returned string has no embedded \0 characters in it. */
|
||||
char *
|
||||
packet_get_cstring(u_int *length_ptr)
|
||||
{
|
||||
return buffer_get_cstring(&active_state->incoming_packet, length_ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends a diagnostic message from the server to the client. This message
|
||||
* can be sent at any time (but not while constructing another message). The
|
||||
@ -1728,14 +1750,13 @@ packet_not_very_much_data_to_write(void)
|
||||
}
|
||||
|
||||
static void
|
||||
packet_set_tos(int interactive)
|
||||
packet_set_tos(int tos)
|
||||
{
|
||||
#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
|
||||
int tos = interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT;
|
||||
|
||||
if (!packet_connection_is_on_socket() ||
|
||||
!packet_connection_is_ipv4())
|
||||
return;
|
||||
debug3("%s: set IP_TOS 0x%02x", __func__, tos);
|
||||
if (setsockopt(active_state->connection_in, IPPROTO_IP, IP_TOS, &tos,
|
||||
sizeof(tos)) < 0)
|
||||
error("setsockopt IP_TOS %d: %.100s:",
|
||||
@ -1746,7 +1767,7 @@ packet_set_tos(int interactive)
|
||||
/* Informs that the current session is interactive. Sets IP flags for that. */
|
||||
|
||||
void
|
||||
packet_set_interactive(int interactive)
|
||||
packet_set_interactive(int interactive, int qos_interactive, int qos_bulk)
|
||||
{
|
||||
if (active_state->set_interactive_called)
|
||||
return;
|
||||
@ -1759,7 +1780,7 @@ packet_set_interactive(int interactive)
|
||||
if (!packet_connection_is_on_socket())
|
||||
return;
|
||||
set_nodelay(active_state->connection_in);
|
||||
packet_set_tos(interactive);
|
||||
packet_set_tos(interactive ? qos_interactive : qos_bulk);
|
||||
}
|
||||
|
||||
/* Returns true if the current connection is interactive. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: packet.h,v 1.52 2009/06/27 09:29:06 andreas Exp $ */
|
||||
/* $OpenBSD: packet.h,v 1.55 2010/11/13 23:27:50 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -19,6 +19,9 @@
|
||||
#include <termios.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
#include <openssl/ec.h>
|
||||
#endif
|
||||
|
||||
void packet_set_connection(int, int);
|
||||
void packet_set_timeout(int, int);
|
||||
@ -31,7 +34,7 @@ u_int packet_get_encryption_key(u_char *);
|
||||
void packet_set_protocol_flags(u_int);
|
||||
u_int packet_get_protocol_flags(void);
|
||||
void packet_start_compression(int);
|
||||
void packet_set_interactive(int);
|
||||
void packet_set_interactive(int, int, int);
|
||||
int packet_is_interactive(void);
|
||||
void packet_set_server(void);
|
||||
void packet_set_authenticated(void);
|
||||
@ -42,6 +45,9 @@ void packet_put_int(u_int value);
|
||||
void packet_put_int64(u_int64_t value);
|
||||
void packet_put_bignum(BIGNUM * value);
|
||||
void packet_put_bignum2(BIGNUM * value);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void packet_put_ecpoint(const EC_GROUP *, const EC_POINT *);
|
||||
#endif
|
||||
void packet_put_string(const void *buf, u_int len);
|
||||
void packet_put_cstring(const char *str);
|
||||
void packet_put_raw(const void *buf, u_int len);
|
||||
@ -59,8 +65,12 @@ u_int packet_get_int(void);
|
||||
u_int64_t packet_get_int64(void);
|
||||
void packet_get_bignum(BIGNUM * value);
|
||||
void packet_get_bignum2(BIGNUM * value);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
void packet_get_ecpoint(const EC_GROUP *, EC_POINT *);
|
||||
#endif
|
||||
void *packet_get_raw(u_int *length_ptr);
|
||||
void *packet_get_string(u_int *length_ptr);
|
||||
char *packet_get_cstring(u_int *length_ptr);
|
||||
void *packet_get_string_ptr(u_int *length_ptr);
|
||||
void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2)));
|
||||
void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2)));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pathnames.h,v 1.19 2010/02/11 20:37:47 djm Exp $ */
|
||||
/* $OpenBSD: pathnames.h,v 1.20 2010/08/31 11:54:45 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -38,6 +38,7 @@
|
||||
#define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config"
|
||||
#define _PATH_HOST_KEY_FILE SSHDIR "/ssh_host_key"
|
||||
#define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key"
|
||||
#define _PATH_HOST_ECDSA_KEY_FILE SSHDIR "/ssh_host_ecdsa_key"
|
||||
#define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key"
|
||||
#define _PATH_DH_MODULI SSHDIR "/moduli"
|
||||
/* Backwards compatibility */
|
||||
@ -74,6 +75,7 @@
|
||||
*/
|
||||
#define _PATH_SSH_CLIENT_IDENTITY ".ssh/identity"
|
||||
#define _PATH_SSH_CLIENT_ID_DSA ".ssh/id_dsa"
|
||||
#define _PATH_SSH_CLIENT_ID_ECDSA ".ssh/id_ecdsa"
|
||||
#define _PATH_SSH_CLIENT_ID_RSA ".ssh/id_rsa"
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: platform.c,v 1.3 2009/12/20 23:49:22 dtucker Exp $ */
|
||||
/* $Id: platform.c,v 1.18 2011/01/11 06:02:25 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Darren Tucker. All rights reserved.
|
||||
@ -16,11 +16,27 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "servconf.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "auth-pam.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include "openbsd-compat/openbsd-compat.h"
|
||||
|
||||
extern int use_privsep;
|
||||
extern ServerOptions options;
|
||||
|
||||
void
|
||||
platform_pre_listen(void)
|
||||
{
|
||||
@ -57,6 +73,118 @@ platform_post_fork_child(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
|
||||
int
|
||||
platform_privileged_uidswap(void)
|
||||
{
|
||||
#ifdef HAVE_CYGWIN
|
||||
/* uid 0 is not special on Cygwin so always try */
|
||||
return 1;
|
||||
#else
|
||||
return (getuid() == 0 || geteuid() == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This gets called before switching UIDs, and is called even when sshd is
|
||||
* not running as root.
|
||||
*/
|
||||
void
|
||||
platform_setusercontext(struct passwd *pw)
|
||||
{
|
||||
#ifdef WITH_SELINUX
|
||||
/* Cache selinux status for later use */
|
||||
(void)ssh_selinux_enabled();
|
||||
#endif
|
||||
|
||||
#ifdef USE_SOLARIS_PROJECTS
|
||||
/* if solaris projects were detected, set the default now */
|
||||
if (getuid() == 0 || geteuid() == 0)
|
||||
solaris_set_default_project(pw);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LOGIN_CAP) && defined (__bsdi__)
|
||||
if (getuid() == 0 || geteuid() == 0)
|
||||
setpgid(0, 0);
|
||||
# endif
|
||||
|
||||
#if defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
|
||||
/*
|
||||
* If we have both LOGIN_CAP and PAM, we want to establish creds
|
||||
* before calling setusercontext (in session.c:do_setusercontext).
|
||||
*/
|
||||
if (getuid() == 0 || geteuid() == 0) {
|
||||
if (options.use_pam) {
|
||||
do_pam_setcred(use_privsep);
|
||||
}
|
||||
}
|
||||
# endif /* USE_PAM */
|
||||
|
||||
#if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
|
||||
if (getuid() == 0 || geteuid() == 0) {
|
||||
/* Sets login uid for accounting */
|
||||
if (getluid() == -1 && setluid(pw->pw_uid) == -1)
|
||||
error("setluid: %s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This gets called after we've established the user's groups, and is only
|
||||
* called if sshd is running as root.
|
||||
*/
|
||||
void
|
||||
platform_setusercontext_post_groups(struct passwd *pw)
|
||||
{
|
||||
#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
|
||||
/*
|
||||
* PAM credentials may take the form of supplementary groups.
|
||||
* These will have been wiped by the above initgroups() call.
|
||||
* Reestablish them here.
|
||||
*/
|
||||
if (options.use_pam) {
|
||||
do_pam_setcred(use_privsep);
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
|
||||
#if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \
|
||||
defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY))
|
||||
irix_setusercontext(pw);
|
||||
#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
|
||||
|
||||
#ifdef _AIX
|
||||
aix_usrinfo(pw);
|
||||
#endif /* _AIX */
|
||||
|
||||
#if !defined(HAVE_LOGIN_CAP) && defined(USE_LIBIAF)
|
||||
if (set_id(pw->pw_name) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
# endif /* USE_LIBIAF */
|
||||
|
||||
#ifdef HAVE_SETPCRED
|
||||
/*
|
||||
* If we have a chroot directory, we set all creds except real
|
||||
* uid which we will need for chroot. If we don't have a
|
||||
* chroot directory, we don't override anything.
|
||||
*/
|
||||
{
|
||||
char **creds = NULL, *chroot_creds[] =
|
||||
{ "REAL_USER=root", NULL };
|
||||
|
||||
if (options.chroot_directory != NULL &&
|
||||
strcasecmp(options.chroot_directory, "none") != 0)
|
||||
creds = chroot_creds;
|
||||
|
||||
if (setpcred(pw->pw_name, creds) == -1)
|
||||
fatal("Failed to set process credentials");
|
||||
}
|
||||
#endif /* HAVE_SETPCRED */
|
||||
#ifdef WITH_SELINUX
|
||||
ssh_selinux_setup_exec_context(pw->pw_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *
|
||||
platform_krb5_get_principal_name(const char *pw_name)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: platform.h,v 1.4 2010/01/14 01:44:16 djm Exp $ */
|
||||
/* $Id: platform.h,v 1.7 2010/11/05 03:47:01 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Darren Tucker. All rights reserved.
|
||||
@ -18,10 +18,15 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
void platform_pre_listen(void);
|
||||
void platform_pre_fork(void);
|
||||
void platform_post_fork_parent(pid_t child_pid);
|
||||
void platform_post_fork_child(void);
|
||||
int platform_privileged_uidswap(void);
|
||||
void platform_setusercontext(struct passwd *);
|
||||
void platform_setusercontext_post_groups(struct passwd *);
|
||||
char *platform_get_krb5_client(const char *);
|
||||
char *platform_krb5_get_principal_name(const char *);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readconf.c,v 1.187 2010/07/19 09:15:12 djm Exp $ */
|
||||
/* $OpenBSD: readconf.c,v 1.190 2010/11/13 23:27:50 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -21,6 +21,8 @@ __RCSID("$FreeBSD$");
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -135,6 +137,7 @@ typedef enum {
|
||||
oHashKnownHosts,
|
||||
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
|
||||
oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
|
||||
oKexAlgorithms, oIPQoS,
|
||||
oVersionAddendum,
|
||||
oDeprecated, oUnsupported
|
||||
} OpCodes;
|
||||
@ -244,6 +247,8 @@ static struct {
|
||||
#else
|
||||
{ "zeroknowledgepasswordauthentication", oUnsupported },
|
||||
#endif
|
||||
{ "kexalgorithms", oKexAlgorithms },
|
||||
{ "ipqos", oIPQoS },
|
||||
|
||||
{ "versionaddendum", oVersionAddendum },
|
||||
{ NULL, oBadOption }
|
||||
@ -716,6 +721,18 @@ process_config_line(Options *options, const char *host,
|
||||
options->macs = xstrdup(arg);
|
||||
break;
|
||||
|
||||
case oKexAlgorithms:
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%.200s line %d: Missing argument.",
|
||||
filename, linenum);
|
||||
if (!kex_names_valid(arg))
|
||||
fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
|
||||
filename, linenum, arg ? arg : "<NONE>");
|
||||
if (*activep && options->kex_algorithms == NULL)
|
||||
options->kex_algorithms = xstrdup(arg);
|
||||
break;
|
||||
|
||||
case oHostKeyAlgorithms:
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
@ -976,6 +993,23 @@ process_config_line(Options *options, const char *host,
|
||||
intptr = &options->visual_host_key;
|
||||
goto parse_flag;
|
||||
|
||||
case oIPQoS:
|
||||
arg = strdelim(&s);
|
||||
if ((value = parse_ipqos(arg)) == -1)
|
||||
fatal("%s line %d: Bad IPQoS value: %s",
|
||||
filename, linenum, arg);
|
||||
arg = strdelim(&s);
|
||||
if (arg == NULL)
|
||||
value2 = value;
|
||||
else if ((value2 = parse_ipqos(arg)) == -1)
|
||||
fatal("%s line %d: Bad IPQoS value: %s",
|
||||
filename, linenum, arg);
|
||||
if (*activep) {
|
||||
options->ip_qos_interactive = value;
|
||||
options->ip_qos_bulk = value2;
|
||||
}
|
||||
break;
|
||||
|
||||
case oUseRoaming:
|
||||
intptr = &options->use_roaming;
|
||||
goto parse_flag;
|
||||
@ -1102,6 +1136,7 @@ initialize_options(Options * options)
|
||||
options->cipher = -1;
|
||||
options->ciphers = NULL;
|
||||
options->macs = NULL;
|
||||
options->kex_algorithms = NULL;
|
||||
options->hostkeyalgorithms = NULL;
|
||||
options->protocol = SSH_PROTO_UNKNOWN;
|
||||
options->num_identity_files = 0;
|
||||
@ -1144,6 +1179,8 @@ initialize_options(Options * options)
|
||||
options->use_roaming = -1;
|
||||
options->visual_host_key = -1;
|
||||
options->zero_knowledge_password_authentication = -1;
|
||||
options->ip_qos_interactive = -1;
|
||||
options->ip_qos_bulk = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1215,6 +1252,7 @@ fill_default_options(Options * options)
|
||||
options->cipher = SSH_CIPHER_NOT_SET;
|
||||
/* options->ciphers, default set in myproposals.h */
|
||||
/* options->macs, default set in myproposals.h */
|
||||
/* options->kex_algorithms, default set in myproposals.h */
|
||||
/* options->hostkeyalgorithms, default set in myproposals.h */
|
||||
if (options->protocol == SSH_PROTO_UNKNOWN)
|
||||
options->protocol = SSH_PROTO_2;
|
||||
@ -1238,6 +1276,13 @@ fill_default_options(Options * options)
|
||||
xmalloc(len);
|
||||
snprintf(options->identity_files[options->num_identity_files++],
|
||||
len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
len = 2 + strlen(_PATH_SSH_CLIENT_ID_ECDSA) + 1;
|
||||
options->identity_files[options->num_identity_files] =
|
||||
xmalloc(len);
|
||||
snprintf(options->identity_files[options->num_identity_files++],
|
||||
len, "~/%.100s", _PATH_SSH_CLIENT_ID_ECDSA);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (options->escape_char == -1)
|
||||
@ -1290,6 +1335,10 @@ fill_default_options(Options * options)
|
||||
options->visual_host_key = 0;
|
||||
if (options->zero_knowledge_password_authentication == -1)
|
||||
options->zero_knowledge_password_authentication = 0;
|
||||
if (options->ip_qos_interactive == -1)
|
||||
options->ip_qos_interactive = IPTOS_LOWDELAY;
|
||||
if (options->ip_qos_bulk == -1)
|
||||
options->ip_qos_bulk = IPTOS_THROUGHPUT;
|
||||
/* options->local_command should not be set by default */
|
||||
/* options->proxy_command should not be set by default */
|
||||
/* options->user will be set in the main program if appropriate */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readconf.h,v 1.86 2010/07/19 09:15:12 djm Exp $ */
|
||||
/* $OpenBSD: readconf.h,v 1.88 2010/11/13 23:27:50 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -59,6 +59,8 @@ typedef struct {
|
||||
int compression_level; /* Compression level 1 (fast) to 9
|
||||
* (best). */
|
||||
int tcp_keep_alive; /* Set SO_KEEPALIVE. */
|
||||
int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */
|
||||
int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */
|
||||
LogLevel log_level; /* Level for logging. */
|
||||
|
||||
int port; /* Port to connect. */
|
||||
@ -73,6 +75,7 @@ typedef struct {
|
||||
char *ciphers; /* SSH2 ciphers in order of preference. */
|
||||
char *macs; /* SSH2 macs in order of preference. */
|
||||
char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */
|
||||
char *kex_algorithms; /* SSH2 kex methods in order of preference. */
|
||||
int protocol; /* Protocol in order of preference. */
|
||||
char *hostname; /* Real host to connect. */
|
||||
char *host_key_alias; /* hostname alias for .ssh/known_hosts */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readpass.c,v 1.47 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/* $OpenBSD: readpass.c,v 1.48 2010/12/15 00:49:27 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -33,6 +33,7 @@
|
||||
#ifdef HAVE_PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -49,11 +50,12 @@
|
||||
static char *
|
||||
ssh_askpass(char *askpass, const char *msg)
|
||||
{
|
||||
pid_t pid;
|
||||
pid_t pid, ret;
|
||||
size_t len;
|
||||
char *pass;
|
||||
int p[2], status, ret;
|
||||
int p[2], status;
|
||||
char buf[1024];
|
||||
void (*osigchld)(int);
|
||||
|
||||
if (fflush(stdout) != 0)
|
||||
error("ssh_askpass: fflush: %s", strerror(errno));
|
||||
@ -63,8 +65,10 @@ ssh_askpass(char *askpass, const char *msg)
|
||||
error("ssh_askpass: pipe: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
osigchld = signal(SIGCHLD, SIG_DFL);
|
||||
if ((pid = fork()) < 0) {
|
||||
error("ssh_askpass: fork: %s", strerror(errno));
|
||||
signal(SIGCHLD, osigchld);
|
||||
return NULL;
|
||||
}
|
||||
if (pid == 0) {
|
||||
@ -77,23 +81,24 @@ ssh_askpass(char *askpass, const char *msg)
|
||||
}
|
||||
close(p[1]);
|
||||
|
||||
len = ret = 0;
|
||||
len = 0;
|
||||
do {
|
||||
ret = read(p[0], buf + len, sizeof(buf) - 1 - len);
|
||||
if (ret == -1 && errno == EINTR)
|
||||
ssize_t r = read(p[0], buf + len, sizeof(buf) - 1 - len);
|
||||
|
||||
if (r == -1 && errno == EINTR)
|
||||
continue;
|
||||
if (ret <= 0)
|
||||
if (r <= 0)
|
||||
break;
|
||||
len += ret;
|
||||
len += r;
|
||||
} while (sizeof(buf) - 1 - len > 0);
|
||||
buf[len] = '\0';
|
||||
|
||||
close(p[0]);
|
||||
while (waitpid(pid, &status, 0) < 0)
|
||||
while ((ret = waitpid(pid, &status, 0)) < 0)
|
||||
if (errno != EINTR)
|
||||
break;
|
||||
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
signal(SIGCHLD, osigchld);
|
||||
if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: schnorr.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
|
||||
/* $OpenBSD: schnorr.c,v 1.5 2010/12/03 23:49:26 djm Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
@ -141,6 +141,10 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
error("%s: g_x < 1", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (BN_cmp(g_x, grp_p) >= 0) {
|
||||
error("%s: g_x > g", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = g_v = r = tmp = v = NULL;
|
||||
if ((bn_ctx = BN_CTX_new()) == NULL) {
|
||||
@ -257,14 +261,19 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
const BIGNUM *r, const BIGNUM *e)
|
||||
{
|
||||
int success = -1;
|
||||
BIGNUM *h, *g_xh, *g_r, *expected;
|
||||
BIGNUM *h = NULL, *g_xh = NULL, *g_r = NULL, *gx_q = NULL;
|
||||
BIGNUM *expected = NULL;
|
||||
BN_CTX *bn_ctx;
|
||||
|
||||
SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
|
||||
|
||||
/* Avoid degenerate cases: g^0 yields a spoofable signature */
|
||||
if (BN_cmp(g_x, BN_value_one()) <= 0) {
|
||||
error("%s: g_x < 1", __func__);
|
||||
error("%s: g_x <= 1", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (BN_cmp(g_x, grp_p) >= 0) {
|
||||
error("%s: g_x >= p", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -275,6 +284,7 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
}
|
||||
if ((g_xh = BN_new()) == NULL ||
|
||||
(g_r = BN_new()) == NULL ||
|
||||
(gx_q = BN_new()) == NULL ||
|
||||
(expected = BN_new()) == NULL) {
|
||||
error("%s: BN_new", __func__);
|
||||
goto out;
|
||||
@ -283,6 +293,17 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
SCHNORR_DEBUG_BN((e, "%s: e = ", __func__));
|
||||
SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
|
||||
|
||||
/* gx_q = (g^x)^q must === 1 mod p */
|
||||
if (BN_mod_exp(gx_q, g_x, grp_q, grp_p, bn_ctx) == -1) {
|
||||
error("%s: BN_mod_exp (g_x^q mod p)", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (BN_cmp(gx_q, BN_value_one()) != 0) {
|
||||
error("%s: Invalid signature (g^x)^q != 1 mod p", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__));
|
||||
/* h = H(g || g^v || g^x || id) */
|
||||
if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x,
|
||||
id, idlen)) == NULL) {
|
||||
@ -317,9 +338,14 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
BN_CTX_free(bn_ctx);
|
||||
if (h != NULL)
|
||||
BN_clear_free(h);
|
||||
BN_clear_free(g_xh);
|
||||
BN_clear_free(g_r);
|
||||
BN_clear_free(expected);
|
||||
if (gx_q != NULL)
|
||||
BN_clear_free(gx_q);
|
||||
if (g_xh != NULL)
|
||||
BN_clear_free(g_xh);
|
||||
if (g_r != NULL)
|
||||
BN_clear_free(g_r);
|
||||
if (expected != NULL)
|
||||
BN_clear_free(expected);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
.\" -*- nroff -*-
|
||||
.\"
|
||||
.\" scp.1
|
||||
.\"
|
||||
@ -9,9 +8,9 @@
|
||||
.\"
|
||||
.\" Created: Sun May 7 00:14:37 1995 ylo
|
||||
.\"
|
||||
.\" $OpenBSD: scp.1,v 1.50 2010/02/08 10:50:20 markus Exp $
|
||||
.\" $OpenBSD: scp.1,v 1.56 2010/12/09 14:13:32 jmc Exp $
|
||||
.\"
|
||||
.Dd February 8, 2010
|
||||
.Dd December 9, 2010
|
||||
.Dt SCP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -20,7 +19,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm scp
|
||||
.Bk -words
|
||||
.Op Fl 1246BCpqrv
|
||||
.Op Fl 12346BCpqrv
|
||||
.Op Fl c Ar cipher
|
||||
.Op Fl F Ar ssh_config
|
||||
.Op Fl i Ar identity_file
|
||||
@ -76,6 +75,11 @@ to use protocol 1.
|
||||
Forces
|
||||
.Nm
|
||||
to use protocol 2.
|
||||
.It Fl 3
|
||||
Copies between two remote hosts are transferred through the local host.
|
||||
Without this option the data is copied directly between the two remote
|
||||
hosts.
|
||||
Note that this option disables the progress meter.
|
||||
.It Fl 4
|
||||
Forces
|
||||
.Nm
|
||||
@ -147,7 +151,9 @@ For full details of the options listed below, and their possible values, see
|
||||
.It HostName
|
||||
.It IdentityFile
|
||||
.It IdentitiesOnly
|
||||
.It IPQoS
|
||||
.It KbdInteractiveDevices
|
||||
.It KexAlgorithms
|
||||
.It LogLevel
|
||||
.It MACs
|
||||
.It NoHostAuthenticationForLocalhost
|
||||
@ -209,7 +215,7 @@ to print debugging messages about their progress.
|
||||
This is helpful in
|
||||
debugging connection, authentication, and configuration problems.
|
||||
.El
|
||||
.Pp
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std scp
|
||||
.Sh SEE ALSO
|
||||
.Xr rcp 1 ,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: scp.c,v 1.166 2010/07/01 13:06:59 millert Exp $ */
|
||||
/* $OpenBSD: scp.c,v 1.170 2010/12/09 14:13:33 jmc Exp $ */
|
||||
/*
|
||||
* scp - secure remote copy. This is basically patched BSD rcp which
|
||||
* uses ssh to do the data transfer (instead of using rcmd).
|
||||
@ -119,14 +119,15 @@ extern char *__progname;
|
||||
#define COPY_BUFLEN 16384
|
||||
|
||||
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);
|
||||
|
||||
void bwlimit(int);
|
||||
int do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout);
|
||||
|
||||
/* Struct for addargs */
|
||||
arglist args;
|
||||
arglist remote_remote_args;
|
||||
|
||||
/* Bandwidth limit */
|
||||
off_t limit_rate = 0;
|
||||
long long limit_kbps = 0;
|
||||
struct bwlimit bwlimit;
|
||||
|
||||
/* Name of current file being transferred. */
|
||||
char *curfile;
|
||||
@ -137,6 +138,12 @@ int verbose_mode = 0;
|
||||
/* This is set to zero if the progressmeter is not desired. */
|
||||
int showprogress = 1;
|
||||
|
||||
/*
|
||||
* This is set to non-zero if remote-remote copy should be piped
|
||||
* through this process.
|
||||
*/
|
||||
int throughlocal = 0;
|
||||
|
||||
/* This is the program to execute for the secured connection. ("ssh" or -S) */
|
||||
char *ssh_program = _PATH_SSH_PROGRAM;
|
||||
|
||||
@ -287,6 +294,50 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This functions executes a command simlar to do_cmd(), but expects the
|
||||
* input and output descriptors to be setup by a previous call to do_cmd().
|
||||
* This way the input and output of two commands can be connected.
|
||||
*/
|
||||
int
|
||||
do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
if (verbose_mode)
|
||||
fprintf(stderr,
|
||||
"Executing: 2nd program %s host %s, user %s, command %s\n",
|
||||
ssh_program, host,
|
||||
remuser ? remuser : "(unspecified)", cmd);
|
||||
|
||||
/* Fork a child to execute the command on the remote host using ssh. */
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
dup2(fdin, 0);
|
||||
dup2(fdout, 1);
|
||||
|
||||
replacearg(&args, 0, "%s", ssh_program);
|
||||
if (remuser != NULL) {
|
||||
addargs(&args, "-l");
|
||||
addargs(&args, "%s", remuser);
|
||||
}
|
||||
addargs(&args, "--");
|
||||
addargs(&args, "%s", host);
|
||||
addargs(&args, "%s", cmd);
|
||||
|
||||
execvp(ssh_program, args.list);
|
||||
perror(ssh_program);
|
||||
exit(1);
|
||||
} else if (pid == -1) {
|
||||
fatal("fork: %s", strerror(errno));
|
||||
}
|
||||
while (waitpid(pid, &status, 0) == -1)
|
||||
if (errno != EINTR)
|
||||
fatal("do_cmd2: waitpid: %s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
size_t cnt;
|
||||
char *buf;
|
||||
@ -312,15 +363,14 @@ void sink(int, char *[]);
|
||||
void source(int, char *[]);
|
||||
void tolocal(int, char *[]);
|
||||
void toremote(char *, int, char *[]);
|
||||
size_t scpio(ssize_t (*)(int, void *, size_t), int, void *, size_t, off_t *);
|
||||
void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch, fflag, tflag, status, n;
|
||||
double speed;
|
||||
char *targ, *endp, **newargv;
|
||||
char *targ, **newargv;
|
||||
const char *errstr;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
@ -336,15 +386,16 @@ main(int argc, char **argv)
|
||||
__progname = ssh_get_progname(argv[0]);
|
||||
|
||||
memset(&args, '\0', sizeof(args));
|
||||
args.list = NULL;
|
||||
memset(&remote_remote_args, '\0', sizeof(remote_remote_args));
|
||||
args.list = remote_remote_args.list = NULL;
|
||||
addargs(&args, "%s", ssh_program);
|
||||
addargs(&args, "-x");
|
||||
addargs(&args, "-oForwardAgent no");
|
||||
addargs(&args, "-oPermitLocalCommand no");
|
||||
addargs(&args, "-oClearAllForwardings yes");
|
||||
addargs(&args, "-oForwardAgent=no");
|
||||
addargs(&args, "-oPermitLocalCommand=no");
|
||||
addargs(&args, "-oClearAllForwardings=yes");
|
||||
|
||||
fflag = tflag = 0;
|
||||
while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1)
|
||||
while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1)
|
||||
switch (ch) {
|
||||
/* User-visible flags. */
|
||||
case '1':
|
||||
@ -353,26 +404,37 @@ main(int argc, char **argv)
|
||||
case '6':
|
||||
case 'C':
|
||||
addargs(&args, "-%c", ch);
|
||||
addargs(&remote_remote_args, "-%c", ch);
|
||||
break;
|
||||
case '3':
|
||||
throughlocal = 1;
|
||||
break;
|
||||
case 'o':
|
||||
case 'c':
|
||||
case 'i':
|
||||
case 'F':
|
||||
addargs(&remote_remote_args, "-%c", ch);
|
||||
addargs(&remote_remote_args, "%s", optarg);
|
||||
addargs(&args, "-%c", ch);
|
||||
addargs(&args, "%s", optarg);
|
||||
break;
|
||||
case 'P':
|
||||
addargs(&remote_remote_args, "-p");
|
||||
addargs(&remote_remote_args, "%s", optarg);
|
||||
addargs(&args, "-p");
|
||||
addargs(&args, "%s", optarg);
|
||||
break;
|
||||
case 'B':
|
||||
addargs(&args, "-oBatchmode yes");
|
||||
addargs(&remote_remote_args, "-oBatchmode=yes");
|
||||
addargs(&args, "-oBatchmode=yes");
|
||||
break;
|
||||
case 'l':
|
||||
speed = strtod(optarg, &endp);
|
||||
if (speed <= 0 || *endp != '\0')
|
||||
limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024,
|
||||
&errstr);
|
||||
if (errstr != NULL)
|
||||
usage();
|
||||
limit_rate = speed * 1024;
|
||||
limit_kbps *= 1024; /* kbps */
|
||||
bandwidth_limit_init(&bwlimit, limit_kbps, COPY_BUFLEN);
|
||||
break;
|
||||
case 'p':
|
||||
pflag = 1;
|
||||
@ -385,10 +447,12 @@ main(int argc, char **argv)
|
||||
break;
|
||||
case 'v':
|
||||
addargs(&args, "-v");
|
||||
addargs(&remote_remote_args, "-v");
|
||||
verbose_mode = 1;
|
||||
break;
|
||||
case 'q':
|
||||
addargs(&args, "-q");
|
||||
addargs(&remote_remote_args, "-q");
|
||||
showprogress = 0;
|
||||
break;
|
||||
|
||||
@ -474,41 +538,16 @@ main(int argc, char **argv)
|
||||
exit(errs != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* atomicio-like wrapper that also applies bandwidth limits and updates
|
||||
* the progressmeter counter.
|
||||
*/
|
||||
size_t
|
||||
scpio(ssize_t (*f)(int, void *, size_t), int fd, void *_p, size_t l, off_t *c)
|
||||
/* Callback from atomicio6 to update progress meter and limit bandwidth */
|
||||
static int
|
||||
scpio(void *_cnt, size_t s)
|
||||
{
|
||||
u_char *p = (u_char *)_p;
|
||||
size_t offset;
|
||||
ssize_t r;
|
||||
struct pollfd pfd;
|
||||
off_t *cnt = (off_t *)_cnt;
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = f == read ? POLLIN : POLLOUT;
|
||||
for (offset = 0; offset < l;) {
|
||||
r = f(fd, p + offset, l - offset);
|
||||
if (r == 0) {
|
||||
errno = EPIPE;
|
||||
return offset;
|
||||
}
|
||||
if (r < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
(void)poll(&pfd, 1, -1); /* Ignore errors */
|
||||
continue;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
offset += (size_t)r;
|
||||
*c += (off_t)r;
|
||||
if (limit_rate)
|
||||
bwlimit(r);
|
||||
}
|
||||
return offset;
|
||||
*cnt += s;
|
||||
if (limit_kbps > 0)
|
||||
bandwidth_limit(&bwlimit, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -517,6 +556,7 @@ toremote(char *targ, int argc, char **argv)
|
||||
char *bp, *host, *src, *suser, *thost, *tuser, *arg;
|
||||
arglist alist;
|
||||
int i;
|
||||
u_int j;
|
||||
|
||||
memset(&alist, '\0', sizeof(alist));
|
||||
alist.list = NULL;
|
||||
@ -544,15 +584,45 @@ toremote(char *targ, int argc, char **argv)
|
||||
|
||||
for (i = 0; i < argc - 1; i++) {
|
||||
src = colon(argv[i]);
|
||||
if (src) { /* remote to remote */
|
||||
if (src && throughlocal) { /* extended remote to remote */
|
||||
*src++ = 0;
|
||||
if (*src == 0)
|
||||
src = ".";
|
||||
host = strrchr(argv[i], '@');
|
||||
if (host) {
|
||||
*host++ = 0;
|
||||
host = cleanhostname(host);
|
||||
suser = argv[i];
|
||||
if (*suser == '\0')
|
||||
suser = pwd->pw_name;
|
||||
else if (!okname(suser))
|
||||
continue;
|
||||
} else {
|
||||
host = cleanhostname(argv[i]);
|
||||
suser = NULL;
|
||||
}
|
||||
xasprintf(&bp, "%s -f -- %s", cmd, src);
|
||||
if (do_cmd(host, suser, bp, &remin, &remout) < 0)
|
||||
exit(1);
|
||||
(void) xfree(bp);
|
||||
host = cleanhostname(thost);
|
||||
xasprintf(&bp, "%s -t -- %s", cmd, targ);
|
||||
if (do_cmd2(host, tuser, bp, remin, remout) < 0)
|
||||
exit(1);
|
||||
(void) xfree(bp);
|
||||
(void) close(remin);
|
||||
(void) close(remout);
|
||||
remin = remout = -1;
|
||||
} else if (src) { /* standard remote to remote */
|
||||
freeargs(&alist);
|
||||
addargs(&alist, "%s", ssh_program);
|
||||
if (verbose_mode)
|
||||
addargs(&alist, "-v");
|
||||
addargs(&alist, "-x");
|
||||
addargs(&alist, "-oClearAllForwardings yes");
|
||||
addargs(&alist, "-oClearAllForwardings=yes");
|
||||
addargs(&alist, "-n");
|
||||
|
||||
for (j = 0; j < remote_remote_args.num; j++) {
|
||||
addargs(&alist, "%s",
|
||||
remote_remote_args.list[j]);
|
||||
}
|
||||
*src++ = 0;
|
||||
if (*src == 0)
|
||||
src = ".";
|
||||
@ -750,7 +820,7 @@ next: if (fd != -1) {
|
||||
(void)atomicio(vwrite, remout, bp->buf, amt);
|
||||
continue;
|
||||
}
|
||||
if (scpio(vwrite, remout, bp->buf, amt,
|
||||
if (atomicio6(vwrite, remout, bp->buf, amt, scpio,
|
||||
&statbytes) != amt)
|
||||
haderr = errno;
|
||||
}
|
||||
@ -824,60 +894,6 @@ rsource(char *name, struct stat *statp)
|
||||
(void) response();
|
||||
}
|
||||
|
||||
void
|
||||
bwlimit(int amount)
|
||||
{
|
||||
static struct timeval bwstart, bwend;
|
||||
static int lamt, thresh = 16384;
|
||||
u_int64_t waitlen;
|
||||
struct timespec ts, rm;
|
||||
|
||||
if (!timerisset(&bwstart)) {
|
||||
gettimeofday(&bwstart, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
lamt += amount;
|
||||
if (lamt < thresh)
|
||||
return;
|
||||
|
||||
gettimeofday(&bwend, NULL);
|
||||
timersub(&bwend, &bwstart, &bwend);
|
||||
if (!timerisset(&bwend))
|
||||
return;
|
||||
|
||||
lamt *= 8;
|
||||
waitlen = (double)1000000L * lamt / limit_rate;
|
||||
|
||||
bwstart.tv_sec = waitlen / 1000000L;
|
||||
bwstart.tv_usec = waitlen % 1000000L;
|
||||
|
||||
if (timercmp(&bwstart, &bwend, >)) {
|
||||
timersub(&bwstart, &bwend, &bwend);
|
||||
|
||||
/* Adjust the wait time */
|
||||
if (bwend.tv_sec) {
|
||||
thresh /= 2;
|
||||
if (thresh < 2048)
|
||||
thresh = 2048;
|
||||
} else if (bwend.tv_usec < 10000) {
|
||||
thresh *= 2;
|
||||
if (thresh > COPY_BUFLEN * 4)
|
||||
thresh = COPY_BUFLEN * 4;
|
||||
}
|
||||
|
||||
TIMEVAL_TO_TIMESPEC(&bwend, &ts);
|
||||
while (nanosleep(&ts, &rm) == -1) {
|
||||
if (errno != EINTR)
|
||||
break;
|
||||
ts = rm;
|
||||
}
|
||||
}
|
||||
|
||||
lamt = 0;
|
||||
gettimeofday(&bwstart, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
sink(int argc, char **argv)
|
||||
{
|
||||
@ -1071,7 +1087,8 @@ bad: run_err("%s: %s", np, strerror(errno));
|
||||
amt = size - i;
|
||||
count += amt;
|
||||
do {
|
||||
j = scpio(read, remin, cp, amt, &statbytes);
|
||||
j = atomicio6(read, remin, cp, amt,
|
||||
scpio, &statbytes);
|
||||
if (j == 0) {
|
||||
run_err("%s", j != EPIPE ?
|
||||
strerror(errno) :
|
||||
@ -1197,7 +1214,7 @@ void
|
||||
usage(void)
|
||||
{
|
||||
(void) fprintf(stderr,
|
||||
"usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
|
||||
"usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
|
||||
" [-l limit] [-o ssh_option] [-P port] [-S program]\n"
|
||||
" [[user@]host1:]file1 ... [[user@]host2:]file2\n");
|
||||
exit(1);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: servconf.c,v 1.209 2010/06/22 04:22:59 djm Exp $ */
|
||||
/* $OpenBSD: servconf.c,v 1.213 2010/11/13 23:27:50 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -16,6 +16,10 @@ __RCSID("$FreeBSD$");
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
@ -111,6 +115,7 @@ initialize_server_options(ServerOptions *options)
|
||||
options->num_deny_groups = 0;
|
||||
options->ciphers = NULL;
|
||||
options->macs = NULL;
|
||||
options->kex_algorithms = NULL;
|
||||
options->protocol = SSH_PROTO_UNKNOWN;
|
||||
options->gateway_ports = -1;
|
||||
options->num_subsystems = 0;
|
||||
@ -134,6 +139,8 @@ initialize_server_options(ServerOptions *options)
|
||||
options->revoked_keys_file = NULL;
|
||||
options->trusted_user_ca_keys = NULL;
|
||||
options->authorized_principals_file = NULL;
|
||||
options->ip_qos_interactive = -1;
|
||||
options->ip_qos_bulk = -1;
|
||||
}
|
||||
|
||||
void
|
||||
@ -156,6 +163,10 @@ fill_default_server_options(ServerOptions *options)
|
||||
_PATH_HOST_RSA_KEY_FILE;
|
||||
options->host_key_files[options->num_host_key_files++] =
|
||||
_PATH_HOST_DSA_KEY_FILE;
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
options->host_key_files[options->num_host_key_files++] =
|
||||
_PATH_HOST_ECDSA_KEY_FILE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* No certificates by default */
|
||||
@ -258,16 +269,20 @@ fill_default_server_options(ServerOptions *options)
|
||||
if (options->authorized_keys_file2 == NULL) {
|
||||
/* authorized_keys_file2 falls back to authorized_keys_file */
|
||||
if (options->authorized_keys_file != NULL)
|
||||
options->authorized_keys_file2 = options->authorized_keys_file;
|
||||
options->authorized_keys_file2 = xstrdup(options->authorized_keys_file);
|
||||
else
|
||||
options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
|
||||
options->authorized_keys_file2 = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2);
|
||||
}
|
||||
if (options->authorized_keys_file == NULL)
|
||||
options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
|
||||
options->authorized_keys_file = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS);
|
||||
if (options->permit_tun == -1)
|
||||
options->permit_tun = SSH_TUNMODE_NO;
|
||||
if (options->zero_knowledge_password_authentication == -1)
|
||||
options->zero_knowledge_password_authentication = 0;
|
||||
if (options->ip_qos_interactive == -1)
|
||||
options->ip_qos_interactive = IPTOS_LOWDELAY;
|
||||
if (options->ip_qos_bulk == -1)
|
||||
options->ip_qos_bulk = IPTOS_THROUGHPUT;
|
||||
|
||||
/* Turn privilege separation on by default */
|
||||
if (use_privsep == -1)
|
||||
@ -314,6 +329,7 @@ typedef enum {
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
sZeroKnowledgePasswordAuthentication, sHostCertificate,
|
||||
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
||||
sKexAlgorithms, sIPQoS,
|
||||
sVersionAddendum,
|
||||
sDeprecated, sUnsupported
|
||||
} ServerOpCodes;
|
||||
@ -437,6 +453,8 @@ static struct {
|
||||
{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
|
||||
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
|
||||
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
|
||||
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
|
||||
{ "ipqos", sIPQoS, SSHCFG_ALL },
|
||||
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
|
||||
{ NULL, sBadOption, 0 }
|
||||
};
|
||||
@ -667,7 +685,7 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
const char *host, const char *address)
|
||||
{
|
||||
char *cp, **charptr, *arg, *p;
|
||||
int cmdline = 0, *intptr, value, n;
|
||||
int cmdline = 0, *intptr, value, value2, n;
|
||||
SyslogFacility *log_facility_ptr;
|
||||
LogLevel *log_level_ptr;
|
||||
ServerOpCodes opcode;
|
||||
@ -1133,6 +1151,18 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
options->macs = xstrdup(arg);
|
||||
break;
|
||||
|
||||
case sKexAlgorithms:
|
||||
arg = strdelim(&cp);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%s line %d: Missing argument.",
|
||||
filename, linenum);
|
||||
if (!kex_names_valid(arg))
|
||||
fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
|
||||
filename, linenum, arg ? arg : "<NONE>");
|
||||
if (options->kex_algorithms == NULL)
|
||||
options->kex_algorithms = xstrdup(arg);
|
||||
break;
|
||||
|
||||
case sProtocol:
|
||||
intptr = &options->protocol;
|
||||
arg = strdelim(&cp);
|
||||
@ -1355,11 +1385,28 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
charptr = &options->revoked_keys_file;
|
||||
goto parse_filename;
|
||||
|
||||
case sIPQoS:
|
||||
arg = strdelim(&cp);
|
||||
if ((value = parse_ipqos(arg)) == -1)
|
||||
fatal("%s line %d: Bad IPQoS value: %s",
|
||||
filename, linenum, arg);
|
||||
arg = strdelim(&cp);
|
||||
if (arg == NULL)
|
||||
value2 = value;
|
||||
else if ((value2 = parse_ipqos(arg)) == -1)
|
||||
fatal("%s line %d: Bad IPQoS value: %s",
|
||||
filename, linenum, arg);
|
||||
if (*activep) {
|
||||
options->ip_qos_interactive = value;
|
||||
options->ip_qos_bulk = value2;
|
||||
}
|
||||
break;
|
||||
|
||||
case sVersionAddendum:
|
||||
ssh_version_set_addendum(strtok(cp, "\n"));
|
||||
do {
|
||||
arg = strdelim(&cp);
|
||||
} while (arg != NULL && *arg != '\0');
|
||||
ssh_version_set_addendum(strtok(cp, "\n"));
|
||||
do {
|
||||
arg = strdelim(&cp);
|
||||
} while (arg != NULL && *arg != '\0');
|
||||
break;
|
||||
|
||||
case sDeprecated:
|
||||
@ -1472,6 +1519,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
||||
M_CP_INTOPT(x11_use_localhost);
|
||||
M_CP_INTOPT(max_sessions);
|
||||
M_CP_INTOPT(max_authtries);
|
||||
M_CP_INTOPT(ip_qos_interactive);
|
||||
M_CP_INTOPT(ip_qos_bulk);
|
||||
|
||||
M_CP_STROPT(banner);
|
||||
if (preauth)
|
||||
@ -1737,5 +1786,7 @@ dump_config(ServerOptions *o)
|
||||
}
|
||||
dump_cfg_string(sPermitTunnel, s);
|
||||
|
||||
printf("ipqos 0x%02x 0x%02x\n", o->ip_qos_interactive, o->ip_qos_bulk);
|
||||
|
||||
channel_print_adm_permitted_opens();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: servconf.h,v 1.93 2010/05/07 11:30:30 djm Exp $ */
|
||||
/* $OpenBSD: servconf.h,v 1.95 2010/11/13 23:27:50 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -70,8 +70,11 @@ typedef struct {
|
||||
char *xauth_location; /* Location of xauth program */
|
||||
int strict_modes; /* If true, require string home dir modes. */
|
||||
int tcp_keep_alive; /* If true, set SO_KEEPALIVE. */
|
||||
int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */
|
||||
int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */
|
||||
char *ciphers; /* Supported SSH2 ciphers. */
|
||||
char *macs; /* Supported SSH2 macs. */
|
||||
char *kex_algorithms; /* SSH2 kex methods in order of preference. */
|
||||
int protocol; /* Supported protocol versions. */
|
||||
int gateway_ports; /* If true, allow remote connects to forwarded ports. */
|
||||
SyslogFacility log_facility; /* Facility for system logging. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: session.c,v 1.256 2010/06/25 07:20:04 djm Exp $ */
|
||||
/* $OpenBSD: session.c,v 1.258 2010/11/25 04:10:09 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -586,7 +586,8 @@ do_exec_no_pty(Session *s, const char *command)
|
||||
|
||||
s->pid = pid;
|
||||
/* Set interactive/non-interactive mode. */
|
||||
packet_set_interactive(s->display != NULL);
|
||||
packet_set_interactive(s->display != NULL,
|
||||
options.ip_qos_interactive, options.ip_qos_bulk);
|
||||
|
||||
/*
|
||||
* Clear loginmsg, since it's the child's responsibility to display
|
||||
@ -740,7 +741,8 @@ do_exec_pty(Session *s, const char *command)
|
||||
|
||||
/* Enter interactive session. */
|
||||
s->ptymaster = ptymaster;
|
||||
packet_set_interactive(1);
|
||||
packet_set_interactive(1,
|
||||
options.ip_qos_interactive, options.ip_qos_bulk);
|
||||
if (compat20) {
|
||||
session_set_fds(s, ptyfd, fdout, -1, 1, 1);
|
||||
} else {
|
||||
@ -1481,36 +1483,16 @@ do_setusercontext(struct passwd *pw)
|
||||
{
|
||||
char *chroot_path, *tmp;
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
/* Cache selinux status for later use */
|
||||
(void)ssh_selinux_enabled();
|
||||
#endif
|
||||
platform_setusercontext(pw);
|
||||
|
||||
#ifndef HAVE_CYGWIN
|
||||
if (getuid() == 0 || geteuid() == 0)
|
||||
#endif /* HAVE_CYGWIN */
|
||||
{
|
||||
if (platform_privileged_uidswap()) {
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
# ifdef __bsdi__
|
||||
setpgid(0, 0);
|
||||
# endif
|
||||
# ifdef USE_PAM
|
||||
if (options.use_pam) {
|
||||
do_pam_setcred(use_privsep);
|
||||
}
|
||||
# endif /* USE_PAM */
|
||||
if (setusercontext(lc, pw, pw->pw_uid,
|
||||
(LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
|
||||
perror("unable to set user context");
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
# if defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
|
||||
/* Sets login uid for accounting */
|
||||
if (getluid() == -1 && setluid(pw->pw_uid) == -1)
|
||||
error("setluid: %s", strerror(errno));
|
||||
# endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */
|
||||
|
||||
if (setlogin(pw->pw_name) < 0)
|
||||
error("setlogin failed: %s", strerror(errno));
|
||||
if (setgid(pw->pw_gid) < 0) {
|
||||
@ -1523,50 +1505,9 @@ do_setusercontext(struct passwd *pw)
|
||||
exit(1);
|
||||
}
|
||||
endgrent();
|
||||
# ifdef USE_PAM
|
||||
/*
|
||||
* PAM credentials may take the form of supplementary groups.
|
||||
* These will have been wiped by the above initgroups() call.
|
||||
* Reestablish them here.
|
||||
*/
|
||||
if (options.use_pam) {
|
||||
do_pam_setcred(use_privsep);
|
||||
}
|
||||
# endif /* USE_PAM */
|
||||
# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
|
||||
irix_setusercontext(pw);
|
||||
# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
|
||||
# ifdef _AIX
|
||||
aix_usrinfo(pw);
|
||||
# endif /* _AIX */
|
||||
# ifdef USE_LIBIAF
|
||||
if (set_id(pw->pw_name) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
# endif /* USE_LIBIAF */
|
||||
#endif
|
||||
#ifdef HAVE_SETPCRED
|
||||
/*
|
||||
* If we have a chroot directory, we set all creds except real
|
||||
* uid which we will need for chroot. If we don't have a
|
||||
* chroot directory, we don't override anything.
|
||||
*/
|
||||
{
|
||||
char **creds = NULL, *chroot_creds[] =
|
||||
{ "REAL_USER=root", NULL };
|
||||
|
||||
if (options.chroot_directory != NULL &&
|
||||
strcasecmp(options.chroot_directory, "none") != 0)
|
||||
creds = chroot_creds;
|
||||
|
||||
if (setpcred(pw->pw_name, creds) == -1)
|
||||
fatal("Failed to set process credentials");
|
||||
}
|
||||
#endif /* HAVE_SETPCRED */
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
ssh_selinux_setup_exec_context(pw->pw_name);
|
||||
#endif
|
||||
platform_setusercontext_post_groups(pw);
|
||||
|
||||
if (options.chroot_directory != NULL &&
|
||||
strcasecmp(options.chroot_directory, "none") != 0) {
|
||||
@ -1640,8 +1581,6 @@ launch_login(struct passwd *pw, const char *hostname)
|
||||
static void
|
||||
child_close_fds(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (packet_get_connection_in() == packet_get_connection_out())
|
||||
close(packet_get_connection_in());
|
||||
else {
|
||||
@ -1667,8 +1606,7 @@ child_close_fds(void)
|
||||
* initgroups, because at least on Solaris 2.3 it leaves file
|
||||
* descriptors open.
|
||||
*/
|
||||
for (i = 3; i < 64; i++)
|
||||
close(i);
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-client.c,v 1.92 2010/07/19 03:16:33 djm Exp $ */
|
||||
/* $OpenBSD: sftp-client.c,v 1.94 2010/12/04 00:18:01 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
@ -75,15 +75,28 @@ struct sftp_conn {
|
||||
#define SFTP_EXT_POSIX_RENAME 0x00000001
|
||||
#define SFTP_EXT_STATVFS 0x00000002
|
||||
#define SFTP_EXT_FSTATVFS 0x00000004
|
||||
#define SFTP_EXT_HARDLINK 0x00000008
|
||||
u_int exts;
|
||||
u_int64_t limit_kbps;
|
||||
struct bwlimit bwlimit_in, bwlimit_out;
|
||||
};
|
||||
|
||||
static char *
|
||||
get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...)
|
||||
__attribute__((format(printf, 4, 5)));
|
||||
get_handle(struct sftp_conn *conn, u_int expected_id, u_int *len,
|
||||
const char *errfmt, ...) __attribute__((format(printf, 4, 5)));
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
sftpio(void *_bwlimit, size_t amount)
|
||||
{
|
||||
struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit;
|
||||
|
||||
bandwidth_limit(bwlimit, amount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
send_msg(int fd, Buffer *m)
|
||||
send_msg(struct sftp_conn *conn, Buffer *m)
|
||||
{
|
||||
u_char mlen[4];
|
||||
struct iovec iov[2];
|
||||
@ -98,19 +111,22 @@ send_msg(int fd, Buffer *m)
|
||||
iov[1].iov_base = buffer_ptr(m);
|
||||
iov[1].iov_len = buffer_len(m);
|
||||
|
||||
if (atomiciov(writev, fd, iov, 2) != buffer_len(m) + sizeof(mlen))
|
||||
if (atomiciov6(writev, conn->fd_out, iov, 2,
|
||||
conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) !=
|
||||
buffer_len(m) + sizeof(mlen))
|
||||
fatal("Couldn't send packet: %s", strerror(errno));
|
||||
|
||||
buffer_clear(m);
|
||||
}
|
||||
|
||||
static void
|
||||
get_msg(int fd, Buffer *m)
|
||||
get_msg(struct sftp_conn *conn, Buffer *m)
|
||||
{
|
||||
u_int msg_len;
|
||||
|
||||
buffer_append_space(m, 4);
|
||||
if (atomicio(read, fd, buffer_ptr(m), 4) != 4) {
|
||||
if (atomicio6(read, conn->fd_in, buffer_ptr(m), 4,
|
||||
conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) {
|
||||
if (errno == EPIPE)
|
||||
fatal("Connection closed");
|
||||
else
|
||||
@ -122,7 +138,9 @@ get_msg(int fd, Buffer *m)
|
||||
fatal("Received message too long %u", msg_len);
|
||||
|
||||
buffer_append_space(m, msg_len);
|
||||
if (atomicio(read, fd, buffer_ptr(m), msg_len) != msg_len) {
|
||||
if (atomicio6(read, conn->fd_in, buffer_ptr(m), msg_len,
|
||||
conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in)
|
||||
!= msg_len) {
|
||||
if (errno == EPIPE)
|
||||
fatal("Connection closed");
|
||||
else
|
||||
@ -131,7 +149,7 @@ get_msg(int fd, Buffer *m)
|
||||
}
|
||||
|
||||
static void
|
||||
send_string_request(int fd, u_int id, u_int code, char *s,
|
||||
send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s,
|
||||
u_int len)
|
||||
{
|
||||
Buffer msg;
|
||||
@ -140,14 +158,14 @@ send_string_request(int fd, u_int id, u_int code, char *s,
|
||||
buffer_put_char(&msg, code);
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_string(&msg, s, len);
|
||||
send_msg(fd, &msg);
|
||||
debug3("Sent message fd %d T:%u I:%u", fd, code, id);
|
||||
send_msg(conn, &msg);
|
||||
debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
|
||||
buffer_free(&msg);
|
||||
}
|
||||
|
||||
static void
|
||||
send_string_attrs_request(int fd, u_int id, u_int code, char *s,
|
||||
u_int len, Attrib *a)
|
||||
send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code,
|
||||
char *s, u_int len, Attrib *a)
|
||||
{
|
||||
Buffer msg;
|
||||
|
||||
@ -156,19 +174,19 @@ send_string_attrs_request(int fd, u_int id, u_int code, char *s,
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_string(&msg, s, len);
|
||||
encode_attrib(&msg, a);
|
||||
send_msg(fd, &msg);
|
||||
debug3("Sent message fd %d T:%u I:%u", fd, code, id);
|
||||
send_msg(conn, &msg);
|
||||
debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
|
||||
buffer_free(&msg);
|
||||
}
|
||||
|
||||
static u_int
|
||||
get_status(int fd, u_int expected_id)
|
||||
get_status(struct sftp_conn *conn, u_int expected_id)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int type, id, status;
|
||||
|
||||
buffer_init(&msg);
|
||||
get_msg(fd, &msg);
|
||||
get_msg(conn, &msg);
|
||||
type = buffer_get_char(&msg);
|
||||
id = buffer_get_int(&msg);
|
||||
|
||||
@ -183,11 +201,12 @@ get_status(int fd, u_int expected_id)
|
||||
|
||||
debug3("SSH2_FXP_STATUS %u", status);
|
||||
|
||||
return(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...)
|
||||
get_handle(struct sftp_conn *conn, u_int expected_id, u_int *len,
|
||||
const char *errfmt, ...)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int type, id;
|
||||
@ -201,7 +220,7 @@ get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...)
|
||||
va_end(args);
|
||||
|
||||
buffer_init(&msg);
|
||||
get_msg(fd, &msg);
|
||||
get_msg(conn, &msg);
|
||||
type = buffer_get_char(&msg);
|
||||
id = buffer_get_int(&msg);
|
||||
|
||||
@ -225,14 +244,14 @@ get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...)
|
||||
}
|
||||
|
||||
static Attrib *
|
||||
get_decode_stat(int fd, u_int expected_id, int quiet)
|
||||
get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int type, id;
|
||||
Attrib *a;
|
||||
|
||||
buffer_init(&msg);
|
||||
get_msg(fd, &msg);
|
||||
get_msg(conn, &msg);
|
||||
|
||||
type = buffer_get_char(&msg);
|
||||
id = buffer_get_int(&msg);
|
||||
@ -260,14 +279,14 @@ get_decode_stat(int fd, u_int expected_id, int quiet)
|
||||
}
|
||||
|
||||
static int
|
||||
get_decode_statvfs(int fd, struct sftp_statvfs *st, u_int expected_id,
|
||||
int quiet)
|
||||
get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
|
||||
u_int expected_id, int quiet)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int type, id, flag;
|
||||
|
||||
buffer_init(&msg);
|
||||
get_msg(fd, &msg);
|
||||
get_msg(conn, &msg);
|
||||
|
||||
type = buffer_get_char(&msg);
|
||||
id = buffer_get_int(&msg);
|
||||
@ -311,21 +330,29 @@ get_decode_statvfs(int fd, struct sftp_statvfs *st, u_int expected_id,
|
||||
}
|
||||
|
||||
struct sftp_conn *
|
||||
do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
|
||||
do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
|
||||
u_int64_t limit_kbps)
|
||||
{
|
||||
u_int type, exts = 0;
|
||||
int version;
|
||||
u_int type;
|
||||
Buffer msg;
|
||||
struct sftp_conn *ret;
|
||||
|
||||
ret = xmalloc(sizeof(*ret));
|
||||
ret->fd_in = fd_in;
|
||||
ret->fd_out = fd_out;
|
||||
ret->transfer_buflen = transfer_buflen;
|
||||
ret->num_requests = num_requests;
|
||||
ret->exts = 0;
|
||||
ret->limit_kbps = 0;
|
||||
|
||||
buffer_init(&msg);
|
||||
buffer_put_char(&msg, SSH2_FXP_INIT);
|
||||
buffer_put_int(&msg, SSH2_FILEXFER_VERSION);
|
||||
send_msg(fd_out, &msg);
|
||||
send_msg(ret, &msg);
|
||||
|
||||
buffer_clear(&msg);
|
||||
|
||||
get_msg(fd_in, &msg);
|
||||
get_msg(ret, &msg);
|
||||
|
||||
/* Expecting a VERSION reply */
|
||||
if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) {
|
||||
@ -334,9 +361,9 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
|
||||
buffer_free(&msg);
|
||||
return(NULL);
|
||||
}
|
||||
version = buffer_get_int(&msg);
|
||||
ret->version = buffer_get_int(&msg);
|
||||
|
||||
debug2("Remote version: %d", version);
|
||||
debug2("Remote version: %u", ret->version);
|
||||
|
||||
/* Check for extensions */
|
||||
while (buffer_len(&msg) > 0) {
|
||||
@ -346,15 +373,19 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
|
||||
|
||||
if (strcmp(name, "posix-rename@openssh.com") == 0 &&
|
||||
strcmp(value, "1") == 0) {
|
||||
exts |= SFTP_EXT_POSIX_RENAME;
|
||||
ret->exts |= SFTP_EXT_POSIX_RENAME;
|
||||
known = 1;
|
||||
} else if (strcmp(name, "statvfs@openssh.com") == 0 &&
|
||||
strcmp(value, "2") == 0) {
|
||||
exts |= SFTP_EXT_STATVFS;
|
||||
ret->exts |= SFTP_EXT_STATVFS;
|
||||
known = 1;
|
||||
} if (strcmp(name, "fstatvfs@openssh.com") == 0 &&
|
||||
} else if (strcmp(name, "fstatvfs@openssh.com") == 0 &&
|
||||
strcmp(value, "2") == 0) {
|
||||
exts |= SFTP_EXT_FSTATVFS;
|
||||
ret->exts |= SFTP_EXT_FSTATVFS;
|
||||
known = 1;
|
||||
} else if (strcmp(name, "hardlink@openssh.com") == 0 &&
|
||||
strcmp(value, "1") == 0) {
|
||||
ret->exts |= SFTP_EXT_HARDLINK;
|
||||
known = 1;
|
||||
}
|
||||
if (known) {
|
||||
@ -369,26 +400,25 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
|
||||
|
||||
buffer_free(&msg);
|
||||
|
||||
ret = xmalloc(sizeof(*ret));
|
||||
ret->fd_in = fd_in;
|
||||
ret->fd_out = fd_out;
|
||||
ret->transfer_buflen = transfer_buflen;
|
||||
ret->num_requests = num_requests;
|
||||
ret->version = version;
|
||||
ret->msg_id = 1;
|
||||
ret->exts = exts;
|
||||
|
||||
/* Some filexfer v.0 servers don't support large packets */
|
||||
if (version == 0)
|
||||
if (ret->version == 0)
|
||||
ret->transfer_buflen = MIN(ret->transfer_buflen, 20480);
|
||||
|
||||
return(ret);
|
||||
ret->limit_kbps = limit_kbps;
|
||||
if (ret->limit_kbps > 0) {
|
||||
bandwidth_limit_init(&ret->bwlimit_in, ret->limit_kbps,
|
||||
ret->transfer_buflen);
|
||||
bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps,
|
||||
ret->transfer_buflen);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u_int
|
||||
sftp_proto_version(struct sftp_conn *conn)
|
||||
{
|
||||
return(conn->version);
|
||||
return conn->version;
|
||||
}
|
||||
|
||||
int
|
||||
@ -403,16 +433,16 @@ do_close(struct sftp_conn *conn, char *handle, u_int handle_len)
|
||||
buffer_put_char(&msg, SSH2_FXP_CLOSE);
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_string(&msg, handle, handle_len);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
debug3("Sent message SSH2_FXP_CLOSE I:%u", id);
|
||||
|
||||
status = get_status(conn->fd_in, id);
|
||||
status = get_status(conn, id);
|
||||
if (status != SSH2_FX_OK)
|
||||
error("Couldn't close file: %s", fx2txt(status));
|
||||
|
||||
buffer_free(&msg);
|
||||
|
||||
return(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@ -430,14 +460,14 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
|
||||
buffer_put_char(&msg, SSH2_FXP_OPENDIR);
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_cstring(&msg, path);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
|
||||
buffer_clear(&msg);
|
||||
|
||||
handle = get_handle(conn->fd_in, id, &handle_len,
|
||||
handle = get_handle(conn, id, &handle_len,
|
||||
"remote readdir(\"%s\")", path);
|
||||
if (handle == NULL)
|
||||
return(-1);
|
||||
return -1;
|
||||
|
||||
if (dir) {
|
||||
ents = 0;
|
||||
@ -454,11 +484,11 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
|
||||
buffer_put_char(&msg, SSH2_FXP_READDIR);
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_string(&msg, handle, handle_len);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
|
||||
buffer_clear(&msg);
|
||||
|
||||
get_msg(conn->fd_in, &msg);
|
||||
get_msg(conn, &msg);
|
||||
|
||||
type = buffer_get_char(&msg);
|
||||
id = buffer_get_int(&msg);
|
||||
@ -537,7 +567,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
|
||||
**dir = NULL;
|
||||
}
|
||||
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
@ -566,9 +596,8 @@ do_rm(struct sftp_conn *conn, char *path)
|
||||
debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
|
||||
|
||||
id = conn->msg_id++;
|
||||
send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path,
|
||||
strlen(path));
|
||||
status = get_status(conn->fd_in, id);
|
||||
send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path));
|
||||
status = get_status(conn, id);
|
||||
if (status != SSH2_FX_OK)
|
||||
error("Couldn't delete file: %s", fx2txt(status));
|
||||
return(status);
|
||||
@ -580,10 +609,10 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag)
|
||||
u_int status, id;
|
||||
|
||||
id = conn->msg_id++;
|
||||
send_string_attrs_request(conn->fd_out, id, SSH2_FXP_MKDIR, path,
|
||||
send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path,
|
||||
strlen(path), a);
|
||||
|
||||
status = get_status(conn->fd_in, id);
|
||||
status = get_status(conn, id);
|
||||
if (status != SSH2_FX_OK && printflag)
|
||||
error("Couldn't create directory: %s", fx2txt(status));
|
||||
|
||||
@ -596,10 +625,10 @@ do_rmdir(struct sftp_conn *conn, char *path)
|
||||
u_int status, id;
|
||||
|
||||
id = conn->msg_id++;
|
||||
send_string_request(conn->fd_out, id, SSH2_FXP_RMDIR, path,
|
||||
send_string_request(conn, id, SSH2_FXP_RMDIR, path,
|
||||
strlen(path));
|
||||
|
||||
status = get_status(conn->fd_in, id);
|
||||
status = get_status(conn, id);
|
||||
if (status != SSH2_FX_OK)
|
||||
error("Couldn't remove directory: %s", fx2txt(status));
|
||||
|
||||
@ -613,11 +642,11 @@ do_stat(struct sftp_conn *conn, char *path, int quiet)
|
||||
|
||||
id = conn->msg_id++;
|
||||
|
||||
send_string_request(conn->fd_out, id,
|
||||
send_string_request(conn, id,
|
||||
conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
|
||||
path, strlen(path));
|
||||
|
||||
return(get_decode_stat(conn->fd_in, id, quiet));
|
||||
return(get_decode_stat(conn, id, quiet));
|
||||
}
|
||||
|
||||
Attrib *
|
||||
@ -634,10 +663,10 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet)
|
||||
}
|
||||
|
||||
id = conn->msg_id++;
|
||||
send_string_request(conn->fd_out, id, SSH2_FXP_LSTAT, path,
|
||||
send_string_request(conn, id, SSH2_FXP_LSTAT, path,
|
||||
strlen(path));
|
||||
|
||||
return(get_decode_stat(conn->fd_in, id, quiet));
|
||||
return(get_decode_stat(conn, id, quiet));
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
@ -647,10 +676,10 @@ do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet)
|
||||
u_int id;
|
||||
|
||||
id = conn->msg_id++;
|
||||
send_string_request(conn->fd_out, id, SSH2_FXP_FSTAT, handle,
|
||||
send_string_request(conn, id, SSH2_FXP_FSTAT, handle,
|
||||
handle_len);
|
||||
|
||||
return(get_decode_stat(conn->fd_in, id, quiet));
|
||||
return(get_decode_stat(conn, id, quiet));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -660,10 +689,10 @@ do_setstat(struct sftp_conn *conn, char *path, Attrib *a)
|
||||
u_int status, id;
|
||||
|
||||
id = conn->msg_id++;
|
||||
send_string_attrs_request(conn->fd_out, id, SSH2_FXP_SETSTAT, path,
|
||||
send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path,
|
||||
strlen(path), a);
|
||||
|
||||
status = get_status(conn->fd_in, id);
|
||||
status = get_status(conn, id);
|
||||
if (status != SSH2_FX_OK)
|
||||
error("Couldn't setstat on \"%s\": %s", path,
|
||||
fx2txt(status));
|
||||
@ -678,10 +707,10 @@ do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len,
|
||||
u_int status, id;
|
||||
|
||||
id = conn->msg_id++;
|
||||
send_string_attrs_request(conn->fd_out, id, SSH2_FXP_FSETSTAT, handle,
|
||||
send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle,
|
||||
handle_len, a);
|
||||
|
||||
status = get_status(conn->fd_in, id);
|
||||
status = get_status(conn, id);
|
||||
if (status != SSH2_FX_OK)
|
||||
error("Couldn't fsetstat: %s", fx2txt(status));
|
||||
|
||||
@ -697,12 +726,12 @@ do_realpath(struct sftp_conn *conn, char *path)
|
||||
Attrib *a;
|
||||
|
||||
expected_id = id = conn->msg_id++;
|
||||
send_string_request(conn->fd_out, id, SSH2_FXP_REALPATH, path,
|
||||
send_string_request(conn, id, SSH2_FXP_REALPATH, path,
|
||||
strlen(path));
|
||||
|
||||
buffer_init(&msg);
|
||||
|
||||
get_msg(conn->fd_in, &msg);
|
||||
get_msg(conn, &msg);
|
||||
type = buffer_get_char(&msg);
|
||||
id = buffer_get_int(&msg);
|
||||
|
||||
@ -756,13 +785,13 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath)
|
||||
}
|
||||
buffer_put_cstring(&msg, oldpath);
|
||||
buffer_put_cstring(&msg, newpath);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
debug3("Sent message %s \"%s\" -> \"%s\"",
|
||||
(conn->exts & SFTP_EXT_POSIX_RENAME) ? "posix-rename@openssh.com" :
|
||||
"SSH2_FXP_RENAME", oldpath, newpath);
|
||||
buffer_free(&msg);
|
||||
|
||||
status = get_status(conn->fd_in, id);
|
||||
status = get_status(conn, id);
|
||||
if (status != SSH2_FX_OK)
|
||||
error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
|
||||
newpath, fx2txt(status));
|
||||
@ -770,6 +799,39 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath)
|
||||
return(status);
|
||||
}
|
||||
|
||||
int
|
||||
do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int status, id;
|
||||
|
||||
buffer_init(&msg);
|
||||
|
||||
/* Send link request */
|
||||
id = conn->msg_id++;
|
||||
if ((conn->exts & SFTP_EXT_HARDLINK) == 0) {
|
||||
error("Server does not support hardlink@openssh.com extension");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer_put_char(&msg, SSH2_FXP_EXTENDED);
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_cstring(&msg, "hardlink@openssh.com");
|
||||
buffer_put_cstring(&msg, oldpath);
|
||||
buffer_put_cstring(&msg, newpath);
|
||||
send_msg(conn, &msg);
|
||||
debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"",
|
||||
oldpath, newpath);
|
||||
buffer_free(&msg);
|
||||
|
||||
status = get_status(conn, id);
|
||||
if (status != SSH2_FX_OK)
|
||||
error("Couldn't link file \"%s\" to \"%s\": %s", oldpath,
|
||||
newpath, fx2txt(status));
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
int
|
||||
do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
|
||||
{
|
||||
@ -789,12 +851,12 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_cstring(&msg, oldpath);
|
||||
buffer_put_cstring(&msg, newpath);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath,
|
||||
newpath);
|
||||
buffer_free(&msg);
|
||||
|
||||
status = get_status(conn->fd_in, id);
|
||||
status = get_status(conn, id);
|
||||
if (status != SSH2_FX_OK)
|
||||
error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath,
|
||||
newpath, fx2txt(status));
|
||||
@ -812,12 +874,11 @@ do_readlink(struct sftp_conn *conn, char *path)
|
||||
Attrib *a;
|
||||
|
||||
expected_id = id = conn->msg_id++;
|
||||
send_string_request(conn->fd_out, id, SSH2_FXP_READLINK, path,
|
||||
strlen(path));
|
||||
send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path));
|
||||
|
||||
buffer_init(&msg);
|
||||
|
||||
get_msg(conn->fd_in, &msg);
|
||||
get_msg(conn, &msg);
|
||||
type = buffer_get_char(&msg);
|
||||
id = buffer_get_int(&msg);
|
||||
|
||||
@ -871,10 +932,10 @@ do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_cstring(&msg, "statvfs@openssh.com");
|
||||
buffer_put_cstring(&msg, path);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
buffer_free(&msg);
|
||||
|
||||
return get_decode_statvfs(conn->fd_in, st, id, quiet);
|
||||
return get_decode_statvfs(conn, st, id, quiet);
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
@ -898,16 +959,16 @@ do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len,
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_cstring(&msg, "fstatvfs@openssh.com");
|
||||
buffer_put_string(&msg, handle, handle_len);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
buffer_free(&msg);
|
||||
|
||||
return get_decode_statvfs(conn->fd_in, st, id, quiet);
|
||||
return get_decode_statvfs(conn, st, id, quiet);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
|
||||
char *handle, u_int handle_len)
|
||||
send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset,
|
||||
u_int len, char *handle, u_int handle_len)
|
||||
{
|
||||
Buffer msg;
|
||||
|
||||
@ -918,7 +979,7 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
|
||||
buffer_put_string(&msg, handle, handle_len);
|
||||
buffer_put_int64(&msg, offset);
|
||||
buffer_put_int(&msg, len);
|
||||
send_msg(fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
buffer_free(&msg);
|
||||
}
|
||||
|
||||
@ -976,10 +1037,10 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
buffer_put_int(&msg, SSH2_FXF_READ);
|
||||
attrib_clear(&junk); /* Send empty attributes */
|
||||
encode_attrib(&msg, &junk);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
|
||||
|
||||
handle = get_handle(conn->fd_in, id, &handle_len,
|
||||
handle = get_handle(conn, id, &handle_len,
|
||||
"remote open(\"%s\")", remote_path);
|
||||
if (handle == NULL) {
|
||||
buffer_free(&msg);
|
||||
@ -1032,12 +1093,12 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
offset += buflen;
|
||||
num_req++;
|
||||
TAILQ_INSERT_TAIL(&requests, req, tq);
|
||||
send_read_request(conn->fd_out, req->id, req->offset,
|
||||
send_read_request(conn, req->id, req->offset,
|
||||
req->len, handle, handle_len);
|
||||
}
|
||||
|
||||
buffer_clear(&msg);
|
||||
get_msg(conn->fd_in, &msg);
|
||||
get_msg(conn, &msg);
|
||||
type = buffer_get_char(&msg);
|
||||
id = buffer_get_int(&msg);
|
||||
debug3("Received reply T:%u I:%u R:%d", type, id, max_req);
|
||||
@ -1092,7 +1153,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
req->id = conn->msg_id++;
|
||||
req->len -= len;
|
||||
req->offset += len;
|
||||
send_read_request(conn->fd_out, req->id,
|
||||
send_read_request(conn, req->id,
|
||||
req->offset, req->len, handle, handle_len);
|
||||
/* Reduce the request size */
|
||||
if (len < buflen)
|
||||
@ -1327,12 +1388,12 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
|
||||
buffer_put_cstring(&msg, remote_path);
|
||||
buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC);
|
||||
encode_attrib(&msg, &a);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
|
||||
|
||||
buffer_clear(&msg);
|
||||
|
||||
handle = get_handle(conn->fd_in, id, &handle_len,
|
||||
handle = get_handle(conn, id, &handle_len,
|
||||
"remote open(\"%s\")", remote_path);
|
||||
if (handle == NULL) {
|
||||
close(local_fd);
|
||||
@ -1381,7 +1442,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
|
||||
buffer_put_string(&msg, handle, handle_len);
|
||||
buffer_put_int64(&msg, offset);
|
||||
buffer_put_string(&msg, data, len);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
send_msg(conn, &msg);
|
||||
debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u",
|
||||
id, (unsigned long long)offset, len);
|
||||
} else if (TAILQ_FIRST(&acks) == NULL)
|
||||
@ -1395,7 +1456,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
|
||||
u_int r_id;
|
||||
|
||||
buffer_clear(&msg);
|
||||
get_msg(conn->fd_in, &msg);
|
||||
get_msg(conn, &msg);
|
||||
type = buffer_get_char(&msg);
|
||||
r_id = buffer_get_int(&msg);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-client.h,v 1.18 2009/08/18 18:36:20 djm Exp $ */
|
||||
/* $OpenBSD: sftp-client.h,v 1.20 2010/12/04 00:18:01 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
@ -51,7 +51,7 @@ struct sftp_statvfs {
|
||||
* Initialise a SSH filexfer connection. Returns NULL on error or
|
||||
* a pointer to a initialized sftp_conn struct on success.
|
||||
*/
|
||||
struct sftp_conn *do_init(int, int, u_int, u_int);
|
||||
struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t);
|
||||
|
||||
u_int sftp_proto_version(struct sftp_conn *);
|
||||
|
||||
@ -94,6 +94,9 @@ int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
|
||||
/* Rename 'oldpath' to 'newpath' */
|
||||
int do_rename(struct sftp_conn *, char *, char *);
|
||||
|
||||
/* Link 'oldpath' to 'newpath' */
|
||||
int do_hardlink(struct sftp_conn *, char *, char *);
|
||||
|
||||
/* Rename 'oldpath' to 'newpath' */
|
||||
int do_symlink(struct sftp_conn *, char *, char *);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-server.c,v 1.91 2010/01/13 01:40:16 djm Exp $ */
|
||||
/* $OpenBSD: sftp-server.c,v 1.93 2010/12/04 00:18:01 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -535,6 +535,9 @@ process_init(void)
|
||||
/* fstatvfs extension */
|
||||
buffer_put_cstring(&msg, "fstatvfs@openssh.com");
|
||||
buffer_put_cstring(&msg, "2"); /* version */
|
||||
/* hardlink extension */
|
||||
buffer_put_cstring(&msg, "hardlink@openssh.com");
|
||||
buffer_put_cstring(&msg, "1"); /* version */
|
||||
send_msg(&msg);
|
||||
buffer_free(&msg);
|
||||
}
|
||||
@ -1222,6 +1225,27 @@ process_extended_fstatvfs(u_int32_t id)
|
||||
send_statvfs(id, &st);
|
||||
}
|
||||
|
||||
static void
|
||||
process_extended_hardlink(u_int32_t id)
|
||||
{
|
||||
char *oldpath, *newpath;
|
||||
int ret, status;
|
||||
|
||||
oldpath = get_string(NULL);
|
||||
newpath = get_string(NULL);
|
||||
debug3("request %u: hardlink", id);
|
||||
logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath);
|
||||
if (readonly)
|
||||
status = SSH2_FX_PERMISSION_DENIED;
|
||||
else {
|
||||
ret = link(oldpath, newpath);
|
||||
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
|
||||
}
|
||||
send_status(id, status);
|
||||
xfree(oldpath);
|
||||
xfree(newpath);
|
||||
}
|
||||
|
||||
static void
|
||||
process_extended(void)
|
||||
{
|
||||
@ -1236,6 +1260,8 @@ process_extended(void)
|
||||
process_extended_statvfs(id);
|
||||
else if (strcmp(request, "fstatvfs@openssh.com") == 0)
|
||||
process_extended_fstatvfs(id);
|
||||
else if (strcmp(request, "hardlink@openssh.com") == 0)
|
||||
process_extended_hardlink(id);
|
||||
else
|
||||
send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */
|
||||
xfree(request);
|
||||
@ -1377,8 +1403,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
ssize_t len, olen, set_size;
|
||||
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
|
||||
char *cp, buf[4*4096];
|
||||
const char *errmsg;
|
||||
mode_t mask;
|
||||
long mask;
|
||||
|
||||
extern char *optarg;
|
||||
extern char *__progname;
|
||||
@ -1412,11 +1437,12 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
error("Invalid log facility \"%s\"", optarg);
|
||||
break;
|
||||
case 'u':
|
||||
mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg);
|
||||
if (errmsg != NULL)
|
||||
fatal("Invalid umask \"%s\": %s",
|
||||
optarg, errmsg);
|
||||
(void)umask(mask);
|
||||
errno = 0;
|
||||
mask = strtol(optarg, &cp, 8);
|
||||
if (mask < 0 || mask > 0777 || *cp != '\0' ||
|
||||
cp == optarg || (mask == 0 && errno != 0))
|
||||
fatal("Invalid umask \"%s\"", optarg);
|
||||
(void)umask((mode_t)mask);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: sftp.1,v 1.83 2010/02/08 10:50:20 markus Exp $
|
||||
.\" $OpenBSD: sftp.1,v 1.88 2010/12/04 00:18:01 djm Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
|
||||
@ -23,7 +23,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 8, 2010
|
||||
.Dd December 4, 2010
|
||||
.Dt SFTP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -39,6 +39,7 @@
|
||||
.Op Fl D Ar sftp_server_path
|
||||
.Op Fl F Ar ssh_config
|
||||
.Op Fl i Ar identity_file
|
||||
.Op Fl l Ar limit
|
||||
.Op Fl o Ar ssh_option
|
||||
.Op Fl P Ar port
|
||||
.Op Fl R Ar num_requests
|
||||
@ -50,9 +51,11 @@
|
||||
.Oo Ar user Ns @ Oc Ns
|
||||
.Ar host Ns Op : Ns Ar
|
||||
.Nm sftp
|
||||
.Oo Ar user Ns @ Oc Ns
|
||||
.Oo
|
||||
.Ar user Ns @ Oc Ns
|
||||
.Ar host Ns Oo : Ns Ar dir Ns
|
||||
.Op Ar / Oc
|
||||
.Op Ar /
|
||||
.Oc
|
||||
.Nm sftp
|
||||
.Fl b Ar batchfile
|
||||
.Oo Ar user Ns @ Oc Ns Ar host
|
||||
@ -126,7 +129,7 @@ commands fail:
|
||||
.Ic get , put , rename , ln ,
|
||||
.Ic rm , mkdir , chdir , ls ,
|
||||
.Ic lchdir , chmod , chown ,
|
||||
.Ic chgrp , lpwd , df ,
|
||||
.Ic chgrp , lpwd , df , symlink ,
|
||||
and
|
||||
.Ic lmkdir .
|
||||
Termination on error can be suppressed on a command by command basis by
|
||||
@ -158,6 +161,8 @@ Selects the file from which the identity (private key) for public key
|
||||
authentication is read.
|
||||
This option is directly passed to
|
||||
.Xr ssh 1 .
|
||||
.It Fl l Ar limit
|
||||
Limits the used bandwidth, specified in Kbit/s.
|
||||
.It Fl o Ar ssh_option
|
||||
Can be used to pass options to
|
||||
.Nm ssh
|
||||
@ -197,7 +202,9 @@ For full details of the options listed below, and their possible values, see
|
||||
.It HostName
|
||||
.It IdentityFile
|
||||
.It IdentitiesOnly
|
||||
.It IPQoS
|
||||
.It KbdInteractiveDevices
|
||||
.It KexAlgorithms
|
||||
.It LogLevel
|
||||
.It MACs
|
||||
.It NoHostAuthenticationForLocalhost
|
||||
@ -386,11 +393,19 @@ characters and may match multiple files.
|
||||
.It Ic lmkdir Ar path
|
||||
Create local directory specified by
|
||||
.Ar path .
|
||||
.It Ic ln Ar oldpath Ar newpath
|
||||
Create a symbolic link from
|
||||
.It Xo Ic ln
|
||||
.Op Fl s
|
||||
.Ar oldpath
|
||||
.Ar newpath
|
||||
.Xc
|
||||
Create a link from
|
||||
.Ar oldpath
|
||||
to
|
||||
.Ar newpath .
|
||||
If the
|
||||
.Fl s
|
||||
flag is specified the created link is a symbolic link, otherwise it is
|
||||
a hard link.
|
||||
.It Ic lpwd
|
||||
Print local working directory.
|
||||
.It Xo Ic ls
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp.c,v 1.125 2010/06/18 00:58:39 djm Exp $ */
|
||||
/* $OpenBSD: sftp.c,v 1.132 2010/12/04 00:18:01 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
@ -132,6 +132,7 @@ extern char *__progname;
|
||||
#define I_GET 5
|
||||
#define I_HELP 6
|
||||
#define I_LCHDIR 7
|
||||
#define I_LINK 25
|
||||
#define I_LLS 8
|
||||
#define I_LMKDIR 9
|
||||
#define I_LPWD 10
|
||||
@ -176,7 +177,7 @@ static const struct CMD cmds[] = {
|
||||
{ "lchdir", I_LCHDIR, LOCAL },
|
||||
{ "lls", I_LLS, LOCAL },
|
||||
{ "lmkdir", I_LMKDIR, LOCAL },
|
||||
{ "ln", I_SYMLINK, REMOTE },
|
||||
{ "ln", I_LINK, REMOTE },
|
||||
{ "lpwd", I_LPWD, LOCAL },
|
||||
{ "ls", I_LS, REMOTE },
|
||||
{ "lumask", I_LUMASK, NOARGS },
|
||||
@ -240,7 +241,7 @@ help(void)
|
||||
"lcd path Change local directory to 'path'\n"
|
||||
"lls [ls-options [path]] Display local directory listing\n"
|
||||
"lmkdir path Create local directory\n"
|
||||
"ln oldpath newpath Symlink remote file\n"
|
||||
"ln [-s] oldpath newpath Link remote file (-s for symlink)\n"
|
||||
"lpwd Print local working directory\n"
|
||||
"ls [-1afhlnrSt] [path] Display remote directory listing\n"
|
||||
"lumask umask Set local umask to 'umask'\n"
|
||||
@ -269,7 +270,7 @@ local_do_shell(const char *args)
|
||||
if (!*args)
|
||||
args = NULL;
|
||||
|
||||
if ((shell = getenv("SHELL")) == NULL)
|
||||
if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
|
||||
shell = _PATH_BSHELL;
|
||||
|
||||
if ((pid = fork()) == -1)
|
||||
@ -376,6 +377,30 @@ parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag,
|
||||
return optind;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_link_flags(const char *cmd, char **argv, int argc, int *sflag)
|
||||
{
|
||||
extern int opterr, optind, optopt, optreset;
|
||||
int ch;
|
||||
|
||||
optind = optreset = 1;
|
||||
opterr = 0;
|
||||
|
||||
*sflag = 0;
|
||||
while ((ch = getopt(argc, argv, "s")) != -1) {
|
||||
switch (ch) {
|
||||
case 's':
|
||||
*sflag = 1;
|
||||
break;
|
||||
default:
|
||||
error("%s: Invalid flag -%c", cmd, optopt);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_ls_flags(char **argv, int argc, int *lflag)
|
||||
{
|
||||
@ -758,18 +783,22 @@ static int
|
||||
do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
|
||||
int lflag)
|
||||
{
|
||||
glob_t g;
|
||||
u_int i, c = 1, colspace = 0, columns = 1;
|
||||
Attrib *a = NULL;
|
||||
char *fname, *lname;
|
||||
glob_t g;
|
||||
int err;
|
||||
struct winsize ws;
|
||||
u_int i, c = 1, colspace = 0, columns = 1, m = 0, width = 80;
|
||||
|
||||
memset(&g, 0, sizeof(g));
|
||||
|
||||
if (remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE,
|
||||
NULL, &g) || (g.gl_pathc && !g.gl_matchc)) {
|
||||
if (remote_glob(conn, path,
|
||||
GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE|GLOB_KEEPSTAT, NULL, &g) ||
|
||||
(g.gl_pathc && !g.gl_matchc)) {
|
||||
if (g.gl_pathc)
|
||||
globfree(&g);
|
||||
error("Can't ls: \"%s\" not found", path);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (interrupted)
|
||||
@ -779,59 +808,35 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
|
||||
* If the glob returns a single match and it is a directory,
|
||||
* then just list its contents.
|
||||
*/
|
||||
if (g.gl_matchc == 1) {
|
||||
if ((a = do_lstat(conn, g.gl_pathv[0], 1)) == NULL) {
|
||||
globfree(&g);
|
||||
return (-1);
|
||||
}
|
||||
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
|
||||
S_ISDIR(a->perm)) {
|
||||
int err;
|
||||
|
||||
err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag);
|
||||
globfree(&g);
|
||||
return (err);
|
||||
}
|
||||
if (g.gl_matchc == 1 && g.gl_statv[0] != NULL &&
|
||||
S_ISDIR(g.gl_statv[0]->st_mode)) {
|
||||
err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag);
|
||||
globfree(&g);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!(lflag & LS_SHORT_VIEW)) {
|
||||
u_int m = 0, width = 80;
|
||||
struct winsize ws;
|
||||
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
|
||||
width = ws.ws_col;
|
||||
|
||||
if (!(lflag & LS_SHORT_VIEW)) {
|
||||
/* Count entries for sort and find longest filename */
|
||||
for (i = 0; g.gl_pathv[i]; i++)
|
||||
m = MAX(m, strlen(g.gl_pathv[i]));
|
||||
|
||||
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
|
||||
width = ws.ws_col;
|
||||
|
||||
columns = width / (m + 2);
|
||||
columns = MAX(columns, 1);
|
||||
colspace = width / columns;
|
||||
}
|
||||
|
||||
for (i = 0; g.gl_pathv[i] && !interrupted; i++, a = NULL) {
|
||||
char *fname;
|
||||
|
||||
fname = path_strip(g.gl_pathv[i], strip_path);
|
||||
|
||||
if (lflag & LS_LONG_VIEW) {
|
||||
char *lname;
|
||||
struct stat sb;
|
||||
|
||||
/*
|
||||
* XXX: this is slow - 1 roundtrip per path
|
||||
* A solution to this is to fork glob() and
|
||||
* build a sftp specific version which keeps the
|
||||
* attribs (which currently get thrown away)
|
||||
* that the server returns as well as the filenames.
|
||||
*/
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
if (a == NULL)
|
||||
a = do_lstat(conn, g.gl_pathv[i], 1);
|
||||
if (a != NULL)
|
||||
attrib_to_stat(a, &sb);
|
||||
lname = ls_file(fname, &sb, 1, (lflag & LS_SI_UNITS));
|
||||
if (g.gl_statv[i] == NULL) {
|
||||
error("no stat information for %s", fname);
|
||||
continue;
|
||||
}
|
||||
lname = ls_file(fname, g.gl_statv[i], 1,
|
||||
(lflag & LS_SI_UNITS));
|
||||
printf("%s\n", lname);
|
||||
xfree(lname);
|
||||
} else {
|
||||
@ -852,7 +857,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
|
||||
if (g.gl_pathc)
|
||||
globfree(&g);
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1108,7 +1113,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
|
||||
|
||||
static int
|
||||
parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
|
||||
int *hflag, unsigned long *n_arg, char **path1, char **path2)
|
||||
int *hflag, int *sflag, unsigned long *n_arg, char **path1, char **path2)
|
||||
{
|
||||
const char *cmd, *cp = *cpp;
|
||||
char *cp2, **argv;
|
||||
@ -1158,7 +1163,8 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
|
||||
switch (cmdnum) {
|
||||
case I_GET:
|
||||
case I_PUT:
|
||||
if ((optidx = parse_getput_flags(cmd, argv, argc, pflag, rflag)) == -1)
|
||||
if ((optidx = parse_getput_flags(cmd, argv, argc,
|
||||
pflag, rflag)) == -1)
|
||||
return -1;
|
||||
/* Get first pathname (mandatory) */
|
||||
if (argc - optidx < 1) {
|
||||
@ -1174,8 +1180,11 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
|
||||
undo_glob_escape(*path2);
|
||||
}
|
||||
break;
|
||||
case I_RENAME:
|
||||
case I_LINK:
|
||||
if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
|
||||
return -1;
|
||||
case I_SYMLINK:
|
||||
case I_RENAME:
|
||||
if (argc - optidx < 2) {
|
||||
error("You must specify two paths after a %s "
|
||||
"command.", cmd);
|
||||
@ -1278,7 +1287,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
int err_abort)
|
||||
{
|
||||
char *path1, *path2, *tmp;
|
||||
int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i;
|
||||
int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, sflag = 0;
|
||||
int cmdnum, i;
|
||||
unsigned long n_arg = 0;
|
||||
Attrib a, *aa;
|
||||
char path_buf[MAXPATHLEN];
|
||||
@ -1286,8 +1296,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
glob_t g;
|
||||
|
||||
path1 = path2 = NULL;
|
||||
cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag, &n_arg,
|
||||
&path1, &path2);
|
||||
cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag,
|
||||
&sflag, &n_arg, &path1, &path2);
|
||||
|
||||
if (iflag != 0)
|
||||
err_abort = 0;
|
||||
@ -1315,8 +1325,11 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
err = do_rename(conn, path1, path2);
|
||||
break;
|
||||
case I_SYMLINK:
|
||||
sflag = 1;
|
||||
case I_LINK:
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
path2 = make_absolute(path2, *pwd);
|
||||
err = do_symlink(conn, path1, path2);
|
||||
err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
|
||||
break;
|
||||
case I_RM:
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
@ -1745,6 +1758,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
|
||||
case '"':
|
||||
case '\\':
|
||||
case '\t':
|
||||
case '[':
|
||||
case ' ':
|
||||
if (quote == '\0' || tmp2[i] == quote) {
|
||||
if (el_insertstr(el, ins) == -1)
|
||||
@ -1874,7 +1888,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
||||
|
||||
/* Tab Completion */
|
||||
el_set(el, EL_ADDFN, "ftp-complete",
|
||||
"Context senstive argument completion", complete);
|
||||
"Context sensitive argument completion", complete);
|
||||
complete_ctx.conn = conn;
|
||||
complete_ctx.remote_pathp = &remote_path;
|
||||
el_set(el, EL_CLIENTDATA, (void*)&complete_ctx);
|
||||
@ -2054,7 +2068,7 @@ usage(void)
|
||||
fprintf(stderr,
|
||||
"usage: %s [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
|
||||
" [-D sftp_server_path] [-F ssh_config] "
|
||||
"[-i identity_file]\n"
|
||||
"[-i identity_file] [-l limit]\n"
|
||||
" [-o ssh_option] [-P port] [-R num_requests] "
|
||||
"[-S program]\n"
|
||||
" [-s subsystem | sftp_server] host\n"
|
||||
@ -2073,6 +2087,7 @@ main(int argc, char **argv)
|
||||
int debug_level = 0, sshver = 2;
|
||||
char *file1 = NULL, *sftp_server = NULL;
|
||||
char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
|
||||
const char *errstr;
|
||||
LogLevel ll = SYSLOG_LEVEL_INFO;
|
||||
arglist args;
|
||||
extern int optind;
|
||||
@ -2080,6 +2095,7 @@ main(int argc, char **argv)
|
||||
struct sftp_conn *conn;
|
||||
size_t copy_buffer_len = DEFAULT_COPY_BUFLEN;
|
||||
size_t num_requests = DEFAULT_NUM_REQUESTS;
|
||||
long long limit_kbps = 0;
|
||||
|
||||
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
||||
sanitise_stdfd();
|
||||
@ -2097,7 +2113,7 @@ main(int argc, char **argv)
|
||||
infile = stdin;
|
||||
|
||||
while ((ch = getopt(argc, argv,
|
||||
"1246hpqrvCc:D:i:o:s:S:b:B:F:P:R:")) != -1) {
|
||||
"1246hpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
|
||||
switch (ch) {
|
||||
/* Passed through to ssh(1) */
|
||||
case '4':
|
||||
@ -2158,6 +2174,13 @@ main(int argc, char **argv)
|
||||
case 'D':
|
||||
sftp_direct = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024,
|
||||
&errstr);
|
||||
if (errstr != NULL)
|
||||
usage();
|
||||
limit_kbps *= 1024; /* kbps */
|
||||
break;
|
||||
case 'r':
|
||||
global_rflag = 1;
|
||||
break;
|
||||
@ -2235,7 +2258,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
freeargs(&args);
|
||||
|
||||
conn = do_init(in, out, copy_buffer_len, num_requests);
|
||||
conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps);
|
||||
if (conn == NULL)
|
||||
fatal("Couldn't initialise connection to server");
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
.\" $OpenBSD: ssh-add.1,v 1.52 2010/03/05 10:28:21 djm Exp $
|
||||
.\"
|
||||
.\" -*- nroff -*-
|
||||
.\" $OpenBSD: ssh-add.1,v 1.55 2010/10/28 18:33:28 jmc Exp $
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -37,12 +35,12 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd March 5, 2010
|
||||
.Dd October 28, 2010
|
||||
.Dt SSH-ADD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ssh-add
|
||||
.Nd adds RSA or DSA identities to the authentication agent
|
||||
.Nd adds private key identities to the authentication agent
|
||||
.Sh SYNOPSIS
|
||||
.Nm ssh-add
|
||||
.Op Fl cDdLlXx
|
||||
@ -54,11 +52,12 @@
|
||||
.Fl e Ar pkcs11
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
adds RSA or DSA identities to the authentication agent,
|
||||
adds private key identities to the authentication agent,
|
||||
.Xr ssh-agent 1 .
|
||||
When run without arguments, it adds the files
|
||||
.Pa ~/.ssh/id_rsa ,
|
||||
.Pa ~/.ssh/id_dsa
|
||||
.Pa ~/.ssh/id_dsa ,
|
||||
.Pa ~/.ssh/id_ecdsa
|
||||
and
|
||||
.Pa ~/.ssh/identity .
|
||||
After loading a private key,
|
||||
@ -165,6 +164,8 @@ socket used to communicate with the agent.
|
||||
Contains the protocol version 1 RSA authentication identity of the user.
|
||||
.It Pa ~/.ssh/id_dsa
|
||||
Contains the protocol version 2 DSA authentication identity of the user.
|
||||
.It Pa ~/.ssh/id_ecdsa
|
||||
Contains the protocol version 2 ECDSA authentication identity of the user.
|
||||
.It Pa ~/.ssh/id_rsa
|
||||
Contains the protocol version 2 RSA authentication identity of the user.
|
||||
.El
|
||||
@ -173,7 +174,7 @@ Identity files should not be readable by anyone but the user.
|
||||
Note that
|
||||
.Nm
|
||||
ignores identity files if they are accessible by others.
|
||||
.Sh DIAGNOSTICS
|
||||
.Sh EXIT STATUS
|
||||
Exit status is 0 on success, 1 if the specified command fails,
|
||||
and 2 if
|
||||
.Nm
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh-add.c,v 1.96 2010/05/14 00:47:22 djm Exp $ */
|
||||
/* $OpenBSD: ssh-add.c,v 1.100 2010/08/31 12:33:38 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -70,6 +70,9 @@ extern char *__progname;
|
||||
static char *default_files[] = {
|
||||
_PATH_SSH_CLIENT_ID_RSA,
|
||||
_PATH_SSH_CLIENT_ID_DSA,
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
_PATH_SSH_CLIENT_ID_ECDSA,
|
||||
#endif
|
||||
_PATH_SSH_CLIENT_IDENTITY,
|
||||
NULL
|
||||
};
|
||||
@ -372,7 +375,7 @@ main(int argc, char **argv)
|
||||
init_rng();
|
||||
seed_rng();
|
||||
|
||||
SSLeay_add_all_algorithms();
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
/* At first, get a connection to the authentication agent. */
|
||||
ac = ssh_get_authentication_connection();
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: ssh-agent.1,v 1.50 2010/01/17 21:49:09 tedu Exp $
|
||||
.\" $OpenBSD: ssh-agent.1,v 1.53 2010/11/21 01:01:13 djm Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -35,7 +35,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd January 17, 2010
|
||||
.Dd November 21, 2010
|
||||
.Dt SSH-AGENT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -43,18 +43,18 @@
|
||||
.Nd authentication agent
|
||||
.Sh SYNOPSIS
|
||||
.Nm ssh-agent
|
||||
.Op Fl c Li | Fl s
|
||||
.Op Fl c | s
|
||||
.Op Fl d
|
||||
.Op Fl a Ar bind_address
|
||||
.Op Fl t Ar life
|
||||
.Op Ar command Op Ar arg ...
|
||||
.Nm ssh-agent
|
||||
.Op Fl c Li | Fl s
|
||||
.Op Fl c | s
|
||||
.Fl k
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a program to hold private keys used for public key authentication
|
||||
(RSA, DSA).
|
||||
(RSA, DSA, ECDSA).
|
||||
The idea is that
|
||||
.Nm
|
||||
is started in the beginning of an X-session or a login session, and
|
||||
@ -73,7 +73,7 @@ Bind the agent to the
|
||||
socket
|
||||
.Ar bind_address .
|
||||
The default is
|
||||
.Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt .
|
||||
.Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt .
|
||||
.It Fl c
|
||||
Generate C-shell commands on
|
||||
.Dv stdout .
|
||||
@ -115,7 +115,8 @@ When executed without arguments,
|
||||
.Xr ssh-add 1
|
||||
adds the files
|
||||
.Pa ~/.ssh/id_rsa ,
|
||||
.Pa ~/.ssh/id_dsa
|
||||
.Pa ~/.ssh/id_dsa ,
|
||||
.Pa ~/.ssh/id_ecdsa
|
||||
and
|
||||
.Pa ~/.ssh/identity .
|
||||
If the identity has a passphrase,
|
||||
@ -188,9 +189,11 @@ line terminates.
|
||||
Contains the protocol version 1 RSA authentication identity of the user.
|
||||
.It Pa ~/.ssh/id_dsa
|
||||
Contains the protocol version 2 DSA authentication identity of the user.
|
||||
.It Pa ~/.ssh/id_ecdsa
|
||||
Contains the protocol version 2 ECDSA authentication identity of the user.
|
||||
.It Pa ~/.ssh/id_rsa
|
||||
Contains the protocol version 2 RSA authentication identity of the user.
|
||||
.It Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt
|
||||
.It Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt
|
||||
.Ux Ns -domain
|
||||
sockets used to contain the connection to the authentication agent.
|
||||
These sockets should only be readable by the owner.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh-agent.c,v 1.166 2010/04/16 01:47:26 djm Exp $ */
|
||||
/* $OpenBSD: ssh-agent.c,v 1.171 2010/11/21 01:01:13 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -469,6 +469,11 @@ process_add_identity(SocketEntry *e, int version)
|
||||
int type, success = 0, death = 0, confirm = 0;
|
||||
char *type_name, *comment;
|
||||
Key *k = NULL;
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
BIGNUM *exponent;
|
||||
EC_POINT *q;
|
||||
char *curve;
|
||||
#endif
|
||||
u_char *cert;
|
||||
u_int len;
|
||||
|
||||
@ -491,7 +496,6 @@ process_add_identity(SocketEntry *e, int version)
|
||||
case 2:
|
||||
type_name = buffer_get_string(&e->request, NULL);
|
||||
type = key_type_from_name(type_name);
|
||||
xfree(type_name);
|
||||
switch (type) {
|
||||
case KEY_DSA:
|
||||
k = key_new_private(type);
|
||||
@ -510,6 +514,59 @@ process_add_identity(SocketEntry *e, int version)
|
||||
key_add_private(k);
|
||||
buffer_get_bignum2(&e->request, k->dsa->priv_key);
|
||||
break;
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
case KEY_ECDSA:
|
||||
k = key_new_private(type);
|
||||
k->ecdsa_nid = key_ecdsa_nid_from_name(type_name);
|
||||
curve = buffer_get_string(&e->request, NULL);
|
||||
if (k->ecdsa_nid != key_curve_name_to_nid(curve))
|
||||
fatal("%s: curve names mismatch", __func__);
|
||||
xfree(curve);
|
||||
k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
|
||||
if (k->ecdsa == NULL)
|
||||
fatal("%s: EC_KEY_new_by_curve_name failed",
|
||||
__func__);
|
||||
q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
|
||||
if (q == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
if ((exponent = BN_new()) == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
buffer_get_ecpoint(&e->request,
|
||||
EC_KEY_get0_group(k->ecdsa), q);
|
||||
buffer_get_bignum2(&e->request, exponent);
|
||||
if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
|
||||
fatal("%s: EC_KEY_set_public_key failed",
|
||||
__func__);
|
||||
if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
|
||||
fatal("%s: EC_KEY_set_private_key failed",
|
||||
__func__);
|
||||
if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
|
||||
EC_KEY_get0_public_key(k->ecdsa)) != 0)
|
||||
fatal("%s: bad ECDSA public key", __func__);
|
||||
if (key_ec_validate_private(k->ecdsa) != 0)
|
||||
fatal("%s: bad ECDSA private key", __func__);
|
||||
BN_clear_free(exponent);
|
||||
EC_POINT_free(q);
|
||||
break;
|
||||
case KEY_ECDSA_CERT:
|
||||
cert = buffer_get_string(&e->request, &len);
|
||||
if ((k = key_from_blob(cert, len)) == NULL)
|
||||
fatal("Certificate parse failed");
|
||||
xfree(cert);
|
||||
key_add_private(k);
|
||||
if ((exponent = BN_new()) == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
buffer_get_bignum2(&e->request, exponent);
|
||||
if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
|
||||
fatal("%s: EC_KEY_set_private_key failed",
|
||||
__func__);
|
||||
if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
|
||||
EC_KEY_get0_public_key(k->ecdsa)) != 0 ||
|
||||
key_ec_validate_private(k->ecdsa) != 0)
|
||||
fatal("%s: bad ECDSA key", __func__);
|
||||
BN_clear_free(exponent);
|
||||
break;
|
||||
#endif /* OPENSSL_HAS_ECC */
|
||||
case KEY_RSA:
|
||||
k = key_new_private(type);
|
||||
buffer_get_bignum2(&e->request, k->rsa->n);
|
||||
@ -535,9 +592,11 @@ process_add_identity(SocketEntry *e, int version)
|
||||
buffer_get_bignum2(&e->request, k->rsa->q);
|
||||
break;
|
||||
default:
|
||||
xfree(type_name);
|
||||
buffer_clear(&e->request);
|
||||
goto send;
|
||||
}
|
||||
xfree(type_name);
|
||||
break;
|
||||
}
|
||||
/* enable blinding */
|
||||
@ -1094,7 +1153,7 @@ main(int ac, char **av)
|
||||
prctl(PR_SET_DUMPABLE, 0);
|
||||
#endif
|
||||
|
||||
SSLeay_add_all_algorithms();
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
init_rng();
|
||||
@ -1175,7 +1234,7 @@ main(int ac, char **av)
|
||||
|
||||
if (agentsocket == NULL) {
|
||||
/* Create private directory for agent socket */
|
||||
strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir);
|
||||
mktemp_proto(socket_dir, sizeof(socket_dir));
|
||||
if (mkdtemp(socket_dir) == NULL) {
|
||||
perror("mkdtemp: private socket dir");
|
||||
exit(1);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user