gluster-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gluster-devel] [PATCH BUG:2999] Add SSL-based authorization as well as


From: Jeff Darcy
Subject: [Gluster-devel] [PATCH BUG:2999] Add SSL-based authorization as well as authentication.
Date: Fri, 24 Jun 2011 11:20:59 -0400
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Lightning/1.0b3pre Thunderbird/3.1.10

>From 621b5e9573179818f23cb6d749794d8f34b5e885 Mon Sep 17 00:00:00 2001

This code checks whether a particular user (as authenticated by SSL)
should be allowed to connect to a particular brick, instead of allowing
any authenticated user to connect to any brick.  This only matters if
multiple bricks are exported through a single protocol/server instance.
When using Gluster tools this won't be the case because volfiles are
written to associate only one brick with each server, so each server can
just use a different valid-certificate list (ssl-ca-list).  With the
CloudFS tools multiple bricks are associated with each server, so that
wouldn't work.  This method also allows unauthorized connections to fail
more cleanly at the gf_auth level with error messages and such, instead
of failing at the SSL level due to lack of an accepted certificate.

Signed-off-by: Jeff Darcy <address@hidden>
---
 rpc/rpc-lib/src/rpc-transport.h                |    1 +
 rpc/rpc-transport/socket/src/socket.c          |   30 +++++++++++++------
 xlators/protocol/auth/login/src/login.c        |   37
++++++++++++++++-------
 xlators/protocol/server/src/server-handshake.c |    9 ++++++
 4 files changed, 56 insertions(+), 21 deletions(-)

diff --git a/rpc/rpc-lib/src/rpc-transport.h
b/rpc/rpc-lib/src/rpc-transport.h
index 3161ec9..99add67 100644
--- a/rpc/rpc-lib/src/rpc-transport.h
+++ b/rpc/rpc-lib/src/rpc-transport.h
@@ -216,6 +216,7 @@ struct rpc_transport {

         struct list_head           list;
         int                        client_bind_insecure;
+       char                      *ssl_name;
 };

 struct rpc_transport_ops {
diff --git a/rpc/rpc-transport/socket/src/socket.c
b/rpc/rpc-transport/socket/src/socket.c
index 762426d..876add3 100644
--- a/rpc/rpc-transport/socket/src/socket.c
+++ b/rpc/rpc-transport/socket/src/socket.c
@@ -143,12 +143,13 @@

 int socket_init (rpc_transport_t *this);

-int
+char *
 ssl_setup_connection (socket_private_t *priv, int server)
 {
-       X509 *peer;
-       char  peer_CN[256];
-       int   ret;
+       X509 *peer          = NULL;
+       char  peer_CN[256]  = "";
+       int   ret           = -1;
+       char *value         = NULL;

        priv->ssl_ssl = SSL_new(priv->ssl_ctx);
        priv->ssl_sbio = BIO_new_socket(priv->sock,BIO_NOCLOSE);
@@ -159,6 +160,7 @@ ssl_setup_connection (socket_private_t *priv, int
server)
        else {
                ret = SSL_connect(priv->ssl_ssl);
        }
+
        if (ret >= 0) {
                gf_log(__func__,GF_LOG_DEBUG,"verify_result = %lu (%d)",
                       SSL_get_verify_result(priv->ssl_ssl), X509_V_OK);
@@ -168,6 +170,8 @@ ssl_setup_connection (socket_private_t *priv, int
server)
                                NID_commonName, peer_CN, sizeof(peer_CN)-1);
                        peer_CN[sizeof(peer_CN)-1] = '\0';
                        gf_log(__func__,GF_LOG_DEBUG,"peer CN = %s", peer_CN);
+                       /* Stop complaining, it's already length-limited. */
+                       value = gf_strdup(peer_CN);
                }
        }
        else {
@@ -181,7 +185,8 @@ ssl_setup_connection (socket_private_t *priv, int
server)
                        gf_log(__func__,GF_LOG_ERROR,"  %s",errbuf);
                }
        }
-       return ret;
+
+       return value;
 }

 int
