Example #1
0
void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header, bool isProxy)
{
    QList<QPair<QString, QString> > values = header.values();
    const char *search = isProxy ? "proxy-authenticate" : "www-authenticate";

    method = None;
    /*
      Fun from the HTTP 1.1 specs, that we currently ignore:

      User agents are advised to take special care in parsing the WWW-
      Authenticate field value as it might contain more than one challenge,
      or if more than one WWW-Authenticate header field is provided, the
      contents of a challenge itself can contain a comma-separated list of
      authentication parameters.
    */

    QString headerVal;
    for (int i = 0; i < values.size(); ++i) {
        const QPair<QString, QString> &current = values.at(i);
        if (current.first.toLower() != QLatin1String(search))
            continue;
        QString str = current.second;
        if (method < Basic && str.startsWith(QLatin1String("Basic"), Qt::CaseInsensitive)) {
            method = Basic; headerVal = str.mid(6);
        } else if (method < Ntlm && str.startsWith(QLatin1String("NTLM"), Qt::CaseInsensitive)) {
            method = Ntlm;
            headerVal = str.mid(5);
        } else if (method < DigestMd5 && str.startsWith(QLatin1String("Digest"), Qt::CaseInsensitive)) {
            method = DigestMd5;
            headerVal = str.mid(7);
        }
    }

    challenge = headerVal.trimmed().toLatin1();
    QHash<QByteArray, QByteArray> options = parseDigestAuthenticationChallenge(challenge);

    switch(method) {
    case Basic:
        realm = QString::fromLatin1(options.value("realm"));
        if (user.isEmpty())
            phase = Done;
        break;
    case Ntlm:
        // #### extract from header
        realm = QString();
        break;
    case DigestMd5: {
        realm = QString::fromLatin1(options.value("realm"));
        if (options.value("stale").toLower() == "true")
            phase = Start;
        if (user.isEmpty())
            phase = Done;
        break;
    }
    default:
        realm = QString();
        challenge = QByteArray();
        phase = Invalid;
    }
}
Example #2
0
QByteArray QAuthenticatorPrivate::digestMd5Response(const QByteArray &challenge, const QByteArray &method, const QByteArray &path)
{
    QHash<QByteArray,QByteArray> options = parseDigestAuthenticationChallenge(challenge);

    ++nonceCount;
    QByteArray nonceCountString = QByteArray::number(nonceCount, 16);
    while (nonceCountString.length() < 8)
        nonceCountString.prepend('0');

    QByteArray nonce = options.value("nonce");
    QByteArray opaque = options.value("opaque");
    QByteArray qop = options.value("qop");

//    qDebug() << "calculating digest: method=" << method << "path=" << path;
    QByteArray response = digestMd5ResponseHelper(options.value("algorithm"), user.toLatin1(),
                                              realm.toLatin1(), password.toLatin1(),
                                              nonce, nonceCountString,
                                              cnonce, qop, method,
                                              path, QByteArray());


    QByteArray credentials;
    credentials += "username=\"" + user.toLatin1() + "\", ";
    credentials += "realm=\"" + realm.toLatin1() + "\", ";
    credentials += "nonce=\"" + nonce + "\", ";
    credentials += "uri=\"" + path + "\", ";
    if (!opaque.isEmpty())
        credentials += "opaque=\"" + opaque + "\", ";
    credentials += "response=\"" + response + '\"';
    if (!options.value("algorithm").isEmpty())
        credentials += ", algorithm=" + options.value("algorithm");
    if (!options.value("qop").isEmpty()) {
        credentials += ", qop=" + qop + ", ";
        credentials += "nc=" + nonceCountString + ", ";
        credentials += "cnonce=\"" + cnonce + '\"';
    }

    return credentials;
}
Example #3
0
void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByteArray> > &values, bool isProxy)
{
    const char *search = isProxy ? "proxy-authenticate" : "www-authenticate";

    method = None;
    /*
      Fun from the HTTP 1.1 specs, that we currently ignore:

      User agents are advised to take special care in parsing the WWW-
      Authenticate field value as it might contain more than one challenge,
      or if more than one WWW-Authenticate header field is provided, the
      contents of a challenge itself can contain a comma-separated list of
      authentication parameters.
    */

    QByteArray headerVal;
    for (int i = 0; i < values.size(); ++i) {
        const QPair<QByteArray, QByteArray> &current = values.at(i);
        if (current.first.toLower() != search)
            continue;
        QByteArray str = current.second.toLower();
        if (method < Basic && str.startsWith("basic")) {
            method = Basic;
            headerVal = current.second.mid(6);
        } else if (method < Ntlm && str.startsWith("ntlm")) {
            method = Ntlm;
            headerVal = current.second.mid(5);
        } else if (method < DigestMd5 && str.startsWith("digest")) {
            method = DigestMd5;
            headerVal = current.second.mid(7);
        }
    }

    // Reparse credentials since we know the method now
    updateCredentials();
    challenge = headerVal.trimmed();
    QHash<QByteArray, QByteArray> options = parseDigestAuthenticationChallenge(challenge);

    switch(method) {
    case Basic:
        this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
        if (user.isEmpty() && password.isEmpty())
            phase = Done;
        break;
    case Ntlm:
        // #### extract from header
        if (user.isEmpty() && password.isEmpty())
            phase = Done;
        break;
    case DigestMd5: {
        this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
        if (options.value("stale").toLower() == "true")
            phase = Start;
        if (user.isEmpty() && password.isEmpty())
            phase = Done;
        break;
    }
    default:
        realm.clear();
        challenge = QByteArray();
        phase = Invalid;
    }
}