diff options
| author | Kamil Dudka <kdudka@redhat.com> | 2011-01-04 13:52:54 +0100 | 
|---|---|---|
| committer | Kamil Dudka <kdudka@redhat.com> | 2011-01-04 17:20:43 +0100 | 
| commit | d8f6d1c3341cfc5a1263e1f3f339b64e10b75dc3 (patch) | |
| tree | 6226d58cddb4ac13045941ffa926d39ee545f512 /lib | |
| parent | 1e52ea92ebcb2c8ba8f9a18005bf54bdb6bc7dd2 (diff) | |
nss: avoid CURLE_OUT_OF_MEMORY given a file name without any slash
Bug: https://bugzilla.redhat.com/623663
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/nss.c | 73 | 
1 files changed, 40 insertions, 33 deletions
| @@ -277,22 +277,35 @@ static int is_file(const char *filename)    return 0;  } -static char *fmt_nickname(char *str, bool *nickname_alloc) +/* Return on heap allocated filename/nickname of a certificate.  The returned + * string should be later deallocated using free().  *is_nickname is set to TRUE + * if the given string is treated as nickname; FALSE if the given string is + * treated as file name. + */ +static char *fmt_nickname(struct SessionHandle *data, enum dupstring cert_kind, +                          bool *is_nickname)  { -  char *nickname = NULL; -  *nickname_alloc = FALSE; - -  if(is_file(str)) { -    char *n = strrchr(str, '/'); -    if(n) { -      *nickname_alloc = TRUE; -      n++; /* skip last slash */ -      nickname = aprintf("PEM Token #%d:%s", 1, n); -    } -    return nickname; +  const char *str = data->set.str[cert_kind]; +  const char *n; +  *is_nickname = TRUE; + +  if(!is_file(str)) +    /* no such file exists, use the string as nickname */ +    return strdup(str); + +  /* search the last slash; we require at least one slash in a file name */ +  n = strrchr(str, '/'); +  if(!n) { +    infof(data, "warning: certificate file name \"%s\" handled as nickname; " +          "please use \"./%s\" to force file name\n", str, str); +    return strdup(str);    } -  return str; +  /* we'll use the PEM reader to read the certificate from file */ +  *is_nickname = FALSE; + +  n++; /* skip last slash */ +  return aprintf("PEM Token #%d:%s", 1, n);  }  static int nss_load_cert(struct ssl_connect_data *ssl, @@ -1304,25 +1317,20 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)    }    if(data->set.str[STRING_CERT]) { -    bool nickname_alloc = FALSE; -    char *nickname = fmt_nickname(data->set.str[STRING_CERT], &nickname_alloc); +    bool is_nickname; +    char *nickname = fmt_nickname(data, STRING_CERT, &is_nickname);      if(!nickname)        return CURLE_OUT_OF_MEMORY; -    if(!cert_stuff(conn, sockindex, data->set.str[STRING_CERT], -                   data->set.str[STRING_KEY])) { +    if(!is_nickname && !cert_stuff(conn, sockindex, data->set.str[STRING_CERT], +                                   data->set.str[STRING_KEY])) {        /* failf() is already done in cert_stuff() */ -      if(nickname_alloc) -        free(nickname); +      free(nickname);        return CURLE_SSL_CERTPROBLEM;      } -    /* this "takes over" the pointer to the allocated name or makes a -       dup of it */ -    connssl->client_nickname = nickname_alloc?nickname:strdup(nickname); -    if(!connssl->client_nickname) -      return CURLE_OUT_OF_MEMORY; - +    /* store the nickname for SelectClientCert() called during handshake */ +    connssl->client_nickname = nickname;    }    else      connssl->client_nickname = NULL; @@ -1376,18 +1384,17 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)    display_conn_info(conn, connssl->handle);    if (data->set.str[STRING_SSL_ISSUERCERT]) { -    SECStatus ret; -    bool nickname_alloc = FALSE; -    char *nickname = fmt_nickname(data->set.str[STRING_SSL_ISSUERCERT], -                                  &nickname_alloc); - +    SECStatus ret = SECFailure; +    bool is_nickname; +    char *nickname = fmt_nickname(data, STRING_SSL_ISSUERCERT, &is_nickname);      if(!nickname)        return CURLE_OUT_OF_MEMORY; -    ret = check_issuer_cert(connssl->handle, nickname); +    if(is_nickname) +      /* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */ +      ret = check_issuer_cert(connssl->handle, nickname); -    if(nickname_alloc) -      free(nickname); +    free(nickname);      if(SECFailure == ret) {        infof(data,"SSL certificate issuer check failed\n"); | 
