diff options
author | Gordon GECOS <u@adam> | 2023-12-05 11:34:09 -0500 |
---|---|---|
committer | Gordon GECOS <u@adam> | 2023-12-05 12:00:43 -0500 |
commit | 0e7558a78fb61b6de50bc3ef12a0eccad3da312c (patch) | |
tree | 3b9d42a7e372f64da1a2c41fe19ed632ea88b2d0 | |
parent | 847a3b4fc36485bb2d6e331d5707f233c7ffc2b5 (diff) |
sign the network part with the system host key
after verifying local connectivity of the IP <-- TODO
and if we have peer nodes,
in our not-at-all-implemented cluster,
then verifying connectivity through that address+key
through encrypting our signed message to the addresses of our peers
in a cryptographic scheme allowing their revelation by vote
thus it is an offline verification allowing us to publish the encrypted data
put that shit in http:///.well-known ??
then extract the local part from the signature's public key
-rwxr-xr-x | signme.bash | 76 | ||||
-rw-r--r-- | src/inet_lnaof.c | 58 | ||||
-rwxr-xr-x | src/inet_ntop | 7 | ||||
-rwxr-xr-x | src/inet_pton | 4 |
4 files changed, 145 insertions, 0 deletions
diff --git a/signme.bash b/signme.bash new file mode 100755 index 0000000..3d764e7 --- /dev/null +++ b/signme.bash | |||
@@ -0,0 +1,76 @@ | |||
1 | #!/bin/bash | ||
2 | set -e | ||
3 | set -o pipefail | ||
4 | |||
5 | extract_local_ip () | ||
6 | { | ||
7 | sed -n -E -e 's/^[0-9]+ bytes from (fe80::[a-f:0-9]+(%[^ ]*)?): .*/\1/ip' | ||
8 | } | ||
9 | |||
10 | local_ips () | ||
11 | { | ||
12 | ping -n -w1 ff02::1${INTERFACE:+%$INTERFACE} 2>/dev/null | extract_local_ip | ||
13 | } | ||
14 | |||
15 | scan () | ||
16 | { | ||
17 | ssh-keyscan -t ed25519 -D "$@" 2>/dev/null | ||
18 | } | ||
19 | |||
20 | select_sha256 () | ||
21 | { | ||
22 | while read | ||
23 | do | ||
24 | set -- $REPLY | ||
25 | if [ "$2 $3 $4 $5" = "IN SSHFP 4 2" ] | ||
26 | then | ||
27 | printf '%s\n' "$1 $6" | ||
28 | fi | ||
29 | done | ||
30 | } | ||
31 | |||
32 | addr_select () | ||
33 | { | ||
34 | jq -r \ | ||
35 | ' | ||
36 | .[] | { | ||
37 | ifname, | ||
38 | addr_info: .addr_info | .[] | select(.scope == "global") | ||
39 | | select(.prefixlen < 128) | ||
40 | | {local, prefixlen} | ||
41 | } | | ||
42 | .ifname + " " + .addr_info.local + " " + (.addr_info.prefixlen | tostring) | ||
43 | ' | ||
44 | } | ||
45 | |||
46 | with_ip_bits() | ||
47 | { | ||
48 | local ip="$1" | ||
49 | shift | ||
50 | ./src/inet_pton "$ip" | "$@" | ./src/inet_ntop | ||
51 | } | ||
52 | |||
53 | self_ip() | ||
54 | { | ||
55 | scan ::1 | select_sha256 | while read localhost hash | ||
56 | do | ||
57 | [ "$localhost" = ::1 ] || exit 28 | ||
58 | printf '%s' "$hash" | tail -c 32 | base16 -d | ./src/inet_ntop | ||
59 | break | ||
60 | done | ||
61 | } | ||
62 | |||
63 | self_ip=$(self_ip) || exit 3 | ||
64 | |||
65 | /sbin/ip -6 -j addr | addr_select | while read iface network_ip bits | ||
66 | do | ||
67 | localip=$(with_ip_bits $self_ip ./a.out $bits) | ||
68 | network=$(with_ip_bits $network_ip ./a.out -$bits) | ||
69 | echo $iface $localip >&2 | ||
70 | echo $network/$bits | ||
71 | done | ||
72 | exit | ||
73 | |||
74 | IPS=($(local_ips)) | ||
75 | scan "${IPS[@]}" | select_sha256 | ||
76 | |||
diff --git a/src/inet_lnaof.c b/src/inet_lnaof.c new file mode 100644 index 0000000..e45ee34 --- /dev/null +++ b/src/inet_lnaof.c | |||
@@ -0,0 +1,58 @@ | |||
1 | #include <assert.h> | ||
2 | #include <netinet/in.h> | ||
3 | #include <stdbool.h> | ||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | #include <strings.h> | ||
7 | #include <sys/socket.h> | ||
8 | |||
9 | /* Why am I writing code like this | ||
10 | in 2023 though? Why isn't this in | ||
11 | some library somewhere I can find? | ||
12 | Seriously, wtf? */ | ||
13 | |||
14 | void zero_from_the_left(uint8_t *res, size_t zero_bits) | ||
15 | { | ||
16 | size_t zero_bytes = zero_bits / 8; | ||
17 | zero_bits -= zero_bytes * 8; | ||
18 | |||
19 | bzero(res, zero_bytes); | ||
20 | res[zero_bytes] <<= zero_bits; | ||
21 | res[zero_bytes] >>= zero_bits; | ||
22 | } | ||
23 | |||
24 | void zero_from_the_right(uint8_t *res, size_t zero_bits) | ||
25 | { | ||
26 | size_t zero_bytes = zero_bits / 8; | ||
27 | zero_bits -= zero_bytes * 8; | ||
28 | |||
29 | assert(zero_bytes <= 16); | ||
30 | bzero(&res[16 - zero_bytes], zero_bytes); | ||
31 | res[0] >>= zero_bits; | ||
32 | res[0] <<= zero_bits; | ||
33 | } | ||
34 | |||
35 | int main(int argc, char **argv) | ||
36 | { | ||
37 | if (argc != 2) | ||
38 | return 1; | ||
39 | int bit_count = atoi(argv[1]); | ||
40 | bool from_right = bit_count < 0; | ||
41 | if (from_right) | ||
42 | bit_count += 128; | ||
43 | if (bit_count < 0) | ||
44 | return 2; | ||
45 | if (bit_count > 128) | ||
46 | return 3; | ||
47 | |||
48 | uint8_t address[16]; | ||
49 | if (fread(address, 16, 1, stdin) != 1) | ||
50 | return 4; | ||
51 | |||
52 | if (from_right) | ||
53 | zero_from_the_right(address, bit_count); | ||
54 | else | ||
55 | zero_from_the_left(address, bit_count); | ||
56 | |||
57 | return fwrite(address, 16, 1, stdout) == 1 ? 0 : 5; | ||
58 | } | ||
diff --git a/src/inet_ntop b/src/inet_ntop new file mode 100755 index 0000000..5c8f5cc --- /dev/null +++ b/src/inet_ntop | |||
@@ -0,0 +1,7 @@ | |||
1 | #!/usr/bin/perl | ||
2 | use Socket qw(inet_ntop AF_INET6); | ||
3 | @ARGV == 0 || die "usage: $0 <<< <binary ipv6 address>\n"; | ||
4 | binmode STDIN, ":raw" or die $!; | ||
5 | read STDIN, $address, 16 or die $!; | ||
6 | $address = inet_ntop (AF_INET6, $address) || die "inet_ntop: $!\n"; | ||
7 | print "$address\n"; | ||
diff --git a/src/inet_pton b/src/inet_pton new file mode 100755 index 0000000..f41f8ad --- /dev/null +++ b/src/inet_pton | |||
@@ -0,0 +1,4 @@ | |||
1 | #!/usr/bin/perl | ||
2 | use Socket qw(inet_pton AF_INET6); | ||
3 | @ARGV == 1 || die "usage: $0 <ipv6 address>\n"; | ||
4 | print STDOUT (inet_pton (AF_INET6, $ARGV[0]) || die "inet_pton: $!\n"); | ||