[ovs-dev] [PATCH 1/6] stream: store stream peer id with stream state
Lance Richardson
lrichard at redhat.com
Mon May 1 14:13:02 UTC 2017
Track authenticated stream peer ID. For SSL connections, the
authenticated ID is the CN (Common Name) field extracted from
the peer's SSL certificate.
Signed-off-by: Lance Richardson <lrichard at redhat.com>
---
lib/stream-provider.h | 1 +
lib/stream-ssl.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
lib/stream.c | 15 +++++++++++++++
lib/stream.h | 2 ++
4 files changed, 62 insertions(+)
diff --git a/lib/stream-provider.h b/lib/stream-provider.h
index 2226a80..ce88785 100644
--- a/lib/stream-provider.h
+++ b/lib/stream-provider.h
@@ -30,6 +30,7 @@ struct stream {
int state;
int error;
char *name;
+ char *peer_id;
};
void stream_init(struct stream *, const struct stream_class *,
diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c
index 5d88b52..b083da6 100644
--- a/lib/stream-ssl.c
+++ b/lib/stream-ssl.c
@@ -420,6 +420,44 @@ do_ca_cert_bootstrap(struct stream *stream)
return EPROTO;
}
+static char *
+get_peer_common_name(const struct ssl_stream *sslv)
+{
+ X509_NAME_ENTRY *cn_entry;
+ ASN1_STRING *cn_data;
+ X509 *peer_cert;
+ int cn_index;
+ const char *cn;
+
+ peer_cert = SSL_get_peer_certificate(sslv->ssl);
+ if (!peer_cert) {
+ return NULL;
+ }
+ cn_index = X509_NAME_get_index_by_NID(X509_get_subject_name(peer_cert),
+ NID_commonName, -1);
+ if (cn_index < 0) {
+ return NULL;
+ }
+
+ cn_entry = X509_NAME_get_entry(X509_get_subject_name(peer_cert), cn_index);
+ if (!cn_entry) {
+ return NULL;
+ }
+
+ cn_data = X509_NAME_ENTRY_get_data(cn_entry);
+ if (!cn_data) {
+ return NULL;
+ }
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ /* ASN1_STRING_data() is deprecated as of OpenSSL version 1.1 */
+ cn = (const char *)ASN1_STRING_data(cn_data);
+#else
+ cn = (const char *)ASN1_STRING_get0_data(cn_data);
+ #endif
+ return xstrdup(cn);
+}
+
static int
ssl_connect(struct stream *stream)
{
@@ -477,6 +515,12 @@ ssl_connect(struct stream *stream)
VLOG_INFO("rejecting SSL connection during bootstrap race window");
return EPROTO;
} else {
+ char *cn = get_peer_common_name(sslv);
+
+ if (cn) {
+ stream_set_peer_id(stream, cn);
+ free(cn);
+ }
return 0;
}
}
diff --git a/lib/stream.c b/lib/stream.c
index f6ea849..5959309 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -278,8 +278,10 @@ stream_close(struct stream *stream)
{
if (stream != NULL) {
char *name = stream->name;
+ char *peer_id = stream->peer_id;
(stream->class->close)(stream);
free(name);
+ free(peer_id);
}
}
@@ -430,6 +432,19 @@ stream_send_wait(struct stream *stream)
stream_wait(stream, STREAM_SEND);
}
+void
+stream_set_peer_id(struct stream *stream, const char *peer_id)
+{
+ free(stream->peer_id);
+ stream->peer_id = xstrdup(peer_id);
+}
+
+const char *
+stream_get_peer_id(const struct stream *stream)
+{
+ return stream->peer_id;
+}
+
/* Given 'name', a pstream name in the form "TYPE:ARGS", stores the class
* named "TYPE" into '*classp' and returns 0. Returns EAFNOSUPPORT and stores
* a null pointer into '*classp' if 'name' is in the wrong form or if no such
diff --git a/lib/stream.h b/lib/stream.h
index f8e1891..7d35fa6 100644
--- a/lib/stream.h
+++ b/lib/stream.h
@@ -53,6 +53,8 @@ void stream_wait(struct stream *, enum stream_wait_type);
void stream_connect_wait(struct stream *);
void stream_recv_wait(struct stream *);
void stream_send_wait(struct stream *);
+void stream_set_peer_id(struct stream *, const char *);
+const char *stream_get_peer_id(const struct stream *);
/* Passive streams: listeners for incoming stream connections. */
int pstream_verify_name(const char *name);
--
2.7.4
More information about the dev
mailing list