Linux-WireGuard

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

## @names = list\_device\_names()

Returns a list of strings.

## $dev\_hr = get\_device( $NAME )

Returns a reference to a hash that describes the $NAME’d device:

- `name`
- `ifindex`
- `public_key` and `private_key` (raw strings, or undef)
- `fwmark` (can be undef)
- `listen_port` (can be undef)
- `peers` - reference to an array of hash references. Each hash is:
    - `public_key` and `preshared_key` (raw strings, or undef)
    - `endpoint` - Raw sockaddr data (a string), or undef. To parse
    the sockaddr, use [Socket](https://metacpan.org/pod/Socket)’s `sockaddr_family()` to determine the
    address family, then `unpack_sockaddr_in()` for Socket::AF\_INET or
    `unpack_sockaddr_in6()` for Socket::AF\_INET6.
    - `rx_bytes` and `tx_bytes`
    - `persistent_keepalive_interval` (can be undef)

WireGuard.xs  view on Meta::CPAN

    wg_peer *peer;

    HV* dev_hv = newHV();

    hv_stores(dev_hv, "name", newSVpv(dev->name, 0));
    hv_stores(dev_hv, "ifindex", newSVuv(dev->ifindex));

    // hv_stores(dev_hv, "flags", newSViv(dev->flags));

    hv_stores(dev_hv, "public_key", dev->flags & WGDEVICE_HAS_PUBLIC_KEY ? newSVpvn((char*) dev->public_key, sizeof(dev->public_key)) : &PL_sv_undef);
    hv_stores(dev_hv, "private_key", dev->flags & WGDEVICE_HAS_PRIVATE_KEY ? newSVpvn((char*) dev->private_key, sizeof(dev->private_key)) : &PL_sv_undef);

    hv_stores(dev_hv, "fwmark", dev->flags & WGDEVICE_HAS_FWMARK ? newSVuv(dev->fwmark) : &PL_sv_undef);
    hv_stores(dev_hv, "listen_port", dev->flags & WGDEVICE_HAS_LISTEN_PORT ? newSVuv(dev->listen_port) : &PL_sv_undef);

    AV* peers = newAV();
    hv_stores(dev_hv, "peers", newRV_noinc((SV*) peers));

    wg_for_each_peer(dev, peer) {
        HV* peer_hv = _wgpeer_to_hv(aTHX_ peer);
        av_push(peers, newRV_noinc((SV*) peer_hv));

WireGuard.xs  view on Meta::CPAN

        del_device = 1
    CODE:
        const char* devname = exs_SvPVbyte_nolen(name_sv);

        int result = ix ? wg_del_device(devname) : wg_add_device(devname);
        if (result) {
            croak("Failed to %s device `%s`: %s", ix ? "delete" : "add", devname, strerror(errno));
        }

SV*
generate_private_key()
    ALIAS:
        generate_preshared_key = 1
    CODE:
        wg_key key;

        if (ix) {
            wg_generate_preshared_key(key);
        }
        else {
            wg_generate_private_key(key);
        }

        RETVAL = newSVpv((char*) key, sizeof(wg_key));
    OUTPUT:
        RETVAL

SV*
generate_public_key(SV* private_key_sv)
    CODE:
        wg_key public_key;

        if (SvROK(private_key_sv)) {
            croak("Reference is nonsensical here!");
        }

        STRLEN keylen;
        const char* private_key_char = SvPVbyte(private_key_sv, keylen);

        if (keylen != sizeof(wg_key)) {
            croak("Key must be exactly %lu characters, not %lu!", sizeof(wg_key), keylen);
        }

        wg_generate_public_key(public_key, (const void*) private_key_char);

        RETVAL = newSVpv((char*) public_key, sizeof(wg_key));
    OUTPUT:
        RETVAL

lib/Linux/WireGuard.pm  view on Meta::CPAN

=head2 $dev_hr = get_device( $NAME )

Returns a reference to a hash that describes the $NAME’d device:

=over

=item * C<name>

=item * C<ifindex>

=item * C<public_key> and C<private_key> (raw strings, or undef)

=item * C<fwmark> (can be undef)

=item * C<listen_port> (can be undef)

=item * C<peers> - reference to an array of hash references. Each hash is:

=over

=item * C<public_key> and C<preshared_key> (raw strings, or undef)

lib/Linux/WireGuard.pm  view on Meta::CPAN

=back

=head2 add_device( $NAME )

Adds a WireGuard device with the given $NAME.

=head2 del_device( $NAME )

Deletes a WireGuard device with the given $NAME.

=head2 $bin = generate_private_key()

Returns a newly-generated private key (raw string).

=head2 $bin = generate_public_key( $PRIVATE_KEY )

Takes a private key and returns its public key. (Both raw strings.)

=head2 $bin = generate_preshared_key()

Returns a newly-generated preshared key (raw string).

libwireguard.c  view on Meta::CPAN

		return -errno;

again:
	nlh = mnlg_msg_prepare(nlg, WG_CMD_SET_DEVICE, NLM_F_REQUEST | NLM_F_ACK);
	mnl_attr_put_strz(nlh, WGDEVICE_A_IFNAME, dev->name);

	if (!peer) {
		uint32_t flags = 0;

		if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
			mnl_attr_put(nlh, WGDEVICE_A_PRIVATE_KEY, sizeof(dev->private_key), dev->private_key);
		if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
			mnl_attr_put_u16(nlh, WGDEVICE_A_LISTEN_PORT, dev->listen_port);
		if (dev->flags & WGDEVICE_HAS_FWMARK)
			mnl_attr_put_u32(nlh, WGDEVICE_A_FWMARK, dev->fwmark);
		if (dev->flags & WGDEVICE_REPLACE_PEERS)
			flags |= WGDEVICE_F_REPLACE_PEERS;
		if (flags)
			mnl_attr_put_u32(nlh, WGDEVICE_A_FLAGS, flags);
	}
	if (!dev->first_peer)

libwireguard.c  view on Meta::CPAN

		if (!mnl_attr_validate(attr, MNL_TYPE_U32))
			device->ifindex = mnl_attr_get_u32(attr);
		break;
	case WGDEVICE_A_IFNAME:
		if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {
			strncpy(device->name, mnl_attr_get_str(attr), sizeof(device->name) - 1);
			device->name[sizeof(device->name) - 1] = '\0';
		}
		break;
	case WGDEVICE_A_PRIVATE_KEY:
		if (mnl_attr_get_payload_len(attr) == sizeof(device->private_key)) {
			memcpy(device->private_key, mnl_attr_get_payload(attr), sizeof(device->private_key));
			device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
		}
		break;
	case WGDEVICE_A_PUBLIC_KEY:
		if (mnl_attr_get_payload_len(attr) == sizeof(device->public_key)) {
			memcpy(device->public_key, mnl_attr_get_payload(attr), sizeof(device->public_key));
			device->flags |= WGDEVICE_HAS_PUBLIC_KEY;
		}
		break;
	case WGDEVICE_A_LISTEN_PORT:

libwireguard.c  view on Meta::CPAN


	memzero_explicit(c, sizeof(c));
}

static void clamp_key(uint8_t *z)
{
	z[31] = (z[31] & 127) | 64;
	z[0] &= 248;
}

void wg_generate_public_key(wg_key public_key, const wg_key private_key)
{
	int i, r;
	uint8_t z[32];
	fe a = { 1 }, b = { 9 }, c = { 0 }, d = { 1 }, e, f;

	memcpy(z, private_key, sizeof(z));
	clamp_key(z);

	for (i = 254; i >= 0; --i) {
		r = (z[i >> 3] >> (i & 7)) & 1;
		cswap(a, b, r);
		cswap(c, d, r);
		add(e, a, c);
		subtract(a, a, c);
		add(c, b, d);
		subtract(b, b, d);

libwireguard.c  view on Meta::CPAN

	memzero_explicit(&r, sizeof(r));
	memzero_explicit(z, sizeof(z));
	memzero_explicit(a, sizeof(a));
	memzero_explicit(b, sizeof(b));
	memzero_explicit(c, sizeof(c));
	memzero_explicit(d, sizeof(d));
	memzero_explicit(e, sizeof(e));
	memzero_explicit(f, sizeof(f));
}

void wg_generate_private_key(wg_key private_key)
{
	wg_generate_preshared_key(private_key);
	clamp_key(private_key);
}

void wg_generate_preshared_key(wg_key preshared_key)
{
	ssize_t ret;
	size_t i;
	int fd;
#if defined(__OpenBSD__) || (defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) || (defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)))
	if (!getentropy(preshared_key, sizeof(wg_key)))
		return;

t/add_del_device.t  view on Meta::CPAN


    my $ipv4_addr_len = length pack_sockaddr_in( 0, "\0" x 4 );
    my $ipv6_addr_len = length pack_sockaddr_in6( 0, "\0" x 16 );

    cmp_deeply(
        $device,
        {
            name        => $devname,
            ifindex     => $uint_re,
            public_key  => undef,
            private_key => undef,
            fwmark      => undef,
            listen_port => undef,
            peers       => [],
        },
        'get_device()',
    ) or diag explain $device;
}

done_testing;

t/devices.t  view on Meta::CPAN


    my $ipv4_addr_len = length pack_sockaddr_in(0, "\0" x 4);
    my $ipv6_addr_len = length pack_sockaddr_in6(0, "\0" x 16);

    cmp_deeply(
        \@devices,
        array_each( {
            name => re( qr<.> ),
            ifindex => $uint_re,
            public_key => $optional_str,
            private_key => $optional_str,
            fwmark => ignore(),
            listen_port => $optional_uint_re,
            peers => array_each( {
                public_key => $optional_str,
                preshared_key => $optional_str,
                endpoint => any(
                    undef,
                    re( qr<\A.{$ipv4_addr_len}\z> ),
                    re( qr<\A.{$ipv6_addr_len}\z> ),
                ),

t/keys.t  view on Meta::CPAN

#!/usr/bin/env perl

use strict;
use warnings;

use Linux::WireGuard;

use Test::More;
use Test::FailWarnings;

my $str = Linux::WireGuard::generate_private_key();
like($str, qr<.>, 'private key generated');

is(
    length($str),
    length( Linux::WireGuard::generate_private_key() ),
    '2 private keys are same length',
);

my $pub = Linux::WireGuard::generate_public_key($str);

is(
    $pub,
    Linux::WireGuard::generate_public_key($str),
    'public key generated the same twice',
);

wireguard-tools/contrib/embeddable-wg-library/test.c  view on Meta::CPAN

	wg_peer new_peer = {
		.flags = WGPEER_HAS_PUBLIC_KEY | WGPEER_REPLACE_ALLOWEDIPS
	};
	wg_device new_device = {
		.name = "wgtest0",
		.listen_port = 1234,
		.flags = WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_LISTEN_PORT,
		.first_peer = &new_peer,
		.last_peer = &new_peer
	};
	wg_key temp_private_key;

	wg_generate_private_key(temp_private_key);
	wg_generate_public_key(new_peer.public_key, temp_private_key);
	wg_generate_private_key(new_device.private_key);

	if (wg_add_device(new_device.name) < 0) {
		perror("Unable to add device");
		exit(1);
	}

	if (wg_set_device(&new_device) < 0) {
		perror("Unable to set device");
		exit(1);
	}

wireguard-tools/contrib/embeddable-wg-library/wireguard.c  view on Meta::CPAN

		return -errno;

again:
	nlh = mnlg_msg_prepare(nlg, WG_CMD_SET_DEVICE, NLM_F_REQUEST | NLM_F_ACK);
	mnl_attr_put_strz(nlh, WGDEVICE_A_IFNAME, dev->name);

	if (!peer) {
		uint32_t flags = 0;

		if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
			mnl_attr_put(nlh, WGDEVICE_A_PRIVATE_KEY, sizeof(dev->private_key), dev->private_key);
		if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
			mnl_attr_put_u16(nlh, WGDEVICE_A_LISTEN_PORT, dev->listen_port);
		if (dev->flags & WGDEVICE_HAS_FWMARK)
			mnl_attr_put_u32(nlh, WGDEVICE_A_FWMARK, dev->fwmark);
		if (dev->flags & WGDEVICE_REPLACE_PEERS)
			flags |= WGDEVICE_F_REPLACE_PEERS;
		if (flags)
			mnl_attr_put_u32(nlh, WGDEVICE_A_FLAGS, flags);
	}
	if (!dev->first_peer)

wireguard-tools/contrib/embeddable-wg-library/wireguard.c  view on Meta::CPAN

		if (!mnl_attr_validate(attr, MNL_TYPE_U32))
			device->ifindex = mnl_attr_get_u32(attr);
		break;
	case WGDEVICE_A_IFNAME:
		if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {
			strncpy(device->name, mnl_attr_get_str(attr), sizeof(device->name) - 1);
			device->name[sizeof(device->name) - 1] = '\0';
		}
		break;
	case WGDEVICE_A_PRIVATE_KEY:
		if (mnl_attr_get_payload_len(attr) == sizeof(device->private_key)) {
			memcpy(device->private_key, mnl_attr_get_payload(attr), sizeof(device->private_key));
			device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
		}
		break;
	case WGDEVICE_A_PUBLIC_KEY:
		if (mnl_attr_get_payload_len(attr) == sizeof(device->public_key)) {
			memcpy(device->public_key, mnl_attr_get_payload(attr), sizeof(device->public_key));
			device->flags |= WGDEVICE_HAS_PUBLIC_KEY;
		}
		break;
	case WGDEVICE_A_LISTEN_PORT:

wireguard-tools/contrib/embeddable-wg-library/wireguard.c  view on Meta::CPAN


	memzero_explicit(c, sizeof(c));
}

static void clamp_key(uint8_t *z)
{
	z[31] = (z[31] & 127) | 64;
	z[0] &= 248;
}

void wg_generate_public_key(wg_key public_key, const wg_key private_key)
{
	int i, r;
	uint8_t z[32];
	fe a = { 1 }, b = { 9 }, c = { 0 }, d = { 1 }, e, f;

	memcpy(z, private_key, sizeof(z));
	clamp_key(z);

	for (i = 254; i >= 0; --i) {
		r = (z[i >> 3] >> (i & 7)) & 1;
		cswap(a, b, r);
		cswap(c, d, r);
		add(e, a, c);
		subtract(a, a, c);
		add(c, b, d);
		subtract(b, b, d);

wireguard-tools/contrib/embeddable-wg-library/wireguard.c  view on Meta::CPAN

	memzero_explicit(&r, sizeof(r));
	memzero_explicit(z, sizeof(z));
	memzero_explicit(a, sizeof(a));
	memzero_explicit(b, sizeof(b));
	memzero_explicit(c, sizeof(c));
	memzero_explicit(d, sizeof(d));
	memzero_explicit(e, sizeof(e));
	memzero_explicit(f, sizeof(f));
}

void wg_generate_private_key(wg_key private_key)
{
	wg_generate_preshared_key(private_key);
	clamp_key(private_key);
}

void wg_generate_preshared_key(wg_key preshared_key)
{
	ssize_t ret;
	size_t i;
	int fd;
#if defined(__OpenBSD__) || (defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) || (defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)))
	if (!getentropy(preshared_key, sizeof(wg_key)))
		return;

wireguard-tools/contrib/embeddable-wg-library/wireguard.h  view on Meta::CPAN

	WGDEVICE_HAS_FWMARK = 1U << 4
};

typedef struct wg_device {
	char name[IFNAMSIZ];
	uint32_t ifindex;

	enum wg_device_flags flags;

	wg_key public_key;
	wg_key private_key;

	uint32_t fwmark;
	uint16_t listen_port;

	struct wg_peer *first_peer, *last_peer;
} wg_device;

#define wg_for_each_device_name(__names, __name, __len) for ((__name) = (__names), (__len) = 0; ((__len) = strlen(__name)); (__name) += (__len) + 1)
#define wg_for_each_peer(__dev, __peer) for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_peer)
#define wg_for_each_allowedip(__peer, __allowedip) for ((__allowedip) = (__peer)->first_allowedip; (__allowedip); (__allowedip) = (__allowedip)->next_allowedip)

int wg_set_device(wg_device *dev);
int wg_get_device(wg_device **dev, const char *device_name);
int wg_add_device(const char *device_name);
int wg_del_device(const char *device_name);
void wg_free_device(wg_device *dev);
char *wg_list_device_names(void); /* first\0second\0third\0forth\0last\0\0 */
void wg_key_to_base64(wg_key_b64_string base64, const wg_key key);
int wg_key_from_base64(wg_key key, const wg_key_b64_string base64);
bool wg_key_is_zero(const wg_key key);
void wg_generate_public_key(wg_key public_key, const wg_key private_key);
void wg_generate_private_key(wg_key private_key);
void wg_generate_preshared_key(wg_key preshared_key);

#endif

wireguard-tools/contrib/external-tests/rust/src/main.rs  view on Meta::CPAN

}

fn main() {
	let socket = UdpSocket::bind("0.0.0.0:0").unwrap();

	let their_public = base64::decode(&"qRCwZSKInrMAq5sepfCdaCsRJaoLe5jhtzfiw7CjbwM=").unwrap();
	let my_private = base64::decode(&"WAmgVYXkbT2bCtdcDwolI88/iVi/aV3/PHcUBTQSYmo=").unwrap();
	let my_preshared = base64::decode(&"FpCyhws9cxwWoV4xELtfJvjJN+zQVRPISllRWgeopVE=").unwrap();

	let mut noise = NoiseBuilder::new("Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s".parse().unwrap())
		.local_private_key(&my_private[..])
		.remote_public_key(&their_public[..])
		.prologue("WireGuard v1 zx2c4 Jason@zx2c4.com".as_bytes())
		.psk(2, &my_preshared[..])
		.build_initiator().unwrap();

	let now = time::get_time();
	let mut tai64n = [0; 12];
	BigEndian::write_i64(&mut tai64n[0..], 4611686018427387914 + now.sec);
	BigEndian::write_i32(&mut tai64n[8..], now.nsec);
	let mut initiation_packet = [0; 148];

wireguard-tools/contrib/json/wg-json  view on Meta::CPAN

#
# Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.

exec < <(exec wg show all dump)

printf '{'
while read -r -d $'\t' device; do
	if [[ $device != "$last_device" ]]; then
		[[ -z $last_device ]] && printf '\n' || printf '%s,\n' "$end"
		last_device="$device"
		read -r private_key public_key listen_port fwmark
		printf '\t"%s": {' "$device"
		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'; }
		[[ $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'; }
		printf '%s\t\t"peers": {' "$delim"; end=$'\n\t\t}\n\t}'
		delim=$'\n'
	else
		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"
		delim=$'\n'
		[[ $preshared_key == "(none)" ]] || { printf '%s\t\t\t\t"presharedKey": "%s"' "$delim" "$preshared_key"; delim=$',\n'; }

wireguard-tools/src/completion/wg.bash-completion  view on Meta::CPAN


	if [[ $COMP_CWORD -eq 3 && ( ${COMP_WORDS[1]} == setconf || ${COMP_WORDS[1]} == addconf || ${COMP_WORDS[1]} == syncconf) ]]; then
		compopt -o filenames
		mapfile -t a < <(compgen -f -- "${COMP_WORDS[3]}")
		COMPREPLY+=( "${a[@]}" )
		return
	fi

	[[ ${COMP_WORDS[1]} == set ]] || return

	local has_listen_port=0 has_fwmark=0 has_private_key=0 has_preshared_key=0 has_peer=0 has_remove=0 has_endpoint=0 has_persistent_keepalive=0 has_allowed_ips=0 words=() i j
	for ((i=3;i<COMP_CWORD;i+=2)); do
		[[ ${COMP_WORDS[i]} == listen-port ]] && has_listen_port=1
		[[ ${COMP_WORDS[i]} == fwmark ]] && has_fwmark=1
		[[ ${COMP_WORDS[i]} == private-key ]] && has_private_key=1
		[[ ${COMP_WORDS[i]} == peer ]] && { has_peer=$i; break; }
	done
	if [[ $has_peer -eq 0 ]]; then
		if ((COMP_CWORD % 2 != 0)); then
			[[ $has_listen_port -eq 1 ]] || words+=( listen-port )
			[[ $has_fwmark -eq 1 ]] || words+=( fwmark )
			[[ $has_private_key -eq 1 ]] || words+=( private-key )
			words+=( peer )
			COMPREPLY+=( $(compgen -W "${words[*]}" -- "${COMP_WORDS[COMP_CWORD]}") )
		elif [[ ${COMP_WORDS[COMP_CWORD-1]} == *-key ]]; then
			compopt -o filenames
			mapfile -t a < <(compgen -f -- "${COMP_WORDS[COMP_CWORD]}")
			COMPREPLY+=( "${a[@]}" )
		fi
		return
	fi

wireguard-tools/src/config.c  view on Meta::CPAN

	}

#define key_match(key) (value = get_value(line, key "="))

	if (ctx->is_device_section) {
		if (key_match("ListenPort"))
			ret = parse_port(&ctx->device->listen_port, &ctx->device->flags, value);
		else if (key_match("FwMark"))
			ret = parse_fwmark(&ctx->device->fwmark, &ctx->device->flags, value);
		else if (key_match("PrivateKey")) {
			ret = parse_key(ctx->device->private_key, value);
			if (ret)
				ctx->device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
		} else
			goto error;
	} else if (ctx->is_peer_section) {
		if (key_match("Endpoint"))
			ret = parse_endpoint(&ctx->last_peer->endpoint.addr, value);
		else if (key_match("PublicKey")) {
			ret = parse_key(ctx->last_peer->public_key, value);
			if (ret)

wireguard-tools/src/config.c  view on Meta::CPAN

			if (!parse_port(&device->listen_port, &device->flags, argv[1]))
				goto error;
			argv += 2;
			argc -= 2;
		} else if (!strcmp(argv[0], "fwmark") && argc >= 2 && !peer) {
			if (!parse_fwmark(&device->fwmark, &device->flags, argv[1]))
				goto error;
			argv += 2;
			argc -= 2;
		} else if (!strcmp(argv[0], "private-key") && argc >= 2 && !peer) {
			if (!parse_keyfile(device->private_key, argv[1]))
				goto error;
			device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
			argv += 2;
			argc -= 2;
		} else if (!strcmp(argv[0], "peer") && argc >= 2) {
			struct wgpeer *new_peer = calloc(1, sizeof(*new_peer));

			allowedip = NULL;
			if (!new_peer) {
				perror("calloc");

wireguard-tools/src/containers.h  view on Meta::CPAN

	WGDEVICE_HAS_FWMARK = 1U << 4
};

struct wgdevice {
	char name[IFNAMSIZ];
	uint32_t ifindex;

	uint32_t flags;

	uint8_t public_key[WG_KEY_LEN];
	uint8_t private_key[WG_KEY_LEN];

	uint32_t fwmark;
	uint16_t listen_port;

	struct wgpeer *first_peer, *last_peer;
};

#define for_each_wgpeer(__dev, __peer) for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_peer)
#define for_each_wgallowedip(__peer, __allowedip) for ((__allowedip) = (__peer)->first_allowedip; (__allowedip); (__allowedip) = (__allowedip)->next_allowedip)

wireguard-tools/src/ipc-freebsd.h  view on Meta::CPAN

	}
	if (nvlist_exists_binary(nvl_device, "public-key")) {
		binary = nvlist_get_binary(nvl_device, "public-key", &size);
		if (binary && size == sizeof(dev->public_key)) {
			memcpy(dev->public_key, binary, sizeof(dev->public_key));
			dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
		}
	}
	if (nvlist_exists_binary(nvl_device, "private-key")) {
		binary = nvlist_get_binary(nvl_device, "private-key", &size);
		if (binary && size == sizeof(dev->private_key)) {
			memcpy(dev->private_key, binary, sizeof(dev->private_key));
			dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
		}
	}
	if (!nvlist_exists_nvlist_array(nvl_device, "peers"))
		goto skip_peers;
	nvl_peers = nvlist_get_nvlist_array(nvl_device, "peers", &peer_count);
	if (!nvl_peers)
		goto skip_peers;
	for (i = 0; i < peer_count; ++i) {
		struct wgpeer *peer;

wireguard-tools/src/ipc-freebsd.h  view on Meta::CPAN

		goto err;

	for_each_wgpeer(dev, peer)
		++peer_count;
	if (peer_count) {
		nvl_peers = calloc(peer_count, sizeof(*nvl_peers));
		if (!nvl_peers)
			goto err;
	}
	if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
		nvlist_add_binary(nvl_device, "private-key", dev->private_key, sizeof(dev->private_key));
	if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
		nvlist_add_number(nvl_device, "listen-port", dev->listen_port);
	if (dev->flags & WGDEVICE_HAS_FWMARK)
		nvlist_add_number(nvl_device, "user-cookie", dev->fwmark);
	if (dev->flags & WGDEVICE_REPLACE_PEERS)
		nvlist_add_bool(nvl_device, "replace-peers", true);

	for_each_wgpeer(dev, peer) {
		size_t aip_count = 0, j = 0;
		nvlist_t **nvl_aips = NULL;

wireguard-tools/src/ipc-linux.h  view on Meta::CPAN

		return -errno;

again:
	nlh = mnlg_msg_prepare(nlg, WG_CMD_SET_DEVICE, NLM_F_REQUEST | NLM_F_ACK);
	mnl_attr_put_strz(nlh, WGDEVICE_A_IFNAME, dev->name);

	if (!peer) {
		uint32_t flags = 0;

		if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
			mnl_attr_put(nlh, WGDEVICE_A_PRIVATE_KEY, sizeof(dev->private_key), dev->private_key);
		if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
			mnl_attr_put_u16(nlh, WGDEVICE_A_LISTEN_PORT, dev->listen_port);
		if (dev->flags & WGDEVICE_HAS_FWMARK)
			mnl_attr_put_u32(nlh, WGDEVICE_A_FWMARK, dev->fwmark);
		if (dev->flags & WGDEVICE_REPLACE_PEERS)
			flags |= WGDEVICE_F_REPLACE_PEERS;
		if (flags)
			mnl_attr_put_u32(nlh, WGDEVICE_A_FLAGS, flags);
	}
	if (!dev->first_peer)

wireguard-tools/src/ipc-linux.h  view on Meta::CPAN

		if (!mnl_attr_validate(attr, MNL_TYPE_U32))
			device->ifindex = mnl_attr_get_u32(attr);
		break;
	case WGDEVICE_A_IFNAME:
		if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {
			strncpy(device->name, mnl_attr_get_str(attr), sizeof(device->name) - 1);
			device->name[sizeof(device->name) - 1] = '\0';
		}
		break;
	case WGDEVICE_A_PRIVATE_KEY:
		if (mnl_attr_get_payload_len(attr) == sizeof(device->private_key)) {
			memcpy(device->private_key, mnl_attr_get_payload(attr), sizeof(device->private_key));
			device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
		}
		break;
	case WGDEVICE_A_PUBLIC_KEY:
		if (mnl_attr_get_payload_len(attr) == sizeof(device->public_key)) {
			memcpy(device->public_key, mnl_attr_get_payload(attr), sizeof(device->public_key));
			device->flags |= WGDEVICE_HAS_PUBLIC_KEY;
		}
		break;
	case WGDEVICE_A_LISTEN_PORT:

wireguard-tools/src/ipc-openbsd.h  view on Meta::CPAN

		dev->listen_port = wg_iface->i_port;
		dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
	}

	if (wg_iface->i_flags & WG_INTERFACE_HAS_PUBLIC) {
		memcpy(dev->public_key, wg_iface->i_public, sizeof(dev->public_key));
		dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
	}

	if (wg_iface->i_flags & WG_INTERFACE_HAS_PRIVATE) {
		memcpy(dev->private_key, wg_iface->i_private, sizeof(dev->private_key));
		dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
	}

	wg_peer = &wg_iface->i_peers[0];
	for (size_t i = 0; i < wg_iface->i_peers_count; ++i) {
		peer = calloc(1, sizeof(*peer));
		if (!peer)
			goto out;

		if (dev->first_peer == NULL)

wireguard-tools/src/ipc-openbsd.h  view on Meta::CPAN

		wgdata.wgd_size += sizeof(struct wg_peer_io);
		for_each_wgallowedip(peer, aip)
			wgdata.wgd_size += sizeof(struct wg_aip_io);
	}
	wg_iface = wgdata.wgd_interface = calloc(1, wgdata.wgd_size);
	if (!wgdata.wgd_interface)
		return -errno;
	strlcpy(wgdata.wgd_name, dev->name, sizeof(wgdata.wgd_name));

	if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY) {
		memcpy(wg_iface->i_private, dev->private_key, sizeof(wg_iface->i_private));
		wg_iface->i_flags |= WG_INTERFACE_HAS_PRIVATE;
	}

	if (dev->flags & WGDEVICE_HAS_LISTEN_PORT) {
		wg_iface->i_port = dev->listen_port;
		wg_iface->i_flags |= WG_INTERFACE_HAS_PORT;
	}

	if (dev->flags & WGDEVICE_HAS_FWMARK) {
		wg_iface->i_rtable = dev->fwmark;

wireguard-tools/src/ipc-uapi.h  view on Meta::CPAN

	socklen_t addr_len;
	size_t line_buffer_len = 0, line_len;
	char *key = NULL, *value;

	f = userspace_interface_file(dev->name);
	if (!f)
		return -errno;
	fprintf(f, "set=1\n");

	if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY) {
		key_to_hex(hex, dev->private_key);
		fprintf(f, "private_key=%s\n", hex);
	}
	if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
		fprintf(f, "listen_port=%u\n", dev->listen_port);
	if (dev->flags & WGDEVICE_HAS_FWMARK)
		fprintf(f, "fwmark=%u\n", dev->fwmark);
	if (dev->flags & WGDEVICE_REPLACE_PEERS)
		fprintf(f, "replace_peers=true\n");

	for_each_wgpeer(dev, peer) {
		key_to_hex(hex, peer->public_key);

wireguard-tools/src/ipc-uapi.h  view on Meta::CPAN


	while (getline(&key, &line_buffer_len, f) > 0) {
		line_len = strlen(key);
		if (line_len == 1 && key[0] == '\n')
			goto err;
		value = strchr(key, '=');
		if (!value || line_len == 0 || key[line_len - 1] != '\n')
			break;
		*value++ = key[--line_len] = '\0';

		if (!peer && !strcmp(key, "private_key")) {
			if (!key_from_hex(dev->private_key, value))
				break;
			curve25519_generate_public(dev->public_key, dev->private_key);
			dev->flags |= WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_PUBLIC_KEY;
		} else if (!peer && !strcmp(key, "listen_port")) {
			dev->listen_port = NUM(0xffffU);
			dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
		} else if (!peer && !strcmp(key, "fwmark")) {
			dev->fwmark = NUM(0xffffffffU);
			dev->flags |= WGDEVICE_HAS_FWMARK;
		} else if (!strcmp(key, "public_key")) {
			struct wgpeer *new_peer = calloc(1, sizeof(*new_peer));

wireguard-tools/src/ipc-windows.h  view on Meta::CPAN

		dev->listen_port = wg_iface->ListenPort;
		dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
	}

	if (wg_iface->Flags & WG_IOCTL_INTERFACE_HAS_PUBLIC_KEY) {
		memcpy(dev->public_key, wg_iface->PublicKey, sizeof(dev->public_key));
		dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
	}

	if (wg_iface->Flags & WG_IOCTL_INTERFACE_HAS_PRIVATE_KEY) {
		memcpy(dev->private_key, wg_iface->PrivateKey, sizeof(dev->private_key));
		dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
	}

	wg_peer = buf + sizeof(WG_IOCTL_INTERFACE);
	for (ULONG i = 0; i < wg_iface->PeersCount; ++i) {
		peer = calloc(1, sizeof(*peer));
		if (!peer)
			goto out;

		if (dev->first_peer == NULL)

wireguard-tools/src/ipc-windows.h  view on Meta::CPAN

				goto out;
			}
			buf_len += sizeof(WG_IOCTL_ALLOWED_IP);
		}
	}
	wg_iface = calloc(1, buf_len);
	if (!wg_iface)
		goto out;

	if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY) {
		memcpy(wg_iface->PrivateKey, dev->private_key, sizeof(wg_iface->PrivateKey));
		wg_iface->Flags |= WG_IOCTL_INTERFACE_HAS_PRIVATE_KEY;
	}

	if (dev->flags & WGDEVICE_HAS_LISTEN_PORT) {
		wg_iface->ListenPort = dev->listen_port;
		wg_iface->Flags |= WG_IOCTL_INTERFACE_HAS_LISTEN_PORT;
	}

	if (dev->flags & WGDEVICE_REPLACE_PEERS)
		wg_iface->Flags |= WG_IOCTL_INTERFACE_REPLACE_PEERS;

wireguard-tools/src/show.c  view on Meta::CPAN

static void pretty_print(struct wgdevice *device)
{
	struct wgpeer *peer;
	struct wgallowedip *allowedip;

	terminal_printf(TERMINAL_RESET);
	terminal_printf(TERMINAL_FG_GREEN TERMINAL_BOLD "interface" TERMINAL_RESET ": " TERMINAL_FG_GREEN "%s" TERMINAL_RESET "\n", device->name);
	if (device->flags & WGDEVICE_HAS_PUBLIC_KEY)
		terminal_printf("  " TERMINAL_BOLD "public key" TERMINAL_RESET ": %s\n", key(device->public_key));
	if (device->flags & WGDEVICE_HAS_PRIVATE_KEY)
		terminal_printf("  " TERMINAL_BOLD "private key" TERMINAL_RESET ": %s\n", masked_key(device->private_key));
	if (device->listen_port)
		terminal_printf("  " TERMINAL_BOLD "listening port" TERMINAL_RESET ": %u\n", device->listen_port);
	if (device->fwmark)
		terminal_printf("  " TERMINAL_BOLD "fwmark" TERMINAL_RESET ": 0x%x\n", device->fwmark);
	if (device->first_peer) {
		sort_peers(device);
		terminal_printf("\n");
	}
	for_each_wgpeer(device, peer) {
		terminal_printf(TERMINAL_FG_YELLOW TERMINAL_BOLD "peer" TERMINAL_RESET ": " TERMINAL_FG_YELLOW "%s" TERMINAL_RESET "\n", key(peer->public_key));

wireguard-tools/src/show.c  view on Meta::CPAN

	}
}

static void dump_print(struct wgdevice *device, bool with_interface)
{
	struct wgpeer *peer;
	struct wgallowedip *allowedip;

	if (with_interface)
		printf("%s\t", device->name);
	printf("%s\t", maybe_key(device->private_key, device->flags & WGDEVICE_HAS_PRIVATE_KEY));
	printf("%s\t", maybe_key(device->public_key, device->flags & WGDEVICE_HAS_PUBLIC_KEY));
	printf("%u\t", device->listen_port);
	if (device->fwmark)
		printf("0x%x\n", device->fwmark);
	else
		printf("off\n");
	for_each_wgpeer(device, peer) {
		if (with_interface)
			printf("%s\t", device->name);
		printf("%s\t", key(peer->public_key));

wireguard-tools/src/show.c  view on Meta::CPAN

	struct wgpeer *peer;
	struct wgallowedip *allowedip;

	if (!strcmp(param, "public-key")) {
		if (with_interface)
			printf("%s\t", device->name);
		printf("%s\n", maybe_key(device->public_key, device->flags & WGDEVICE_HAS_PUBLIC_KEY));
	} else if (!strcmp(param, "private-key")) {
		if (with_interface)
			printf("%s\t", device->name);
		printf("%s\n", maybe_key(device->private_key, device->flags & WGDEVICE_HAS_PRIVATE_KEY));
	} else if (!strcmp(param, "listen-port")) {
		if (with_interface)
			printf("%s\t", device->name);
		printf("%u\n", device->listen_port);
	} else if (!strcmp(param, "fwmark")) {
		if (with_interface)
			printf("%s\t", device->name);
		if (device->fwmark)
			printf("0x%x\n", device->fwmark);
		else

wireguard-tools/src/showconf.c  view on Meta::CPAN

		perror("Unable to access interface");
		goto cleanup;
	}

	printf("[Interface]\n");
	if (device->listen_port)
		printf("ListenPort = %u\n", device->listen_port);
	if (device->fwmark)
		printf("FwMark = 0x%x\n", device->fwmark);
	if (device->flags & WGDEVICE_HAS_PRIVATE_KEY) {
		key_to_base64(base64, device->private_key);
		printf("PrivateKey = %s\n", base64);
	}
	printf("\n");
	for_each_wgpeer(device, peer) {
		key_to_base64(base64, peer->public_key);
		printf("[Peer]\nPublicKey = %s\n", base64);
		if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
			key_to_base64(base64, peer->preshared_key);
			printf("PresharedKey = %s\n", base64);
		}

wireguard.h  view on Meta::CPAN

	WGDEVICE_HAS_FWMARK = 1U << 4
};

typedef struct wg_device {
	char name[IFNAMSIZ];
	uint32_t ifindex;

	enum wg_device_flags flags;

	wg_key public_key;
	wg_key private_key;

	uint32_t fwmark;
	uint16_t listen_port;

	struct wg_peer *first_peer, *last_peer;
} wg_device;

#define wg_for_each_device_name(__names, __name, __len) for ((__name) = (__names), (__len) = 0; ((__len) = strlen(__name)); (__name) += (__len) + 1)
#define wg_for_each_peer(__dev, __peer) for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_peer)
#define wg_for_each_allowedip(__peer, __allowedip) for ((__allowedip) = (__peer)->first_allowedip; (__allowedip); (__allowedip) = (__allowedip)->next_allowedip)

int wg_set_device(wg_device *dev);
int wg_get_device(wg_device **dev, const char *device_name);
int wg_add_device(const char *device_name);
int wg_del_device(const char *device_name);
void wg_free_device(wg_device *dev);
char *wg_list_device_names(void); /* first\0second\0third\0forth\0last\0\0 */
void wg_key_to_base64(wg_key_b64_string base64, const wg_key key);
int wg_key_from_base64(wg_key key, const wg_key_b64_string base64);
bool wg_key_is_zero(const wg_key key);
void wg_generate_public_key(wg_key public_key, const wg_key private_key);
void wg_generate_private_key(wg_key private_key);
void wg_generate_preshared_key(wg_key preshared_key);

#endif



( run in 0.377 second using v1.01-cache-2.11-cpan-4d50c553e7e )