added psl_is_cookie_domain_acceptable()
This commit is contained in:
parent
b8f7a79947
commit
2c7c11d8a6
|
@ -49,8 +49,12 @@ psl_ctx_t *
|
||||||
psl_load_fp(FILE *fp);
|
psl_load_fp(FILE *fp);
|
||||||
const psl_ctx_t *
|
const psl_ctx_t *
|
||||||
psl_builtin(void);
|
psl_builtin(void);
|
||||||
|
// checks wether domain is a public suffix or not
|
||||||
int
|
int
|
||||||
psl_is_public_suffix(const psl_ctx_t *psl, const char *domain);
|
psl_is_public_suffix(const psl_ctx_t *psl, const char *domain);
|
||||||
|
// checks wether cookie_domain is acceptable for domain or not
|
||||||
|
int
|
||||||
|
psl_is_cookie_domain_acceptable(const psl_ctx_t *psl, const char *hostname, const char *cookie_domain);
|
||||||
// returns the longest unregistrable domain within 'domain' or NULL if none found
|
// returns the longest unregistrable domain within 'domain' or NULL if none found
|
||||||
const char *
|
const char *
|
||||||
psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain);
|
psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain);
|
||||||
|
|
96
src/psl.c
96
src/psl.c
|
@ -360,29 +360,20 @@ int psl_is_public_suffix(const psl_ctx_t *psl, const char *domain)
|
||||||
*/
|
*/
|
||||||
const char *psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain)
|
const char *psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain)
|
||||||
{
|
{
|
||||||
const char *p, *ret_domain;
|
|
||||||
|
|
||||||
if (!psl || !domain)
|
if (!psl || !domain)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// We check from right to left, e.g. in www.xxx.org we check org, xxx.org, www.xxx.org in this order
|
// We check from left to right to catch special PSL entries like 'forgot.his.name':
|
||||||
// for being a registered domain.
|
// 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not.
|
||||||
|
|
||||||
if (!(p = strrchr(domain, '.')))
|
while (!psl_is_public_suffix(psl, domain)) {
|
||||||
return psl_is_public_suffix(psl, domain) ? domain : NULL;
|
if ((domain = strchr(domain, '.')))
|
||||||
|
domain++;
|
||||||
for (ret_domain = NULL; ;) {
|
else
|
||||||
if (!psl_is_public_suffix(psl, p))
|
break; // prevent endless loop if psl_is_public_suffix() is broken.
|
||||||
return ret_domain;
|
|
||||||
else if (p == domain)
|
|
||||||
return domain;
|
|
||||||
|
|
||||||
ret_domain = p + 1;
|
|
||||||
|
|
||||||
// go left to next dot
|
|
||||||
while (p > domain && *--p != '.')
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -403,25 +394,23 @@ const char *psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain)
|
||||||
*/
|
*/
|
||||||
const char *psl_registrable_domain(const psl_ctx_t *psl, const char *domain)
|
const char *psl_registrable_domain(const psl_ctx_t *psl, const char *domain)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p, *regdom = NULL;
|
||||||
int ispublic;
|
|
||||||
|
|
||||||
if (!psl || !domain || *domain == '.')
|
if (!psl || !domain || *domain == '.')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// We check from right to left, e.g. in www.xxx.org we check org, xxx.org, www.xxx.org in this order
|
// We check from left to right to catch special PSL entries like 'forgot.his.name':
|
||||||
// for being a registrable domain.
|
// 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not.
|
||||||
|
|
||||||
if (!(p = strrchr(domain, '.')))
|
while (!psl_is_public_suffix(psl, domain)) {
|
||||||
p = domain;
|
if ((p = strchr(domain, '.'))) {
|
||||||
|
regdom = domain;
|
||||||
while ((ispublic = psl_is_public_suffix(psl, p)) && p > domain) {
|
domain = p + 1;
|
||||||
// go left to next dot
|
} else
|
||||||
while (p > domain && *--p != '.')
|
break; // prevent endless loop if psl_is_public_suffix() is broken.
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ispublic ? NULL : (*p == '.' ? p + 1 : p);
|
return regdom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -647,3 +636,50 @@ const char *psl_builtin_sha1sum(void)
|
||||||
{
|
{
|
||||||
return _psl_sha1_checksum;
|
return _psl_sha1_checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* psl_is_cookie_domain_acceptable:
|
||||||
|
* @psl: PSL context pointer
|
||||||
|
* @hostname: The request hostname.
|
||||||
|
* @cookie_domain: The domain value from a cookie
|
||||||
|
*
|
||||||
|
* This helper function checks whether @cookie_domain is an acceptable cookie domain value for the request
|
||||||
|
* @hostname.
|
||||||
|
*
|
||||||
|
* Returns: 1 if acceptable, 0 if not acceptable.
|
||||||
|
*
|
||||||
|
* Since: 0.1
|
||||||
|
*/
|
||||||
|
int psl_is_cookie_domain_acceptable(const psl_ctx_t *psl, const char *hostname, const char *cookie_domain)
|
||||||
|
{
|
||||||
|
const char *registrable_domain, *p;
|
||||||
|
size_t hostname_length, cookie_domain_length;
|
||||||
|
|
||||||
|
if (!psl || !hostname || !cookie_domain)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (*cookie_domain == '.')
|
||||||
|
cookie_domain++;
|
||||||
|
|
||||||
|
if (!strcmp(hostname, cookie_domain))
|
||||||
|
return 1; // an exact match is acceptable (and pretty common)
|
||||||
|
|
||||||
|
cookie_domain_length = strlen(cookie_domain);
|
||||||
|
hostname_length = strlen(hostname);
|
||||||
|
|
||||||
|
if (cookie_domain_length >= hostname_length)
|
||||||
|
return 0; // cookie_domain is too long
|
||||||
|
|
||||||
|
p = hostname + hostname_length - cookie_domain_length;
|
||||||
|
if (!strcmp(p, cookie_domain) && p[-1] == '.') {
|
||||||
|
// OK, cookie_domain matches, but it must be longer than the longest public suffix in 'hostname'
|
||||||
|
|
||||||
|
if (!(p = psl_unregistrable_domain(psl, hostname)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (cookie_domain_length > strlen(p))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue