Skip to content

Commit

Permalink
Merge branch 'dev' (version 0.2.0)
Browse files Browse the repository at this point in the history
  • Loading branch information
droscy committed May 20, 2023
2 parents ad6fec3 + e70aebf commit 9b7a576
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 23 deletions.
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ for `esp-idf` only but it seems to work on `Arduino` too.

## Usage

Add the following configuration to your `yaml` file:
Add the following configuration to your ESPHome `yaml` file:

```yaml
# Define wireguard external source
Expand All @@ -55,9 +55,9 @@ time:
# Setup WireGuard
wireguard:
address: x.y.z.w
private_key: !secret wg_privkey
private_key: private_key=
peer_endpoint: wg.server.example
peer_public_key: !secret wg_peer_pubkey
peer_public_key: public_key=

# optional netmask (this is the default if omitted)
netmask: 255.255.255.255
Expand All @@ -66,10 +66,19 @@ wireguard:
peer_port: 51820

# optional pre-shared key
peer_preshared_key: !secret wg_peer_shrdkey
peer_preshared_key: shared_key=

# optional keepalive in seconds (disabled by default)
peer_persistent_keepalive: 25

# optional list of allowed ip/mask (the default is to allow any host if omitted)
peer_allowed_ips:
- x.y.z.0/24
- l.m.n.o/32 # the /32 can be omitted for single host
- [...]

# reboot the board if remote peer in unreachable (default to 15min, set to 0s to disable)
reboot_timeout: 15min
```
### Sensors
Expand Down
14 changes: 14 additions & 0 deletions include/esp_wireguard.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2022 Tomoyuki Sakurai <[email protected]>
* Copyright (c) 2023 Simone Rossetto <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
Expand Down Expand Up @@ -145,6 +146,19 @@ esp_err_t esp_wireguardif_peer_is_up(const wireguard_ctx_t *ctx);
*/
esp_err_t esp_wireguard_latest_handshake(const wireguard_ctx_t *ctx, time_t *result);

/**
* @brief Add new allowed IP/mask to the list of allowed ip/mask
* @param ctx Context of WireGuard
* @param allowed_ip The new IP to be allowed through tunnel
* @param allowed_ip_mask The mask of the new IP
* @return
* - ESP_OK on success
* - ESP_FAIL if the adding failed
* - ESP_ERR_INVALID_ARG if ctx, allowed_ip or allowed_ip_mask are invalid or empty
* - ESP_ERR_INVALID_STATE if data inside ctx is not valid
*/
esp_err_t esp_wireguard_add_allowed_ip(const wireguard_ctx_t *ctx, const char *allowed_ip, const char *allowed_ip_mask);

/**
* @brief Disconnect from the peer
*
Expand Down
9 changes: 2 additions & 7 deletions library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "esp_wireguard",
"version": "0.1.0",
"version": "0.2.0",
"description": "WireGuard implementation for ESPHome",
"keywords":[
"communication",
Expand Down Expand Up @@ -57,11 +57,6 @@
},
"build":{
"includeDir": "include",
"srcDir": "src",
"flags": [
"-DCONFIG_WIREGUARD_MAX_PEERS=1",
"-DCONFIG_WIREGUARD_MAX_SRC_IPS=1",
"-DCONFIG_MAX_INITIATIONS_PER_SECOND=2"
]
"srcDir": "src"
}
}
65 changes: 56 additions & 9 deletions src/esp_wireguard.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2022 Tomoyuki Sakurai <[email protected]>
* Copyright (c) 2023 Simone Rossetto <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
Expand Down Expand Up @@ -49,6 +50,7 @@
#define TAG "esp_wireguard"
#define WG_KEY_LEN (32)
#define WG_B64_KEY_LEN (4 * ((WG_KEY_LEN + 2) / 3))

#if defined(CONFIG_LWIP_IPV6)
#define WG_ADDRSTRLEN INET6_ADDRSTRLEN
#else
Expand Down Expand Up @@ -98,12 +100,19 @@ static esp_err_t esp_wireguard_peer_init(const wireguard_config_t *config, struc
}
peer->keep_alive = config->persistent_keepalive;

/* Allow all IPs through tunnel */
/* Allow device address/netmask through tunnel */
{
ip_addr_t allowed_ip = IPADDR4_INIT_BYTES(0, 0, 0, 0);
peer->allowed_ip = allowed_ip;
ip_addr_t allowed_mask = IPADDR4_INIT_BYTES(0, 0, 0, 0);
peer->allowed_mask = allowed_mask;
if(ipaddr_aton(config->allowed_ip, &(peer->allowed_ip)) != 1) {
ESP_LOGE(TAG, "peer_init: invalid allowed_ip: `%s`", config->allowed_ip);
err = ESP_ERR_INVALID_ARG;
goto fail;
}

if(ipaddr_aton(config->allowed_ip_mask, &(peer->allowed_mask)) != 1) {
ESP_LOGE(TAG, "peer_init: invalid allowed_ip_mask: `%s`", config->allowed_ip_mask);
err = ESP_ERR_INVALID_ARG;
goto fail;
}
}

/* resolve peer name or IP address */
Expand Down Expand Up @@ -166,19 +175,19 @@ static esp_err_t esp_wireguard_netif_create(const wireguard_config_t *config)
wg.listen_port = config->listen_port;
wg.bind_netif = NULL;

ESP_LOGI(TAG, "allowed_ip: %s", config->allowed_ip);

if (ipaddr_aton(config->allowed_ip, &ip_addr) != 1) {
ESP_LOGE(TAG, "ipaddr_aton: invalid allowed_ip: `%s`", config->allowed_ip);
ESP_LOGE(TAG, "netif_create: invalid allowed_ip: `%s`", config->allowed_ip);
err = ESP_ERR_INVALID_ARG;
goto fail;
}
if (ipaddr_aton(config->allowed_ip_mask, &netmask) != 1) {
ESP_LOGE(TAG, "ipaddr_aton: invalid allowed_ip_mask: `%s`", config->allowed_ip_mask);
ESP_LOGE(TAG, "netif_create: invalid allowed_ip_mask: `%s`", config->allowed_ip_mask);
err = ESP_ERR_INVALID_ARG;
goto fail;
}

ESP_LOGI(TAG, "default allowed_ip: %s/%s", config->allowed_ip, config->allowed_ip_mask);

/* Register the new WireGuard network interface with lwIP */
wg_netif = netif_add(
&wg_netif_struct,
Expand Down Expand Up @@ -360,6 +369,44 @@ esp_err_t esp_wireguard_latest_handshake(const wireguard_ctx_t *ctx, time_t *res
*result = wireguardif_latest_handshake(ctx->netif, wireguard_peer_index);
err = (*result > 0) ? ESP_OK : ESP_FAIL;

fail:
return err;
}

esp_err_t esp_wireguard_add_allowed_ip(const wireguard_ctx_t *ctx, const char *allowed_ip, const char *allowed_ip_mask)
{
esp_err_t err;
err_t lwip_err;

ip_addr_t ip_addr;
ip_addr_t netmask;

if (!ctx || !allowed_ip || !allowed_ip_mask) {
err = ESP_ERR_INVALID_ARG;
goto fail;
}

if (!ctx->netif) {
err = ESP_ERR_INVALID_STATE;
goto fail;
}

if (ipaddr_aton(allowed_ip, &ip_addr) != 1) {
ESP_LOGE(TAG, "add_allowed_ip: invalid allowed_ip: `%s`", allowed_ip);
err = ESP_ERR_INVALID_ARG;
goto fail;
}

if (ipaddr_aton(allowed_ip_mask, &netmask) != 1) {
ESP_LOGE(TAG, "add_allowed_ip: invalid allowed_ip_mask: `%s`", allowed_ip_mask);
err = ESP_ERR_INVALID_ARG;
goto fail;
}

ESP_LOGI(TAG, "add allowed_ip: %s/%s", allowed_ip, allowed_ip_mask);
lwip_err = wireguardif_add_allowed_ip(ctx->netif, wireguard_peer_index, ip_addr, netmask);
err = (lwip_err == ERR_OK ? ESP_OK : ESP_FAIL);

fail:
return err;
}
Expand Down
19 changes: 16 additions & 3 deletions src/wireguard-platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,24 @@ extern "C" {
#include "esp_err.h"

// Peers are allocated statically inside the device structure to avoid malloc
#define WIREGUARD_MAX_PEERS (CONFIG_WIREGUARD_MAX_PEERS)
#define WIREGUARD_MAX_SRC_IPS (CONFIG_WIREGUARD_MAX_SRC_IPS)
#ifdef CONFIG_WIREGUARD_MAX_PEERS
#define WIREGUARD_MAX_PEERS (CONFIG_WIREGUARD_MAX_PEERS)
#else
#define WIREGUARD_MAX_PEERS (1)
#endif

#ifdef CONFIG_WIREGUARD_MAX_SRC_IPS
#define WIREGUARD_MAX_SRC_IPS (CONFIG_WIREGUARD_MAX_SRC_IPS)
#else
#define WIREGUARD_MAX_SRC_IPS (1)
#endif

// Per device limit on accepting (valid) initiation requests - per peer
#define MAX_INITIATIONS_PER_SECOND (CONFIG_MAX_INITIATIONS_PER_SECOND)
#ifdef CONFIG_WIREGUARD_MAX_INIT_PER_SECOND
#define MAX_INITIATIONS_PER_SECOND (CONFIG_WIREGUARD_MAX_INIT_PER_SECOND)
#else
#define MAX_INITIATIONS_PER_SECOND (2)
#endif

// Initialize crypto backend (return ESP_OK on success)
esp_err_t wireguard_platform_init();
Expand Down
14 changes: 14 additions & 0 deletions src/wireguardif.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
* Copyright (c) 2021 Kenta Ida ([email protected])
* Copyright (c) 2023 Simone Rossetto <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
Expand Down Expand Up @@ -731,6 +732,19 @@ time_t wireguardif_latest_handshake(struct netif *netif, u8_t peer_index) {
return result;
}

err_t wireguardif_add_allowed_ip(struct netif *netif, u8_t peer_index, ip_addr_t ip, ip_addr_t mask) {
struct wireguard_peer *peer;
err_t result = wireguardif_lookup_peer(netif, peer_index, &peer);
if (result == ERR_OK) {
if(peer_add_ip(peer, ip, mask)) {
result = ERR_OK;
} else {
result = ERR_MEM;
}
}
return result;
}

err_t wireguardif_remove_peer(struct netif *netif, u8_t peer_index) {
struct wireguard_peer *peer;
err_t result = wireguardif_lookup_peer(netif, peer_index, &peer);
Expand Down
4 changes: 4 additions & 0 deletions src/wireguardif.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
* Copyright (c) 2023 Simone Rossetto <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
Expand Down Expand Up @@ -139,6 +140,9 @@ err_t wireguardif_peer_is_up(struct netif *netif, u8_t peer_index, ip_addr_t *cu
// Return 0 if no handshake already done or in case of errors
time_t wireguardif_latest_handshake(struct netif *netif, u8_t peer_index);

// Add ip/mask to the list of allowed ips of the given peer
err_t wireguardif_add_allowed_ip(struct netif *netif, u8_t peer_index, ip_addr_t ip, ip_addr_t mask);

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 9b7a576

Please sign in to comment.