From caa8a4ea50734378e7e19f70b39a837c58e9d229 Mon Sep 17 00:00:00 2001 From: Jeff Darcy Date: Thu, 17 Apr 2014 23:21:05 +0000 Subject: rpc/auth: allow SSL identity to be used for authorization Access to a volume is now controlled by the following options, based on whether SSL is enabled or not. * server.ssl-allow: get identity from certificate, no password needed * auth.allow: get identity and matching password from command line It is not possible to allow both simultaneously, since the connection itself is either using SSL or it isn't. Change-Id: I5a5be66520f56778563d62f4b3ab35c66cc41ac0 BUG: 1114604 Signed-off-by: Jeff Darcy Reviewed-on: http://review.gluster.org/3695 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/mgmt/glusterd/src/glusterd-volgen.c | 10 ++++ xlators/mgmt/glusterd/src/glusterd-volume-set.c | 6 ++ xlators/protocol/auth/login/src/login.c | 78 ++++++++++++++++--------- xlators/protocol/server/src/server-handshake.c | 7 +++ 4 files changed, 72 insertions(+), 29 deletions(-) (limited to 'xlators') diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 664c37af9d6..777e69535df 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -1517,6 +1517,7 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, gf_boolean_t quota_enabled = _gf_true; gf_boolean_t pgfid_feat = _gf_false; char *value = NULL; + char *ssl_user = NULL; brickinfo = param; path = brickinfo->path; @@ -1816,6 +1817,15 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, return -1; } + if (dict_get_str (volinfo->dict, "auth.ssl-allow", &ssl_user) == 0) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "auth.login.%s.ssl-allow", path); + + ret = xlator_set_option (xl, key, ssl_user); + if (ret) + return -1; + } + ret = volgen_graph_set_options_generic (graph, set_dict, (xlator && loglevel) ? (void *)set_dict : volinfo, (xlator && loglevel) ? &server_spec_extended_option_handler : diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index b1d3fe54f88..4a0a50dfe66 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -950,6 +950,12 @@ struct volopt_map_entry glusterd_volopt_map[] = { .type = NO_DOC, .op_version = 2 }, + { .key = "auth.ssl-allow", + .voltype = "protocol/server", + .option = "!ssl-allow", + .type = NO_DOC, + .op_version = GD_OP_VERSION_3_6_0, + }, { .key = "server.manage-gids", .voltype = "protocol/server", .op_version = GD_OP_VERSION_3_6_0, diff --git a/xlators/protocol/auth/login/src/login.c b/xlators/protocol/auth/login/src/login.c index c2f0bf0d0c7..56b93a9f9e9 100644 --- a/xlators/protocol/auth/login/src/login.c +++ b/xlators/protocol/auth/login/src/login.c @@ -19,36 +19,43 @@ auth_result_t gf_auth (dict_t *input_params, dict_t *config_params) { auth_result_t result = AUTH_DONT_CARE; - int ret = 0; - data_t *allow_user = NULL; - data_t *username_data = NULL; - data_t *passwd_data = NULL; - data_t *password_data = NULL; - char *username = NULL; - char *password = NULL; - char *brick_name = NULL; - char *searchstr = NULL; - char *username_str = NULL; - char *tmp = NULL; - char *username_cpy = NULL; - - 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; + int ret = 0; + data_t *allow_user = NULL; + data_t *username_data = NULL; + data_t *passwd_data = NULL; + data_t *password_data = NULL; + char *username = NULL; + char *password = NULL; + char *brick_name = NULL; + char *searchstr = NULL; + char *username_str = NULL; + char *tmp = NULL; + char *username_cpy = NULL; + gf_boolean_t using_ssl = _gf_false; + + username_data = dict_get (input_params, "ssl-name"); + if (username_data) { + gf_log ("auth/login", GF_LOG_INFO, + "connecting user name: %s", username_data->data); + using_ssl = _gf_true; + result = AUTH_REJECT; } - - 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; + else { + 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; + } + 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); } - - password = data_to_str (password_data); + username = data_to_str (username_data); brick_name = data_to_str (dict_get (input_params, "remote-subvolume")); if (!brick_name) { @@ -58,7 +65,8 @@ auth_result_t gf_auth (dict_t *input_params, dict_t *config_params) goto out; } - ret = gf_asprintf (&searchstr, "auth.login.%s.allow", brick_name); + ret = gf_asprintf (&searchstr, "auth.login.%s.%s", brick_name, + using_ssl ? "ssl-allow" : "allow"); if (-1 == ret) { gf_log ("auth/login", GF_LOG_WARNING, "asprintf failed while setting search string, " @@ -70,14 +78,26 @@ auth_result_t gf_auth (dict_t *input_params, dict_t *config_params) GF_FREE (searchstr); if (allow_user) { + gf_log ("auth/login", GF_LOG_INFO, + "allowed user names: %s", allow_user->data); username_cpy = gf_strdup (allow_user->data); if (!username_cpy) goto out; username_str = strtok_r (username_cpy, " ,", &tmp); + /* + * We have to match a user's *authenticated* name to one in the + * list. If we're using SSL, they're already authenticated. + * Otherwise, they need a matching password to complete the + * process. + */ while (username_str) { if (!fnmatch (username_str, username, 0)) { + if (using_ssl) { + 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 6b1a39936f4..98418e77893 100644 --- a/xlators/protocol/server/src/server-handshake.c +++ b/xlators/protocol/server/src/server-handshake.c @@ -450,6 +450,13 @@ server_setvolume (rpcsvc_request_t *req) req->trans->xl_private = client; auth_set_username_passwd (params, config_params, client); + if (req->trans->ssl_name) { + if (dict_set_str(params,"ssl-name",req->trans->ssl_name) != 0) { + gf_log (this->name, GF_LOG_WARNING, + "failed to set ssl_name %s", req->trans->ssl_name); + /* Not fatal, auth will just fail. */ + } + } ret = dict_get_int32 (params, "fops-version", &fop_version); if (ret < 0) { -- cgit