[NCF-299]

When a .dodsrc file is present, and
specifies user name and password,
it is being ignored after the first time.

Fix required a major rewrite of ocrc.c because
it was mishandling a number of .dodsrc entries.
This commit is contained in:
dmh 2014-04-16 14:08:12 -06:00
parent 883608adb2
commit 98d27e838d
5 changed files with 130 additions and 100 deletions

View File

@ -9,13 +9,12 @@
ACLOCAL_AMFLAGS = -I m4
# These files get added to the distribution.
EXTRA_DIST = README README.md COPYRIGHT INSTALL INSTALL.cmake test_prog.c \
EXTRA_DIST = README.md COPYRIGHT INSTALL INSTALL.cmake test_prog.c \
lib_flags.am cmake CMakeLists.txt COMPILE.cmake.txt config.h.in.cmake \
config.h.in.cmake cmake_uninstall.cmake.in \
netcdf-config-version.cmake.in \
netcdf-config.cmake.in FixBundle.cmake.in \
nc-config.in.cmake RELEASE_NOTES.md CTestCustom.cmake \
CTestConfig.cmake
nc-config.in.cmake RELEASE_NOTES.md CTestCustom.cmake
# Doxygen doesn't build nicely in vpath builds.
# Don't do this; it wipes out any exported values

View File

@ -9,6 +9,9 @@ This file contains a high-level description of this package's evolution. Release
### 4.3.2-rc3 Released TBD
* The oc .dodsrc reader was improperly handling the user name and password
entries. [NCF-299](https://bugtracking.unidata.ucar.edu/browse/NCF-299)
### 4.3.2-rc2 Released 2014-04-15
* Cleaned up a number of CMake inconsistencies related to CMake usage, parallel builds.

View File

@ -12,7 +12,7 @@ static char* URL2 =
"http://remotetest.unidata.ucar.edu/thredds/dodsC/restrict/testData.nc";
/* .dodsrc file */
static char* DODSRC = "HTTP.CREDENTIALS.USER=tiggeUser\nHTTP.CREDENTIALS.PASSWORD=tigge\n";
static char* CONTENT = "HTTP.CREDENTIALS.USER=tiggeUser\nHTTP.CREDENTIALS.PASSWORD=tigge\n";
static void
CHECK(int e, const char* msg)
@ -23,41 +23,50 @@ CHECK(int e, const char* msg)
exit(1);
}
int
main()
main(int argc, char** argv)
{
int ncid,retval,pass;
char** url;
FILE* dodsrc;
printf("Testing: Http Basic Authorization\n\n");
printf("Embedded user:pwd: %s\n",URL1);
pass = 1; /* assume success */
retval = nc_open(URL1, 0, &ncid);
if(retval != NC_NOERR) {
pass = 0;
printf("*** FAIL: Embedded user:pwd %s\n",URL1);
} else
retval = nc_close(ncid);
printf(".dodsrc user:pwd: %s\n",URL1);
dodsrc = fopen(".dodsrc","w");
if(dodsrc == NULL) {
fprintf(stderr,"Cannot create .dodsrc\n");
exit(1);
exit(1);
}
fprintf(dodsrc,DODSRC);
fprintf(dodsrc,CONTENT);
fclose(dodsrc);
retval = nc_open(URL1, 0, &ncid);
if(retval != NC_NOERR) {
pass = 0;
printf("*** FAIL: .dodsrc user:pwd %s\n",URL1);
} else
retval = nc_close(ncid);
// unlink(".dodsrc"); /* delete the file */
if(!pass)
return 1;
printf("*** PASS: Http Basic Authorization\n");
return 0;
printf("Testing: Http Basic Authorization\n\n");
if(1) {
printf("Embedded user:pwd: %s\n",URL1);
retval = nc_open(URL1, 0, &ncid);
if(retval != NC_NOERR) {
pass = 0;
printf("*** FAIL: Embedded user:pwd\n");
} else {
printf("*** PASS: Embedded user:pwd\n");
retval = nc_close(ncid);
}
fflush(stdout);
}
if(1) {
printf(".dodsrc user:pwd: %s\n",URL1);
retval = nc_open(URL2, 0, &ncid);
if(retval != NC_NOERR) {
pass = 0;
printf("*** FAIL: .dodsrc user:pwd\n");
} else {
retval = nc_close(ncid);
printf("*** PASS: .dodsrc user:pwd\n");
}
fflush(stdout);
}
unlink(".dodsrc"); /* delete the file */
return !pass;
}

View File

