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

wifi: WPA-Enterprise support #119

Merged
merged 2 commits into from
Jun 28, 2018
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file
automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
This project adheres to [Semantic Versioning](http://semver.org/).

## v0.11.0 - 2018-06-28

* Wifi: WPA-Enterprise support #119 [majorz]

## v0.10.0 - 2018-03-14

* Expose `RequestScan` through `WiFiDevice::request_scan` #117 [majorz]
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "network-manager"
version = "0.10.0"
version = "0.11.0"
authors = ["Zahari Petkov <zahari@resin.io>", "Aaron Brodersen <aaron@resin.io>"]
description = "Rust NetworkManager bindings"
homepage = "https://github.com/resin-io-modules/network-manager"
Expand All @@ -14,7 +14,7 @@ dbus = "0.5"
futures = "0.1"
futures-cpupool = "0.1"
tokio-timer = "0.1"
bitflags = "0.9"
bitflags = "1.0"
ascii = "0.8"
log = "0.3"

Expand Down
8 changes: 6 additions & 2 deletions examples/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::env;
use std::process;
use std::io::Write;

use network_manager::{AccessPoint, Device, DeviceType, NetworkManager};
use network_manager::{AccessPoint, AccessPointCredentials, Device, DeviceType, NetworkManager};

mod errors {
use network_manager;
Expand Down Expand Up @@ -61,7 +61,11 @@ fn run() -> Result<()> {

let ap_index = find_access_point(&access_points, &args[1] as &str)?;

wifi_device.connect(&access_points[ap_index], &args[2] as &str)?;
let credentials = AccessPointCredentials::Wpa {
passphrase: args[2].clone(),
};

wifi_device.connect(&access_points[ap_index], &credentials)?;

Ok(())
}
Expand Down
32 changes: 9 additions & 23 deletions src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ use std::rc::Rc;
use std::fmt;
use std::net::Ipv4Addr;

use ascii::AsAsciiStr;

use errors::*;
use dbus_nm::DBusNetworkManager;

use wifi::Security;
use wifi::{AccessPoint, AccessPointCredentials};
use device::{get_active_connection_devices, Device};
use ssid::{AsSsidSlice, Ssid, SsidSlice};
use ssid::{AsSsidSlice, Ssid};

#[derive(Clone)]
pub struct Connection {
Expand Down Expand Up @@ -243,24 +241,13 @@ pub fn get_active_connections(dbus_manager: &Rc<DBusNetworkManager>) -> Result<V
Ok(connections)
}

pub fn connect_to_access_point<P>(
pub fn connect_to_access_point(
dbus_manager: &Rc<DBusNetworkManager>,
device_path: &str,
access_point_path: &str,
ssid: &SsidSlice,
security: &Security,
password: &P,
) -> Result<(Connection, ConnectionState)>
where
P: AsAsciiStr + ?Sized,
{
let (path, _) = dbus_manager.connect_to_access_point(
device_path,
access_point_path,
ssid,
security,
password,
)?;
access_point: &AccessPoint,
credentials: &AccessPointCredentials,
) -> Result<(Connection, ConnectionState)> {
let (path, _) = dbus_manager.connect_to_access_point(device_path, access_point, credentials)?;

let connection = Connection::init(dbus_manager, &path)?;

Expand All @@ -273,17 +260,16 @@ where
Ok((connection, state))
}

pub fn create_hotspot<S, P>(
pub fn create_hotspot<S>(
dbus_manager: &Rc<DBusNetworkManager>,
device_path: &str,
interface: &str,
ssid: &S,
password: Option<&P>,
password: Option<&str>,
address: Option<Ipv4Addr>,
) -> Result<(Connection, ConnectionState)>
where
S: AsSsidSlice + ?Sized,
P: AsAsciiStr + ?Sized,
{
let (path, _) = dbus_manager.create_hotspot(device_path, interface, ssid, password, address)?;

Expand Down
94 changes: 62 additions & 32 deletions src/dbus_nm.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use std::collections::HashMap;
use std::net::Ipv4Addr;

use ascii::AsAsciiStr;

use dbus::Path;
use dbus::arg::{Array, Dict, Iter, RefArg, Variant};

use ascii::AsciiStr;

use errors::*;
use dbus_api::{extract, path_to_string, DBusApi, VariantTo, variant_iter_to_vec_u8};
use manager::{Connectivity, NetworkManagerState};
use connection::{ConnectionSettings, ConnectionState};
use ssid::{AsSsidSlice, Ssid, SsidSlice};
use ssid::{AsSsidSlice, Ssid};
use device::{DeviceState, DeviceType};
use wifi::{NM80211ApFlags, NM80211ApSecurityFlags, Security, NONE, WEP};
use wifi::{AccessPoint, AccessPointCredentials, NM80211ApFlags, NM80211ApSecurityFlags};

type VariantMap = HashMap<String, Variant<Box<RefArg>>>;

Expand Down Expand Up @@ -187,27 +187,26 @@ impl DBusNetworkManager {
Ok(())
}

pub fn connect_to_access_point<P>(
pub fn connect_to_access_point(
&self,
device_path: &str,
ap_path: &str,
ssid: &SsidSlice,
security: &Security,
password: &P,
) -> Result<(String, String)>
where
P: AsAsciiStr + ?Sized,
{
access_point: &AccessPoint,
credentials: &AccessPointCredentials,
) -> Result<(String, String)> {
let mut settings: HashMap<String, VariantMap> = HashMap::new();

let mut wireless: VariantMap = HashMap::new();
add_val(&mut wireless, "ssid", ssid.as_bytes().to_vec());
add_val(
&mut wireless,
"ssid",
access_point.ssid().as_bytes().to_vec(),
);
settings.insert("802-11-wireless".to_string(), wireless);

if *security != NONE {
let mut security_settings: VariantMap = HashMap::new();
match *credentials {
AccessPointCredentials::Wep { ref passphrase } => {
let mut security_settings: VariantMap = HashMap::new();

if security.contains(WEP) {
add_val(
&mut security_settings,
"wep-key-type",
Expand All @@ -216,15 +215,42 @@ impl DBusNetworkManager {
add_str(
&mut security_settings,
"wep-key0",
verify_password(password)?,
verify_ascii_password(passphrase)?,
);
} else {

settings.insert("802-11-wireless-security".to_string(), security_settings);
},
AccessPointCredentials::Wpa { ref passphrase } => {
let mut security_settings: VariantMap = HashMap::new();

add_str(&mut security_settings, "key-mgmt", "wpa-psk");
add_str(&mut security_settings, "psk", verify_password(password)?);
};
add_str(
&mut security_settings,
"psk",
verify_ascii_password(passphrase)?,
);

settings.insert("802-11-wireless-security".to_string(), security_settings);
}
settings.insert("802-11-wireless-security".to_string(), security_settings);
},
AccessPointCredentials::Enterprise {
ref identity,
ref passphrase,
} => {
let mut security_settings: VariantMap = HashMap::new();

add_str(&mut security_settings, "key-mgmt", "wpa-eap");

let mut eap: VariantMap = HashMap::new();
add_val(&mut eap, "eap", vec!["peap".to_string()]);
add_str(&mut eap, "identity", identity as &str);
add_str(&mut eap, "password", passphrase as &str);
add_str(&mut eap, "phase2-auth", "mschapv2");

settings.insert("802-11-wireless-security".to_string(), security_settings);
settings.insert("802-1x".to_string(), eap);
},
AccessPointCredentials::None => {},
};

let response = self.dbus.call_with_args(
NM_SERVICE_PATH,
Expand All @@ -233,7 +259,7 @@ impl DBusNetworkManager {
&[
&settings as &RefArg,
&Path::new(device_path.to_string())? as &RefArg,
&Path::new(ap_path.to_string())? as &RefArg,
&Path::new(access_point.path.to_string())? as &RefArg,
],
)?;

Expand All @@ -245,17 +271,16 @@ impl DBusNetworkManager {
))
}

pub fn create_hotspot<T, U>(
pub fn create_hotspot<T>(
&self,
device_path: &str,
interface: &str,
ssid: &T,
password: Option<&U>,
password: Option<&str>,
address: Option<Ipv4Addr>,
) -> Result<(String, String)>
where
T: AsSsidSlice + ?Sized,
U: AsAsciiStr + ?Sized,
{
let ssid = ssid.as_ssid_slice()?;
let ssid_vec = ssid.as_bytes().to_vec();
Expand Down Expand Up @@ -294,7 +319,7 @@ impl DBusNetworkManager {

let mut security: VariantMap = HashMap::new();
add_str(&mut security, "key-mgmt", "wpa-psk");
add_str(&mut security, "psk", verify_password(password)?);
add_str(&mut security, "psk", verify_ascii_password(password)?);

settings.insert("802-11-wireless-security".to_string(), security);
}
Expand Down Expand Up @@ -466,17 +491,22 @@ where
map.insert(key.into(), Variant(Box::new(value.into())));
}

fn verify_password<T: AsAsciiStr + ?Sized>(password: &T) -> Result<&str> {
match password.as_ascii_str() {
fn verify_ascii_password(password: &str) -> Result<&str> {
match AsciiStr::from_ascii(password) {
Err(e) => Err(e).chain_err(|| ErrorKind::PreSharedKey("Not an ASCII password".into())),
Ok(p) => {
if p.len() > 64 {
if p.len() < 8 {
bail!(ErrorKind::PreSharedKey(format!(
"Password length should be at least 8 characters: {} len",
p.len()
)))
} else if p.len() > 64 {
bail!(ErrorKind::PreSharedKey(format!(
"Password length should not exceed 64: {} len",
p.len()
)))
} else {
Ok(p.as_str())
Ok(password)
}
},
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ mod ssid;
pub use manager::{Connectivity, NetworkManager};
pub use connection::{Connection, ConnectionSettings, ConnectionState};
pub use device::{Device, DeviceState, DeviceType};
pub use wifi::AccessPoint;
pub use wifi::{AccessPoint, AccessPointCredentials, Security};
pub use service::ServiceState;
Loading