mirror of
https://github.com/curl/curl.git
synced 2025-09-17 17:42:49 +03:00
netrc: support quoted strings
The .netrc parser now accepts strings within double-quotes in order to deal with for example passwords containing white space - which previously was not possible. A password that starts with a double-quote also ends with one, and double-quotes themselves are escaped with backslashes, like \". It also supports \n, \r and \t for newline, carriage return and tabs respectively. If the password does not start with a double quote, it will end at first white space and no escaping is performed. WARNING: this change is not entirely backwards compatible. If anyone previously used a double-quote as the first letter of their password, the parser will now get it differently compared to before. This is highly unfortunate but hard to avoid. Reported-by: ImpatientHippo on GitHub Fixes #8908 Closes #8937
This commit is contained in:
parent
b1f8d50a92
commit
eeaae10c0f
73
lib/netrc.c
73
lib/netrc.c
|
@ -78,24 +78,80 @@ static int parsenetrc(const char *host,
|
||||||
|
|
||||||
file = fopen(netrcfile, FOPEN_READTEXT);
|
file = fopen(netrcfile, FOPEN_READTEXT);
|
||||||
if(file) {
|
if(file) {
|
||||||
char *tok;
|
|
||||||
char *tok_buf;
|
|
||||||
bool done = FALSE;
|
bool done = FALSE;
|
||||||
char netrcbuffer[4096];
|
char netrcbuffer[4096];
|
||||||
int netrcbuffsize = (int)sizeof(netrcbuffer);
|
int netrcbuffsize = (int)sizeof(netrcbuffer);
|
||||||
|
|
||||||
while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
|
while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
|
||||||
|
char *tok;
|
||||||
|
char *tok_end;
|
||||||
|
bool quoted;
|
||||||
if(state == MACDEF) {
|
if(state == MACDEF) {
|
||||||
if((netrcbuffer[0] == '\n') || (netrcbuffer[0] == '\r'))
|
if((netrcbuffer[0] == '\n') || (netrcbuffer[0] == '\r'))
|
||||||
state = NOTHING;
|
state = NOTHING;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tok = strtok_r(netrcbuffer, " \t\n", &tok_buf);
|
tok = netrcbuffer;
|
||||||
if(tok && *tok == '#')
|
|
||||||
/* treat an initial hash as a comment line */
|
|
||||||
continue;
|
|
||||||
while(tok) {
|
while(tok) {
|
||||||
|
while(ISSPACE(*tok))
|
||||||
|
tok++;
|
||||||
|
/* tok is first non-space letter */
|
||||||
|
if(!*tok || (*tok == '#'))
|
||||||
|
/* end of line or the rest is a comment */
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* leading double-quote means quoted string */
|
||||||
|
quoted = (*tok == '\"');
|
||||||
|
|
||||||
|
tok_end = tok;
|
||||||
|
if(!quoted) {
|
||||||
|
while(!ISSPACE(*tok_end))
|
||||||
|
tok_end++;
|
||||||
|
*tok_end = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bool escape = FALSE;
|
||||||
|
bool endquote = FALSE;
|
||||||
|
char *store = tok;
|
||||||
|
tok_end++; /* pass the leading quote */
|
||||||
|
while(*tok_end) {
|
||||||
|
char s = *tok_end;
|
||||||
|
if(escape) {
|
||||||
|
escape = FALSE;
|
||||||
|
switch(s) {
|
||||||
|
case 'n':
|
||||||
|
s = '\n';
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
s = '\r';
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
s = '\t';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(s == '\\') {
|
||||||
|
escape = TRUE;
|
||||||
|
tok_end++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if(s == '\"') {
|
||||||
|
tok_end++; /* pass the ending quote */
|
||||||
|
endquote = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*store++ = s;
|
||||||
|
tok_end++;
|
||||||
|
}
|
||||||
|
*store = 0;
|
||||||
|
if(escape || !endquote) {
|
||||||
|
/* bad syntax, get out */
|
||||||
|
retcode = NETRC_FAILED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if((login && *login) && (password && *password)) {
|
if((login && *login) && (password && *password)) {
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -183,9 +239,8 @@ static int parsenetrc(const char *host,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} /* switch (state) */
|
} /* switch (state) */
|
||||||
|
tok = ++tok_end;
|
||||||
tok = strtok_r(NULL, " \t\n", &tok_buf);
|
}
|
||||||
} /* while(tok) */
|
|
||||||
} /* while fgets() */
|
} /* while fgets() */
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -3011,7 +3011,8 @@ static CURLcode override_login(struct Curl_easy *data,
|
||||||
conn->host.name, data->set.str[STRING_NETRC_FILE]);
|
conn->host.name, data->set.str[STRING_NETRC_FILE]);
|
||||||
}
|
}
|
||||||
else if(ret < 0) {
|
else if(ret < 0) {
|
||||||
return CURLE_OUT_OF_MEMORY;
|
failf(data, ".netrc parser error");
|
||||||
|
return CURLE_READ_ERROR;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* set bits.netrc TRUE to remember that we got the name from a .netrc
|
/* set bits.netrc TRUE to remember that we got the name from a .netrc
|
||||||
|
|
Loading…
Reference in New Issue
Block a user