@ -96,13 +96,14 @@ ocfetchurl(CURL* curl, const char* url, OCbytes* buf, long* filetime,
int stat = OC_NOERR;
CURLcode cstat = CURLE_OK;
size_t len;
long httpcode = 0;
long httpcode = 0;
char tbuf[1024];
/* Set the URL */
cstat = curl_easy_setopt(curl, CURLOPT_URL, (void*)url);
if (cstat != CURLE_OK)
goto fail;
#if 0
if(creds != NULL && creds->password != NULL && creds->username != NULL) {
/* Set user and password */
#if defined (HAVE_CURLOPT_USERNAME) && defined (HAVE_CURLOPT_PASSWORD)
@ -119,7 +120,7 @@ ocfetchurl(CURL* curl, const char* url, OCbytes* buf, long* filetime,
goto fail;
#endif
}
#endif
/* send all data to this function */
cstat = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
if (cstat != CURLE_OK)

View File

@ -20,15 +20,12 @@
#define TRIMCHARS " \t\r\n"
#define TRIM(x) rctrimright(rctrimleft((x),TRIMCHARS),TRIMCHARS)
#define HTTPPREFIXDEPRECATED "CURL."
#define HTTPPREFIX "HTTP."
static int parseproxy(OCstate* state, char* v);
static int rcreadline(FILE* f, char* more, int morelen);
static char* rctrimright(char* more, char* trimchars);
static char* rctrimleft(char* more, char* trimchars);
static void rctrim(char* text);
static void ocdodsrcdump(char* msg, struct OCTriple*, int ntriples);
@ -84,7 +81,7 @@ ocextract_credentials(const char *url, char **name, char **pw, char **result_url
url_len = strlen(url) - up_len;
*result_url = malloc(sizeof(char) * (url_len + 1));
if (!result_url)
if(*result_url == NULL)
return OC_ENOMEM;
strncpy(*result_url, url, (size_t)(pos - url));
@ -123,26 +120,29 @@ rcreadline(FILE* f, char* more, int morelen)
return 1;
}
/* Trim specified characters from front/left */
static char*
rctrimleft(char* more, char* trimchars)
{
char* p = more;
int c;
while((c=*p) != '\0') {if(strchr(trimchars,c) != NULL) p++; else break;}
return p;
}
/* Trim specified characters from end/right */
static char*
rctrimright(char* more, char* trimchars)
/* Trim TRIMCHARS from both ends of text; */
static void
rctrim(char* text)
{
int len = strlen(more);
char* p = more + (len - 1);
while(p != more) {if(strchr(trimchars,*p) != NULL) p--; else break;}
/* null terminate */
p[1] = '\0';
return more;
char* p = text;
size_t len = strlen(text);
int i;
/* locate first non-trimchar */
for(;*p;p++) {
if(strchr(TRIMCHARS,*p) == NULL) break; /* hit non-trim char */
}
strncpy(text,p,len);
len = strlen(text);
/* locate last non-trimchar */
if(len > 0) {
for(i=(len-1);i>=0;i--) {
if(strchr(TRIMCHARS,text[i]) == NULL) {
text[i+1] = '\0'; /* elide trailing trimchars */
break;
}
}
}
}
static int
@ -173,7 +173,7 @@ parseproxy(OCstate* state, char* v)
*port_sep = '\0';
host_len = strlen(host_pos);
state->proxy.host = malloc(sizeof(char) * host_len + 1);
if (!state->proxy.host)
if(state->proxy.host == NULL)
return OC_ENOMEM;
strncpy(state->proxy.host, host_pos, host_len);
@ -183,7 +183,7 @@ parseproxy(OCstate* state, char* v)
} else {
size_t host_len = strlen(host_pos);
state->proxy.host = malloc(sizeof(char) * host_len + 1);
if (!state->proxy.host)
if(state->proxy.host == NULL)
return OC_ENOMEM;
strncpy(state->proxy.host, host_pos, host_len);
@ -196,13 +196,13 @@ parseproxy(OCstate* state, char* v)
state->proxy.port = atoi(v);
s_len = strlen(v);
state->proxy.user = malloc(sizeof(char) * s_len + 1);
if (!state->proxy.user)
if(state->proxy.user == NULL)
return OC_ENOMEM;
strncpy(state->proxy.user, v, s_len);
state->proxy.user[s_len] = '\0';
p_len = strlen(v);
state->proxy.password = malloc(sizeof(char) * p_len + 1);
if (!state->proxy.password)
if(state->proxy.password == NULL)
return OC_ENOMEM;
strncpy(state->proxy.password, v, p_len);
state->proxy.password[p_len] = '\0';
@ -300,6 +300,7 @@ ocdodsrc_read(char* basename, char* path)
for(;;) {
char *line,*key,*value;
int c;
if(!rcreadline(in_file,line0,sizeof(line0))) break;
linecount++;
if(linecount >= MAXRCLINES) {
@ -308,15 +309,17 @@ ocdodsrc_read(char* basename, char* path)
}
line = line0;
/* check for comment */
if (line[0] == '#') continue;
/* trim leading blanks */
line = rctrimleft(line,TRIMCHARS);
c = line[0];
if (c == '#') continue;
rctrim(line); /* trim leading and trailing blanks */
if(strlen(line) >= MAXRCLINESIZE) {
oclog(OCLOGERR, "%s line too long: %s",basename,line0);
return 0;
}
/* parse the line */
ocdodsrc->triples[ocdodsrc->ntriples].url[0] = '\0'; /*assume no url*/
/* setup */
ocdodsrc->triples[ocdodsrc->ntriples].url[0] = '\0';
ocdodsrc->triples[ocdodsrc->ntriples].key[0] = '\0';
ocdodsrc->triples[ocdodsrc->ntriples].value[0] = '\0';
if(line[0] == LTAG) {
char* url = ++line;
char* rtag = strchr(line,RTAG);
@ -326,29 +329,26 @@ ocdodsrc_read(char* basename, char* path)
}
line = rtag + 1;
*rtag = '\0';
/* trim again */
line = rctrimleft(line,TRIMCHARS);
/* save the url */
strncpy(ocdodsrc->triples[ocdodsrc->ntriples].url,TRIM(url),strlen(url));
strncpy(ocdodsrc->triples[ocdodsrc->ntriples].url,url,MAXRCLINESIZE);
rctrim(ocdodsrc->triples[ocdodsrc->ntriples].url);
}
if(strlen(line)==0) continue; /* empty line */
/* split off key and value */
key=line;
value = strchr(line, '=');
if(value == NULL) {
/* add fake '=1' */
if(strlen(line) + strlen("=1") >= MAXRCLINESIZE) {
oclog(OCLOGERR, "%s entry too long: %s",basename,line);
continue;
}
strncat(line,"=1",2);
value = strchr(line,'=');
if(value == NULL)
value = line + strlen(line);
else {
*value = '\0';
value++;
}
if(value == NULL) continue;
*value = '\0';
value++;
strncpy(ocdodsrc->triples[ocdodsrc->ntriples].key,TRIM(key),strlen(key));
strncpy(ocdodsrc->triples[ocdodsrc->ntriples].value,TRIM(value),strlen(value));
strncpy(ocdodsrc->triples[ocdodsrc->ntriples].key,key,MAXRCLINESIZE);
if(*value == '\0')
strcpy(ocdodsrc->triples[ocdodsrc->ntriples].value,"1");/*dfalt*/
else
strncpy(ocdodsrc->triples[ocdodsrc->ntriples].value,value,MAXRCLINESIZE);
rctrim( ocdodsrc->triples[ocdodsrc->ntriples].key);
rctrim( ocdodsrc->triples[ocdodsrc->ntriples].value);
ocdodsrc->ntriples++;
}
fclose(in_file);
@ -382,22 +382,22 @@ ocdodsrc_process(OCstate* state)
oclog(OCLOGNOTE,"curl.timeout: %ld", state->curlflags.timeout);
}
if((value = curllookup("USERAGENT",url)) != NULL) {
if(atoi(value)) state->curlflags.useragent = strdup(TRIM(value));
if(!state->curlflags.useragent) {stat = OC_ENOMEM; goto done;}
if(atoi(value)) state->curlflags.useragent = strdup(value);
if(state->curlflags.useragent == NULL) {stat = OC_ENOMEM; goto done;}
if(ocdebug > 0)
oclog(OCLOGNOTE,"USERAGENT: %s", state->curlflags.useragent);
}
if((value = curllookup("COOKIEJAR",url))
|| (value = curllookup("COOKIE_JAR",url))) {
state->curlflags.cookiejar = strdup(TRIM(value));
if(!state->curlflags.cookiejar) {stat = OC_ENOMEM; goto done;}
state->curlflags.cookiejar = strdup(value);
if(state->curlflags.cookiejar == NULL) {stat = OC_ENOMEM; goto done;}
if(ocdebug > 0)
oclog(OCLOGNOTE,"COOKIEJAR: %s", state->curlflags.cookiejar);
}
if((value = curllookup("PROXY_SERVER",url)) != NULL) {
stat = parseproxy(state,TRIM(value));
stat = parseproxy(state,value);
if(stat != OC_NOERR) goto done;
}
@ -408,22 +408,22 @@ ocdodsrc_process(OCstate* state)
}
if((value = curllookup("SSL.CERTIFICATE",url)) != NULL) {
state->ssl.certificate = strdup(TRIM(value));
if(!state->ssl.certificate) {stat = OC_ENOMEM; goto done;}
state->ssl.certificate = strdup(value);
if(state->ssl.certificate == NULL) {stat = OC_ENOMEM; goto done;}
if(ocdebug > 0)
oclog(OCLOGNOTE,"CREDENTIALS.SSL.CERTIFICATE: %s", state->ssl.certificate);
}
if((value = curllookup("SSL.KEY",url)) != NULL) {
state->ssl.key = strdup(TRIM(value));
if(!state->ssl.key) {stat = OC_ENOMEM; goto done;}
state->ssl.key = strdup(value);
if(state->ssl.key == NULL) {stat = OC_ENOMEM; goto done;}
if(ocdebug > 0)
oclog(OCLOGNOTE,"CREDENTIALS.SSL.KEY: %s", state->ssl.key);
}
if((value = curllookup("SSL.KEYPASSWORD",url)) != NULL) {
state->ssl.keypasswd = strdup(TRIM(value));
if(!state->ssl.keypasswd) {stat = OC_ENOMEM; goto done;}
state->ssl.keypasswd = strdup(value);
if(state->ssl.keypasswd == NULL) {stat = OC_ENOMEM; goto done;}
#ifdef INSECURE
if(ocdebug > 0)
oclog(OCLOGNOTE,"CREDENTIALS.SSL.KEYPASSWORD: %s", state->ssl.keypasswd);
@ -431,21 +431,21 @@ ocdodsrc_process(OCstate* state)
}
if((value = curllookup("SSL.CAINFO",url)) != NULL) {
state->ssl.cainfo = strdup(TRIM(value));
if(!state->ssl.cainfo) {stat = OC_ENOMEM; goto done;}
state->ssl.cainfo = strdup(value);
if(state->ssl.cainfo == NULL) {stat = OC_ENOMEM; goto done;}
if(ocdebug > 0)
oclog(OCLOGNOTE,"SSL.CAINFO: %s", state->ssl.cainfo);
}
if((value = curllookup("SSL.CAPATH",url)) != NULL) {
state->ssl.capath = strdup(TRIM(value));
if(!state->ssl.capath) {stat = OC_ENOMEM; goto done;}
state->ssl.capath = strdup(value);
if(state->ssl.capath == NULL) {stat = OC_ENOMEM; goto done;}
if(ocdebug > 0)
oclog(OCLOGNOTE,"SSL.CAPATH: %s", state->ssl.capath);
}
if((value = curllookup("SSL.VERIFYPEER",url)) != NULL) {
char* s = strdup(TRIM(value));
char* s = strdup(value);
int tf = 0;
if(s == NULL || strcmp(s,"0")==0 || strcasecmp(s,"false")==0)
tf = 0;
@ -459,16 +459,32 @@ ocdodsrc_process(OCstate* state)
}
if((value = curllookup("CREDENTIALS.USER",url)) != NULL) {
state->creds.username = strdup(TRIM(value));
if(!state->creds.username) {stat = OC_ENOMEM; goto done;}
state->creds.username = strdup(value);
if(state->creds.username == NULL) {stat = OC_ENOMEM; goto done;}
if(ocdebug > 0)
oclog(OCLOGNOTE,"CREDENTIALS.USER: %s", state->creds.username);
}
if((value = curllookup("CREDENTIALS.PASSWORD",url)) != NULL) {
state->creds.password = strdup(TRIM(value));
if(!state->creds.password) {stat = OC_ENOMEM; goto done;}
state->creds.password = strdup(value);
if(state->creds.password == NULL) {stat = OC_ENOMEM; goto done;}
}
/* Support combined case */
if((value = curllookup("CREDENTIALS.USERPASSWORD",url)) != NULL) {
char* combined = value;
if(combined == NULL) {stat = OC_ENOMEM; goto done;}
char* sep = (char*)strchr(combined,':');
if(sep == NULL) {
oclog(OCLOGERR,"CREDENTIALS.USERPASSWORD: no ':' found");
stat = OC_EINVAL;
goto done;
}
*sep = '\0';
state->creds.username = strdup(combined);
state->creds.password = strdup(sep+1);
}
/* else ignore */
done:
@ -527,7 +543,9 @@ ocdodsrcdump(char* msg, struct OCTriple* triples, int ntriples)
}
}
/* Isolate the "CURL." prefix to allow changing to something else */
/* Isolate the "HTTP." (or "CURL.")
prefix to allow changing to something else
*/
static char*
curllookup(char* suffix, char* url)
{