Skip to content

Commit

Permalink
Make qop parameter of the xyz_challenge() positional-dependent,
Browse files Browse the repository at this point in the history
so that it's possible to generate qop="auth-int,auth" as well as
qop="auth,auth-int". Tested @ OpenSIPIt'02.
  • Loading branch information
sobomax committed Nov 17, 2021
1 parent f3abb0f commit f6c1f03
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 15 deletions.
2 changes: 1 addition & 1 deletion lib/digest_auth/dauth_nonce.c
Expand Up @@ -59,7 +59,7 @@ _Static_assert(offsetof(struct nonce_context_priv, pub) == 0,

struct nonce_payload {
int index;
uint64_t qop:2;
uint64_t qop:3;
uint64_t alg:3;
uint64_t expires_sec:34;
uint64_t expires_usec:20;
Expand Down
15 changes: 11 additions & 4 deletions modules/auth/api.c
Expand Up @@ -229,10 +229,17 @@ auth_result_t pre_auth(struct sip_msg* _m, str* _realm, hdr_types_t _hftype,
goto stalenonce;
}
qop_type_t qop = dcp->qop.qop_parsed;
if ((np.qop != qop) &&
(np.qop != QOP_TYPE_BOTH || (qop != QOP_AUTH_D && qop != QOP_AUTHINT_D))) {
LM_DBG("nonce does not match qop\n");
goto stalenonce;
if (np.qop != qop) {
switch (np.qop) {
case QOP_TYPE_AUTH_AUTH_INT:
case QOP_TYPE_AUTH_INT_AUTH:
if (qop == QOP_AUTH_D || qop == QOP_AUTHINT_D)
break;
/* Fall through */
default:
LM_DBG("nonce (%d) does not match qop (%d)\n", np.qop, qop);
goto stalenonce;
}
}
if (is_nonce_stale(&np, nonce_expire)) {
LM_DBG("stale nonce value received\n");
Expand Down
25 changes: 18 additions & 7 deletions modules/auth/challenge.c
Expand Up @@ -60,7 +60,8 @@

#define QOP_AUTH ", qop=\"" QOP_AUTH_STR "\""
#define QOP_AUTH_INT ", qop=\"" QOP_AUTHINT_STR "\""
#define QOP_AUTH_BOTH ", qop=\"" QOP_AUTH_STR "," QOP_AUTHINT_STR "\""
#define QOP_AUTH_BOTH_AAI ", qop=\"" QOP_AUTH_STR "," QOP_AUTHINT_STR "\""
#define QOP_AUTH_BOTH_AIA ", qop=\"" QOP_AUTHINT_STR "," QOP_AUTH_STR "\""
#define STALE_PARAM ", stale=true"
#define DIGEST_REALM ": Digest realm=\""
#define DIGEST_NONCE "\", nonce=\""
Expand All @@ -84,12 +85,22 @@ static inline char *build_auth_hf(int _retries, int _stale,
struct nonce_params calc_np;

if (_qop) {
if (_qop == QOP_TYPE_AUTH) {
switch (_qop) {
case QOP_TYPE_AUTH:
qop_param = str_const_init(QOP_AUTH);
} else if (_qop == QOP_TYPE_AUTH_INT) {
break;
case QOP_TYPE_AUTH_INT:
qop_param = str_const_init(QOP_AUTH_INT);
} else {
qop_param = str_const_init(QOP_AUTH_BOTH);
break;
case QOP_TYPE_AUTH_AUTH_INT:
qop_param = str_const_init(QOP_AUTH_BOTH_AAI);
break;
case QOP_TYPE_AUTH_INT_AUTH:
qop_param = str_const_init(QOP_AUTH_BOTH_AIA);
break;
default:
LM_ERR("Wrong _qop value: %d\n", _qop);
abort();
}
}
if (_stale)
Expand Down Expand Up @@ -264,12 +275,12 @@ int fixup_qop(void** param)
for (q = q_csv; q; q = q->next) {
if (!str_strcmp(&q->s, const_str(QOP_AUTH_STR))) {
if (qop_type == QOP_TYPE_AUTH_INT)
qop_type = QOP_TYPE_BOTH;
qop_type = QOP_TYPE_AUTH_INT_AUTH;
else
qop_type = QOP_TYPE_AUTH;
} else if (!str_strcmp(&q->s, const_str(QOP_AUTHINT_STR))) {
if (qop_type == QOP_TYPE_AUTH)
qop_type = QOP_TYPE_BOTH;
qop_type = QOP_TYPE_AUTH_AUTH_INT;
else
qop_type = QOP_TYPE_AUTH_INT;
} else {
Expand Down
3 changes: 2 additions & 1 deletion modules/auth/challenge.h
Expand Up @@ -28,7 +28,8 @@

#define QOP_TYPE_AUTH QOP_AUTH_D
#define QOP_TYPE_AUTH_INT QOP_AUTHINT_D
#define QOP_TYPE_BOTH (QOP_AUTH_D + QOP_AUTHINT_D)
#define QOP_TYPE_AUTH_INT_AUTH QOP_AUTHINT_AUTH_D
#define QOP_TYPE_AUTH_AUTH_INT QOP_AUTH_AUTHINT_D

int fixup_qop(void** param);

Expand Down
4 changes: 3 additions & 1 deletion parser/digest/digest.c
Expand Up @@ -125,7 +125,7 @@ dig_err_t check_dig_cred(dig_cred_t* _c)
/* If QOP parameter is present, some additional
* requirements must be met
*/
if ((_c->qop.qop_parsed == QOP_AUTH_D) || (_c->qop.qop_parsed == QOP_AUTHINT_D)) {
if (_c->qop.qop_parsed != QOP_UNSPEC_D) {
/* CNONCE must be specified */
if (_c->cnonce.s == 0) res |= E_DIG_CNONCE;
/* and also nonce count must be specified */
Expand Down Expand Up @@ -175,6 +175,8 @@ void print_cred(dig_cred_t* _c)
CASE_PRINTENUM(QOP_UNSPEC_D);
CASE_PRINTENUM(QOP_AUTH_D);
CASE_PRINTENUM(QOP_AUTHINT_D);
CASE_PRINTENUM(QOP_AUTHINT_AUTH_D);
CASE_PRINTENUM(QOP_AUTH_AUTHINT_D);
CASE_PRINTENUM(QOP_OTHER_D);
}
printf("NC = \'%.*s\'\n", _c->nc.len, _c->nc.s);
Expand Down
4 changes: 3 additions & 1 deletion parser/digest/digest_parser.h
Expand Up @@ -69,7 +69,9 @@ typedef enum qop_type {
QOP_UNSPEC_D = 0, /* QOP parameter not present in response */
QOP_AUTH_D = 1, /* Authentication only */
QOP_AUTHINT_D = 2, /* Authentication with integrity checks */
QOP_OTHER_D = 4 /* Unknown */
QOP_AUTHINT_AUTH_D = 3, /* Authentication with integrity checks+Authentication only */
QOP_AUTH_AUTHINT_D = 4, /* Authentication only+Authentication with integrity checks */
QOP_OTHER_D = 5 /* Unknown */
} qop_type_t;

/* Canonical QOP names */
Expand Down

0 comments on commit f6c1f03

Please sign in to comment.