From patchwork Thu Apr 13 15:00:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Richardson X-Patchwork-Id: 750478 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3w3kVr6CzWz9sCZ for ; Fri, 14 Apr 2017 01:00:36 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id DA8CFB47; Thu, 13 Apr 2017 15:00:32 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 2CFE58D7 for ; Thu, 13 Apr 2017 15:00:32 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id B33E8176 for ; Thu, 13 Apr 2017 15:00:31 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0E72119D00C; Thu, 13 Apr 2017 15:00:31 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 0E72119D00C Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=lrichard@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 0E72119D00C Received: from thinkcentre.localdomain.com (ovpn-120-23.rdu2.redhat.com [10.10.120.23]) by smtp.corp.redhat.com (Postfix) with ESMTP id 012A7C05BB; Thu, 13 Apr 2017 15:00:28 +0000 (UTC) From: Lance Richardson To: dev@openvswitch.org, blp@ovn.org, russell@ovn.org, mickeys.dev@gmail.com Date: Thu, 13 Apr 2017 11:00:22 -0400 Message-Id: <20170413150026.394-2-lrichard@redhat.com> In-Reply-To: <20170413150026.394-1-lrichard@redhat.com> References: <20170413150026.394-1-lrichard@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 13 Apr 2017 15:00:31 +0000 (UTC) X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC v2 1/5] stream: store stream peer id with stream state X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org 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 --- v2: - Accomodate OpenSSL 1.1 deprecation of ASN1_STRING_data(). - Added comment explaining source of "id:" in CN field. lib/stream-provider.h | 1 + lib/stream-ssl.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/stream.c | 16 ++++++++++++++++ lib/stream.h | 3 +++ 4 files changed, 71 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..4816a11 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,19 @@ 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) { + /* ovs-pki appends " id:" to the user-specified name, + * remove it if present */ + 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..f183a4d 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,20 @@ 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);