@@ -2029,15 +2034,16 @@ int
 socket_server_event_handler (int fd, int idx, void *data,
                              int poll_in, int poll_out, int poll_err)
 {
-        rpc_transport_t             *this = NULL;
+        rpc_transport_t         *this = NULL;
         socket_private_t        *priv = NULL;
         int                      ret = 0;
         int                      new_sock = -1;
-        rpc_transport_t             *new_trans = NULL;
+        rpc_transport_t         *new_trans = NULL;
         struct sockaddr_storage  new_sockaddr = {0, };
         socklen_t                addrlen = sizeof (new_sockaddr);
         socket_private_t        *new_priv = NULL;
         glusterfs_ctx_t         *ctx = NULL;
+       char                    *cname = NULL;

         this = data;
         GF_VALIDATE_OR_GOTO ("socket", this, out);
@@ -2126,12 +2132,14 @@ socket_server_event_handler (int fd, int idx,
void *data,

                        if (priv->use_ssl) {
                                new_priv->ssl_ctx = priv->ssl_ctx;
-                               if (ssl_setup_connection(new_priv,1) < 0) {
+                               cname = ssl_setup_connection(new_priv,1);
+                               if (!cname) {
                                        gf_log(this->name,GF_LOG_ERROR,
                                               "server setup failed");
                                        close(new_sock);
                                        goto unlock;
                                }
+                               new_trans->ssl_name = cname;
                        }

                         if (!priv->bio) {
@@ -2227,6 +2235,7 @@ socket_connect (rpc_transport_t *this, int port)
         glusterfs_ctx_t         *ctx = NULL;
         sa_family_t              sa_family = {0, };
         union gf_sock_union      sock_union;
+       char                     *cname = NULL;

         GF_VALIDATE_OR_GOTO ("socket", this, err);
         GF_VALIDATE_OR_GOTO ("socket", this->private, err);
@@ -2351,14 +2360,15 @@ socket_connect (rpc_transport_t *this, int port)
                 }

                if (priv->use_ssl) {
-                       ret = ssl_setup_connection(priv,0);
-                       if (ret < 0) {
+                       cname = ssl_setup_connection(priv,0);
+                       if (!cname) {
                                gf_log(this->name,GF_LOG_ERROR,
                                        "client setup failed");
                                close(priv->sock);
                                priv->sock = -1;
                                goto unlock;
                        }
+                       this->ssl_name = cname;
                }

                 if (!priv->bio) {
diff --git a/xlators/protocol/auth/login/src/login.c
b/xlators/protocol/auth/login/src/login.c
index 81b8efa..8583548 100644
--- a/xlators/protocol/auth/login/src/login.c
+++ b/xlators/protocol/auth/login/src/login.c
@@ -40,24 +40,30 @@ auth_result_t gf_auth (dict_t *input_params, dict_t
*config_params)
         char    *username_str  = NULL;
         char    *tmp           = NULL;
         char    *username_cpy  = NULL;
+       int      using_ssl     = 0;

         username_data = dict_get (input_params, "username");
         if (!username_data) {
-                gf_log ("auth/login", GF_LOG_DEBUG,
-                        "username not found, returning DONT-CARE");
-                goto out;
+               username_data = dict_get(input_params,"ssl-name");
+               if (!username_data) {
+                       gf_log ("auth/login", GF_LOG_DEBUG,
+                               "username not found, returning DONT-CARE");
+                       goto out;
+               }
+               using_ssl = 1;
         }

         username = data_to_str (username_data);

-        password_data = dict_get (input_params, "password");
-        if (!password_data) {
-                gf_log ("auth/login", GF_LOG_WARNING,
-                        "password not found, returning DONT-CARE");
-                goto out;
-        }
-
-        password = data_to_str (password_data);
+       if (!using_ssl) {
+               password_data = dict_get (input_params, "password");
+               if (!password_data) {
+                       gf_log ("auth/login", GF_LOG_WARNING,
+                               "password not found, returning DONT-CARE");
+                       goto out;
+               }
+               password = data_to_str (password_data);
+       }

         brick_name = data_to_str (dict_get (input_params,
"remote-subvolume"));
         if (!brick_name) {
@@ -87,6 +93,15 @@ auth_result_t gf_auth (dict_t *input_params, dict_t
*config_params)

                 while (username_str) {
                         if (!fnmatch (username_str, username, 0)) {
+                               if (using_ssl) {
+                                       /*
+                                        * SSL code already did a much stronger
+                                        * kind of authentication, so we don't
+                                        * need a password.
+                                        */
+                                       result = AUTH_ACCEPT;
+                                       break;
+                               }
                                 ret = gf_asprintf (&searchstr,

"auth.login.%s.password",
                                                    username);
diff --git a/xlators/protocol/server/src/server-handshake.c
b/xlators/protocol/server/src/server-handshake.c
index 66b9ea7..2764239 100644
--- a/xlators/protocol/server/src/server-handshake.c
+++ b/xlators/protocol/server/src/server-handshake.c
@@ -409,6 +409,15 @@ server_setvolume (rpcsvc_request_t *req)
                 goto fail;
         }

+       if (req->trans->ssl_name) {
+               ret = dict_set_dynstr(params,"ssl-name",req->trans->ssl_name);
+                if (ret < 0) {
+                        gf_log (this->name, GF_LOG_DEBUG,
+                                "failed to set SSL name");
+                       /* Not fatal. */
+               }
+       }
+

         conn = server_connection_get (this, process_uuid);
         if (req->trans->xl_private != conn)
-- 
1.7.3.4



reply via email to

[Prev in Thread] Current Thread [Next in Thread]