|
|
0d097b |
From f9b3c0d1009da8d8dbe273c38d6725100789e57b Mon Sep 17 00:00:00 2001
|
|
|
0d097b |
From: Sumit Bose <sbose@redhat.com>
|
|
|
0d097b |
Date: Wed, 8 Jan 2020 13:46:22 +0100
|
|
|
0d097b |
Subject: [PATCH 26/27] ssh: do not mix different certificate lists
|
|
|
0d097b |
MIME-Version: 1.0
|
|
|
0d097b |
Content-Type: text/plain; charset=UTF-8
|
|
|
0d097b |
Content-Transfer-Encoding: 8bit
|
|
|
0d097b |
|
|
|
0d097b |
There was a list of binary certificates and a list with base64 encoded
|
|
|
0d097b |
ones which might be different depending on the active matching rules.
|
|
|
0d097b |
Only the base64 one with the filtered results should be used.
|
|
|
0d097b |
|
|
|
0d097b |
Related to https://pagure.io/SSSD/sssd/issue/4121
|
|
|
0d097b |
|
|
|
0d097b |
Reviewed-by: Tomáš Halman <thalman@redhat.com>
|
|
|
0d097b |
---
|
|
|
0d097b |
src/tests/cmocka/test_cert_utils.c | 80 +++++++++++++++++++++++++++
|
|
|
0d097b |
src/util/cert.h | 3 +
|
|
|
0d097b |
src/util/cert/cert_common.c | 20 +++++++
|
|
|
0d097b |
src/util/cert/cert_common_p11_child.c | 12 ++--
|
|
|
0d097b |
4 files changed, 108 insertions(+), 7 deletions(-)
|
|
|
0d097b |
|
|
|
0d097b |
diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c
|
|
|
0d097b |
index 325e49f00..c2c9ca270 100644
|
|
|
0d097b |
--- a/src/tests/cmocka/test_cert_utils.c
|
|
|
0d097b |
+++ b/src/tests/cmocka/test_cert_utils.c
|
|
|
0d097b |
@@ -711,6 +711,84 @@ void test_cert_to_ssh_2keys_with_certmap_send(void **state)
|
|
|
0d097b |
talloc_free(ev);
|
|
|
0d097b |
}
|
|
|
0d097b |
|
|
|
0d097b |
+void test_cert_to_ssh_2keys_with_certmap_2_done(struct tevent_req *req)
|
|
|
0d097b |
+{
|
|
|
0d097b |
+ int ret;
|
|
|
0d097b |
+ struct test_state *ts = tevent_req_callback_data(req, struct test_state);
|
|
|
0d097b |
+ struct ldb_val *keys;
|
|
|
0d097b |
+ uint8_t *exp_key;
|
|
|
0d097b |
+ size_t exp_key_size;
|
|
|
0d097b |
+ size_t valid_keys;
|
|
|
0d097b |
+
|
|
|
0d097b |
+ assert_non_null(ts);
|
|
|
0d097b |
+ ts->done = true;
|
|
|
0d097b |
+
|
|
|
0d097b |
+ ret = cert_to_ssh_key_recv(req, ts, &keys, &valid_keys);
|
|
|
0d097b |
+ talloc_free(req);
|
|
|
0d097b |
+ assert_int_equal(ret, 0);
|
|
|
0d097b |
+ assert_non_null(keys[0].data);
|
|
|
0d097b |
+ assert_int_equal(valid_keys, 1);
|
|
|
0d097b |
+
|
|
|
0d097b |
+ exp_key = sss_base64_decode(ts, SSSD_TEST_CERT_SSH_KEY_0002, &exp_key_size);
|
|
|
0d097b |
+ assert_non_null(exp_key);
|
|
|
0d097b |
+ assert_int_equal(keys[0].length, exp_key_size);
|
|
|
0d097b |
+ assert_memory_equal(keys[0].data, exp_key, exp_key_size);
|
|
|
0d097b |
+ talloc_free(exp_key);
|
|
|
0d097b |
+
|
|
|
0d097b |
+ talloc_free(keys);
|
|
|
0d097b |
+ sss_certmap_free_ctx(ts->sss_certmap_ctx);
|
|
|
0d097b |
+}
|
|
|
0d097b |
+
|
|
|
0d097b |
+void test_cert_to_ssh_2keys_with_certmap_2_send(void **state)
|
|
|
0d097b |
+{
|
|
|
0d097b |
+ int ret;
|
|
|
0d097b |
+ struct tevent_context *ev;
|
|
|
0d097b |
+ struct tevent_req *req;
|
|
|
0d097b |
+ struct ldb_val val[2];
|
|
|
0d097b |
+
|
|
|
0d097b |
+ struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
|
|
|
0d097b |
+ assert_non_null(ts);
|
|
|
0d097b |
+ ts->done = false;
|
|
|
0d097b |
+
|
|
|
0d097b |
+ ret = sss_certmap_init(ts, NULL, NULL, &ts->sss_certmap_ctx);
|
|
|
0d097b |
+ assert_int_equal(ret, EOK);
|
|
|
0d097b |
+
|
|
|
0d097b |
+ ret = sss_certmap_add_rule(ts->sss_certmap_ctx, -1,
|
|
|
0d097b |
+ "<SUBJECT>CN=SSSD test cert 0002,.*", NULL,
|
|
|
0d097b |
+ NULL);
|
|
|
0d097b |
+ assert_int_equal(ret, EOK);
|
|
|
0d097b |
+
|
|
|
0d097b |
+ val[0].data = sss_base64_decode(ts, SSSD_TEST_CERT_0001,
|
|
|
0d097b |
+ &val[0].length);
|
|
|
0d097b |
+ assert_non_null(val[0].data);
|
|
|
0d097b |
+
|
|
|
0d097b |
+ val[1].data = sss_base64_decode(ts, SSSD_TEST_CERT_0002,
|
|
|
0d097b |
+ &val[1].length);
|
|
|
0d097b |
+ assert_non_null(val[1].data);
|
|
|
0d097b |
+
|
|
|
0d097b |
+ ev = tevent_context_init(ts);
|
|
|
0d097b |
+ assert_non_null(ev);
|
|
|
0d097b |
+
|
|
|
0d097b |
+ req = cert_to_ssh_key_send(ts, ev, -1, P11_CHILD_TIMEOUT,
|
|
|
0d097b |
+#ifdef HAVE_NSS
|
|
|
0d097b |
+ "sql:" ABS_BUILD_DIR "/src/tests/test_CA/p11_nssdb",
|
|
|
0d097b |
+#else
|
|
|
0d097b |
+ ABS_BUILD_DIR "/src/tests/test_CA/SSSD_test_CA.pem",
|
|
|
0d097b |
+#endif
|
|
|
0d097b |
+ ts->sss_certmap_ctx, 2, &val[0], NULL);
|
|
|
0d097b |
+ assert_non_null(req);
|
|
|
0d097b |
+
|
|
|
0d097b |
+ tevent_req_set_callback(req, test_cert_to_ssh_2keys_with_certmap_2_done, ts);
|
|
|
0d097b |
+
|
|
|
0d097b |
+ while (!ts->done) {
|
|
|
0d097b |
+ tevent_loop_once(ev);
|
|
|
0d097b |
+ }
|
|
|
0d097b |
+
|
|
|
0d097b |
+ talloc_free(val[0].data);
|
|
|
0d097b |
+ talloc_free(val[1].data);
|
|
|
0d097b |
+ talloc_free(ev);
|
|
|
0d097b |
+}
|
|
|
0d097b |
+
|
|
|
0d097b |
int main(int argc, const char *argv[])
|
|
|
0d097b |
{
|
|
|
0d097b |
poptContext pc;
|
|
|
0d097b |
@@ -746,6 +824,8 @@ int main(int argc, const char *argv[])
|
|
|
0d097b |
setup, teardown),
|
|
|
0d097b |
cmocka_unit_test_setup_teardown(test_cert_to_ssh_2keys_with_certmap_send,
|
|
|
0d097b |
setup, teardown),
|
|
|
0d097b |
+ cmocka_unit_test_setup_teardown(test_cert_to_ssh_2keys_with_certmap_2_send,
|
|
|
0d097b |
+ setup, teardown),
|
|
|
0d097b |
#endif
|
|
|
0d097b |
};
|
|
|
0d097b |
|
|
|
0d097b |
diff --git a/src/util/cert.h b/src/util/cert.h
|
|
|
0d097b |
index e0d44e3d6..d038a99f6 100644
|
|
|
0d097b |
--- a/src/util/cert.h
|
|
|
0d097b |
+++ b/src/util/cert.h
|
|
|
0d097b |
@@ -52,6 +52,9 @@ errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx,
|
|
|
0d097b |
uint8_t *der_blob, size_t der_size,
|
|
|
0d097b |
uint8_t **key_blob, size_t *key_size);
|
|
|
0d097b |
|
|
|
0d097b |
+errno_t get_ssh_key_from_derb64(TALLOC_CTX *mem_ctx, const char *derb64,
|
|
|
0d097b |
+ uint8_t **key_blob, size_t *key_size);
|
|
|
0d097b |
+
|
|
|
0d097b |
struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
|
|
|
0d097b |
struct tevent_context *ev,
|
|
|
0d097b |
int child_debug_fd, time_t timeout,
|
|
|
0d097b |
diff --git a/src/util/cert/cert_common.c b/src/util/cert/cert_common.c
|
|
|
0d097b |
index 766877089..511fddd4d 100644
|
|
|
0d097b |
--- a/src/util/cert/cert_common.c
|
|
|
0d097b |
+++ b/src/util/cert/cert_common.c
|
|
|
0d097b |
@@ -206,3 +206,23 @@ done:
|
|
|
0d097b |
|
|
|
0d097b |
return ret;
|
|
|
0d097b |
}
|
|
|
0d097b |
+
|
|
|
0d097b |
+errno_t get_ssh_key_from_derb64(TALLOC_CTX *mem_ctx, const char *derb64,
|
|
|
0d097b |
+ uint8_t **key_blob, size_t *key_size)
|
|
|
0d097b |
+{
|
|
|
0d097b |
+ int ret;
|
|
|
0d097b |
+ uint8_t *der_blob;
|
|
|
0d097b |
+ size_t der_size;
|
|
|
0d097b |
+
|
|
|
0d097b |
+ der_blob = sss_base64_decode(mem_ctx, derb64, &der_size);
|
|
|
0d097b |
+ if (der_blob == NULL) {
|
|
|
0d097b |
+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n");
|
|
|
0d097b |
+ return EIO;
|
|
|
0d097b |
+ }
|
|
|
0d097b |
+
|
|
|
0d097b |
+ ret = get_ssh_key_from_cert(mem_ctx, der_blob, der_size,
|
|
|
0d097b |
+ key_blob, key_size);
|
|
|
0d097b |
+ talloc_free(der_blob);
|
|
|
0d097b |
+
|
|
|
0d097b |
+ return ret;
|
|
|
0d097b |
+}
|
|
|
0d097b |
diff --git a/src/util/cert/cert_common_p11_child.c b/src/util/cert/cert_common_p11_child.c
|
|
|
0d097b |
index 80c10eff1..1846ff89a 100644
|
|
|
0d097b |
--- a/src/util/cert/cert_common_p11_child.c
|
|
|
0d097b |
+++ b/src/util/cert/cert_common_p11_child.c
|
|
|
0d097b |
@@ -28,7 +28,6 @@ struct cert_to_ssh_key_state {
|
|
|
0d097b |
time_t timeout;
|
|
|
0d097b |
const char **extra_args;
|
|
|
0d097b |
const char **certs;
|
|
|
0d097b |
- struct ldb_val *bin_certs;
|
|
|
0d097b |
struct ldb_val *keys;
|
|
|
0d097b |
size_t cert_count;
|
|
|
0d097b |
size_t iter;
|
|
|
0d097b |
@@ -74,7 +73,6 @@ struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
|
|
|
0d097b |
state->child_debug_fd = (child_debug_fd == -1) ? STDERR_FILENO
|
|
|
0d097b |
: child_debug_fd;
|
|
|
0d097b |
state->timeout = timeout;
|
|
|
0d097b |
- state->bin_certs = bin_certs;
|
|
|
0d097b |
state->io = talloc(state, struct child_io_fds);
|
|
|
0d097b |
if (state->io == NULL) {
|
|
|
0d097b |
DEBUG(SSSDBG_OP_FAILURE, "talloc failed.\n");
|
|
|
0d097b |
@@ -138,6 +136,7 @@ struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
|
|
|
0d097b |
ret = EINVAL;
|
|
|
0d097b |
goto done;
|
|
|
0d097b |
}
|
|
|
0d097b |
+
|
|
|
0d097b |
state->cert_count++;
|
|
|
0d097b |
}
|
|
|
0d097b |
|
|
|
0d097b |
@@ -289,11 +288,10 @@ static void cert_to_ssh_key_done(int child_status,
|
|
|
0d097b |
if (valid) {
|
|
|
0d097b |
DEBUG(SSSDBG_TRACE_LIBS, "Certificate [%s] is valid.\n",
|
|
|
0d097b |
state->certs[state->iter]);
|
|
|
0d097b |
- ret = get_ssh_key_from_cert(state->keys,
|
|
|
0d097b |
- state->bin_certs[state->iter].data,
|
|
|
0d097b |
- state->bin_certs[state->iter].length,
|
|
|
0d097b |
- &state->keys[state->iter].data,
|
|
|
0d097b |
- &state->keys[state->iter].length);
|
|
|
0d097b |
+ ret = get_ssh_key_from_derb64(state->keys,
|
|
|
0d097b |
+ state->certs[state->iter],
|
|
|
0d097b |
+ &state->keys[state->iter].data,
|
|
|
0d097b |
+ &state->keys[state->iter].length);
|
|
|
0d097b |
if (ret == EOK) {
|
|
|
0d097b |
state->valid_keys++;
|
|
|
0d097b |
} else {
|
|
|
0d097b |
--
|
|
|
0d097b |
2.20.1
|
|
|
0d097b |
|