From 6807c7f6e14f79657a713e6a86513b8573ed5854 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 11 Aug 2021 13:54:52 +0200 Subject: [PATCH] ADMIN: dyncookie: implement a simple dynamic cookie calculator This utility can be useful to figure what cookie value a server will have based on the secret, its IP and its port. --- .gitignore | 1 + Makefile | 4 +++ admin/dyncookie/dyncookie.c | 55 +++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 admin/dyncookie/dyncookie.c diff --git a/.gitignore b/.gitignore index cd92620b5..ec9dd62d0 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ *.bak # And reject some specific files /admin/halog/halog +/admin/dyncookie/dyncookie /admin/iprange/ip6range /admin/iprange/iprange /admin/systemd/haproxy.service diff --git a/Makefile b/Makefile index d598e60ac..e88ab302e 100644 --- a/Makefile +++ b/Makefile @@ -937,6 +937,9 @@ objsize: haproxy admin/halog/halog: admin/halog/halog.o admin/halog/fgets2.o src/ebtree.o src/eb32tree.o src/eb64tree.o src/ebmbtree.o src/ebsttree.o src/ebistree.o src/ebimtree.o $(cmd_LD) $(LDFLAGS) -o $@ $^ $(LDOPTS) +admin/dyncookie/dyncookie: admin/dyncookie/dyncookie.o + $(cmd_LD) $(LDFLAGS) -o $@ $^ $(LDOPTS) + dev/flags/flags: dev/flags/flags.o $(cmd_LD) $(LDFLAGS) -o $@ $^ $(LDOPTS) @@ -1012,6 +1015,7 @@ clean: $(Q)rm -f addons/wurfl/*.[oas] addons/wurfl/dummy/*.[oas] $(Q)rm -f admin/*/*.[oas] admin/*/*/*.[oas] $(Q)rm -f admin/iprange/iprange admin/iprange/ip6range admin/halog/halog + $(Q)rm -f admin/dyncookie/dyncookie $(Q)rm -f dev/*/*.[oas] $(Q)rm -f dev/flags/flags dev/poll/poll dev/tcploop/tcploop $(Q)rm -f dev/hpack/decode dev/hpack/gen-enc dev/hpack/gen-rht diff --git a/admin/dyncookie/dyncookie.c b/admin/dyncookie/dyncookie.c new file mode 100644 index 000000000..0c778eb7a --- /dev/null +++ b/admin/dyncookie/dyncookie.c @@ -0,0 +1,55 @@ +/* + * Dynamic server cookie calculator + * + * Copyright 2021 Willy Tarreau + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include + +__attribute__((noreturn)) void die(int code, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + exit(code); +} + +int main(int argc, char **argv) +{ + size_t key_len; + int addr_len; + char *buf; + int port; + + if (argc < 4) + die(1, "Usage: %s \n", argv[0]); + + key_len = strlen(argv[1]); + buf = realloc(strdup(argv[1]), key_len + 16 + 4); + if (!buf) + die(2, "Not enough memory\n"); + + if (inet_pton(AF_INET, argv[2], buf + key_len) > 0) + addr_len = 4; + else if (inet_pton(AF_INET6, argv[2], buf + key_len) > 0) + addr_len = 16; + else + die(3, "Cannot parse address <%s> as IPv4/IPv6\n", argv[2]); + + port = htonl(atoi(argv[3])); + memcpy(buf + key_len + addr_len, &port, 4); + printf("%016llx\n", (long long)XXH64(buf, key_len + addr_len + 4, 0)); + return 0; +}