浏览代码

- check if nonce creation time is in the future (it might happen after a
system backward time adjustment or in a cluster which is not
time-synchrponized) and if the difference is greater then
nonce_auth_max_drift (new module parameter), consider the nonce stale
(and re-challenge).

Andrei Pelinescu-Onciul 17 年之前
父节点
当前提交
2e3672f1ae
共有 3 个文件被更改,包括 23 次插入3 次删除
  1. 1 0
      modules_s/auth/auth_mod.c
  2. 15 3
      modules_s/auth/nonce.c
  3. 7 0
      modules_s/auth/nonce.h

+ 1 - 0
modules_s/auth/auth_mod.c

@@ -119,6 +119,7 @@ static cmd_export_t cmds[] = {
 static param_export_t params[] = {
     {"secret",                 PARAM_STRING, &sec_param             },
     {"nonce_expire",           PARAM_INT,    &nonce_expire          },
+	{"nonce_auth_max_drift",   PARAM_INT,    &nonce_auth_max_drift  },
     {"protect_contacts",       PARAM_INT,    &protect_contacts      },
     {"challenge_attr",         PARAM_STR,    &challenge_attr        },
     {"proxy_challenge_header", PARAM_STR,    &proxy_challenge_header},

+ 15 - 3
modules_s/auth/nonce.c

@@ -67,6 +67,11 @@ int auth_checks_reg = 0;
 int auth_checks_ood = 0;
 int auth_checks_ind = 0;
 
+/* maximum time drift accepted for the nonce creation time
+ * (e.g. nonce generated by another proxy in the same cluster with the
+ * clock slightly in the future)
+ */
+unsigned int nonce_auth_max_drift = 3; /* in s */
 
 /** Select extra check configuration based on request type.
  * This function determines which configuration variable for
@@ -269,8 +274,7 @@ int calc_nonce(char* nonce, int *nonce_len, int cfg, int since, int expires,
  * @param b_nonce a pointer to a union bin_nonce to be checked.
  * @return 1 the nonce is stale, 0 the nonce is not stale.
  */
-#define is_bin_nonce_stale(b_nonce)\
-	(get_bin_nonce_expire(b_nonce) < ser_time(0))
+#define is_bin_nonce_stale(b_nonce, t) (get_bin_nonce_expire(b_nonce) < (t))
 
 
 
@@ -306,6 +310,7 @@ int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
 	int since, b_nonce2_len, b_nonce_len, cfg;
 	union bin_nonce b_nonce;
 	union bin_nonce b_nonce2;
+	time_t t;
 #if defined USE_NC || defined USE_OT_NONCE
 	unsigned int n_id;
 	unsigned char pf;
@@ -351,6 +356,13 @@ int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
 		   without prompting for password */
 		return 4;
 	}
+	t=ser_time(0);
+	if (unlikely((since > t) && ((since-t) > nonce_auth_max_drift) )){
+		/* the nonce comes from the future, either because of an external
+		 * time adjustment, or because it was generated by another host
+		 * which has the time slightly unsynchronized */
+		return 4; /* consider it stale */
+	}
 	b_nonce2=b_nonce; /*pre-fill it with the values from the received nonce*/
 	b_nonce2.n.expire=b_nonce.n.expire;
 	b_nonce2.n.since=b_nonce.n.since;
@@ -433,7 +445,7 @@ int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
 #ifdef USE_NC
 check_stale:
 #endif /* USE_NC */
-		if (unlikely(is_bin_nonce_stale(&b_nonce)))
+		if (unlikely(is_bin_nonce_stale(&b_nonce, t)))
 			return 4;
 		return 0;
 	}

+ 7 - 0
modules_s/auth/nonce.h

@@ -37,6 +37,7 @@
 #include "../../basex.h"
 #include <time.h>
 
+
 /* auth_extra_checks flags */
 
 #define AUTH_CHECK_FULL_URI (1 << 0)
@@ -193,6 +194,12 @@ extern int auth_checks_ood;
 /* Extra authentication checks for in-dialog requests */
 extern int auth_checks_ind;
 
+/* maximum time drift accepted for the nonce creation time
+ * (e.g. nonce generated by another proxy in the same cluster with the
+ * clock slightly in the future)
+ */
+extern unsigned int  nonce_auth_max_drift;
+
 
 int get_auth_checks(struct sip_msg* msg);