The unified diff between revisions [42a3aae6..] and [7d35b89c..] is displayed below. It can also be downloaded as a raw diff.

#
#
# patch "src/wccp2.c"
#  from [1b190df818172582f99db350a9efb6c578107aba]
#    to [d0cf73950338967c508af753697bdbc1ac8c48fe]
#
============================================================
--- src/wccp2.c	1b190df818172582f99db350a9efb6c578107aba
+++ src/wccp2.c	d0cf73950338967c508af753697bdbc1ac8c48fe
@@ -399,6 +399,7 @@ wccp2_update_md5_security(char *password
 	ws = (struct wccp2_security_md5_t *) ptr;
 	assert(ws->security_type == WCCP2_SECURITY_INFO);
 	/* Its the security part */
+	/* XXX shouldn't this be ntohl() ? */
 	if (htonl(ws->security_option) != WCCP2_MD5_SECURITY) {
 		debug(80, 5) ("wccp2_update_md5_security: this service ain't md5'ing, abort\n");
 		return 0;
@@ -427,7 +428,38 @@ wccp2_check_security(struct wccp2_servic
 char
 wccp2_check_security(struct wccp2_service_list_t *srv, char *security, char *packet, int len)
 {
-	return 1;
+	struct wccp2_security_md5_t *ws = (struct wccp2_security_md5_t *) security;
+	u_int8_t md5_digest[16], md5_challenge[16];
+	char pwd[WCCP2_PASSWORD_LEN];
+	MD5_CTX M;
+
+	/* Make sure the security type matches what we expect */
+	if (ntohl(ws->security_option) != srv->wccp2_security_type) {
+		debug(80, 1) ("wccp2_check_security: received packet has the wrong security option\n");
+		return 0;
+	}
+	if (srv->wccp2_security_type == WCCP2_NO_SECURITY) {
+		return 1;
+	}
+	if (srv->wccp2_security_type != WCCP2_MD5_SECURITY) {
+		debug(80, 1) ("wccp2_check_security: invalid security option\n");
+		return 1;
+	}
+	/* If execution makes it here then we have an MD5 security */
+
+	/* The password field, for the MD5 hash, needs to be 8 bytes and NUL padded. */
+	bzero(pwd, sizeof(pwd));
+	strncpy(pwd, srv->wccp_password, sizeof(pwd));
+
+	/* Take a copy of the challenge: we need to NUL it before comparing */
+	memcpy(md5_challenge, ws->security_implementation, 16);
+	bzero(ws->security_implementation, sizeof(ws->security_implementation));
+	MD5Init(&M);
+	MD5Update(&M, pwd, 8);
+	MD5Update(&M, packet, len);
+	MD5Final(md5_digest, &M);
+
+	return (memcmp(md5_digest, md5_challenge, 16) == 0);
 }


@@ -892,7 +924,6 @@ wccp2HandleUdp(int sock, void *not_used)
 	return;
     }

-    /* TODO: MD5 security */
     if(ntohl(security_info->security_option) != ntohl(service_list_ptr->security_info->security_option)) {
 	debug(80, 1) ("Invalid security option in WCCPv2 Packet (%d vs %d).\n",
 	    ntohl(security_info->security_option),