From 96b687b9b8d58fc70dfaaed42dbe1b35799117f8 Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Tue, 31 Mar 2009 06:22:16 -0700 Subject: Add new type of option type INTERNET_ADDRESS for validation - used to validate options like remote-host, bind-address. - Also validate options of translators created during fetch of volume specification file from remote server. Signed-off-by: Anand V. Avati --- glusterfsd/src/fetch-spec.c | 34 +++++-- libglusterfs/src/xlator.c | 125 ++++++++++++++++++++++++++ libglusterfs/src/xlator.h | 1 + transport/socket/src/socket.c | 2 +- xlators/protocol/client/src/client-protocol.c | 2 +- 5 files changed, 157 insertions(+), 7 deletions(-) diff --git a/glusterfsd/src/fetch-spec.c b/glusterfsd/src/fetch-spec.c index 6f2b991bc..f914a416d 100644 --- a/glusterfsd/src/fetch-spec.c +++ b/glusterfsd/src/fetch-spec.c @@ -107,16 +107,21 @@ get_shrub (glusterfs_ctx_t *ctx, const char *transport, uint32_t remote_port) { + volume_opt_list_t *vol_opt = NULL; + xlator_t *trav = NULL; int ret = 0; xlator_t *top = NULL; xlator_t *trans = NULL; xlator_list_t *parent = NULL, *tmp = NULL; - + top = CALLOC (1, sizeof (*top)); ERR_ABORT (top); trans = CALLOC (1, sizeof (*trans)); ERR_ABORT (trans); + INIT_LIST_HEAD (&top->volume_options); + INIT_LIST_HEAD (&trans->volume_options); + top->name = "top"; top->ctx = ctx; top->next = trans; @@ -145,9 +150,10 @@ get_shrub (glusterfs_ctx_t *ctx, } /* TODO: log on failure to set dict */ - if (remote_host) - ret = dict_set_static_ptr (trans->options, "remote-host", - (char *)remote_host); + if (remote_host) { + ret = dict_set (trans->options, "remote-host", + str_to_data ((char *)remote_host)); + } if (remote_port) ret = dict_set_uint32 (trans->options, "remote-port", @@ -174,7 +180,25 @@ get_shrub (glusterfs_ctx_t *ctx, } xlator_set_type (trans, "protocol/client"); - + + trav = top; + while (trav) { + /* Get the first volume_option */ + if (!list_empty (&trav->volume_options)) { + list_for_each_entry (vol_opt, + &trav->volume_options, list) + break; + if ((ret = + validate_xlator_volume_options (trav, + vol_opt->given_opt)) < 0) { + gf_log (trav->name, GF_LOG_ERROR, + "validating translator failed"); + return NULL; + } + } + trav = trav->next; + } + if (xlator_tree_init (top) != 0) return NULL; diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 986608153..6af2c8e8f 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -114,6 +114,124 @@ fill_defaults (xlator_t *xl) return; } +/* RFC 1123 & 952 */ +static char +valid_host_name (char *address, int length) +{ + int i = 0; + char ret = 1; + + if ((length > 24) || (length == 1)) { + ret = 0; + goto out; + } + + if (!isalnum (address[length - 1])) { + ret = 0; + goto out; + } + + for (i = 0; i < length; i++) { + if (!isalnum (address[i]) && (address[i] != '.') + && (address[i] != '-')) { + ret = 0; + goto out; + } + } + +out: + return ret; +} + +static char +valid_ipv4_address (char *address, int length) +{ + int octets = 0; + int value = 0; + char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL; + char ret = 1; + + prev = tmp = strdup (address); + prev = strtok_r (tmp, ".", &ptr); + + while (prev != NULL) + { + octets++; + value = strtol (prev, &endptr, 10); + if ((value > 255) || (value < 0) || (endptr != NULL)) { + ret = 0; + goto out; + } + + prev = strtok_r (NULL, ".", &ptr); + } + + if (octets != 4) { + ret = 0; + } + +out: + FREE (tmp); + return ret; +} + +static char +valid_ipv6_address (char *address, int length) +{ + int hex_numbers = 0; + int value = 0; + char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL; + char ret = 1; + + tmp = strdup (address); + prev = strtok_r (tmp, ":", &ptr); + + while (prev != NULL) + { + hex_numbers++; + value = strtol (prev, &endptr, 16); + if ((value > 0xffff) || (value < 0) || (endptr != NULL)) { + ret = 0; + goto out; + } + + prev = strtok_r (NULL, ":", &ptr); + } + + if (hex_numbers > 8) { + ret = 0; + } + +out: + FREE (tmp); + return ret; +} + +static char +valid_internet_address (char *address) +{ + char ret = 0; + int length = 0; + + if (address == NULL) { + goto out; + } + + length = strlen (address); + if (length == 0) { + goto out; + } + + if (valid_ipv4_address (address, length) + || valid_ipv6_address (address, length) + || valid_host_name (address, length)) { + ret = 1; + } + +out: + return ret; +} + int _volume_option_value_validate (xlator_t *xl, data_pair_t *pair, @@ -380,6 +498,13 @@ _volume_option_value_validate (xlator_t *xl, ret = 0; } break; + case GF_OPTION_TYPE_INTERNET_ADDRESS: + { + if (valid_internet_address (pair->value->data)) { + ret = 0; + } + } + break; case GF_OPTION_TYPE_ANY: /* NO CHECK */ ret = 0; diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 2f35643c3..fe50c8147 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -809,6 +809,7 @@ typedef enum { GF_OPTION_TYPE_PATH, GF_OPTION_TYPE_TIME, GF_OPTION_TYPE_DOUBLE, + GF_OPTION_TYPE_INTERNET_ADDRESS, } volume_option_type_t; #define ZR_VOLUME_MAX_NUM_KEY 4 diff --git a/transport/socket/src/socket.c b/transport/socket/src/socket.c index ea9555bcf..fe18808a0 100644 --- a/transport/socket/src/socket.c +++ b/transport/socket/src/socket.c @@ -1347,7 +1347,7 @@ struct volume_options options[] = { .type = GF_OPTION_TYPE_INT }, { .key = {"transport.socket.bind-address", "bind-address" }, - .type = GF_OPTION_TYPE_ANY + .type = GF_OPTION_TYPE_INTERNET_ADDRESS }, { .key = {"transport.socket.connect-path", "connect-path"}, .type = GF_OPTION_TYPE_ANY diff --git a/xlators/protocol/client/src/client-protocol.c b/xlators/protocol/client/src/client-protocol.c index ab8fc3dcb..e7fda9f0e 100644 --- a/xlators/protocol/client/src/client-protocol.c +++ b/xlators/protocol/client/src/client-protocol.c @@ -6998,7 +6998,7 @@ struct volume_options options[] = { .type = GF_OPTION_TYPE_STR }, { .key = {"remote-host"}, - .type = GF_OPTION_TYPE_ANY + .type = GF_OPTION_TYPE_INTERNET_ADDRESS }, { .key = {"remote-subvolume"}, .type = GF_OPTION_TYPE_ANY -- cgit