Fix redirect URL validation bypass

It turns out that browsers silently convert backslash characters into
forward slashes, while apr_uri_parse() does not.

This mismatch allows an attacker to bypass the redirect URL validation
by using an URL like:

  https://sp.example.org/mellon/logout?ReturnTo=https:%5c%5cmalicious.example.org/

mod_auth_mellon will assume that it is a relative URL and allow the
request to pass through, while the browsers will use it as an absolute
url and redirect to https://malicious.example.org/ .

This patch fixes this issue by rejecting all redirect URLs with
backslashes.
const char *am_xstrtok(request_rec *r, const char *str,
                       const char *sep, char **last)
{
    char *s;
    char *np;

    /* Resume */
    if (str != NULL)
        s = apr_pstrdup(r->pool, str);
    else
        s = *last;

    /* End of string */
    if (*s == '\0')
        return NULL;

    /* Next sep exists? */
    if ((np = strstr(s, sep)) == NULL) {
        *last = s + strlen(s);
    } else {
        *last = np + strlen(sep);
        memset(np, 0, strlen(sep));
    }

    return s;
}

const char *am_xstrtok(request_rec *r, const char *str,
                       const char *sep, char **last)
{
    char *s;
    char *np;

    /* Resume */
    if (str != NULL)
        s = apr_pstrdup(r->pool, str);
    else
        s = *last;

    /* End of string */
    if (*s == '\0')
        return NULL;

    /* Next sep exists? */
    if ((np = strstr(s, sep)) == NULL) {
        *last = s + strlen(s);
    } else {
        *last = np + strlen(sep);
        memset(np, 0, strlen(sep));
    }

    return s;
}
