summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaushal M <kaushal@redhat.com>2015-04-02 23:06:18 +0530
committerKrishnan Parthasarathi <kparthas@redhat.com>2015-04-09 12:05:09 +0000
commite0de0cd9b24169b90c95e1f6a87f05c060185089 (patch)
tree557ab813c610f6f2f7ce1764ec1e4b9763e58d29
parent026d59f04b4226c646c6bd9ac1018863057b02c1 (diff)
glusterd: Better GlusterD handshake request validation
To allow handshake requests to be validated correctly in a multi network environment, the request validation process has been improved. The handshake request initiator will add it's peer ID the request. The handshake request reciever will allow a request (as before) if, - it has no peers, or - the request came from a known peer Identifying the known peer is done as follows. - If the request contains a peer ID, it is matched against the IDs in the peer list. If a match is found, the request is allowed. - The address of the incoming request is matched against the peer addresses in the peer list. If a match is found, the request is allowed. - Otherwise, the request if disallowed Change-Id: I9eabe2935d16276bb147dfeebf8c8beb08e01411 BUG: 1207611 Signed-off-by: Kaushal M <kaushal@redhat.com> Reviewed-on: http://review.gluster.org/10122 Reviewed-by: Atin Mukherjee <amukherj@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com> Tested-by: Krishnan Parthasarathi <kparthas@redhat.com>
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index 850427714c0..bc00e99b62f 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -38,6 +38,7 @@ extern struct rpc_clnt_program gd_mgmt_v3_prog;
#define TRUSTED_PREFIX "trusted-"
+#define GD_PEER_ID_KEY "peer-id"
typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *data);
@@ -955,14 +956,20 @@ out:
* Requests are allowed if,
* - glusterd has no peers, or
* - the request came from a known peer
+ * A known peer is identified using the following steps
+ * - the dict is checked for a peer uuid, which if present is matched with the
+ * peer list, else
+ * - the incoming request address is matched with the peer list
*/
gf_boolean_t
-gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req)
+gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req, dict_t *dict)
{
int ret = -1;
char hostname[UNIX_PATH_MAX + 1] = {0,};
glusterd_peerinfo_t *peer = NULL;
xlator_t *this = NULL;
+ char *uuid_str = NULL;
+ uuid_t peer_uuid = {0,};
this = THIS;
GF_ASSERT (this);
@@ -970,6 +977,19 @@ gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req)
if (!glusterd_have_peers ())
return _gf_true;
+ ret = dict_get_str (dict, GD_PEER_ID_KEY, &uuid_str);
+ /* Try to match uuid only if available, don't fail as older peers will
+ * not send a uuid
+ */
+ if (!ret) {
+ gf_uuid_parse (uuid_str, peer_uuid);
+ rcu_read_lock ();
+ ret = (glusterd_peerinfo_find (peer_uuid, NULL) != NULL);
+ rcu_read_unlock ();
+ if (ret)
+ return _gf_true;
+ }
+
/* If you cannot get the hostname, you cannot authenticate */
ret = glusterd_remote_hostname_get (req, hostname, sizeof (hostname));
if (ret)
@@ -999,16 +1019,11 @@ __glusterd_mgmt_hndsk_versions (rpcsvc_request_t *req)
int op_errno = EINVAL;
gf_mgmt_hndsk_req args = {{0,},};
gf_mgmt_hndsk_rsp rsp = {0,};
+ dict_t *args_dict = NULL;
this = THIS;
conf = this->private;
- /* Check if we can service the request */
- if (!gd_validate_mgmt_hndsk_req (req)) {
- ret = -1;
- goto out;
- }
-
ret = xdr_to_generic (req->msg[0], &args,
(xdrproc_t)xdr_gf_mgmt_hndsk_req);
if (ret < 0) {
@@ -1017,6 +1032,16 @@ __glusterd_mgmt_hndsk_versions (rpcsvc_request_t *req)
goto out;
}
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, args_dict, args.hndsk.hndsk_val,
+ (args.hndsk.hndsk_len), ret, op_errno,
+ out);
+
+ /* Check if we can service the request */
+ if (!gd_validate_mgmt_hndsk_req (req, args_dict)) {
+ ret = -1;
+ goto out;
+ }
+
dict = dict_new ();
if (!dict)
goto out;
@@ -1093,12 +1118,6 @@ __glusterd_mgmt_hndsk_versions_ack (rpcsvc_request_t *req)
this = THIS;
conf = this->private;
- /* Check if we can service the request */
- if (!gd_validate_mgmt_hndsk_req (req)) {
- ret = -1;
- goto out;
- }
-
ret = xdr_to_generic (req->msg[0], &args,
(xdrproc_t)xdr_gf_mgmt_hndsk_req);
if (ret < 0) {
@@ -1813,7 +1832,9 @@ glusterd_mgmt_handshake (xlator_t *this, glusterd_peerctx_t *peerctx)
call_frame_t *frame = NULL;
gf_mgmt_hndsk_req req = {{0,},};
glusterd_peerinfo_t *peerinfo = NULL;
+ dict_t *req_dict = NULL;
int ret = -1;
+ int op_errno = EINVAL;
frame = create_frame (this, this->ctx->pool);
if (!frame)
@@ -1821,6 +1842,21 @@ glusterd_mgmt_handshake (xlator_t *this, glusterd_peerctx_t *peerctx)
frame->local = peerctx;
+ req_dict = dict_new ();
+ if (!req_dict)
+ goto out;
+
+ ret = dict_set_dynstr (req_dict, GD_PEER_ID_KEY,
+ gf_strdup (uuid_utoa (MY_UUID)));
+ if (ret) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "failed to set peer ID in dict");
+ goto out;
+ }
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, req_dict, (&req.hndsk.hndsk_val),
+ req.hndsk.hndsk_len, op_errno, out);
+
rcu_read_lock ();
peerinfo = glusterd_peerinfo_find (peerctx->peerid, peerctx->peername);