Skip to content

Commit

Permalink
server: remove username and password support (#383)
Browse files Browse the repository at this point in the history
* remove username and password support

* remove sqlx dependency
  • Loading branch information
conradoplg authored Dec 26, 2024
1 parent fe7ea0a commit 2a07585
Show file tree
Hide file tree
Showing 22 changed files with 187 additions and 1,372 deletions.
643 changes: 3 additions & 640 deletions Cargo.lock

Large diffs are not rendered by default.

36 changes: 4 additions & 32 deletions coordinator/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,6 @@ pub struct Args {
#[arg(long, default_value_t = false)]
pub http: bool,

/// The username to use in HTTP mode.
#[arg(short = 'u', long, default_value = "")]
pub username: String,

/// The password to use in HTTP mode. If specified, it will be read from the
/// environment variable with the given name.
#[arg(short = 'w', long, default_value = "")]
pub password: String,

/// The comma-separated usernames of the signers to use in HTTP mode.
/// If HTTP mode is enabled and this is empty, then the session ID
/// will be printed and will have to be shared manually.
Expand Down Expand Up @@ -99,16 +90,6 @@ pub struct ProcessedArgs<C: Ciphersuite> {
/// FROST server.
pub http: bool,

/// The username to use in HTTP mode.
pub username: String,

/// The (actual) password to use in HTTP mode.
pub password: String,

/// The authentication token to use in HTTP mode; if not specified
/// it will login with `password`
pub authentication_token: Option<String>,

/// The comma-separated keys of the signers to use in
/// HTTP mode. If HTTP mode is enabled and this is empty, then the session
/// ID will be printed and will have to be shared manually.
Expand Down Expand Up @@ -138,15 +119,15 @@ pub struct ProcessedArgs<C: Ciphersuite> {
/// Port to connect to, if using HTTP mode.
pub port: u16,

/// The coordinator's communication private key. Specifying this along with
/// `comm_participant_pubkey_getter` enables encryption.
/// The coordinator's communication private key for HTTP mode.
pub comm_privkey: Option<Vec<u8>>,

/// The coordinator's communication public key.
/// The coordinator's communication public key for HTTP mode.
pub comm_pubkey: Option<Vec<u8>>,

/// A function that confirms if the public key of a participant is in the
/// user's contact book, returning the same public key, or None if not.
/// user's contact book, returning the same public key, or None if not. For
/// HTTP mode.
// It is a `Rc<dyn Fn>` to make it easier to use;
// using `fn()` would preclude using closures and using generics would
// require a lot of code change for something simple.
Expand All @@ -163,12 +144,6 @@ impl<C: Ciphersuite + 'static> ProcessedArgs<C> {
input: &mut dyn BufRead,
output: &mut dyn Write,
) -> Result<Self, Box<dyn Error>> {
let password = if args.http {
read_password(&args.password)?
} else {
String::new()
};

let num_signers = if !args.signers.is_empty() {
args.signers.len() as u16
} else if args.num_signers == 0 {
Expand Down Expand Up @@ -204,8 +179,6 @@ impl<C: Ciphersuite + 'static> ProcessedArgs<C> {
Ok(ProcessedArgs {
cli: args.cli,
http: args.http,
username: args.username.clone(),
password,
signers,
num_signers,
public_key_package,
Expand All @@ -214,7 +187,6 @@ impl<C: Ciphersuite + 'static> ProcessedArgs<C> {
signature: args.signature.clone(),
ip: args.ip.clone(),
port: args.port,
authentication_token: None,
comm_privkey: None,
comm_pubkey: None,
comm_participant_pubkey_getter: None,
Expand Down
83 changes: 48 additions & 35 deletions coordinator/src/comms/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,12 +266,11 @@ pub struct HTTPComms<C: Ciphersuite> {
client: reqwest::Client,
host_port: String,
session_id: Option<Uuid>,
access_token: String,
access_token: Option<String>,
num_signers: u16,
args: ProcessedArgs<C>,
state: SessionState<C>,
pubkeys: HashMap<Vec<u8>, Identifier<C>>,
should_logout: bool,
// The "send" Noise objects by pubkey of recipients.
send_noise: Option<HashMap<Vec<u8>, Noise>>,
// The "receive" Noise objects by pubkey of senders.
Expand All @@ -286,12 +285,11 @@ impl<C: Ciphersuite> HTTPComms<C> {
client,
host_port: format!("http://{}:{}", args.ip, args.port),
session_id: None,
access_token: args.authentication_token.clone().unwrap_or_default(),
access_token: None,
num_signers: 0,
args: args.clone(),
state: SessionState::new(args.messages.len(), args.num_signers as usize),
pubkeys: Default::default(),
should_logout: args.authentication_token.is_none(),
send_noise: None,
recv_noise: None,
_phantom: Default::default(),
Expand Down Expand Up @@ -370,29 +368,30 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
);
let signature: [u8; 64] = privkey.sign(challenge.as_bytes(), &mut rng);

self.access_token = self
.client
.post(format!("{}/key_login", self.host_port))
.json(&server::KeyLoginArgs {
uuid: challenge,
pubkey: self
.args
.comm_pubkey
.clone()
.ok_or_eyre("comm_pubkey must be specified")?,
signature: signature.to_vec(),
})
.send()
.await?
.json::<server::LoginOutput>()
.await?
.access_token
.to_string();
self.access_token = Some(
self.client
.post(format!("{}/login", self.host_port))
.json(&server::KeyLoginArgs {
uuid: challenge,
pubkey: self
.args
.comm_pubkey
.clone()
.ok_or_eyre("comm_pubkey must be specified")?,
signature: signature.to_vec(),
})
.send()
.await?
.json::<server::LoginOutput>()
.await?
.access_token
.to_string(),
);

let r = self
.client
.post(format!("{}/create_new_session", self.host_port))
.bearer_auth(&self.access_token)
.bearer_auth(self.access_token.as_ref().expect("was just set"))
.json(&server::CreateNewSessionArgs {
pubkeys: self.args.signers.iter().cloned().map(PublicKey).collect(),
num_signers,
Expand Down Expand Up @@ -460,7 +459,7 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
let r = self
.client
.post(format!("{}/receive", self.host_port))
.bearer_auth(&self.access_token)
.bearer_auth(self.access_token.as_ref().expect("was just set"))
.json(&server::ReceiveArgs {
session_id: r.session_id,
as_coordinator: true,
Expand Down Expand Up @@ -511,7 +510,11 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
let _r = self
.client
.post(format!("{}/send", self.host_port))
.bearer_auth(&self.access_token)
.bearer_auth(
self.access_token
.as_ref()
.expect("must have been set before"),
)
.json(&server::SendArgs {
session_id: self.session_id.unwrap(),
recipients: vec![server::PublicKey(recipient.clone())],
Expand All @@ -529,7 +532,11 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
let r = self
.client
.post(format!("{}/receive", self.host_port))
.bearer_auth(&self.access_token)
.bearer_auth(
self.access_token
.as_ref()
.expect("must have been set before"),
)
.json(&server::ReceiveArgs {
session_id: self.session_id.unwrap(),
as_coordinator: true,
Expand All @@ -553,21 +560,27 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
let _r = self
.client
.post(format!("{}/close_session", self.host_port))
.bearer_auth(&self.access_token)
.bearer_auth(
self.access_token
.as_ref()
.expect("must have been set before"),
)
.json(&server::CloseSessionArgs {
session_id: self.session_id.unwrap(),
})
.send()
.await?;

if self.should_logout {
let _r = self
.client
.post(format!("{}/logout", self.host_port))
.bearer_auth(&self.access_token)
.send()
.await?;
}
let _r = self
.client
.post(format!("{}/logout", self.host_port))
.bearer_auth(
self.access_token
.as_ref()
.expect("must have been set before"),
)
.send()
.await?;

let signature_shares = self.state.signature_shares()?;

Expand Down
34 changes: 2 additions & 32 deletions frost-client/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,9 @@ pub(crate) struct Args {

#[derive(Subcommand, Clone)]
pub(crate) enum Command {
/// Initializes the user, generating a communication key pair and optionally
/// registering with a FROST server. The key pair and additional information
/// are saved to the config file. You can rerun the command to register
/// in other servers; the communication key pair will not be regenerated.
Init {
/// The username to use when registering, if desired.
#[arg(short, long)]
username: Option<String>,
/// The server URL to use, if desired.
#[arg(short, long)]
server_url: Option<String>,
/// The path to the config file to manage. If not specified, it uses
/// $HOME/.local/frost/credentials.toml
#[arg(short, long)]
config: Option<String>,
},
/// Logs the user on the server and saves the returned authentication token
/// Initializes the user, generating a communication key pair and saving
/// to the config file.
Login {
/// The username to use when logging in.
#[arg(short, long)]
username: String,
/// The server URL to use.
#[arg(short, long)]
server_url: String,
Init {
/// The path to the config file to manage. If not specified, it uses
/// $HOME/.local/frost/credentials.toml
#[arg(short, long)]
Expand All @@ -45,10 +23,6 @@ pub(crate) enum Command {
/// The name to use when exporting.
#[arg(short, long)]
name: String,
/// The server URL for which to export a contact. You can use a
/// substring of the URL.
#[arg(short, long)]
server_url: Option<String>,
/// The path to the config file to manage. If not specified, it uses
/// $HOME/.local/frost/credentials.toml
#[arg(short, long)]
Expand Down Expand Up @@ -86,10 +60,6 @@ pub(crate) enum Command {
/// The comma-separated name of each participant.
#[arg(short = 'N', long, value_delimiter = ',')]
names: Vec<String>,
/// The comma-separated username of each participant in the same order
/// as `names`. Note: these won't be checked in the server.
#[arg(short, long, value_delimiter = ',')]
usernames: Vec<String>,
/// The server URL, if desired. Note that this does not connect to the
/// server; it will just associated the server URL with the group in the
/// config file.
Expand Down
27 changes: 1 addition & 26 deletions frost-client/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ pub struct Config {
#[serde(skip)]
path: Option<PathBuf>,
pub version: u8,
/// The registry of servers the user has registered into, keyed by server
/// URL.
#[serde(default)]
pub registry: BTreeMap<String, Registry>,
/// The communication key pair for the user.
pub communication_key: Option<CommunicationKey>,
/// The address book of the user, keyed by each contact's name.
Expand All @@ -41,25 +37,6 @@ impl Config {
.cloned()
.ok_or_eyre("contact not found")?)
}

pub fn username_by_server_url(&self, server_url: &str) -> Result<String, Box<dyn Error>> {
Ok(self
.registry
.get(server_url)
.ok_or_eyre("Not logged in in the giver server")?
.username
.clone())
}
}

/// A registry entry. Note that the server URL is not in the struct;
/// it is the key in the `registry` map in Config.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Registry {
/// The authentication token, if the user is logged in.
pub token: Option<String>,
/// The username of the user
pub username: String,
}

/// The communication key pair for the user.
Expand Down Expand Up @@ -117,7 +94,7 @@ impl Group {
);
for participant in self.participant.values() {
let contact = config.contact_by_pubkey(&participant.pubkey)?;
s += &format!("\t{}\n", contact.name);
s += &format!("\t{} ({})\n", contact.name, hex::encode(contact.pubkey));
}
Ok(s)
}
Expand All @@ -138,8 +115,6 @@ pub struct Participant {
deserialize_with = "serdect::slice::deserialize_hex_or_bin_vec"
)]
pub pubkey: Vec<u8>,
/// The username of the participant in the server, if any.
pub username: Option<String>,
}

impl Config {
Expand Down
Loading

0 comments on commit 2a07585

Please sign in to comment.