noise: redesign preshared key mode
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
13db708a0f
commit
fabb6eca2b
|
@ -37,16 +37,17 @@ func ipChecksum(buf []byte) uint16 {
|
||||||
func main() {
|
func main() {
|
||||||
ourPrivate, _ := base64.StdEncoding.DecodeString("WAmgVYXkbT2bCtdcDwolI88/iVi/aV3/PHcUBTQSYmo=")
|
ourPrivate, _ := base64.StdEncoding.DecodeString("WAmgVYXkbT2bCtdcDwolI88/iVi/aV3/PHcUBTQSYmo=")
|
||||||
ourPublic, _ := base64.StdEncoding.DecodeString("K5sF9yESrSBsOXPd6TcpKNgqoy1Ik3ZFKl4FolzrRyI=")
|
ourPublic, _ := base64.StdEncoding.DecodeString("K5sF9yESrSBsOXPd6TcpKNgqoy1Ik3ZFKl4FolzrRyI=")
|
||||||
preshared, _ := base64.StdEncoding.DecodeString("FpCyhws9cxwWoV4xELtfJvjJN+zQVRPISllRWgeopVE=")
|
|
||||||
theirPublic, _ := base64.StdEncoding.DecodeString("qRCwZSKInrMAq5sepfCdaCsRJaoLe5jhtzfiw7CjbwM=")
|
theirPublic, _ := base64.StdEncoding.DecodeString("qRCwZSKInrMAq5sepfCdaCsRJaoLe5jhtzfiw7CjbwM=")
|
||||||
|
preshared, _ := base64.StdEncoding.DecodeString("FpCyhws9cxwWoV4xELtfJvjJN+zQVRPISllRWgeopVE=")
|
||||||
cs := noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashBLAKE2s)
|
cs := noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashBLAKE2s)
|
||||||
hs := noise.NewHandshakeState(noise.Config{
|
hs := noise.NewHandshakeState(noise.Config{
|
||||||
CipherSuite: cs,
|
CipherSuite: cs,
|
||||||
Random: rand.Reader,
|
Random: rand.Reader,
|
||||||
Pattern: noise.HandshakeIK,
|
Pattern: noise.HandshakeIK,
|
||||||
Initiator: true,
|
Initiator: true,
|
||||||
Prologue: []byte("WireGuard v0 zx2c4 Jason@zx2c4.com"),
|
Prologue: []byte("WireGuard v1 zx2c4 Jason@zx2c4.com"),
|
||||||
PresharedKey: preshared,
|
PresharedKey: preshared,
|
||||||
|
PresharedKeyPlacement: 2,
|
||||||
StaticKeypair: noise.DHKey{Private: ourPrivate, Public: ourPublic},
|
StaticKeypair: noise.DHKey{Private: ourPrivate, Public: ourPublic},
|
||||||
PeerStatic: theirPublic,
|
PeerStatic: theirPublic,
|
||||||
})
|
})
|
||||||
|
@ -68,8 +69,10 @@ func main() {
|
||||||
initiationPacket[3] = 0 // Reserved
|
initiationPacket[3] = 0 // Reserved
|
||||||
binary.LittleEndian.PutUint32(initiationPacket[4:], 28) // Sender index: 28 (arbitrary)
|
binary.LittleEndian.PutUint32(initiationPacket[4:], 28) // Sender index: 28 (arbitrary)
|
||||||
initiationPacket, _, _ = hs.WriteMessage(initiationPacket, tai64n)
|
initiationPacket, _, _ = hs.WriteMessage(initiationPacket, tai64n)
|
||||||
hasher, _ := blake2s.New(&blake2s.Config{Size: 16, Key: preshared})
|
hasher, _ := blake2s.New(&blake2s.Config{Size: 32})
|
||||||
|
hasher.Write([]byte("mac1----"))
|
||||||
hasher.Write(theirPublic)
|
hasher.Write(theirPublic)
|
||||||
|
hasher, _ = blake2s.New(&blake2s.Config{Size: 16, Key: hasher.Sum(nil)})
|
||||||
hasher.Write(initiationPacket)
|
hasher.Write(initiationPacket)
|
||||||
initiationPacket = append(initiationPacket, hasher.Sum(nil)[:16]...)
|
initiationPacket = append(initiationPacket, hasher.Sum(nil)[:16]...)
|
||||||
initiationPacket = append(initiationPacket, make([]byte, 16)...)
|
initiationPacket = append(initiationPacket, make([]byte, 16)...)
|
||||||
|
|
|
@ -34,7 +34,7 @@ w :: PublicKey Curve25519
|
||||||
-> IO ()
|
-> IO ()
|
||||||
w theirPub (Plaintext myPSK) sock addr msg = do
|
w theirPub (Plaintext myPSK) sock addr msg = do
|
||||||
let x = "\x01\x00\x00\x00\x00\x00" `mappend` msg
|
let x = "\x01\x00\x00\x00\x00\x00" `mappend` msg
|
||||||
mac = hash 16 myPSK (sbToBS' (curvePubToBytes theirPub) `mappend` sbToBS' x)
|
mac = hash 16 myPSK (sbToBS' (curvePubToBytes theirPub) `mappend` sbToBS' x) -- TODO: this should actually be blake2s(key=blake2s("mac1----" || theirPub), payload=blah)
|
||||||
void $ NBS.sendTo sock (x `mappend` mac `mappend` replicate 16 '\0') addr
|
void $ NBS.sendTo sock (x `mappend` mac `mappend` replicate 16 '\0') addr
|
||||||
|
|
||||||
r :: MVar ByteString -> Socket -> IO ByteString
|
r :: MVar ByteString -> Socket -> IO ByteString
|
||||||
|
@ -63,8 +63,8 @@ main = do
|
||||||
serverkey' = curveBytesToPub . bsToSB' . either undefined id . B64.decode . pack $ serverkey :: PublicKey Curve25519
|
serverkey' = curveBytesToPub . bsToSB' . either undefined id . B64.decode . pack $ serverkey :: PublicKey Curve25519
|
||||||
psk' = Plaintext . bsToSB' . either undefined id . B64.decode . pack $ psk
|
psk' = Plaintext . bsToSB' . either undefined id . B64.decode . pack $ psk
|
||||||
hs = handshakeState $ HandshakeStateParams
|
hs = handshakeState $ HandshakeStateParams
|
||||||
noiseIK
|
noiseIK -- TODO: specify psk2 mode
|
||||||
"WireGuard v0 zx2c4 Jason@zx2c4.com"
|
"WireGuard v1 zx2c4 Jason@zx2c4.com"
|
||||||
(Just psk')
|
(Just psk')
|
||||||
(Just mykey')
|
(Just mykey')
|
||||||
Nothing
|
Nothing
|
||||||
|
|
|
@ -39,11 +39,12 @@ fn main() {
|
||||||
owner.set_rs(&their_public);
|
owner.set_rs(&their_public);
|
||||||
let mut cipherstate1 : CipherState<CipherChaChaPoly> = Default::default();
|
let mut cipherstate1 : CipherState<CipherChaChaPoly> = Default::default();
|
||||||
let mut cipherstate2 : CipherState<CipherChaChaPoly> = Default::default();
|
let mut cipherstate2 : CipherState<CipherChaChaPoly> = Default::default();
|
||||||
let mut handshake = HandshakeState::new_from_owner(&mut owner, true, HandshakePattern::IK, "WireGuard v0 zx2c4 Jason@zx2c4.com".as_bytes(), Some(&my_preshared[..]), &mut cipherstate1, &mut cipherstate2);
|
//TODO: specify psk2 mode
|
||||||
|
let mut handshake = HandshakeState::new_from_owner(&mut owner, true, HandshakePattern::IK, "WireGuard v1 zx2c4 Jason@zx2c4.com".as_bytes(), Some(&my_preshared[..]), &mut cipherstate1, &mut cipherstate2);
|
||||||
|
|
||||||
let now = time::get_time();
|
let now = time::get_time();
|
||||||
let mut tai64n = [0; 12];
|
let mut tai64n = [0; 12];
|
||||||
BigEndian::write_i64(&mut tai64n[0..], 4611686018427387914ULL + now.sec);
|
BigEndian::write_i64(&mut tai64n[0..], 4611686018427387914 + now.sec);
|
||||||
BigEndian::write_i32(&mut tai64n[8..], now.nsec);
|
BigEndian::write_i32(&mut tai64n[8..], now.nsec);
|
||||||
let mut initiation_packet = [0; 148];
|
let mut initiation_packet = [0; 148];
|
||||||
initiation_packet[0] = 1; /* Type: Initiation */
|
initiation_packet[0] = 1; /* Type: Initiation */
|
||||||
|
@ -52,11 +53,13 @@ fn main() {
|
||||||
initiation_packet[3] = 0; /* Reserved */
|
initiation_packet[3] = 0; /* Reserved */
|
||||||
LittleEndian::write_u32(&mut initiation_packet[4..], 28); /* Sender index: 28 (arbitrary) */
|
LittleEndian::write_u32(&mut initiation_packet[4..], 28); /* Sender index: 28 (arbitrary) */
|
||||||
handshake.write_message(&tai64n, &mut initiation_packet[8..]);
|
handshake.write_message(&tai64n, &mut initiation_packet[8..]);
|
||||||
let mut mac_material = [0; 148];
|
let mut mac_key_input = [0; 40];
|
||||||
memcpy(&mut mac_material, &their_public);
|
let mut mac_key = [0; 32];
|
||||||
memcpy(&mut mac_material[32..], &initiation_packet[0..116]);
|
memcpy(&mut mac_key_input, b"mac1----");
|
||||||
|
memcpy(&mut mac_key_input[8..], &their_public);
|
||||||
|
Blake2s::blake2s(&mut mac_key, &mac_key_input, &[0; 0]);
|
||||||
let mut mac = [0; 16];
|
let mut mac = [0; 16];
|
||||||
Blake2s::blake2s(&mut mac, &mac_material, &my_preshared);
|
Blake2s::blake2s(&mut mac, &initiation_packet[0..116], &mac_key);
|
||||||
memcpy(&mut initiation_packet[116..], &mac);
|
memcpy(&mut initiation_packet[116..], &mac);
|
||||||
socket.send_to(&initiation_packet, &send_addr).unwrap();
|
socket.send_to(&initiation_packet, &send_addr).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -9,20 +9,20 @@ while read -r -d $'\t' device; do
|
||||||
if [[ $device != "$last_device" ]]; then
|
if [[ $device != "$last_device" ]]; then
|
||||||
[[ -z $last_device ]] && printf '\n' || printf '%s,\n' "$end"
|
[[ -z $last_device ]] && printf '\n' || printf '%s,\n' "$end"
|
||||||
last_device="$device"
|
last_device="$device"
|
||||||
read -r private_key public_key preshared_key listen_port fwmark
|
read -r private_key public_key listen_port fwmark
|
||||||
printf '\t"%s": {' "$device"
|
printf '\t"%s": {' "$device"
|
||||||
delim=$'\n'
|
delim=$'\n'
|
||||||
[[ $private_key == "(none)" ]] || { printf '%s\t\t"privateKey": "%s"' "$delim" "$private_key"; delim=$',\n'; }
|
[[ $private_key == "(none)" ]] || { printf '%s\t\t"privateKey": "%s"' "$delim" "$private_key"; delim=$',\n'; }
|
||||||
[[ $public_key == "(none)" ]] || { printf '%s\t\t"publicKey": "%s"' "$delim" "$public_key"; delim=$',\n'; }
|
[[ $public_key == "(none)" ]] || { printf '%s\t\t"publicKey": "%s"' "$delim" "$public_key"; delim=$',\n'; }
|
||||||
[[ $preshared_key == "(none)" ]] || { printf '%s\t\t"presharedKey": "%s"' "$delim" "$preshared_key"; delim=$',\n'; }
|
|
||||||
[[ $listen_port == "0" ]] || { printf '%s\t\t"listenPort": %u' "$delim" $(( $listen_port )); delim=$',\n'; }
|
[[ $listen_port == "0" ]] || { printf '%s\t\t"listenPort": %u' "$delim" $(( $listen_port )); delim=$',\n'; }
|
||||||
[[ $fwmark == "off" ]] || { printf '%s\t\t"fwmark": %u' "$delim" $(( $fwmark )); delim=$',\n'; }
|
[[ $fwmark == "off" ]] || { printf '%s\t\t"fwmark": %u' "$delim" $(( $fwmark )); delim=$',\n'; }
|
||||||
printf '%s\t\t"peers": {' "$delim"; end=$'\n\t\t}\n\t}'
|
printf '%s\t\t"peers": {' "$delim"; end=$'\n\t\t}\n\t}'
|
||||||
delim=$'\n'
|
delim=$'\n'
|
||||||
else
|
else
|
||||||
read -r public_key endpoint allowed_ips latest_handshake transfer_rx transfer_tx persistent_keepalive
|
read -r public_key preshared_key endpoint allowed_ips latest_handshake transfer_rx transfer_tx persistent_keepalive
|
||||||
printf '%s\t\t\t"%s": {' "$delim" "$public_key"
|
printf '%s\t\t\t"%s": {' "$delim" "$public_key"
|
||||||
delim=$'\n'
|
delim=$'\n'
|
||||||
|
[[ $preshared_key == "(none)" ]] || { printf '%s\t\t\t\t"presharedKey": "%s"' "$delim" "$preshared_key"; delim=$',\n'; }
|
||||||
[[ $endpoint == "(none)" ]] || { printf '%s\t\t\t\t"endpoint": "%s"' "$delim" "$endpoint"; delim=$',\n'; }
|
[[ $endpoint == "(none)" ]] || { printf '%s\t\t\t\t"endpoint": "%s"' "$delim" "$endpoint"; delim=$',\n'; }
|
||||||
[[ $latest_handshake == "0" ]] || { printf '%s\t\t\t\t"latestHandshake": %u' "$delim" $(( $latest_handshake )); delim=$',\n'; }
|
[[ $latest_handshake == "0" ]] || { printf '%s\t\t\t\t"latestHandshake": %u' "$delim" $(( $latest_handshake )); delim=$',\n'; }
|
||||||
[[ $transfer_rx == "0" ]] || { printf '%s\t\t\t\t"transferRx": %u' "$delim" $(( $transfer_rx )); delim=$',\n'; }
|
[[ $transfer_rx == "0" ]] || { printf '%s\t\t\t\t"transferRx": %u' "$delim" $(( $transfer_rx )); delim=$',\n'; }
|
||||||
|
|
|
@ -21,7 +21,7 @@ _wg_completion() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $COMP_CWORD -eq 3 && ${COMP_WORDS[1]} == show && ${COMP_WORDS[2]} != interfaces ]]; then
|
if [[ $COMP_CWORD -eq 3 && ${COMP_WORDS[1]} == show && ${COMP_WORDS[2]} != interfaces ]]; then
|
||||||
COMPREPLY+=( $(compgen -W "public-key private-key preshared-key listen-port peers endpoints allowed-ips fwmark latest-handshakes persistent-keepalive transfer dump" -- "${COMP_WORDS[3]}") )
|
COMPREPLY+=( $(compgen -W "public-key private-key listen-port peers preshared-keys endpoints allowed-ips fwmark latest-handshakes persistent-keepalive transfer dump" -- "${COMP_WORDS[3]}") )
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -39,7 +39,6 @@ _wg_completion() {
|
||||||
[[ ${COMP_WORDS[i]} == listen-port ]] && has_listen_port=1
|
[[ ${COMP_WORDS[i]} == listen-port ]] && has_listen_port=1
|
||||||
[[ ${COMP_WORDS[i]} == fwmark ]] && has_fwmark=1
|
[[ ${COMP_WORDS[i]} == fwmark ]] && has_fwmark=1
|
||||||
[[ ${COMP_WORDS[i]} == private-key ]] && has_private_key=1
|
[[ ${COMP_WORDS[i]} == private-key ]] && has_private_key=1
|
||||||
[[ ${COMP_WORDS[i]} == preshared-key ]] && has_preshared_key=1
|
|
||||||
[[ ${COMP_WORDS[i]} == peer ]] && { has_peer=$i; break; }
|
[[ ${COMP_WORDS[i]} == peer ]] && { has_peer=$i; break; }
|
||||||
done
|
done
|
||||||
if [[ $has_peer -eq 0 ]]; then
|
if [[ $has_peer -eq 0 ]]; then
|
||||||
|
@ -47,7 +46,6 @@ _wg_completion() {
|
||||||
[[ $has_listen_port -eq 1 ]] || words+=( listen-port )
|
[[ $has_listen_port -eq 1 ]] || words+=( listen-port )
|
||||||
[[ $has_fwmark -eq 1 ]] || words+=( fwmark )
|
[[ $has_fwmark -eq 1 ]] || words+=( fwmark )
|
||||||
[[ $has_private_key -eq 1 ]] || words+=( private-key )
|
[[ $has_private_key -eq 1 ]] || words+=( private-key )
|
||||||
[[ $has_preshared_key -eq 1 ]] || words+=( preshared-key )
|
|
||||||
words+=( peer )
|
words+=( peer )
|
||||||
COMPREPLY+=( $(compgen -W "${words[*]}" -- "${COMP_WORDS[COMP_CWORD]}") )
|
COMPREPLY+=( $(compgen -W "${words[*]}" -- "${COMP_WORDS[COMP_CWORD]}") )
|
||||||
elif [[ ${COMP_WORDS[COMP_CWORD-1]} == *-key ]]; then
|
elif [[ ${COMP_WORDS[COMP_CWORD-1]} == *-key ]]; then
|
||||||
|
@ -70,6 +68,7 @@ _wg_completion() {
|
||||||
has_endpoint=0
|
has_endpoint=0
|
||||||
has_persistent_keepalive=0
|
has_persistent_keepalive=0
|
||||||
has_allowed_ips=0
|
has_allowed_ips=0
|
||||||
|
has_preshared_key=0
|
||||||
[[ ${COMP_WORDS[i+2]} == = ]] && ((i+=2)) || ((i++))
|
[[ ${COMP_WORDS[i+2]} == = ]] && ((i+=2)) || ((i++))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
@ -77,6 +76,7 @@ _wg_completion() {
|
||||||
[[ ${COMP_WORDS[i]} == endpoint ]] && has_endpoint=1
|
[[ ${COMP_WORDS[i]} == endpoint ]] && has_endpoint=1
|
||||||
[[ ${COMP_WORDS[i]} == persistent-keepalive ]] && has_persistent_keepalive=1
|
[[ ${COMP_WORDS[i]} == persistent-keepalive ]] && has_persistent_keepalive=1
|
||||||
[[ ${COMP_WORDS[i]} == allowed-ips ]] && has_allowed_ips=1
|
[[ ${COMP_WORDS[i]} == allowed-ips ]] && has_allowed_ips=1
|
||||||
|
[[ ${COMP_WORDS[i]} == preshared-key ]] && has_preshared_key=1
|
||||||
|
|
||||||
[[ ${COMP_WORDS[i]} == remove ]] || ((i++))
|
[[ ${COMP_WORDS[i]} == remove ]] || ((i++))
|
||||||
done
|
done
|
||||||
|
@ -84,6 +84,7 @@ _wg_completion() {
|
||||||
((COMP_CWORD == j)) || return
|
((COMP_CWORD == j)) || return
|
||||||
|
|
||||||
if [[ $has_remove -ne 1 ]]; then
|
if [[ $has_remove -ne 1 ]]; then
|
||||||
|
[[ $has_preshared_key -eq 1 ]] || words+=( preshared-key )
|
||||||
[[ $has_endpoint -eq 1 ]] || words+=( endpoint )
|
[[ $has_endpoint -eq 1 ]] || words+=( endpoint )
|
||||||
[[ $has_allowed_ips -eq 1 ]] || words+=( allowed-ips )
|
[[ $has_allowed_ips -eq 1 ]] || words+=( allowed-ips )
|
||||||
[[ $has_persistent_keepalive -eq 1 ]] || words+=( persistent-keepalive )
|
[[ $has_persistent_keepalive -eq 1 ]] || words+=( persistent-keepalive )
|
||||||
|
|
43
src/config.c
43
src/config.c
|
@ -323,10 +323,6 @@ static bool process_line(struct config_ctx *ctx, const char *line)
|
||||||
ret = parse_key(ctx->buf.dev->private_key, value);
|
ret = parse_key(ctx->buf.dev->private_key, value);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
memset(ctx->buf.dev->private_key, 0, WG_KEY_LEN);
|
memset(ctx->buf.dev->private_key, 0, WG_KEY_LEN);
|
||||||
} else if (key_match("PresharedKey")) {
|
|
||||||
ret = parse_key(ctx->buf.dev->preshared_key, value);
|
|
||||||
if (!ret)
|
|
||||||
memset(ctx->buf.dev->preshared_key, 0, WG_KEY_LEN);
|
|
||||||
} else
|
} else
|
||||||
goto error;
|
goto error;
|
||||||
} else if (ctx->is_peer_section) {
|
} else if (ctx->is_peer_section) {
|
||||||
|
@ -338,7 +334,11 @@ static bool process_line(struct config_ctx *ctx, const char *line)
|
||||||
ret = parse_ipmasks(&ctx->buf, ctx->peer_offset, value);
|
ret = parse_ipmasks(&ctx->buf, ctx->peer_offset, value);
|
||||||
else if (key_match("PersistentKeepalive"))
|
else if (key_match("PersistentKeepalive"))
|
||||||
ret = parse_persistent_keepalive(&peer_from_offset(ctx->buf.dev, ctx->peer_offset)->persistent_keepalive_interval, value);
|
ret = parse_persistent_keepalive(&peer_from_offset(ctx->buf.dev, ctx->peer_offset)->persistent_keepalive_interval, value);
|
||||||
else
|
else if (key_match("PresharedKey")) {
|
||||||
|
ret = parse_key(peer_from_offset(ctx->buf.dev, ctx->peer_offset)->preshared_key, value);
|
||||||
|
if (!ret)
|
||||||
|
memset(peer_from_offset(ctx->buf.dev, ctx->peer_offset)->preshared_key, 0, WG_KEY_LEN);
|
||||||
|
} else
|
||||||
goto error;
|
goto error;
|
||||||
} else
|
} else
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -408,8 +408,6 @@ bool config_read_finish(struct config_ctx *ctx)
|
||||||
fprintf(stderr, "No private key configured\n");
|
fprintf(stderr, "No private key configured\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (ctx->buf.dev->flags & WGDEVICE_REPLACE_PEERS && !key_is_valid(ctx->buf.dev->preshared_key))
|
|
||||||
ctx->buf.dev->flags |= WGDEVICE_REMOVE_PRESHARED_KEY;
|
|
||||||
if (ctx->buf.dev->flags & WGDEVICE_REPLACE_PEERS && !ctx->buf.dev->fwmark)
|
if (ctx->buf.dev->flags & WGDEVICE_REPLACE_PEERS && !ctx->buf.dev->fwmark)
|
||||||
ctx->buf.dev->flags |= WGDEVICE_REMOVE_FWMARK;
|
ctx->buf.dev->flags |= WGDEVICE_REMOVE_FWMARK;
|
||||||
|
|
||||||
|
@ -508,21 +506,6 @@ bool config_read_cmd(struct wgdevice **device, char *argv[], int argc)
|
||||||
goto error;
|
goto error;
|
||||||
argv += 2;
|
argv += 2;
|
||||||
argc -= 2;
|
argc -= 2;
|
||||||
} else if (!strcmp(argv[0], "preshared-key") && argc >= 2 && !buf.dev->num_peers) {
|
|
||||||
char *line;
|
|
||||||
int ret = read_line(&line, argv[1]);
|
|
||||||
if (ret == 0) {
|
|
||||||
if (!parse_key(buf.dev->preshared_key, line)) {
|
|
||||||
free(line);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
free(line);
|
|
||||||
} else if (ret == 1)
|
|
||||||
buf.dev->flags |= WGDEVICE_REMOVE_PRESHARED_KEY;
|
|
||||||
else
|
|
||||||
goto error;
|
|
||||||
argv += 2;
|
|
||||||
argc -= 2;
|
|
||||||
} else if (!strcmp(argv[0], "peer") && argc >= 2) {
|
} else if (!strcmp(argv[0], "peer") && argc >= 2) {
|
||||||
peer_offset = buf.pos;
|
peer_offset = buf.pos;
|
||||||
if (use_space(&buf, sizeof(struct wgpeer)) < 0) {
|
if (use_space(&buf, sizeof(struct wgpeer)) < 0) {
|
||||||
|
@ -560,6 +543,22 @@ bool config_read_cmd(struct wgdevice **device, char *argv[], int argc)
|
||||||
goto error;
|
goto error;
|
||||||
argv += 2;
|
argv += 2;
|
||||||
argc -= 2;
|
argc -= 2;
|
||||||
|
} else if (!strcmp(argv[0], "preshared-key") && argc >= 2 && buf.dev->num_peers) {
|
||||||
|
char *line;
|
||||||
|
int ret = read_line(&line, argv[1]);
|
||||||
|
if (ret == 0) {
|
||||||
|
if (!parse_key(peer_from_offset(buf.dev, peer_offset)->preshared_key, line)) {
|
||||||
|
free(line);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
free(line);
|
||||||
|
} else if (ret == 1) {
|
||||||
|
free(line);
|
||||||
|
buf.dev->flags |= WGPEER_REMOVE_PRESHARED_KEY;
|
||||||
|
} else
|
||||||
|
goto error;
|
||||||
|
argv += 2;
|
||||||
|
argc -= 2;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Invalid argument: %s\n", argv[0]);
|
fprintf(stderr, "Invalid argument: %s\n", argv[0]);
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
@ -13,7 +13,7 @@ int set_main(int argc, char *argv[])
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...] ]...\n", PROG_NAME, argv[0]);
|
fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [preshared-key <file path>] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...] ]...\n", PROG_NAME, argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
src/show.c
19
src/show.c
|
@ -201,7 +201,7 @@ static char *bytes(uint64_t b)
|
||||||
static const char *COMMAND_NAME = NULL;
|
static const char *COMMAND_NAME = NULL;
|
||||||
static void show_usage(void)
|
static void show_usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces } [public-key | private-key | preshared-key | listen-port | fwmark | peers | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump]\n", PROG_NAME, COMMAND_NAME);
|
fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces } [public-key | private-key | listen-port | fwmark | peers | preshared-keys | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump]\n", PROG_NAME, COMMAND_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pretty_print(struct wgdevice *device)
|
static void pretty_print(struct wgdevice *device)
|
||||||
|
@ -216,8 +216,6 @@ static void pretty_print(struct wgdevice *device)
|
||||||
terminal_printf(" " TERMINAL_BOLD "public key" TERMINAL_RESET ": %s\n", key(device->public_key));
|
terminal_printf(" " TERMINAL_BOLD "public key" TERMINAL_RESET ": %s\n", key(device->public_key));
|
||||||
if (memcmp(device->private_key, zero, WG_KEY_LEN))
|
if (memcmp(device->private_key, zero, WG_KEY_LEN))
|
||||||
terminal_printf(" " TERMINAL_BOLD "private key" TERMINAL_RESET ": %s\n", masked_key(device->private_key));
|
terminal_printf(" " TERMINAL_BOLD "private key" TERMINAL_RESET ": %s\n", masked_key(device->private_key));
|
||||||
if (memcmp(device->preshared_key, zero, WG_KEY_LEN))
|
|
||||||
terminal_printf(" " TERMINAL_BOLD "preshared key" TERMINAL_RESET ": %s\n", masked_key(device->preshared_key));
|
|
||||||
if (device->port)
|
if (device->port)
|
||||||
terminal_printf(" " TERMINAL_BOLD "listening port" TERMINAL_RESET ": %u\n", device->port);
|
terminal_printf(" " TERMINAL_BOLD "listening port" TERMINAL_RESET ": %u\n", device->port);
|
||||||
if (device->fwmark)
|
if (device->fwmark)
|
||||||
|
@ -228,6 +226,8 @@ static void pretty_print(struct wgdevice *device)
|
||||||
}
|
}
|
||||||
for_each_wgpeer(device, peer, i) {
|
for_each_wgpeer(device, peer, i) {
|
||||||
terminal_printf(TERMINAL_FG_YELLOW TERMINAL_BOLD "peer" TERMINAL_RESET ": " TERMINAL_FG_YELLOW "%s" TERMINAL_RESET "\n", key(peer->public_key));
|
terminal_printf(TERMINAL_FG_YELLOW TERMINAL_BOLD "peer" TERMINAL_RESET ": " TERMINAL_FG_YELLOW "%s" TERMINAL_RESET "\n", key(peer->public_key));
|
||||||
|
if (memcmp(peer->preshared_key, zero, WG_KEY_LEN))
|
||||||
|
terminal_printf(" " TERMINAL_BOLD "preshared key" TERMINAL_RESET ": %s\n", masked_key(peer->preshared_key));
|
||||||
if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
|
if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
|
||||||
terminal_printf(" " TERMINAL_BOLD "endpoint" TERMINAL_RESET ": %s\n", endpoint(&peer->endpoint.addr));
|
terminal_printf(" " TERMINAL_BOLD "endpoint" TERMINAL_RESET ": %s\n", endpoint(&peer->endpoint.addr));
|
||||||
terminal_printf(" " TERMINAL_BOLD "allowed ips" TERMINAL_RESET ": ");
|
terminal_printf(" " TERMINAL_BOLD "allowed ips" TERMINAL_RESET ": ");
|
||||||
|
@ -260,7 +260,6 @@ static void dump_print(struct wgdevice *device, bool with_interface)
|
||||||
printf("%s\t", device->interface);
|
printf("%s\t", device->interface);
|
||||||
printf("%s\t", key(device->private_key));
|
printf("%s\t", key(device->private_key));
|
||||||
printf("%s\t", key(device->public_key));
|
printf("%s\t", key(device->public_key));
|
||||||
printf("%s\t", key(device->preshared_key));
|
|
||||||
printf("%u\t", device->port);
|
printf("%u\t", device->port);
|
||||||
if (device->fwmark)
|
if (device->fwmark)
|
||||||
printf("0x%x\n", device->fwmark);
|
printf("0x%x\n", device->fwmark);
|
||||||
|
@ -270,6 +269,7 @@ static void dump_print(struct wgdevice *device, bool with_interface)
|
||||||
if (with_interface)
|
if (with_interface)
|
||||||
printf("%s\t", device->interface);
|
printf("%s\t", device->interface);
|
||||||
printf("%s\t", key(peer->public_key));
|
printf("%s\t", key(peer->public_key));
|
||||||
|
printf("%s\t", key(peer->preshared_key));
|
||||||
if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
|
if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
|
||||||
printf("%s\t", endpoint(&peer->endpoint.addr));
|
printf("%s\t", endpoint(&peer->endpoint.addr));
|
||||||
else
|
else
|
||||||
|
@ -301,10 +301,6 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int
|
||||||
if (with_interface)
|
if (with_interface)
|
||||||
printf("%s\t", device->interface);
|
printf("%s\t", device->interface);
|
||||||
printf("%s\n", key(device->private_key));
|
printf("%s\n", key(device->private_key));
|
||||||
} else if (!strcmp(param, "preshared-key")) {
|
|
||||||
if (with_interface)
|
|
||||||
printf("%s\t", device->interface);
|
|
||||||
printf("%s\n", key(device->preshared_key));
|
|
||||||
} else if (!strcmp(param, "listen-port")) {
|
} else if (!strcmp(param, "listen-port")) {
|
||||||
if (with_interface)
|
if (with_interface)
|
||||||
printf("%s\t", device->interface);
|
printf("%s\t", device->interface);
|
||||||
|
@ -358,6 +354,13 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int
|
||||||
else
|
else
|
||||||
printf("%s\toff\n", key(peer->public_key));
|
printf("%s\toff\n", key(peer->public_key));
|
||||||
}
|
}
|
||||||
|
} else if (!strcmp(param, "preshared-keys")) {
|
||||||
|
for_each_wgpeer(device, peer, i) {
|
||||||
|
if (with_interface)
|
||||||
|
printf("%s\t", device->interface);
|
||||||
|
printf("%s\t", key(peer->public_key));
|
||||||
|
printf("%s\n", key(peer->preshared_key));
|
||||||
|
}
|
||||||
} else if (!strcmp(param, "peers")) {
|
} else if (!strcmp(param, "peers")) {
|
||||||
for_each_wgpeer(device, peer, i) {
|
for_each_wgpeer(device, peer, i) {
|
||||||
if (with_interface)
|
if (with_interface)
|
||||||
|
|
|
@ -50,14 +50,14 @@ int showconf_main(int argc, char *argv[])
|
||||||
key_to_base64(base64, device->private_key);
|
key_to_base64(base64, device->private_key);
|
||||||
printf("PrivateKey = %s\n", base64);
|
printf("PrivateKey = %s\n", base64);
|
||||||
}
|
}
|
||||||
if (memcmp(device->preshared_key, zero, WG_KEY_LEN)) {
|
|
||||||
key_to_base64(base64, device->preshared_key);
|
|
||||||
printf("PresharedKey = %s\n", base64);
|
|
||||||
}
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
for_each_wgpeer(device, peer, i) {
|
for_each_wgpeer(device, peer, i) {
|
||||||
key_to_base64(base64, peer->public_key);
|
key_to_base64(base64, peer->public_key);
|
||||||
printf("[Peer]\nPublicKey = %s\n", base64);
|
printf("[Peer]\nPublicKey = %s\n", base64);
|
||||||
|
if (memcmp(peer->preshared_key, zero, WG_KEY_LEN)) {
|
||||||
|
key_to_base64(base64, peer->preshared_key);
|
||||||
|
printf("PresharedKey = %s\n", base64);
|
||||||
|
}
|
||||||
if (peer->num_ipmasks)
|
if (peer->num_ipmasks)
|
||||||
printf("AllowedIPs = ");
|
printf("AllowedIPs = ");
|
||||||
for_each_wgipmask(peer, ipmask, j) {
|
for_each_wgipmask(peer, ipmask, j) {
|
||||||
|
|
22
src/wg.8
22
src/wg.8
|
@ -36,7 +36,7 @@ Sub-commands that take an INTERFACE must be passed a WireGuard interface.
|
||||||
.SH COMMANDS
|
.SH COMMANDS
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBshow\fP { \fI<interface>\fP | \fIall\fP | \fIinterfaces\fP } [\fIpublic-key\fP | \fIprivate-key\fP | \fIpreshared-key\fP | \fIlisten-port\fP | \fIfwmark\fP | \fIpeers\fP | \fIendpoints\fP | \fIallowed-ips\fP | \fIlatest-handshakes\fP | \fIpersistent-keepalive\fP | \fItransfer\fP | \fIdump\fP]
|
\fBshow\fP { \fI<interface>\fP | \fIall\fP | \fIinterfaces\fP } [\fIpublic-key\fP | \fIprivate-key\fP | \fIlisten-port\fP | \fIfwmark\fP | \fIpeers\fP | \fIpreshared-keys\fP | \fIendpoints\fP | \fIallowed-ips\fP | \fIlatest-handshakes\fP | \fIpersistent-keepalive\fP | \fItransfer\fP | \fIdump\fP]
|
||||||
Shows current WireGuard configuration of specified \fI<interface>\fP.
|
Shows current WireGuard configuration of specified \fI<interface>\fP.
|
||||||
If no \fI<interface>\fP is specified, \fI<interface>\fP defaults to \fIall\fP.
|
If no \fI<interface>\fP is specified, \fI<interface>\fP defaults to \fIall\fP.
|
||||||
If \fIinterfaces\fP is specified, prints a list of all WireGuard interfaces,
|
If \fIinterfaces\fP is specified, prints a list of all WireGuard interfaces,
|
||||||
|
@ -46,16 +46,16 @@ meant for the terminal. Otherwise, prints specified information grouped by
|
||||||
newlines and tabs, meant to be used in scripts. For this script-friendly display,
|
newlines and tabs, meant to be used in scripts. For this script-friendly display,
|
||||||
if \fIall\fP is specified, then the first field for all categories of information
|
if \fIall\fP is specified, then the first field for all categories of information
|
||||||
is the interface name. If \fPdump\fP is specified, then several lines are printed;
|
is the interface name. If \fPdump\fP is specified, then several lines are printed;
|
||||||
the first contains in order separated by tab: private-key, public-key, preshared-key,
|
the first contains in order separated by tab: private-key, public-key, listen-port,
|
||||||
listen-port, fwmark. Subsequent lines are printed for each peer and contain in order
|
fwmark. Subsequent lines are printed for each peer and contain in order separated
|
||||||
separated by tab: public-key, endpoint, allowed-ips, latest-handshake, transfer-rx,
|
by tab: public-key, preshared-key, endpoint, allowed-ips, latest-handshake,
|
||||||
transfer-tx, persistent-keepalive.
|
transfer-rx, transfer-tx, persistent-keepalive.
|
||||||
.TP
|
.TP
|
||||||
\fBshowconf\fP \fI<interface>\fP
|
\fBshowconf\fP \fI<interface>\fP
|
||||||
Shows the current configuration of \fI<interface>\fP in the format described
|
Shows the current configuration of \fI<interface>\fP in the format described
|
||||||
by \fICONFIGURATION FILE FORMAT\fP below.
|
by \fICONFIGURATION FILE FORMAT\fP below.
|
||||||
.TP
|
.TP
|
||||||
\fBset\fP \fI<interface>\fP [\fIlisten-port\fP \fI<port>\fP] [\fIfwmark\fP \fI<fwmark>\fP] [\fIprivate-key\fP \fI<file-path>\fP] [\fIpreshared-key\fP \fI<file-path>\fP] [\fIpeer\fP \fI<base64-public-key>\fP [\fIremove\fP] [\fIendpoint\fP \fI<ip>:<port>\fP] [\fIpersistent-keepalive\fP \fI<interval seconds>\fP] [\fIallowed-ips\fP \fI<ip1>/<cidr1>\fP[,\fI<ip2>/<cidr2>\fP]...] ]...
|
\fBset\fP \fI<interface>\fP [\fIlisten-port\fP \fI<port>\fP] [\fIfwmark\fP \fI<fwmark>\fP] [\fIprivate-key\fP \fI<file-path>\fP] [\fIpeer\fP \fI<base64-public-key>\fP [\fIremove\fP] [\fIpreshared-key\fP \fI<file-path>\fP] [\fIendpoint\fP \fI<ip>:<port>\fP] [\fIpersistent-keepalive\fP \fI<interval seconds>\fP] [\fIallowed-ips\fP \fI<ip1>/<cidr1>\fP[,\fI<ip2>/<cidr2>\fP]...] ]...
|
||||||
Sets configuration values for the specified \fI<interface>\fP. Multiple
|
Sets configuration values for the specified \fI<interface>\fP. Multiple
|
||||||
\fIpeer\fPs may be specified, and if the \fIremove\fP argument is given
|
\fIpeer\fPs may be specified, and if the \fIremove\fP argument is given
|
||||||
for a peer, that peer is removed, not configured. If \fIlisten-port\fP
|
for a peer, that peer is removed, not configured. If \fIlisten-port\fP
|
||||||
|
@ -126,11 +126,6 @@ The \fIInterface\fP section may contain the following fields:
|
||||||
.IP \(bu
|
.IP \(bu
|
||||||
PrivateKey \(em a base64 private key generated by \fIwg genkey\fP. Required.
|
PrivateKey \(em a base64 private key generated by \fIwg genkey\fP. Required.
|
||||||
.IP \(bu
|
.IP \(bu
|
||||||
PresharedKey \(em a base64 preshared key generated by \fIwg genpsk\fP. Optional,
|
|
||||||
and may be omitted. This option adds an additional layer of symmetric-key
|
|
||||||
cryptography to be mixed into the already existing public-key cryptography,
|
|
||||||
for post-quantum resistance.
|
|
||||||
.IP \(bu
|
|
||||||
ListenPort \(em a 16-bit port for listening. Optional; if not specified, chosen
|
ListenPort \(em a 16-bit port for listening. Optional; if not specified, chosen
|
||||||
randomly.
|
randomly.
|
||||||
.IP \(bu
|
.IP \(bu
|
||||||
|
@ -143,6 +138,11 @@ PublicKey \(em a base64 public key calculated by \fIwg pubkey\fP from a
|
||||||
private key, and usually transmitted out of band to the author of the
|
private key, and usually transmitted out of band to the author of the
|
||||||
configuration file. Required.
|
configuration file. Required.
|
||||||
.IP \(bu
|
.IP \(bu
|
||||||
|
PresharedKey \(em a base64 preshared key generated by \fIwg genpsk\fP. Optional,
|
||||||
|
and may be omitted. This option adds an additional layer of symmetric-key
|
||||||
|
cryptography to be mixed into the already existing public-key cryptography,
|
||||||
|
for post-quantum resistance.
|
||||||
|
.IP \(bu
|
||||||
AllowedIPs \(em a comma-separated list of ip (v4 or v6) addresses with
|
AllowedIPs \(em a comma-separated list of ip (v4 or v6) addresses with
|
||||||
CIDR masks from which this peer is allowed to send incoming traffic and
|
CIDR masks from which this peer is allowed to send incoming traffic and
|
||||||
to which outgoing traffic for this peer is directed. The catch-all
|
to which outgoing traffic for this peer is directed. The catch-all
|
||||||
|
|
Loading…
Reference in a new issue