Skip to content
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
79 changes: 60 additions & 19 deletions rsfbclient-rust/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ pub struct FirebirdWireConnection {
lazy_count: u32,

pub(crate) charset: Charset,

/// AuthPlugin data for use on attach when WireCrypt = Disabled
pub(crate) auth_plugin: Option<AuthPlugin>,
/// Key for the srp auth
pub(crate) srp_key: [u8; 32],
}

/// Data to keep track about a prepared statement
Expand Down Expand Up @@ -349,17 +354,22 @@ impl FirebirdWireConnection {

let ConnectionResponse {
version,
auth_plugin,
mut auth_plugin,
continue_auth,
} = parse_accept(&mut resp)?;

if let Some(mut auth_plugin) = auth_plugin {
if let Some(auth_plugin) = &mut auth_plugin {
loop {
match auth_plugin.kind {
plugin @ AuthPluginType::Srp => {
let srp = SrpClient::<sha1::Sha1>::new(&srp_key, &SRP_GROUP);

if let Some(data) = auth_plugin.data {
socket = srp_auth(socket, &mut buff, srp, plugin, user, pass, data)?;
if let Some(data) = auth_plugin.data.clone() {
if continue_auth {
// Continue autentication if needed
socket =
srp_auth(socket, &mut buff, srp, plugin, user, pass, &data)?;
}

// Authentication Ok
break;
Expand All @@ -378,14 +388,18 @@ impl FirebirdWireConnection {
let len = socket.read(&mut buff)?;
let mut resp = Bytes::copy_from_slice(&buff[..len]);

auth_plugin = parse_cont_auth(&mut resp)?;
*auth_plugin = parse_cont_auth(&mut resp)?;
}
}
plugin @ AuthPluginType::Srp256 => {
let srp = SrpClient::<sha2::Sha256>::new(&srp_key, &SRP_GROUP);

if let Some(data) = auth_plugin.data {
socket = srp_auth(socket, &mut buff, srp, plugin, user, pass, data)?;
if let Some(data) = auth_plugin.data.clone() {
if continue_auth {
// Continue autentication if needed
socket =
srp_auth(socket, &mut buff, srp, plugin, user, pass, &data)?;
}

// Authentication Ok
break;
Expand All @@ -404,7 +418,7 @@ impl FirebirdWireConnection {
let len = socket.read(&mut buff)?;
let mut resp = Bytes::copy_from_slice(&buff[..len]);

auth_plugin = parse_cont_auth(&mut resp)?;
*auth_plugin = parse_cont_auth(&mut resp)?;
}
}
}
Expand All @@ -417,6 +431,14 @@ impl FirebirdWireConnection {
buff,
lazy_count: 0,
charset,
auth_plugin: if continue_auth {
// Already authenticated
None
} else {
// Needs to authenticate in attach
auth_plugin
},
srp_key,
})
}

Expand All @@ -437,9 +459,11 @@ impl FirebirdWireConnection {
self.version,
self.charset.clone(),
page_size,
role_name.clone(),
role_name,
dialect,
))?;
self.auth_plugin.as_ref(),
&self.srp_key,
)?)?;
self.socket.flush()?;

let resp = self.read_response()?;
Expand All @@ -463,10 +487,12 @@ impl FirebirdWireConnection {
pass,
self.version,
self.charset.clone(),
role_name.clone(),
role_name,
dialect,
no_db_triggers,
))?;
self.auth_plugin.as_ref(),
&self.srp_key,
)?)?;
self.socket.flush()?;

let resp = self.read_response()?;
Expand Down Expand Up @@ -1124,16 +1150,12 @@ fn read_packet(socket: &mut impl Read, buff: &mut [u8]) -> Result<(u32, Bytes),
Ok((op_code, resp))
}

/// Performs the srp authentication with the server, returning the encrypted stream
fn srp_auth<D>(
mut socket: FbStream,
buff: &mut [u8],
pub(crate) fn srp_verifier<D>(
srp: SrpClient<D>,
plugin: AuthPluginType,
user: &str,
pass: &str,
data: SrpAuthData,
) -> Result<FbStream, FbError>
data: &SrpAuthData,
) -> Result<SrpClientVerifier<D>, FbError>
where
D: digest::Digest,
{
Expand All @@ -1145,6 +1167,25 @@ where
.process_reply(user.as_bytes(), &data.salt, &private_key, &data.pub_key)
.map_err(|e| FbError::from(format!("Srp error: {}", e)))?;

// Generate a proof to send to the server so it can verify the password
Ok(verifier)
}

/// Performs the srp authentication with the server, returning the encrypted stream
fn srp_auth<D>(
mut socket: FbStream,
buff: &mut [u8],
srp: SrpClient<D>,
plugin: AuthPluginType,
user: &str,
pass: &str,
data: &SrpAuthData,
) -> Result<FbStream, FbError>
where
D: digest::Digest,
{
let verifier = srp_verifier(srp, user, pass, data)?;

// Generate a proof to send to the server so it can verify the password
let proof = hex::encode(verifier.get_proof());

Expand Down
2 changes: 1 addition & 1 deletion rsfbclient-rust/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
ClientCrypt = 11,
}

#[derive(Debug)]
#[derive(Debug, Clone, Copy)]
pub enum AuthPluginType {
Srp256,
Srp,
Expand Down Expand Up @@ -196,7 +196,7 @@
}
}

#[cfg(not(tarpaulin_include))]

Check warning on line 199 in rsfbclient-rust/src/consts.rs

View workflow job for this annotation

GitHub Actions / testing (macos-latest, v3, pure_rust)

unexpected `cfg` condition name: `tarpaulin_include`

Check warning on line 199 in rsfbclient-rust/src/consts.rs

View workflow job for this annotation

GitHub Actions / testing (macos-latest, v3, pure_rust)

unexpected `cfg` condition name: `tarpaulin_include`

Check warning on line 199 in rsfbclient-rust/src/consts.rs

View workflow job for this annotation

GitHub Actions / testing (macos-latest, v3, pure_rust)

unexpected `cfg` condition name: `tarpaulin_include`

Check warning on line 199 in rsfbclient-rust/src/consts.rs

View workflow job for this annotation

GitHub Actions / testing (macos-latest, v3, pure_rust)

unexpected `cfg` condition name: `tarpaulin_include`

Check warning on line 199 in rsfbclient-rust/src/consts.rs

View workflow job for this annotation

GitHub Actions / testing (windows-latest, v5, pure_rust)

unexpected `cfg` condition name: `tarpaulin_include`

Check warning on line 199 in rsfbclient-rust/src/consts.rs

View workflow job for this annotation

GitHub Actions / testing (windows-latest, v5, pure_rust)

unexpected `cfg` condition name: `tarpaulin_include`

Check warning on line 199 in rsfbclient-rust/src/consts.rs

View workflow job for this annotation

GitHub Actions / testing (windows-latest, v5, pure_rust)

unexpected `cfg` condition name: `tarpaulin_include`
/// Converts a gds_code to a error message
pub fn gds_to_msg(gds_code: u32) -> &'static str {
match gds_code {
Expand Down
Loading
Loading