|
Packit Service |
779887 |
/*
|
|
Packit Service |
779887 |
Copyright (C) 2015 ABRT team
|
|
Packit Service |
779887 |
Copyright (C) 2015 RedHat Inc
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
779887 |
it under the terms of the GNU General Public License as published by
|
|
Packit Service |
779887 |
the Free Software Foundation; either version 2 of the License, or
|
|
Packit Service |
779887 |
(at your option) any later version.
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
This program is distributed in the hope that it will be useful,
|
|
Packit Service |
779887 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
779887 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
779887 |
GNU General Public License for more details.
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
You should have received a copy of the GNU General Public License along
|
|
Packit Service |
779887 |
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit Service |
779887 |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit Service |
779887 |
*/
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
#include "internal_libreport.h"
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
#include <regex.h>
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
int uri_userinfo_remove(const char *uri, char **result, char **scheme, char **hostname, char **username, char **password, char **location)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
/* https://www.ietf.org/rfc/rfc3986.txt
|
|
Packit Service |
779887 |
* Appendix B. Parsing a URI Reference with a Regular Expression
|
|
Packit Service |
779887 |
*
|
|
Packit Service |
779887 |
* scheme = $2
|
|
Packit Service |
779887 |
* authority = $4
|
|
Packit Service |
779887 |
* location = $5 <- introduced by jfilak
|
|
Packit Service |
779887 |
* path = $6
|
|
Packit Service |
779887 |
* query = $8
|
|
Packit Service |
779887 |
* fragment = $10
|
|
Packit Service |
779887 |
* 12 3 4 56 7 8 9 10 */
|
|
Packit Service |
779887 |
const char *rfc3986_rx = "^(([^:/?#]+):)?(//([^/?#]*))?(([^?#]*)(\\?([^#]*))?(#(.*))?)$";
|
|
Packit Service |
779887 |
regex_t re;
|
|
Packit Service |
779887 |
int r = regcomp(&re, rfc3986_rx, REG_EXTENDED);
|
|
Packit Service |
779887 |
assert(r == 0 || !"BUG: invalid regular expression");
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
regmatch_t matchptr[10];
|
|
Packit Service |
779887 |
r = regexec(&re, uri, ARRAY_SIZE(matchptr), matchptr, 0);
|
|
Packit Service |
779887 |
if (r != 0)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
log_debug("URI does not match RFC3986 regular expression.");
|
|
Packit Service |
779887 |
return -EINVAL;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
char *ptr = xzalloc((strlen(uri) + 1) * sizeof(char));
|
|
Packit Service |
779887 |
*result = ptr;
|
|
Packit Service |
779887 |
if (scheme != NULL)
|
|
Packit Service |
779887 |
*scheme = NULL;
|
|
Packit Service |
779887 |
if (hostname != NULL)
|
|
Packit Service |
779887 |
*hostname = NULL;
|
|
Packit Service |
779887 |
if (username != NULL)
|
|
Packit Service |
779887 |
*username = NULL;
|
|
Packit Service |
779887 |
if (password != NULL)
|
|
Packit Service |
779887 |
*password = NULL;
|
|
Packit Service |
779887 |
if (location != NULL)
|
|
Packit Service |
779887 |
*location= NULL;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
/* https://www.ietf.org/rfc/rfc3986.txt
|
|
Packit Service |
779887 |
* 5.3. Component Recomposition
|
|
Packit Service |
779887 |
*
|
|
Packit Service |
779887 |
result = ""
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
if defined(scheme) then
|
|
Packit Service |
779887 |
append scheme to result;
|
|
Packit Service |
779887 |
append ":" to result;
|
|
Packit Service |
779887 |
endif;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
if defined(authority) then
|
|
Packit Service |
779887 |
append "//" to result;
|
|
Packit Service |
779887 |
append authority to result;
|
|
Packit Service |
779887 |
endif;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
append path to result;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
if defined(query) then
|
|
Packit Service |
779887 |
append "?" to result;
|
|
Packit Service |
779887 |
append query to result;
|
|
Packit Service |
779887 |
endif;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
if defined(fragment) then
|
|
Packit Service |
779887 |
append "#" to result;
|
|
Packit Service |
779887 |
append fragment to result;
|
|
Packit Service |
779887 |
endif;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
return result;
|
|
Packit Service |
779887 |
*/
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
#define APPEND_MATCH(i, output) \
|
|
Packit Service |
779887 |
if (matchptr[(i)].rm_so != -1) \
|
|
Packit Service |
779887 |
{ \
|
|
Packit Service |
779887 |
size_t len = 0; \
|
|
Packit Service |
779887 |
len = matchptr[(i)].rm_eo - matchptr[(i)].rm_so; \
|
|
Packit Service |
779887 |
if (output) *output = xstrndup(uri + matchptr[(i)].rm_so, len); \
|
|
Packit Service |
779887 |
strncpy(ptr, uri + matchptr[(i)].rm_so, len); \
|
|
Packit Service |
779887 |
ptr += len; \
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
/* Append "scheme:" if defined */
|
|
Packit Service |
779887 |
APPEND_MATCH(1, scheme);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
/* If authority is defined, append "//" */
|
|
Packit Service |
779887 |
regmatch_t *match_authority = matchptr + 3;
|
|
Packit Service |
779887 |
if (match_authority->rm_so != -1)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
strcat(ptr, "//");
|
|
Packit Service |
779887 |
ptr += 2;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
++match_authority;
|
|
Packit Service |
779887 |
/* If authority has address part, remove userinfo and add the address */
|
|
Packit Service |
779887 |
if (match_authority->rm_so != -1)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
size_t len = match_authority->rm_eo - match_authority->rm_so;
|
|
Packit Service |
779887 |
const char *authority = uri + match_authority->rm_so;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
/* Find the last '@'. Just for the case some used @ in username or
|
|
Packit Service |
779887 |
* password */
|
|
Packit Service |
779887 |
size_t at = len;
|
|
Packit Service |
779887 |
while (at != 0)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (authority[--at] != '@')
|
|
Packit Service |
779887 |
continue;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
/* Find the first ':' before @. There should not be more ':' but this
|
|
Packit Service |
779887 |
* is the most secure way -> avoid leaking an excerpt of a password
|
|
Packit Service |
779887 |
* containing ':'.*/
|
|
Packit Service |
779887 |
size_t colon = 0;
|
|
Packit Service |
779887 |
while (colon < at)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (authority[colon] != ':')
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
++colon;
|
|
Packit Service |
779887 |
continue;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
if (password != NULL)
|
|
Packit Service |
779887 |
*password = xstrndup(authority + colon + 1, at - colon - 1);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
break;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
if (username != NULL)
|
|
Packit Service |
779887 |
*username = xstrndup(authority, colon);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
++at;
|
|
Packit Service |
779887 |
break;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
len -= at;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
if (hostname != NULL)
|
|
Packit Service |
779887 |
*hostname = xstrndup(authority + at, len);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
strncpy(ptr, authority + at, len);
|
|
Packit Service |
779887 |
ptr += len;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
/* Append path, query and fragment or "" */
|
|
Packit Service |
779887 |
APPEND_MATCH(5, location);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
return 0;
|
|
Packit Service |
779887 |
}
|