2013-09-19 06:09:33 +02:00
|
|
|
# auditing key-based authentication (both server and client)
|
|
|
|
# based on:
|
|
|
|
# https://bugzilla.mindrot.org/show_bug.cgi?id=1402
|
|
|
|
# https://bugzilla.mindrot.org/attachment.cgi?id=2012
|
|
|
|
# (replaces: https://bugzilla.mindrot.org/attachment.cgi?id=1975)
|
|
|
|
# by jchadima@redhat.com
|
|
|
|
|
2014-01-31 13:18:41 +01:00
|
|
|
diff --git a/openssh-6.4p1/audit-bsm.c b/openssh-6.4p1/audit-bsm.c
|
|
|
|
--- a/openssh-6.4p1/audit-bsm.c
|
|
|
|
+++ b/openssh-6.4p1/audit-bsm.c
|
2013-09-19 06:09:33 +02:00
|
|
|
@@ -401,16 +401,22 @@ audit_session_open(struct logininfo *li)
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
audit_session_close(struct logininfo *li)
|
|
|
|
{
|
|
|
|
/* not implemented */
|
|
|
|
}
|
|
|
|
|
|
|
|
+int
|
|
|
|
+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
|
|
|
|
+{
|
|
|
|
+ /* not implemented */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
void
|
|
|
|
audit_event(ssh_audit_event_t event)
|
|
|
|
{
|
|
|
|
char textbuf[BSM_TEXTBUFSZ];
|
|
|
|
static int logged_in = 0;
|
|
|
|
const char *user = the_authctxt ? the_authctxt->user : "(unknown user)";
|
|
|
|
|
|
|
|
if (cannot_audit(0))
|
2014-01-31 13:18:41 +01:00
|
|
|
diff --git a/openssh-6.4p1/audit-linux.c b/openssh-6.4p1/audit-linux.c
|
|
|
|
--- a/openssh-6.4p1/audit-linux.c
|
|
|
|
+++ b/openssh-6.4p1/audit-linux.c
|
2013-09-19 06:09:33 +02:00
|
|
|
@@ -36,16 +36,18 @@
|
|
|
|
#include "log.h"
|
|
|
|
#include "audit.h"
|
|
|
|
#include "key.h"
|
|
|
|
#include "hostfile.h"
|
|
|
|
#include "auth.h"
|
|
|
|
#include "servconf.h"
|
|
|
|
#include "canohost.h"
|
|
|
|
|
|
|
|
+#define AUDIT_LOG_SIZE 128
|
|
|
|
+
|
|
|
|
extern ServerOptions options;
|
|
|
|
extern Authctxt *the_authctxt;
|
|
|
|
extern u_int utmp_len;
|
|
|
|
const char* audit_username(void);
|
|
|
|
|
|
|
|
static void
|
|
|
|
linux_audit_user_logxxx(int uid, const char *username,
|
|
|
|
const char *hostname, const char *ip, const char *ttyn, int success, int event)
|
|
|
|
@@ -125,16 +127,47 @@ linux_audit_user_auth(int uid, const cha
|
|
|
|
rc = 0;
|
|
|
|
errno = saved_errno;
|
|
|
|
if (rc < 0) {
|
|
|
|
fatal_report:
|
|
|
|
fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+int
|
|
|
|
+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
|
|
|
|
+{
|
|
|
|
+ char buf[AUDIT_LOG_SIZE];
|
|
|
|
+ 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 */
|
|
|
|
+ }
|
|
|
|
+ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", get_remote_port());
|
|
|
|
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
|
|
|
|
+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv);
|
|
|
|
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
|
|
|
|
+ goto out;
|
|
|
|
+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d",
|
|
|
|
+ type, bits, fp, get_remote_port());
|
|
|
|
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
|
|
|
|
+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv);
|
|
|
|
+out:
|
|
|
|
+ saved_errno = errno;
|
|
|
|
+ audit_close(audit_fd);
|
|
|
|
+ errno = saved_errno;
|
|
|
|
+ /* do not report error if the error is EPERM and sshd is run as non root user */
|
|
|
|
+ return (rc >= 0) || ((rc == -EPERM) && (getuid() != 0));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static int user_login_count = 0;
|
|
|
|
|
|
|
|
/* Below is the sshd audit API code */
|
|
|
|
|
|
|
|
void
|
|
|
|
audit_connection_from(const char *host, int port)
|
|
|
|
{
|
|
|
|
/* not implemented */
|
2014-01-31 13:18:41 +01:00
|
|
|
diff --git a/openssh-6.4p1/audit.c b/openssh-6.4p1/audit.c
|
|
|
|
--- a/openssh-6.4p1/audit.c
|
|
|
|
+++ b/openssh-6.4p1/audit.c
|
2013-09-19 06:09:33 +02:00
|
|
|
@@ -31,16 +31,17 @@
|
|
|
|
|
|
|
|
#ifdef SSH_AUDIT_EVENTS
|
|
|
|
|
|
|
|
#include "audit.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "key.h"
|
|
|
|
#include "hostfile.h"
|
|
|
|
#include "auth.h"
|
|
|
|
+#include "xmalloc.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Care must be taken when using this since it WILL NOT be initialized when
|
|
|
|
* audit_connection_from() is called and MAY NOT be initialized when
|
|
|
|
* audit_event(CONNECTION_ABANDON) is called. Test for NULL before using.
|
|
|
|
*/
|
|
|
|
extern Authctxt *the_authctxt;
|
|
|
|
|
|
|
|
@@ -106,16 +107,32 @@ audit_event_lookup(ssh_audit_event_t ev)
|
|
|
|
};
|
|
|
|
|
|
|
|
for (i = 0; event_lookup[i].event != SSH_AUDIT_UNKNOWN; i++)
|
|
|
|
if (event_lookup[i].event == ev)
|
|
|
|
break;
|
|
|
|
return(event_lookup[i].name);
|
|
|
|
}
|
|
|
|
|
|
|
|
+void
|
|
|
|
+audit_key(int host_user, int *rv, const Key *key)
|
|
|
|
+{
|
|
|
|
+ char *fp;
|
|
|
|
+ const char *crypto_name;
|
|
|
|
+
|
|
|
|
+ fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX);
|
|
|
|
+ if (key->type == KEY_RSA1)
|
|
|
|
+ crypto_name = "ssh-rsa1";
|
|
|
|
+ else
|
|
|
|
+ crypto_name = key_ssh_name(key);
|
|
|
|
+ if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0)
|
|
|
|
+ *rv = 0;
|
2014-01-31 13:18:41 +01:00
|
|
|
+ free(fp);
|
2013-09-19 06:09:33 +02:00
|
|
|
+}
|
|
|
|
+
|
|
|
|
# ifndef CUSTOM_SSH_AUDIT_EVENTS
|
|
|
|
/*
|
|
|
|
* Null implementations of audit functions.
|
|
|
|
* These get used if SSH_AUDIT_EVENTS is defined but no audit module is enabled.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Called after a connection has been accepted but before any authentication
|
|
|
|
@@ -204,10 +221,22 @@ audit_run_command(const char *command)
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
audit_end_command(int handle, const char *command)
|
|
|
|
{
|
|
|
|
debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(),
|
|
|
|
audit_username(), command);
|
|
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key.
|
|
|
|
+ *
|
|
|
|
+ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key.
|
|
|
|
+ */
|
|
|
|
+int
|
|
|
|
+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
|
|
|
|
+{
|
|
|
|
+ debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s, result %d",
|
|
|
|
+ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits,
|
|
|
|
+ fp, rv);
|
|
|
|
+}
|
|
|
|
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
|
|
|
#endif /* SSH_AUDIT_EVENTS */
|
2014-01-31 13:18:41 +01:00
|
|
|
diff --git a/openssh-6.4p1/audit.h b/openssh-6.4p1/audit.h
|
|
|
|
--- a/openssh-6.4p1/audit.h
|
|
|
|
+++ b/openssh-6.4p1/audit.h
|
2013-09-19 06:09:33 +02:00
|
|
|
@@ -23,16 +23,17 @@
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _SSH_AUDIT_H
|
|
|
|
# define _SSH_AUDIT_H
|
|
|
|
|
|
|
|
#include "loginrec.h"
|
|
|
|
+#include "key.h"
|
|
|
|
|
|
|
|
enum ssh_audit_event_type {
|
|
|
|
SSH_LOGIN_EXCEED_MAXTRIES,
|
|
|
|
SSH_LOGIN_ROOT_DENIED,
|
|
|
|
SSH_AUTH_SUCCESS,
|
|
|
|
SSH_AUTH_FAIL_NONE,
|
|
|
|
SSH_AUTH_FAIL_PASSWD,
|
|
|
|
SSH_AUTH_FAIL_KBDINT, /* keyboard-interactive or challenge-response */
|
|
|
|
@@ -50,10 +51,12 @@ typedef enum ssh_audit_event_type ssh_au
|
|
|
|
void audit_connection_from(const char *, int);
|
|
|
|
void audit_event(ssh_audit_event_t);
|
|
|
|
void audit_count_session_open(void);
|
|
|
|
void audit_session_open(struct logininfo *);
|
|
|
|
void audit_session_close(struct logininfo *);
|
|
|
|
int audit_run_command(const char *);
|
|
|
|
void audit_end_command(int, const char *);
|
|
|
|
ssh_audit_event_t audit_classify_auth(const char *);
|
|
|
|
+int audit_keyusage(int, const char *, unsigned, char *, int);
|
|
|
|
+void audit_key(int, int *, const Key *);
|
|
|
|
|
|
|
|
#endif /* _SSH_AUDIT_H */
|
2014-01-31 13:18:41 +01:00
|
|
|
diff --git a/openssh-6.4p1/auth-rsa.c b/openssh-6.4p1/auth-rsa.c
|
|
|
|
--- a/openssh-6.4p1/auth-rsa.c
|
|
|
|
+++ b/openssh-6.4p1/auth-rsa.c
|
2013-09-19 06:09:33 +02:00
|
|
|
@@ -87,17 +87,20 @@ auth_rsa_generate_challenge(Key *key)
|
|
|
|
return challenge;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
|
|
|
|
{
|
|
|
|
u_char buf[32], mdbuf[16];
|
|
|
|
MD5_CTX md;
|
|
|
|
- int len;
|
|
|
|
+ int len, rv;
|
|
|
|
+#ifdef SSH_AUDIT_EVENTS
|
|
|
|
+ char *fp;
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
/* 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",
|
|
|
|
BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -108,22 +111,28 @@ auth_rsa_verify_response(Key *key, BIGNU
|
|
|
|
memset(buf, 0, 32);
|
|
|
|
BN_bn2bin(challenge, buf + 32 - len);
|
|
|
|
MD5_Init(&md);
|
|
|
|
MD5_Update(&md, buf, 32);
|
|
|
|
MD5_Update(&md, session_id, 16);
|
|
|
|
MD5_Final(mdbuf, &md);
|
|
|
|
|
|
|
|
/* Verify that the response is the original challenge. */
|
|
|
|
- if (timingsafe_bcmp(response, mdbuf, 16) != 0) {
|
|
|
|
- /* Wrong answer. */
|
|
|
|
- return (0);
|
|
|
|
+ rv = timingsafe_bcmp(response, mdbuf, 16) == 0;
|
|
|
|
+
|
|
|
|
+#ifdef SSH_AUDIT_EVENTS
|
|
|
|
+ fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX);
|
|
|
|
+ if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) == 0) {
|
|
|
|
+ debug("unsuccessful audit");
|
|
|
|
+ rv = 0;
|
|
|
|
}
|
|
|
|
- /* Correct answer. */
|
|
|
|
- return (1);
|
2014-01-31 13:18:41 +01:00
|
|
|
+ free(fp);
|
2013-09-19 06:09:33 +02:00
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Performs the RSA authentication challenge-response dialog with the client,
|
|
|
|
* and returns true (non-zero) if the client gave the correct answer to
|
|
|
|
* our challenge; returns zero if the client gives a wrong answer.
|
|
|
|
*/
|
|
|
|
|
2014-01-31 13:18:41 +01:00
|
|
|
diff --git a/openssh-6.4p1/auth.h b/openssh-6.4p1/auth.h
|
|
|
|
--- a/openssh-6.4p1/auth.h
|
|
|
|
+++ b/openssh-6.4p1/auth.h
|
|
|
|
@@ -182,16 +182,17 @@ int allowed_user(struct passwd *);
|
2013-09-19 06:09:33 +02:00
|
|
|
struct passwd * getpwnamallow(const char *user);
|
|
|
|
|
|
|
|
char *get_challenge(Authctxt *);
|
|
|
|
int verify_response(Authctxt *, const char *);
|
|
|
|
void abandon_challenge_response(Authctxt *);
|
|
|
|
|
|
|
|
char *expand_authorized_keys(const char *, struct passwd *pw);
|
|
|
|
char *authorized_principals_file(struct passwd *);
|
|
|
|
+int user_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
|
|
|
|
|
|
|
FILE *auth_openkeyfile(const char *, struct passwd *, int);
|
|
|
|
FILE *auth_openprincipals(const char *, struct passwd *, int);
|
|
|
|
int auth_key_is_revoked(Key *);
|
|
|
|
|
|
|
|
HostStatus
|
|
|
|
check_key_in_hostfiles(struct passwd *, Key *, const char *,
|
|
|
|
const char *, const char *);
|
2014-01-31 13:18:41 +01:00
|
|
|
@@ -199,16 +200,17 @@ check_key_in_hostfiles(struct passwd *,
|
2013-09-19 06:09:33 +02:00
|
|
|
/* hostkey handling */
|
|
|
|
Key *get_hostkey_by_index(int);
|
2014-01-31 13:18:41 +01:00
|
|
|
Key *get_hostkey_public_by_index(int);
|
2013-09-19 06:09:33 +02:00
|
|
|
Key *get_hostkey_public_by_type(int);
|
|
|
|
Key *get_hostkey_private_by_type(int);
|
|
|
|
int get_hostkey_index(Key *);
|
|
|
|
int ssh1_session_key(BIGNUM *);
|
2014-01-31 13:18:41 +01:00
|
|
|
void sshd_hostkey_sign(Key *, Key *, u_char **, u_int *, u_char *, u_int);
|
2013-09-19 06:09:33 +02:00
|
|
|
+int hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
|
|
|
|
|
|
|
/* debug messages during authentication */
|
|
|
|
void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
|
|
|
|
void auth_debug_send(void);
|
|
|
|
void auth_debug_reset(void);
|
|
|
|
|
|
|
|
struct passwd *fakepw(void);
|
|
|
|
|
2014-01-31 13:18:41 +01:00
|
|
|
diff --git a/openssh-6.4p1/auth2-hostbased.c b/openssh-6.4p1/auth2-hostbased.c
|
|
|
|
--- a/openssh-6.4p1/auth2-hostbased.c
|
|
|
|
+++ b/openssh-6.4p1/auth2-hostbased.c
|
|
|
|
@@ -118,33 +118,45 @@ userauth_hostbased(Authctxt *authctxt)
|
2013-09-19 06:09:33 +02:00
|
|
|
#endif
|
2014-01-31 13:18:41 +01:00
|
|
|
|
|
|
|
pubkey_auth_info(authctxt, key,
|
|
|
|
"client user \"%.100s\", client host \"%.100s\"", cuser, chost);
|
|
|
|
|
2013-09-19 06:09:33 +02:00
|
|
|
/* test for allowed key and correct signature */
|
|
|
|
authenticated = 0;
|
|
|
|
if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
|
|
|
|
- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
|
|
|
|
+ PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b),
|
|
|
|
buffer_len(&b))) == 1)
|
|
|
|
authenticated = 1;
|
|
|
|
|
|
|
|
buffer_free(&b);
|
|
|
|
done:
|
|
|
|
debug2("userauth_hostbased: authenticated %d", authenticated);
|
|
|
|
if (key != NULL)
|
|
|
|
key_free(key);
|
2014-01-31 13:18:41 +01:00
|
|
|
free(pkalg);
|
|
|
|
free(pkblob);
|
|
|
|
free(cuser);
|
|
|
|
free(chost);
|
|
|
|
free(sig);
|
2013-09-19 06:09:33 +02:00
|
|
|
return authenticated;
|
|
|
|
}
|
|
|
|
|
|
|
|
+int
|
|
|
|
+hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
|
|
|
|
+{
|
|
|
|
+ int rv;
|
|
|
|
+
|
|
|
|
+ rv = key_verify(key, sig, slen, data, datalen);
|
|
|
|
+#ifdef SSH_AUDIT_EVENTS
|
|
|
|
+ audit_key(0, &rv, key);
|
|
|
|
+#endif
|
|
|
|
+ return rv;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
/* return 1 if given hostkey is allowed */
|
|
|
|
int
|
|
|
|
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
|
|
|
|
Key *key)
|
|
|
|
{
|
|
|
|
const char *resolvedname, *ipaddr, *lookup, *reason;
|
|
|
|
HostStatus host_status;
|
|
|
|
int len;
|
2014-01-31 13:18:41 +01:00
|
|
|
diff --git a/openssh-6.4p1/auth2-pubkey.c b/openssh-6.4p1/auth2-pubkey.c
|
|
|
|
--- a/openssh-6.4p1/auth2-pubkey.c
|
|
|
|
+++ b/openssh-6.4p1/auth2-pubkey.c
|
|
|
|
@@ -147,17 +147,17 @@ userauth_pubkey(Authctxt *authctxt)
|
2013-09-19 06:09:33 +02:00
|
|
|
#ifdef DEBUG_PK
|
|
|
|
buffer_dump(&b);
|
|
|
|
#endif
|
2014-01-31 13:18:41 +01:00
|
|
|
pubkey_auth_info(authctxt, key, NULL);
|
|
|
|
|
2013-09-19 06:09:33 +02:00
|
|
|
/* test for correct signature */
|
|
|
|
authenticated = 0;
|
|
|
|
if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
|
|
|
|
- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
|
|
|
|
+ PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b),
|
|
|
|
buffer_len(&b))) == 1)
|
|
|
|
authenticated = 1;
|
|
|
|
buffer_free(&b);
|
2014-01-31 13:18:41 +01:00
|
|
|
free(sig);
|
2013-09-19 06:09:33 +02:00
|
|
|
} else {
|
|
|
|
debug("test whether pkalg/pkblob are acceptable");
|
|
|
|
packet_check_eom();
|
|
|
|
|
2014-01-31 13:18:41 +01:00
|
|
|
@@ -184,16 +184,28 @@ done:
|
2013-09-19 06:09:33 +02:00
|
|
|
debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
|
|
|
|
if (key != NULL)
|
|
|
|
key_free(key);
|
2014-01-31 13:18:41 +01:00
|
|
|
free(pkalg);
|
|
|
|
free(pkblob);
|
2013-09-19 06:09:33 +02:00
|
|
|
return authenticated;
|
|
|
|
}
|
|
|
|
|
|
|
|
+int
|
|
|
|
+user_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
|
|
|
|
+{
|
|
|
|
+ int rv;
|
|
|
|
+
|
|
|
|
+ rv = key_verify(key, sig, slen, data, datalen);
|
|
|
|
+#ifdef SSH_AUDIT_EVENTS
|
|
|
|
+ audit_key(1, &rv, key);
|
|
|
|
+#endif
|
|
|
|
+ return rv;
|
|
|
|
+}
|
|
|
|
+
|
2014-01-31 13:18:41 +01:00
|
|
|
void
|
|
|
|
pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
|
2013-09-19 06:09:33 +02:00
|
|
|
{
|
2014-01-31 13:18:41 +01:00
|
|
|
char *fp, *extra;
|
|
|
|
va_list ap;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
extra = NULL;
|
|
|
|
diff --git a/openssh-6.4p1/monitor.c b/openssh-6.4p1/monitor.c
|
|
|
|
--- a/openssh-6.4p1/monitor.c
|
|
|
|
+++ b/openssh-6.4p1/monitor.c
|
|
|
|
@@ -1362,26 +1362,30 @@ monitor_valid_hostbasedblob(u_char *data
|
2013-09-19 06:09:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
mm_answer_keyverify(int sock, Buffer *m)
|
|
|
|
{
|
|
|
|
Key *key;
|
|
|
|
u_char *signature, *data, *blob;
|
|
|
|
u_int signaturelen, datalen, bloblen;
|
|
|
|
+ int type = 0;
|
|
|
|
int verified = 0;
|
|
|
|
int valid_data = 0;
|
|
|
|
|
|
|
|
+ type = buffer_get_int(m);
|
|
|
|
blob = buffer_get_string(m, &bloblen);
|
|
|
|
signature = buffer_get_string(m, &signaturelen);
|
|
|
|
data = buffer_get_string(m, &datalen);
|
|
|
|
|
|
|
|
if (hostbased_cuser == NULL || hostbased_chost == NULL ||
|
|
|
|
!monitor_allowed_key(blob, bloblen))
|
|
|
|
fatal("%s: bad key, not previously allowed", __func__);
|
|
|
|
+ if (type != key_blobtype)
|
|
|
|
+ fatal("%s: bad key type", __func__);
|
|
|
|
|
|
|
|
key = key_from_blob(blob, bloblen);
|
|
|
|
if (key == NULL)
|
|
|
|
fatal("%s: bad public key blob", __func__);
|
|
|
|
|
|
|
|
switch (key_blobtype) {
|
|
|
|
case MM_USERKEY:
|
|
|
|
valid_data = monitor_valid_userblob(data, datalen);
|
2014-01-31 13:18:41 +01:00
|
|
|
@@ -1392,17 +1396,27 @@ mm_answer_keyverify(int sock, Buffer *m)
|
2013-09-19 06:09:33 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
valid_data = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!valid_data)
|
|
|
|
fatal("%s: bad signature data blob", __func__);
|
|
|
|
|
|
|
|
- verified = key_verify(key, signature, signaturelen, data, datalen);
|
|
|
|
+ switch (key_blobtype) {
|
|
|
|
+ case MM_USERKEY:
|
|
|
|
+ verified = user_key_verify(key, signature, signaturelen, data, datalen);
|
|
|
|
+ break;
|
|
|
|
+ case MM_HOSTKEY:
|
|
|
|
+ verified = hostbased_key_verify(key, signature, signaturelen, data, datalen);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ verified = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
debug3("%s: key %p signature %s",
|
|
|
|
__func__, key, (verified == 1) ? "verified" : "unverified");
|
|
|
|
|
|
|
|
key_free(key);
|
2014-01-31 13:18:41 +01:00
|
|
|
free(blob);
|
|
|
|
free(signature);
|
|
|
|
free(data);
|
2013-09-19 06:09:33 +02:00
|
|
|
|
2014-01-31 13:18:41 +01:00
|
|
|
diff --git a/openssh-6.4p1/monitor_wrap.c b/openssh-6.4p1/monitor_wrap.c
|
|
|
|
--- a/openssh-6.4p1/monitor_wrap.c
|
|
|
|
+++ b/openssh-6.4p1/monitor_wrap.c
|
|
|
|
@@ -428,30 +428,31 @@ mm_key_allowed(enum mm_keytype type, cha
|
2013-09-19 06:09:33 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This key verify needs to send the key type along, because the
|
|
|
|
* privileged parent makes the decision if the key is allowed
|
|
|
|
* for authentication.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
|
|
|
-mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
|
|
|
+mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
|
|
|
{
|
|
|
|
Buffer m;
|
|
|
|
u_char *blob;
|
|
|
|
u_int len;
|
|
|
|
int verified = 0;
|
|
|
|
|
|
|
|
debug3("%s entering", __func__);
|
|
|
|
|
|
|
|
/* Convert the key to a blob and the pass it over */
|
|
|
|
if (!key_to_blob(key, &blob, &len))
|
|
|
|
return (0);
|
|
|
|
|
|
|
|
buffer_init(&m);
|
|
|
|
+ buffer_put_int(&m, type);
|
|
|
|
buffer_put_string(&m, blob, len);
|
|
|
|
buffer_put_string(&m, sig, siglen);
|
|
|
|
buffer_put_string(&m, data, datalen);
|
2014-01-31 13:18:41 +01:00
|
|
|
free(blob);
|
2013-09-19 06:09:33 +02:00
|
|
|
|
|
|
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
|
|
|
|
|
|
|
|
debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
|
2014-01-31 13:18:41 +01:00
|
|
|
@@ -459,16 +460,29 @@ mm_key_verify(Key *key, u_char *sig, u_i
|
2013-09-19 06:09:33 +02:00
|
|
|
|
|
|
|
verified = buffer_get_int(&m);
|
|
|
|
|
|
|
|
buffer_free(&m);
|
|
|
|
|
|
|
|
return (verified);
|
|
|
|
}
|
|
|
|
|
|
|
|
+int
|
|
|
|
+mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
|
|
|
+{
|
|
|
|
+ return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, datalen);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int
|
|
|
|
+mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
|
|
|
+{
|
|
|
|
+ return mm_key_verify(MM_USERKEY, key, sig, siglen, data, datalen);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
/* Export key state after authentication */
|
|
|
|
Newkeys *
|
|
|
|
mm_newkeys_from_blob(u_char *blob, int blen)
|
|
|
|
{
|
|
|
|
Buffer b;
|
|
|
|
u_int len;
|
|
|
|
Newkeys *newkey = NULL;
|
|
|
|
Enc *enc;
|
2014-01-31 13:18:41 +01:00
|
|
|
diff --git a/openssh-6.4p1/monitor_wrap.h b/openssh-6.4p1/monitor_wrap.h
|
|
|
|
--- a/openssh-6.4p1/monitor_wrap.h
|
|
|
|
+++ b/openssh-6.4p1/monitor_wrap.h
|
2013-09-19 06:09:33 +02:00
|
|
|
@@ -44,17 +44,18 @@ int mm_key_sign(Key *, u_char **, u_int
|
|
|
|
void mm_inform_authserv(char *, char *);
|
|
|
|
struct passwd *mm_getpwnamallow(const char *);
|
|
|
|
char *mm_auth2_read_banner(void);
|
|
|
|
int mm_auth_password(struct Authctxt *, char *);
|
|
|
|
int mm_key_allowed(enum mm_keytype, char *, char *, Key *);
|
|
|
|
int mm_user_key_allowed(struct passwd *, Key *);
|
|
|
|
int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *);
|
|
|
|
int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
|
|
|
|
-int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);
|
|
|
|
+int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int);
|
|
|
|
+int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int);
|
|
|
|
int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
|
|
|
|
int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
|
|
|
|
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
|
|
|
|
|
|
|
|
#ifdef GSSAPI
|
|
|
|
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
|
|
|
|
OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
|
|
|
|
gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
|