diff options
| author | Kaushal M <kaushal@gluster.com> | 2011-08-23 12:23:53 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vijay@gluster.com> | 2012-02-05 22:19:54 -0800 | 
| commit | b708b18b833d1f2ba4da394884bc762a821ff56b (patch) | |
| tree | 03ad6be7de107e6a5477a1d912a997781b06d57d | |
| parent | 1d77fe2458be6dc567435dc59bb94870cd0fe529 (diff) | |
cli, protocol/server : improve validation for the option auth.(allow/reject)
cli now checks validity of address list given for 'volume set auth.*'
Server xlator checks addresses supplied to auth.(allow/reject) option
including wildcards for correctness in case volfile is manually edited.
Original patch done by shylesh@gluster.com
Original patch  is at http://patches.gluster.com/patch/7566/
Change-Id: Icf52d6eeef64d6632b15aa90a379fadacdf74fef
BUG: 764197
Signed-off-by: Kaushal M <kaushal@redhat.com>
Reviewed-on: http://review.gluster.com/306
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Reviewed-by: Vijay Bellur <vijay@gluster.com>
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 50 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.c | 149 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 3 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server.c | 43 | 
4 files changed, 216 insertions, 29 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index ef69235d673..b169b77c68d 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -36,7 +36,6 @@  #include "protocol-common.h"  #include "cli1-xdr.h" -  static const char *  id_sel (void *wcon)  { @@ -636,6 +635,43 @@ out:  }  int32_t +cli_cmd_valid_ip_list (char *iplist) +{ +        int     ret = 0; +        char    *duplist = NULL; +        char    *addr = NULL; +        char    *saveptr = NULL; + +        GF_ASSERT (iplist); +        duplist = gf_strdup (iplist); + +        if (!duplist) { +                ret = -1; +                goto out; +        } + +        addr = strtok_r (duplist, ",", &saveptr); +        if (!addr) { +                ret = -1; +                goto out; +        } +        while (addr) { +                if (!valid_internet_address (addr) && +                    !valid_wildcard_internet_address (addr)) { +                        cli_out ("Invalid ip or wildcard : %s", addr); +                        ret= -1; +                        goto out; +                } +                addr = strtok_r (NULL, ",", &saveptr); +        } +out: +        if (duplist) +                GF_FREE (duplist); +        gf_log ("cli", GF_LOG_INFO, "Returning %d", ret); +        return ret; +} + +int32_t  cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options)  {          dict_t  *dict = NULL; @@ -691,10 +727,18 @@ cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options)  		if ( !key || !value) {  			ret = -1;  			goto out; -        	} +	        }                  count++; - +                if (!strncmp ("auth.allow", key, sizeof (key)) || +                    !strncmp ("auth.reject", key, sizeof (key))) { +                        ret = cli_cmd_valid_ip_list (value); +                        if (ret) { +                                gf_log ("cli", GF_LOG_ERROR, +                                        "invalid ips given"); +                                goto out; +                        } +                }                  sprintf (str, "key%d", count);                  ret = dict_set_str (dict, str, key);                  if (ret) diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 42bfd035569..068bd846027 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1529,30 +1529,36 @@ get_nth_word (const char *str, int n)  }  /* RFC 1123 & 952 */ + +/* The functions below validate given internet addresses and + * wildcard internet address for correctness. + * All return 1 on success and 0 on failure + */ +  char  valid_host_name (char *address, int length)  { -        int i = 0; -        char ret = 1; +        int     i = 0; +        char    ret = 0; +        int     flag = 0; -        if ((length > 75) || (length == 1)) { -                ret = 0; +        if ((length > 255) || (length == 1))                  goto out; -        } -        if (!isalnum (address[length - 1])) { -                ret = 0; +        if (!isalnum (address[length - 1]))                  goto out; -        }          for (i = 0; i < length; i++) {                  if (!isalnum (address[i]) && (address[i] != '.') -                    && (address[i] != '-')) { -                        ret = 0; +                    && (address[i] != '-'))                          goto out; -                } + +                if (isalpha(address[i])) +                        flag = 1;          } +        if (flag) +                ret = 1;  out:          return ret;  } @@ -1563,7 +1569,7 @@ 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; +        char ret = 0;          tmp = gf_strdup (address);          prev = tmp; @@ -1572,16 +1578,14 @@ valid_ipv4_address (char *address, int length)          while (prev != NULL) {                  octets++;                  value = strtol (prev, &endptr, 10); -                if ((value > 255) || (value < 0) || (endptr != NULL)) { -                        ret = 0; +                if ((value > 255) || (value < 0) || +                    (endptr != NULL && *endptr != '\0'))                          goto out; -                }                  prev = strtok_r (NULL, ".", &ptr);          } -        if (octets != 4) { -                ret = 0; -        } +        if (octets == 4) +                ret = 1;  out:          GF_FREE (tmp); @@ -1594,7 +1598,7 @@ 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; +        char ret = 0;          tmp = gf_strdup (address);          prev = strtok_r (tmp, ":", &ptr); @@ -1603,16 +1607,13 @@ valid_ipv6_address (char *address, int length)                  hex_numbers++;                  value = strtol (prev, &endptr, 16);                  if ((value > 0xffff) || (value < 0) -                    || (endptr != NULL && *endptr != '\0')) { -                        ret = 0; +                    || (endptr != NULL && *endptr != '\0'))                          goto out; -                }                  prev = strtok_r (NULL, ":", &ptr);          } -        if (hex_numbers > 8) { -                ret = 0; -        } +        if (hex_numbers <= 8) +                ret = 1;  out:          GF_FREE (tmp); @@ -1643,6 +1644,104 @@ out:          return ret;  } +char +valid_ipv4_wildcard_check (char *address) +{ +        char    ret = 0; +        int     octets = 0; +        char    *tmp = NULL; +        char    *prev = NULL; +        char    *endptr = NULL; +        int     value = 0; +        int     is_wildcard = 0; + +        tmp = gf_strdup (address); +        prev = strtok (tmp, "."); + +        while (prev != NULL) { +                octets++; + +                if (!strcmp (prev, "*")) { +                        is_wildcard = 1; +                } else { +                        value = strtol (prev, &endptr, 10); + +                        if ((value > 255) || (value < 0) || +                            (endptr != NULL && *endptr != '\0')) +                                goto out; +                } +                prev = strtok (NULL, "."); +        } + +        if (is_wildcard && (octets <= 4)) +                ret = 1; + +out: +        if (tmp) +                GF_FREE (tmp); +        return ret; + +} + +char +valid_ipv6_wildcard_check (char *address) +{ +        char    ret = 0; +        int     hex_numbers = 0; +        int     value = 0; +        char    *tmp = NULL; +        char    *prev = NULL; +        char    *endptr = NULL; +        int     is_wildcard = 0; + +        tmp = gf_strdup (address); +        prev = strtok (tmp, ":"); + +        while (prev != NULL) { +                hex_numbers++; + +                if (!strcmp (prev, "*")) { +                        is_wildcard = 1; +                } else { +                        value = strtol (prev, &endptr, 16); + +                        if ((value > 0xffff) || (value < 0) || +                            (endptr != NULL && *endptr != '\0')) +                                goto out; +                } +                prev = strtok (NULL, ":"); +        } + +        if (is_wildcard && (hex_numbers <= 8)) +                ret = 1; +out: +        if (tmp) +                GF_FREE (tmp); +        return ret; +} + +char +valid_wildcard_internet_address (char *address) +{ +        char    ret = 0; + +        if (address == NULL) { +                gf_log_callingfn (THIS->name, GF_LOG_WARNING, +                                  "argument invalid"); +                goto out; +        } + +        if (strlen (address) == 0) +                goto out; + +        if (valid_ipv4_wildcard_check (address) || +            valid_ipv6_wildcard_check (address)) +                ret = 1; + +out: +        return ret; +} +  /*Thread safe conversion function*/  char *  uuid_utoa (uuid_t uuid) diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 4647c4a4d9c..63566fb53bc 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -445,6 +445,9 @@ char valid_host_name (char *address, int length);  char valid_ipv4_address (char *address, int length);  char valid_ipv6_address (char *address, int length);  char valid_internet_address (char *address); +char valid_ipv4_wildcard_check (char *address); +char valid_ipv6_wildcard_check (char *address); +char valid_wildcard_internet_address (char *address);  char *uuid_utoa (uuid_t uuid);  char *uuid_utoa_r (uuid_t uuid, char *dst); diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index 60bc517ddbe..b0697bb7b9d 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -469,6 +469,8 @@ validate_auth_options (xlator_t *this, dict_t *dict)          xlator_list_t *trav = NULL;          data_pair_t   *pair = NULL;          char          *tail = NULL; +        char          *addr = NULL; +        char          *tmp_str = NULL;          GF_VALIDATE_OR_GOTO ("server", this, out);          GF_VALIDATE_OR_GOTO ("server", dict, out); @@ -492,9 +494,47 @@ validate_auth_options (xlator_t *this, dict_t *dict)                          if (*tail == '.') {                                  error = 0; -                                break; + +                                /* when we are here, the key is checked for +                                 * valid auth.allow.<xlator> +                                 * Now we verify the ip address +                                 */ +                                if (!strcmp (pair->value->data, "*")) { +                                     error = 0; +                                     goto out; +                                } + +                                addr = strtok_r (pair->value->data, ",", +                                                &tmp_str); +                                if (!addr) +                                        addr = pair->value->data; + +                                while (addr) { + +                                        if (valid_internet_address (addr) || +                                        valid_wildcard_internet_address (addr)) +                                        { +                                                error = 0; +                                        } else { +                                                error = -1; +                                                gf_log (this->name, GF_LOG_ERROR, +                                                        "internet address '%s'" +                                                        " does not conform to" +                                                        " standards.", addr); +                                                goto out; + +                                        } +                                        if (tmp_str) +                                                addr = strtok_r (NULL, ",", +                                                                 &tmp_str); +                                        else +                                                addr = NULL; +                                } +                          } +                  } +                  if (-1 == error) {                          gf_log (this->name, GF_LOG_ERROR,                                  "volume '%s' defined as subvolume, but no " @@ -504,6 +544,7 @@ validate_auth_options (xlator_t *this, dict_t *dict)                  }                  trav = trav->next;          } +  out:          return error;  }  | 
