diff options
| author | Steve Holme <steve_holme@hotmail.com> | 2013-04-18 17:52:05 +0100 | 
|---|---|---|
| committer | Steve Holme <steve_holme@hotmail.com> | 2013-04-18 18:09:53 +0100 | 
| commit | bb20989a6384f95a73fd68b0e109fc860e0c7a57 (patch) | |
| tree | e658131f3a7f3ce7bcd475966e7865996481c60e /lib | |
| parent | 0d49e408a48246b9a27448473e78ce3fd237b19e (diff) | |
url: Moved parsing of login details out of parse_url_login()
Separated the parsing of login details from the processing of them in
parse_url_login() ready for use by setstropt_userpwd().
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/url.c | 218 | 
1 files changed, 158 insertions, 60 deletions
| @@ -144,6 +144,9 @@ static CURLcode do_init(struct connectdata *conn);  static CURLcode parse_url_login(struct SessionHandle *data,                                  struct connectdata *conn,                                  char *user, char *passwd, char *options); +static CURLcode parse_login_details(const char *login, const size_t len, +                                    char **userptr, char **passwdptr, +                                    char **optionsptr);  /*   * Protocol table.   */ @@ -4326,6 +4329,7 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data,  #endif /* CURL_DISABLE_PROXY */  /* + * parse_url_login()   *   * Parse the login details (user name, password and options) from the URL and   * strip them out of the host name @@ -4344,6 +4348,11 @@ static CURLcode parse_url_login(struct SessionHandle *data,                                  struct connectdata *conn,                                  char *user, char *passwd, char *options)  { +  CURLcode result = CURLE_OK; +  char *userp = NULL; +  char *passwdp = NULL; +  char *optionsp = NULL; +    /* At this point, we're hoping all the other special cases have     * been taken care of, so conn->host.name is at most     *    [user[:password][;options]]@]hostname @@ -4352,7 +4361,7 @@ static CURLcode parse_url_login(struct SessionHandle *data,     */    char *ptr = strchr(conn->host.name, '@'); -  char *userpass = conn->host.name; +  char *login = conn->host.name;    user[0] = 0;   /* to make everything well-defined */    passwd[0] = 0; @@ -4361,7 +4370,7 @@ static CURLcode parse_url_login(struct SessionHandle *data,    /* We will now try to extract the     * possible login information in a string like:     * ftp://user:password@ftp.my.site:8021/README */ -  if(ptr != NULL) { +  if(ptr) {      /* There's login information to the left of the @ */      conn->host.name = ++ptr; @@ -4373,80 +4382,169 @@ static CURLcode parse_url_login(struct SessionHandle *data,       */      if(data->set.use_netrc != CURL_NETRC_REQUIRED) { -      /* We could use the information in the URL so extract it */ -      if(*userpass != ':') { -        if(*userpass != ';') { -          /* The user is given so extract the user, password and options */ -          int result = sscanf(userpass, -                              "%" MAX_CURL_USER_LENGTH_TXT "[^:;@]:" -                              "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];" -                              "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", -                              user, passwd, options); - -          /* The extract failed so extract the user and options instead */ -          if(result == 1) -            sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:;@];" -                             "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", -                              user, options); -        } -        else { -          /* No name or password are given so extract the options only */ -        sscanf(userpass, ";%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", options); +      /* We could use the login information in the URL so extract it */ +      result = parse_login_details(login, ptr - login - 1, +                                   &userp, &passwdp, &optionsp); +      if(!result) { +        if(userp) { +          char *newname; + +          /* We have a user in the URL */ +          conn->bits.userpwd_in_url = TRUE; +          conn->bits.user_passwd = TRUE; /* enable user+password */ + +          /* Decode the user */ +          newname = curl_easy_unescape(data, userp, 0, NULL); +          if(!newname) +            return CURLE_OUT_OF_MEMORY; + +          if(strlen(newname) < MAX_CURL_USER_LENGTH) +            strcpy(user, newname); + +          free(newname);          } -      } -      else -        /* No name is given so extract the password and options */ -        sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];" -               "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", -               passwd, options); -      if(user[0]) { -        char *newname; +        if(passwdp) { +          /* We have a password in the URL so decode it */ +          char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL); +          if(!newpasswd) +            return CURLE_OUT_OF_MEMORY; + +          if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) +            strcpy(passwd, newpasswd); -        /* We have a user in the URL */ -        conn->bits.userpwd_in_url = TRUE; -        conn->bits.user_passwd = TRUE; /* enable user+password */ +          free(newpasswd); +        } -        /* Decode the user */ -        newname = curl_easy_unescape(data, user, 0, NULL); -        if(!newname) -          return CURLE_OUT_OF_MEMORY; +        if(optionsp) { +          /* We have an options list in the URL so decode it */ +          char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL); +          if(!newoptions) +            return CURLE_OUT_OF_MEMORY; -        if(strlen(newname) < MAX_CURL_USER_LENGTH) -          strcpy(user, newname); +          if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH) +            strcpy(options, newoptions); -        /* if the new name is longer than accepted, then just use -           the unconverted name, it'll be wrong but what the heck */ -        free(newname); +          free(newoptions); +        }        } -      if(passwd[0]) { -        /* We have a password in the URL so decode it */ -        char *newpasswd = curl_easy_unescape(data, passwd, 0, NULL); -        if(!newpasswd) -          return CURLE_OUT_OF_MEMORY; +      Curl_safefree(userp); +      Curl_safefree(passwdp); +      Curl_safefree(optionsp); +    } +  } -        if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) -          strcpy(passwd, newpasswd); +  return result; +} -        free(newpasswd); -      } +/* + * parse_login_details() + * + * This is used to parse a login string for user name, password and options in + * the following formats: + * + *   user + *   user:password + *   user:password;options + *   user;options + *   user;options:password + *   :password + *   :password;options + *   ;options + *   ;options:password + * + * Parameters: + * + * login    [in]     - The login string. + * len      [in]     - The length of the login string. + * userp    [in/out] - The address where a pointer to newly allocated memory + *                     holding the user will be stored upon completion. + * passdwp  [in/out] - The address where a pointer to newly allocated memory + *                     holding the password will be stored upon completion. + * optionsp [in/out] - The address where a pointer to newly allocated memory + *                     holding the options will be stored upon completion. + * + * Returns CURLE_OK on success. + */ +static CURLcode parse_login_details(const char *login, const size_t len, +                                    char **userp, char **passwdp, char **optionsp) +{ +  int result = CURLE_OK; +  char *utemp = NULL; +  char *ptemp = NULL; +  char *otemp = NULL; +  const char *psep = NULL; +  const char *osep = NULL; +  size_t ulen; +  size_t plen; +  size_t olen; + +  /* Attempt to find the password separator */ +  if(passwdp) +    psep = strchr(login, ':'); + +  /* Attempt to find the options separator */ +  if(optionsp) +    osep = strchr(login, ';'); + +  /* Calculate the portion lengths */ +  ulen = (psep ? +          (osep && psep > osep ? osep - login : psep - login) : +          (osep ? osep - login : len)); +  plen = (psep ? +          (osep && osep > psep ? osep - psep : login + len - psep) - 1 : 0); +  olen = (osep ? +          (psep && psep > osep ? psep - osep : login + len - osep) - 1 : 0); + +  /* Allocate the user portion temporary buffer */ +  if(userp && ulen) { +    utemp = malloc(ulen + 1); +    if(!utemp) +      result = CURLE_OUT_OF_MEMORY; +  } + +  /* Allocate the password portion temporary buffer */ +  if(!result && passwdp && plen) { +    ptemp = malloc(plen + 1); +    if(!ptemp) +      result = CURLE_OUT_OF_MEMORY; +  } + +  /* Allocate the options  portion temporary buffer */ +  if(!result && optionsp && olen) { +    otemp = malloc(olen + 1); +    if(!otemp) +      result = CURLE_OUT_OF_MEMORY; +  } -      if(options[0]) { -        /* We have an options list in the URL so decode it */ -        char *newoptions = curl_easy_unescape(data, options, 0, NULL); -        if(!newoptions) -          return CURLE_OUT_OF_MEMORY; +  if(!result) { +    /* Copy the user portion if necessary */ +    if(utemp) { +      memcpy(utemp, login, ulen); +      utemp[ulen] = '\0'; +      Curl_safefree(*userp); +      *userp = utemp; +    } -        if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH) -          strcpy(options, newoptions); +    /* Copy the password portion if necessary */ +    if(ptemp) { +      memcpy(ptemp, psep + 1, plen); +      ptemp[plen] = '\0'; +      Curl_safefree(*passwdp); +      *passwdp = ptemp; +    } -        free(newoptions); -      } +    /* Copy the password portion if necessary */ +    if(otemp) { +      memcpy(otemp, osep + 1, olen); +      otemp[olen] = '\0'; +      Curl_safefree(*optionsp); +      *optionsp = otemp;      }    } -  return CURLE_OK; +  return result;  }  /************************************************************* | 
