|
| 1 | +use super::{sync, GroupId, RemoteGroup, RemoteProject, RemoteUser}; |
1 | 2 | use binaryninjacore_sys::*; |
| 3 | +use std::env::VarError; |
2 | 4 | use std::ffi::c_void; |
3 | 5 | use std::ptr::NonNull; |
4 | 6 |
|
5 | | -use super::{sync, GroupId, RemoteGroup, RemoteProject, RemoteUser}; |
6 | | - |
7 | 7 | use crate::binary_view::BinaryView; |
8 | 8 | use crate::database::Database; |
9 | 9 | use crate::enterprise; |
10 | 10 | use crate::progress::{NoProgressCallback, ProgressCallback}; |
11 | 11 | use crate::project::Project; |
12 | 12 | use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; |
| 13 | +use crate::secrets_provider::CoreSecretsProvider; |
| 14 | +use crate::settings::Settings; |
13 | 15 | use crate::string::{BnString, IntoCStr}; |
14 | 16 |
|
15 | 17 | #[repr(transparent)] |
@@ -185,20 +187,22 @@ impl Remote { |
185 | 187 | /// Use [Remote::connect_with_opts] if you cannot otherwise automatically connect using enterprise. |
186 | 188 | /// |
187 | 189 | /// WARNING: This is currently **not** thread safe, if you try and connect/disconnect to a remote on |
188 | | - /// multiple threads you will be subject to race conditions. To avoid this wrap the [`Remote`] in |
189 | | - /// a synchronization primitive, and pass that to your threads. Or don't try and connect on multiple threads. |
| 190 | + /// multiple threads, you will be subject to race conditions. To avoid this, wrap the [`Remote`] in |
| 191 | + /// a synchronization primitive and pass that to your threads. Or don't try and connect on multiple threads. |
190 | 192 | pub fn connect(&self) -> Result<(), ()> { |
191 | | - // TODO: implement SecretsProvider |
192 | 193 | if self.is_enterprise()? && enterprise::is_server_authenticated() { |
193 | 194 | self.connect_with_opts(ConnectionOptions::from_enterprise()?) |
194 | 195 | } else { |
195 | | - // TODO: Make this error instead. |
196 | | - let username = |
197 | | - std::env::var("BN_ENTERPRISE_USERNAME").expect("No username for connection!"); |
198 | | - let password = |
199 | | - std::env::var("BN_ENTERPRISE_PASSWORD").expect("No password for connection!"); |
200 | | - let connection_opts = ConnectionOptions::new_with_password(username, password); |
201 | | - self.connect_with_opts(connection_opts) |
| 196 | + // Try to load from env vars. |
| 197 | + match ConnectionOptions::from_env_variables() { |
| 198 | + Ok(connection_opts) => self.connect_with_opts(connection_opts), |
| 199 | + Err(_) => { |
| 200 | + // Try to load from the enterprise secrets provider. |
| 201 | + let secrets_connection_opts = |
| 202 | + ConnectionOptions::from_secrets_provider(&self.address())?; |
| 203 | + self.connect_with_opts(secrets_connection_opts) |
| 204 | + } |
| 205 | + } |
202 | 206 | } |
203 | 207 | } |
204 | 208 |
|
@@ -870,11 +874,31 @@ impl ConnectionOptions { |
870 | 874 | // TODO: Check if enterprise is initialized and error if not. |
871 | 875 | let username = enterprise::server_username(); |
872 | 876 | let token = enterprise::server_token(); |
| 877 | + Ok(Self::new_with_token(username, token)) |
| 878 | + } |
| 879 | + |
| 880 | + /// Retrieves the [`ConnectionOptions`] for the given address. |
| 881 | + /// |
| 882 | + /// NOTE: Uses the secret's provider specified by the setting "enterprise.secretsProvider". |
| 883 | + pub fn from_secrets_provider(address: &str) -> Result<Self, ()> { |
| 884 | + let secrets_provider_name = Settings::new().get_string("enterprise.secretsProvider"); |
| 885 | + let provider = CoreSecretsProvider::by_name(&secrets_provider_name).ok_or(())?; |
| 886 | + let cred_data_str = provider.get_data(address); |
| 887 | + if cred_data_str.is_empty() { |
| 888 | + return Err(()); |
| 889 | + } |
| 890 | + let cred_data: serde_json::Value = serde_json::from_str(&cred_data_str).map_err(|_| ())?; |
| 891 | + let username = cred_data["username"].as_str().ok_or(())?; |
| 892 | + let token = cred_data["token"].as_str().ok_or(())?; |
873 | 893 | Ok(Self::new_with_token( |
874 | 894 | username.to_string(), |
875 | 895 | token.to_string(), |
876 | 896 | )) |
877 | 897 | } |
878 | 898 |
|
879 | | - // TODO: from_secrets_provider |
| 899 | + pub fn from_env_variables() -> Result<Self, VarError> { |
| 900 | + let username = std::env::var("BN_ENTERPRISE_USERNAME")?; |
| 901 | + let password = std::env::var("BN_ENTERPRISE_PASSWORD")?; |
| 902 | + Ok(ConnectionOptions::new_with_password(username, password)) |
| 903 | + } |
880 | 904 | } |
0 commit comments