Keep track of authenticated ID for stream peer. For SSL connections, the authenticated ID is the CN (Common Name) field from the peer's SSL certificate.
Signed-off-by: Lance Richardson <lrich...@redhat.com> --- lib/stream-provider.h | 1 + lib/stream-ssl.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ lib/stream.c | 14 ++++++++++++++ lib/stream.h | 3 +++ 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..0f60e03 100644 --- a/lib/stream-ssl.c +++ b/lib/stream-ssl.c @@ -420,6 +420,39 @@ 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; + } + + cn = (const char *)ASN1_STRING_data(cn_data); + return xstrdup(cn); +} + static int ssl_connect(struct stream *stream) { @@ -477,6 +510,17 @@ 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) { + char *ptr = strstr(cn, " id:"); + + if (ptr) { + *ptr = '\0'; + } + stream_set_peer_id(stream, cn); + free(cn); + } return 0; } } diff --git a/lib/stream.c b/lib/stream.c index f6ea849..cb4320c 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,18 @@ 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..f9bfdc8 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -53,6 +53,9 @@ 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 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev