Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: prepare initial crate release #14

Merged
merged 8 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
changelog:
exclude:
labels:
- ignore-for-release
categories:
- title: Breaking Changes 🛠
labels:
- Semver-Major
- breaking-change
- title: Exciting New Features 🎉
labels:
- Semver-Minor
- enhancement
- title: Other Changes
labels:
- "*"
18 changes: 18 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Create a new GitHub release
on:
push:
tags:
- v*.*.*

jobs:
create-release:
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Create release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
draft: true
generate_release_notes: true
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/target
.idea/
42 changes: 21 additions & 21 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
[package]
name = "wireguard_rs"
version = "0.1.0"
name = "defguard_wireguard_rs"
version = "0.2.0"
edition = "2021"

description = "A unified multi-platform high-level API for managing WireGuard interfaces"
license = "Apache-2.0"
readme = "README.md"
homepage = "https://github.com/DefGuard/wireguard-rs"
repository = "https://github.com/DefGuard/wireguard-rs"
keywords = ["wireguard", "network", "vpn"]
categories = ["network-programming"]

[dependencies]
base64 = "0.21"
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img src="docs/header.png" alt="defguard">
</p>

**wireguard-rs** is a Rust library providing a unified high-level API for managing WireGuard interfaces using native OS kernel and userspace WireGuard protocol implementations.
**defguard_wireguard_rs** is a multi-platform Rust library providing a unified high-level API for managing WireGuard interfaces using native OS kernel and userspace WireGuard protocol implementations.
It can be used to create your own [WireGuard:tm:](https://www.wireguard.com/) VPN servers or clients for secure and private networking.

It was developed as part of [defguard](https://github.com/defguard/defguard) security platform and used in the [gateway/server](https://github.com/defguard/gateway) as well as [desktop client](https://github.com/defguard/client).
Expand All @@ -18,6 +18,11 @@ It was developed as part of [defguard](https://github.com/defguard/defguard) sec
- macOS
- FreeBSD

### Note on `wireguard-go`
If you intend to use the userspace WireGuard implementation you should note that currently the library assumes
that the `wireguard-go` binary will be available at runtime. There are some sanity checks when instantiating the API,
but installing it is outside the scope of this project.

## Examples

* Client: https://github.com/DefGuard/wireguard-rs/blob/main/examples/client.rs
Expand Down
Binary file modified docs/header.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions examples/client.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{net::SocketAddr, str::FromStr};

use wireguard_rs::{
wgapi::WGApi, InterfaceConfiguration, IpAddrMask, Key, Peer, WireguardInterfaceApi,
use defguard_wireguard_rs::{
host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi,
};
use x25519_dalek::{EphemeralSecret, PublicKey};

Expand Down
4 changes: 2 additions & 2 deletions examples/server.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::str::FromStr;

use wireguard_rs::{
wgapi::WGApi, InterfaceConfiguration, IpAddrMask, Key, Peer, WireguardInterfaceApi,
use defguard_wireguard_rs::{
host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi,
};
use x25519_dalek::{EphemeralSecret, PublicKey};

Expand Down
7 changes: 4 additions & 3 deletions examples/userspace.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use defguard_wireguard_rs::{
host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WireguardApiUserspace,
WireguardInterfaceApi,
};
use std::{
io::{stdin, stdout, Read, Write},
net::SocketAddr,
str::FromStr,
};
use wireguard_rs::{
InterfaceConfiguration, IpAddrMask, Key, Peer, WireguardApiUserspace, WireguardInterfaceApi,
};
use x25519_dalek::{EphemeralSecret, PublicKey};

fn pause() {
Expand Down
4 changes: 2 additions & 2 deletions src/bsd/nvlist.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// https://github.com/freebsd/freebsd-src/tree/main/sys/contrib/libnv
// https://github.com/freebsd/freebsd-src/blob/main/sys/sys/nv.h
//! `nvlist` implementation in Rust.

use std::{error::Error, ffi::CStr, fmt};

/// `NV_HEADER_SIZE` is for both: `nvlist_header` and `nvpair_header`.
Expand Down
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Interface management errors

use thiserror::Error;

#[derive(Debug, Error)]
Expand Down
6 changes: 6 additions & 0 deletions src/host.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Host interface configuration

use std::{
collections::HashMap,
io::{self, BufRead, BufReader, Read},
Expand All @@ -14,6 +16,7 @@ use netlink_packet_wireguard::{

use crate::{key::Key, net::IpAddrMask};

/// WireGuard peer representation.
#[derive(Debug, Default, PartialEq, Clone)]
pub struct Peer {
pub public_key: Key,
Expand All @@ -28,6 +31,7 @@ pub struct Peer {
}

impl Peer {
/// Create new `Peer` with a given `public_key`.
#[must_use]
pub fn new(public_key: Key) -> Self {
Self {
Expand Down Expand Up @@ -153,6 +157,7 @@ impl Peer {
}
}

/// WireGuard host representation.
#[derive(Debug, Default)]
pub struct Host {
pub listen_port: u16,
Expand All @@ -162,6 +167,7 @@ pub struct Host {
}

impl Host {
/// Create new `Host` with a given `listen_port` and `private_key`.
#[must_use]
pub fn new(listen_port: u16, private_key: Key) -> Self {
Self {
Expand Down
10 changes: 10 additions & 0 deletions src/key.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Public key utilities

use std::{
error, fmt,
hash::{Hash, Hasher},
Expand All @@ -8,6 +10,7 @@ use base64::{prelude::BASE64_STANDARD, DecodeError, Engine};

const KEY_LENGTH: usize = 32;

/// WireGuard key representation in binary form.
#[derive(Clone, Default)]
pub struct Key([u8; KEY_LENGTH]);

Expand All @@ -31,6 +34,7 @@ impl fmt::Display for KeyError {
}

impl Key {
/// Create a new key from buffer.
#[must_use]
pub fn new(buf: [u8; KEY_LENGTH]) -> Self {
Self(buf)
Expand All @@ -46,6 +50,7 @@ impl Key {
self.0.as_slice()
}

/// Converts `Key` to `String` of lower case hexadecimal digits.
#[must_use]
pub fn to_lower_hex(&self) -> String {
let mut hex = String::with_capacity(64);
Expand All @@ -62,6 +67,11 @@ impl Key {
hex
}

/// Converts a text string of hexadecimal digits to `Key`.
///
/// # Errors
/// Will return `KeyError` if text string has wrong length,
/// or contains an invalid character.
pub fn decode<T: AsRef<[u8]>>(hex: T) -> Result<Self, KeyError> {
let hex = hex.as_ref();
let length = hex.len();
Expand Down
78 changes: 65 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
//! # `defguard_wireguard_rs`
//!
//! `defguard_wireguard_rs` is a multi-platform Rust library providing a unified high-level API
//! for managing WireGuard interfaces using native OS kernel and userspace WireGuard protocol implementations.
//!
//! It can be used to create your own [WireGuard:tm:](https://www.wireguard.com/) VPN servers or clients for secure and private networking.
//!
//! It was developed as part of [defguard](https://github.com/defguard/defguard) security platform and used in the [gateway/server](https://github.com/defguard/gateway) as well as [desktop client](https://github.com/defguard/client).
//!
//! ## Example
//!
//! ```no_run
//! use x25519_dalek::{EphemeralSecret, PublicKey};
//! use defguard_wireguard_rs::{InterfaceConfiguration, WGApi, WireguardInterfaceApi, host::Peer};
//! # use defguard_wireguard_rs::error::WireguardInterfaceError;
//!
//! // Create new API struct for interface
//! let ifname: String = if cfg!(target_os = "linux") || cfg!(target_os = "freebsd") {
//! "wg0".into()
//! } else {
//! "utun3".into()
//! };
//! let wgapi = WGApi::new(ifname.clone(), false)?;
//!
//! // Create host interfaces
//! wgapi.create_interface()?;
//!
//! // Configure host interface
//! let interface_config = InterfaceConfiguration {
//! name: ifname.clone(),
//! prvkey: "AAECAwQFBgcICQoLDA0OD/Dh0sO0pZaHeGlaSzwtHg8=".to_string(),
//! address: "10.6.0.30".to_string(),
//! port: 12345,
//! peers: vec![],
//! };
//! wgapi.configure_interface(&interface_config)?;
//!
//! // Create, add & remove peers
//! for _ in 0..32 {
//! let secret = EphemeralSecret::random();
//! let key = PublicKey::from(&secret);
//! let peer = Peer::new(key.as_ref().try_into().unwrap());
//! wgapi.configure_peer(&peer)?;
//! wgapi.remove_peer(&peer.public_key)?;
//! }
//!
//! // Remove host interface
//! wgapi.remove_interface()?;
//! # Ok::<(), WireguardInterfaceError>(())
//! ```

#[cfg(target_os = "freebsd")]
pub mod bsd;
pub mod error;
Expand All @@ -6,7 +57,7 @@ pub mod key;
pub mod net;
#[cfg(target_os = "linux")]
pub mod netlink;
pub mod wgapi;
mod wgapi;

#[cfg(target_os = "freebsd")]
mod wgapi_freebsd;
Expand All @@ -21,23 +72,24 @@ extern crate log;

use std::process::Output;

// public reexports
use self::{
error::WireguardInterfaceError,
host::{Host, Peer},
key::Key,
net::IpAddrMask,
};

// public re-exports
pub use wgapi::WGApi;
#[cfg(target_os = "freebsd")]
pub use wgapi_freebsd::WireguardApiFreebsd;
#[cfg(target_os = "linux")]
pub use wgapi_linux::WireguardApiLinux;
#[cfg(target_family = "unix")]
pub use wgapi_userspace::WireguardApiUserspace;
pub use {
self::error::WireguardInterfaceError,
host::{Host, Peer},
key::Key,
net::{IpAddrMask, IpAddrParseError},
wgapi::WGApi,
wireguard_interface::WireguardInterfaceApi,
};
pub use wireguard_interface::WireguardInterfaceApi;

/// Wireguard Interface configuration
/// Host WireGuard interface configuration
#[derive(Debug, Clone)]
pub struct InterfaceConfiguration {
pub name: String,
Expand All @@ -63,8 +115,8 @@ impl TryFrom<&InterfaceConfiguration> for Host {
}
}

/// Util function which checks external command output status.
pub fn check_command_output_status(output: Output) -> Result<(), WireguardInterfaceError> {
/// Utility function which checks external command output status.
fn check_command_output_status(output: Output) -> Result<(), WireguardInterfaceError> {
if !output.status.success() {
let stdout = String::from_utf8(output.stdout).expect("Invalid UTF8 sequence in stdout");
let stderr = String::from_utf8(output.stderr).expect("Invalid UTF8 sequence in stderr");
Expand Down
Loading