Mercurial > hg > dhcpcd
changeset 4266:bd15cb1af330 draft
auth: allow different tokens for send and receive
It was silly of me to assume that the same key would be used for
both sending and receiving. Because token protocol is not digested,
replace the digest argument with 0x123/0x456 where 0x123 is the
sending key and 0x456 is the receiving key.
Receiving key defaults to sending key, sending key defaults to zero.
This should allow existing configurations to work as is.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Sun, 29 Apr 2018 21:38:58 +0100 |
| parents | 59d30b522937 |
| children | b5284aa7f420 |
| files | src/auth.c src/auth.h src/dhcpcd.conf.5.in src/if-options.c |
| diffstat | 4 files changed, 50 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth.c Sun Apr 29 21:28:15 2018 +0100 +++ b/src/auth.c Sun Apr 29 21:38:58 2018 +0100 @@ -191,7 +191,7 @@ * Rest of data is MAC. */ switch (protocol) { case AUTH_PROTO_TOKEN: - secretid = 0; + secretid = auth->token_rcv_secretid; break; case AUTH_PROTO_DELAYED: if (dlen < sizeof(secretid) + sizeof(hmac_code)) { @@ -199,6 +199,7 @@ return NULL; } memcpy(&secretid, d, sizeof(secretid)); + secretid = ntohl(secretid); d += sizeof(secretid); dlen -= sizeof(secretid); break; @@ -214,6 +215,7 @@ dlen -= realm_len; } memcpy(&secretid, d, sizeof(secretid)); + secretid = ntohl(secretid); d += sizeof(secretid); dlen -= sizeof(secretid); break; @@ -283,7 +285,6 @@ } /* Find a token for the realm and secret */ - secretid = ntohl(secretid); TAILQ_FOREACH(t, &auth->tokens, next) { if (t->secretid == secretid && t->realm_len == realm_len && @@ -499,11 +500,12 @@ uint32_t giaddr, secretid; bool auth_info; - if (auth->protocol == 0 && t == NULL) { + /* Ignore the token argument given to us - always send using the + * configured token. */ + if (auth->protocol == AUTH_PROTO_TOKEN) { TAILQ_FOREACH(t, &auth->tokens, next) { - if (t->secretid == 0 && - t->realm_len == 0) - break; + if (t->secretid == auth->token_snd_secretid) + break; } if (t == NULL) { errno = EINVAL;
--- a/src/auth.h Sun Apr 29 21:28:15 2018 +0100 +++ b/src/auth.h Sun Apr 29 21:38:58 2018 +0100 @@ -71,6 +71,8 @@ uint64_t last_replay; uint8_t last_replay_set; struct token_head tokens; + uint32_t token_snd_secretid; + uint32_t token_rcv_secretid; #endif };
--- a/src/dhcpcd.conf.5.in Sun Apr 29 21:28:15 2018 +0100 +++ b/src/dhcpcd.conf.5.in Sun Apr 29 21:38:58 2018 +0100 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd February 2, 2018 +.Dd April 29, 2018 .Dt DHCPCD.CONF 5 .Os .Sh NAME @@ -74,9 +74,16 @@ .D1 # A generic 192.168.0.1 network .D1 profile 192.168.0.1 .D1 static ip_address=192.168.0.98/24 -.It Ic authprotocol Ar protocol Ar algorithm Ar rdm +.It Ic authprotocol Ar protocol Op Ar algorithm Op Ar rdm Authenticate DHCP messages. See the Supported Authentication Protocols section. +If +.Ar protocol +is +.Ar token +then +.Ar algorithm is +snd_secretid/rcv_secretid so you can send and recieve different tokens. .It Ic authtoken Ar secretid Ar realm Ar expire Ar key Define a shared key for use in authentication. .Ar realm @@ -863,7 +870,11 @@ .Ss Supported Authentication Protocols .Bl -tag -width -indent .It Ic token -Sends and expects the token with the secretid 0 and realm of "" in each message. +Sends a plain text token the server expects and matches a token sent by +the server. +The tokens to not have to be the same. +If unspecified, the token with secretid of 0 will be used in sending messages +and validating received messages. .It Ic delayedrealm Delayed Authentication. .Nm dhcpcd
--- a/src/if-options.c Sun Apr 29 21:28:15 2018 +0100 +++ b/src/if-options.c Sun Apr 29 21:38:58 2018 +0100 @@ -1913,12 +1913,32 @@ } if (fp) *fp++ = '\0'; - if (strcasecmp(arg, "hmacmd5") == 0 || - strcasecmp(arg, "hmac-md5") == 0) - ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; - else { - logerrx("%s: unsupported algorithm", arg); - return 1; + if (ifo->auth.protocol == AUTH_PROTO_TOKEN) { + np = strchr(arg, '/'); + if (np) { + if (fp == NULL || np < fp) + *np++ = '\0'; + else + np = NULL; + } + if (parse_uint32(&ifo->auth.token_snd_secretid, + arg) == -1) + logerrx("%s: not a number", arg); + else + ifo->auth.token_rcv_secretid = + ifo->auth.token_snd_secretid; + if (np && + parse_uint32(&ifo->auth.token_rcv_secretid, + np) == -1) + logerrx("%s: not a number", arg); + } else { + if (strcasecmp(arg, "hmacmd5") == 0 || + strcasecmp(arg, "hmac-md5") == 0) + ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; + else { + logerrx("%s: unsupported algorithm", arg); + return 1; + } } arg = fp; if (arg == NULL) {
