diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2018-03-02 13:02:57 +0100 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2018-03-02 19:30:56 +0100 |
| commit | 62c82f7a111293e71eeda120cf9f2da47efd1c63 (patch) | |
| tree | 48e2bb0a169abdac4ab66adc418759496b28b11e | |
| parent | 9c1c410d7de819385962b33a3491c1324df1fa7a (diff) | |
| download | mullvadvpn-62c82f7a111293e71eeda120cf9f2da47efd1c63.tar.xz mullvadvpn-62c82f7a111293e71eeda120cf9f2da47efd1c63.zip | |
Add --disable-rpc-auth flag to make the CLI work
| -rw-r--r-- | mullvad-daemon/src/cli.rs | 12 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 27 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 25 |
3 files changed, 46 insertions, 18 deletions
diff --git a/mullvad-daemon/src/cli.rs b/mullvad-daemon/src/cli.rs index 17af99f266..0550613232 100644 --- a/mullvad-daemon/src/cli.rs +++ b/mullvad-daemon/src/cli.rs @@ -8,6 +8,7 @@ pub struct Config { pub log_file: Option<PathBuf>, pub tunnel_log_file: Option<PathBuf>, pub resource_dir: Option<PathBuf>, + pub require_auth: bool, } pub fn get_config() -> Config { @@ -22,12 +23,14 @@ pub fn get_config() -> Config { let log_file = matches.value_of_os("log_file").map(PathBuf::from); let tunnel_log_file = matches.value_of_os("tunnel_log_file").map(PathBuf::from); let resource_dir = matches.value_of_os("resource_dir").map(PathBuf::from); + let require_auth = !matches.is_present("disable_rpc_auth"); Config { log_level, log_file, tunnel_log_file, resource_dir, + require_auth, } } @@ -50,14 +53,14 @@ fn create_app() -> App<'static, 'static> { .long("log") .takes_value(true) .value_name("PATH") - .help("Activates file logging to the given path"), + .help("Activates file logging to the given path."), ) .arg( Arg::with_name("tunnel_log_file") .long("tunnel-log") .takes_value(true) .value_name("PATH") - .help("Save log from tunnel implementation process to this file path"), + .help("Save log from tunnel implementation process to this file path."), ) .arg( Arg::with_name("resource_dir") @@ -66,4 +69,9 @@ fn create_app() -> App<'static, 'static> { .value_name("DIR") .help("Uses the given directory to read needed resources, such as certificates."), ) + .arg( + Arg::with_name("disable_rpc_auth") + .long("disable-rpc-auth") + .help("Don't require authentication on the RPC management interface."), + ) } diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index 4249714d47..8bd5ff9826 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -202,7 +202,11 @@ struct Daemon { } impl Daemon { - pub fn new(tunnel_log: Option<PathBuf>, resource_dir: PathBuf) -> Result<Self> { + pub fn new( + tunnel_log: Option<PathBuf>, + resource_dir: PathBuf, + require_auth: bool, + ) -> Result<Self> { let (rpc_handle, http_handle, tokio_remote) = mullvad_rpc::event_loop::create(|core| { let handle = core.handle(); @@ -217,7 +221,8 @@ impl Daemon { let relay_selector = Self::create_relay_selector(rpc_handle.clone(), &resource_dir)?; let (tx, rx) = mpsc::channel(); - let management_interface_broadcaster = Self::start_management_interface(tx.clone())?; + let management_interface_broadcaster = + Self::start_management_interface(tx.clone(), require_auth)?; let state = TunnelState::NotRunning; let target_state = TargetState::Unsecured; Ok(Daemon { @@ -266,9 +271,10 @@ impl Daemon { // Returns a handle that allows notifying all subscribers on events. fn start_management_interface( event_tx: mpsc::Sender<DaemonEvent>, + require_auth: bool, ) -> Result<management_interface::EventBroadcaster> { let multiplex_event_tx = IntoSender::from(event_tx.clone()); - let server = Self::start_management_interface_server(multiplex_event_tx)?; + let server = Self::start_management_interface_server(multiplex_event_tx, require_auth)?; let event_broadcaster = server.event_broadcaster(); Self::spawn_management_interface_wait_thread(server, event_tx); Ok(event_broadcaster) @@ -276,15 +282,24 @@ impl Daemon { fn start_management_interface_server( event_tx: IntoSender<TunnelCommand, DaemonEvent>, + require_auth: bool, ) -> Result<ManagementInterfaceServer> { - let shared_secret = uuid::Uuid::new_v4().to_string(); + let shared_secret = if require_auth { + Some(uuid::Uuid::new_v4().to_string()) + } else { + warn!("RPC management interface allows unauthorized access"); + None + }; + let server = ManagementInterfaceServer::start(event_tx, shared_secret.clone()) .chain_err(|| ErrorKind::ManagementInterfaceError("Failed to start server"))?; info!( "Mullvad management interface listening on {}", server.address() ); - rpc_info::write(server.address(), &shared_secret).chain_err(|| { + + let written_shared_secret = shared_secret.unwrap_or(String::from("")); + rpc_info::write(server.address(), &written_shared_secret).chain_err(|| { ErrorKind::ManagementInterfaceError("Failed to write RPC connection info to file") })?; Ok(server) @@ -753,7 +768,7 @@ fn run() -> Result<()> { log_version(); let resource_dir = config.resource_dir.unwrap_or_else(|| get_resource_dir()); - let daemon = Daemon::new(config.tunnel_log_file, resource_dir) + let daemon = Daemon::new(config.tunnel_log_file, resource_dir, config.require_auth) .chain_err(|| "Unable to initialize daemon")?; let shutdown_handle = daemon.shutdown_handle(); diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index ccc4fdeebb..8d6c2ebbc4 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -183,7 +183,7 @@ pub struct ManagementInterfaceServer { impl ManagementInterfaceServer { pub fn start<T>( tunnel_tx: IntoSender<TunnelCommand, T>, - shared_secret: String, + shared_secret: Option<String>, ) -> talpid_ipc::Result<Self> where T: From<TunnelCommand> + 'static + Send, @@ -256,11 +256,11 @@ impl EventBroadcaster { struct ManagementInterface<T: From<TunnelCommand> + 'static + Send> { subscriptions: Arc<ActiveSubscriptions>, tx: Mutex<IntoSender<TunnelCommand, T>>, - shared_secret: String, + shared_secret: Option<String>, } impl<T: From<TunnelCommand> + 'static + Send> ManagementInterface<T> { - pub fn new(tx: IntoSender<TunnelCommand, T>, shared_secret: String) -> Self { + pub fn new(tx: IntoSender<TunnelCommand, T>, shared_secret: Option<String>) -> Self { ManagementInterface { subscriptions: Default::default(), tx: Mutex::new(tx), @@ -330,7 +330,7 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterface<T> { } fn check_auth(&self, meta: &Meta) -> Result<(), Error> { - if meta.authenticated.load(Ordering::SeqCst) { + if self.shared_secret.is_none() || meta.authenticated.load(Ordering::SeqCst) { trace!("auth success"); Ok(()) } else { @@ -354,13 +354,18 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem type Metadata = Meta; fn auth(&self, meta: Self::Metadata, shared_secret: String) -> BoxFuture<(), Error> { - let authenticated = shared_secret == self.shared_secret; - meta.authenticated.store(authenticated, Ordering::SeqCst); - debug!("authenticated: {}", authenticated); - if authenticated { - Box::new(future::ok(())) + if let Some(ref self_shared_secret) = self.shared_secret { + let authenticated = &shared_secret == self_shared_secret; + meta.authenticated.store(authenticated, Ordering::SeqCst); + debug!("authenticated: {}", authenticated); + if authenticated { + Box::new(future::ok(())) + } else { + Box::new(future::err(Error::internal_error())) + } } else { - Box::new(future::err(Error::internal_error())) + warn!("Ignoring auth call since authentication is disabled"); + Box::new(future::ok(())) } } |
