Trait sspi::Sspi

source ·
pub trait Sspi
where Self: Sized + SspiImpl,
{
Show 15 methods // Required methods fn complete_auth_token( &mut self, token: &mut [SecurityBuffer] ) -> Result<SecurityStatus>; fn encrypt_message( &mut self, flags: EncryptionFlags, message: &mut [SecurityBuffer], sequence_number: u32 ) -> Result<SecurityStatus>; fn decrypt_message( &mut self, message: &mut [DecryptBuffer<'_>], sequence_number: u32 ) -> Result<DecryptionFlags>; fn query_context_sizes(&mut self) -> Result<ContextSizes>; fn query_context_names(&mut self) -> Result<ContextNames>; fn query_context_package_info(&mut self) -> Result<PackageInfo>; fn query_context_cert_trust_status(&mut self) -> Result<CertTrustStatus>; fn change_password<'a>( &'a mut self, change_password: ChangePassword<'a> ) -> Result<GeneratorChangePassword<'_>>; // Provided methods fn acquire_credentials_handle<'a>( &mut self ) -> EmptyAcquireCredentialsHandle<'a, Self::CredentialsHandle, Self::AuthenticationData> { ... } fn initialize_security_context<'a>( &mut self ) -> EmptyInitializeSecurityContext<'a, Self::CredentialsHandle> { ... } fn accept_security_context<'a>( &mut self ) -> EmptyAcceptSecurityContext<'a, Self::CredentialsHandle> { ... } fn query_context_stream_sizes(&mut self) -> Result<StreamSizes> { ... } fn query_context_remote_cert(&mut self) -> Result<CertContext> { ... } fn query_context_negotiation_package(&mut self) -> Result<PackageInfo> { ... } fn query_context_connection_info(&mut self) -> Result<ConnectionInfo> { ... }
}
Expand description

This trait provides interface for all available SSPI functions. The acquire_credentials_handle, initialize_security_context, and accept_security_context methods return Builders that make it easier to assemble the list of arguments for the function and then execute it.

§MSDN

Required Methods§

source

fn complete_auth_token( &mut self, token: &mut [SecurityBuffer] ) -> Result<SecurityStatus>

Completes an authentication token. This function is used by protocols, such as DCE, that need to revise the security information after the transport application has updated some message parameters.

§Parameters
  • token: SecurityBuffer that contains the buffer descriptor for the entire message
§Returns
  • SspiOk on success
  • Error on error
§Example
use sspi::Sspi;
use sspi::Username;
use sspi::builders::EmptyInitializeSecurityContext;
use sspi::SspiImpl;

let mut client_ntlm = sspi::Ntlm::new();
let mut ntlm = sspi::Ntlm::new();

let mut client_output_buffer = vec![sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token)];
let mut output_buffer = vec![sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token)];

let identity = sspi::AuthIdentity {
    username: Username::parse("user").unwrap(),
    password: "password".to_string().into(),
};

let mut client_acq_cred_result = client_ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Outbound)
    .with_auth_data(&identity)
    .execute(&mut ntlm)
    .unwrap();

let mut server_acq_cred_result = ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Inbound)
    .with_auth_data(&identity)
    .execute(&mut ntlm)
    .unwrap();

loop {
    client_output_buffer[0].buffer.clear();

    let mut builder = client_ntlm.initialize_security_context()
        .with_credentials_handle(&mut client_acq_cred_result.credentials_handle)
        .with_context_requirements(
            sspi::ClientRequestFlags::CONFIDENTIALITY | sspi::ClientRequestFlags::ALLOCATE_MEMORY,
        )
        .with_target_data_representation(sspi::DataRepresentation::Native)
        .with_target_name("user")
        .with_input(&mut output_buffer)
        .with_output(&mut client_output_buffer);

    let _client_result = client_ntlm.initialize_security_context_impl(&mut builder)
        .unwrap()
        .resolve_to_result()
        .unwrap();

    let server_result = ntlm
        .accept_security_context()
        .with_credentials_handle(&mut server_acq_cred_result.credentials_handle)
        .with_context_requirements(sspi::ServerRequestFlags::ALLOCATE_MEMORY)
        .with_target_data_representation(sspi::DataRepresentation::Native)
        .with_input(&mut client_output_buffer)
        .with_output(&mut output_buffer)
        .execute(&mut ntlm)
        .unwrap();

    if server_result.status == sspi::SecurityStatus::CompleteAndContinue
        || server_result.status == sspi::SecurityStatus::CompleteNeeded
    {
        break;
    }
}

#[allow(unused_variables)]
let result = ntlm
    .complete_auth_token(&mut output_buffer)
    .unwrap();
§MSDN
source

fn encrypt_message( &mut self, flags: EncryptionFlags, message: &mut [SecurityBuffer], sequence_number: u32 ) -> Result<SecurityStatus>

Encrypts a message to provide privacy. The function allows the application to choose among cryptographic algorithms supported by the chosen mechanism. Some packages do not have messages to be encrypted or decrypted but rather provide an integrity hash that can be checked.

§Parameters
  • flags: package-specific flags that indicate the quality of protection. A security package can use this parameter to enable the selection of cryptographic algorithms
  • message: on input, the structure accepts one or more SecurityBuffer structures that can be of type SecurityBufferType::Data. That buffer contains the message to be encrypted. The message is encrypted in place, overwriting the original contents of the structure.
  • sequence_number: the sequence number that the transport application assigned to the message. If the transport application does not maintain sequence numbers, this parameter must be zero
§Example
use sspi::Sspi;
use sspi::Username;
use sspi::builders::EmptyInitializeSecurityContext;
use sspi::SspiImpl;

let mut client_ntlm = sspi::Ntlm::new();
let mut ntlm = sspi::Ntlm::new();

let mut client_output_buffer = vec![sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token)];
let mut server_output_buffer = vec![sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token)];

let identity = sspi::AuthIdentity {
    username: Username::parse("user").unwrap(),
    password: "password".to_string().into(),
};

let mut client_acq_cred_result = client_ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Outbound)
    .with_auth_data(&identity)
    .execute(&mut client_ntlm)
    .unwrap();

let mut server_acq_cred_result = ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Inbound)
    .with_auth_data(&identity)
    .execute(&mut ntlm)
    .unwrap();

loop {
    client_output_buffer[0].buffer.clear();

    let mut builder = client_ntlm.initialize_security_context()
        .with_credentials_handle(&mut client_acq_cred_result.credentials_handle)
        .with_context_requirements(
            sspi::ClientRequestFlags::CONFIDENTIALITY | sspi::ClientRequestFlags::ALLOCATE_MEMORY,
        )
        .with_target_data_representation(sspi::DataRepresentation::Native)
        .with_target_name("user")
        .with_input(&mut server_output_buffer)
        .with_output(&mut client_output_buffer);

    let _client_result = client_ntlm.initialize_security_context_impl(&mut builder)
        .unwrap()
        .resolve_to_result()
        .unwrap();

    let server_result = ntlm
        .accept_security_context()
        .with_credentials_handle(&mut server_acq_cred_result.credentials_handle)
        .with_context_requirements(sspi::ServerRequestFlags::ALLOCATE_MEMORY)
        .with_target_data_representation(sspi::DataRepresentation::Native)
        .with_input(&mut client_output_buffer)
        .with_output(&mut server_output_buffer)
        .execute(&mut ntlm)
        .unwrap();

    if server_result.status == sspi::SecurityStatus::CompleteAndContinue
        || server_result.status == sspi::SecurityStatus::CompleteNeeded
    {
        break;
    }
}

let _result = ntlm
    .complete_auth_token(&mut server_output_buffer)
    .unwrap();

let mut msg_buffer = vec![sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token),
    sspi::SecurityBuffer::new(Vec::from("This is a message".as_bytes()), sspi::SecurityBufferType::Data)];

println!("Unencrypted: {:?}", msg_buffer[1].buffer);

let result = ntlm
    .encrypt_message(sspi::EncryptionFlags::empty(), &mut msg_buffer, 0).unwrap();

println!("Encrypted: {:?}", msg_buffer[1].buffer);
§Returns
  • SspiOk on success
  • Error on error
§MSDN
source

fn decrypt_message( &mut self, message: &mut [DecryptBuffer<'_>], sequence_number: u32 ) -> Result<DecryptionFlags>

Decrypts a message. Some packages do not encrypt and decrypt messages but rather perform and check an integrity hash.

§Parameters
  • message: on input, the structure references one or more SecurityBuffer structures. At least one of these must be of type SecurityBufferType::Data. That buffer contains the encrypted message. The encrypted message is decrypted in place, overwriting the original contents of its buffer
  • sequence_number: the sequence number that the transport application assigned to the message. If the transport application does not maintain sequence numbers, this parameter must be zero
§Returns
  • DecryptionFlags upon success
  • Error on error
§Example
use sspi::Sspi;
use sspi::Username;
use sspi::builders::EmptyInitializeSecurityContext;
use sspi::SspiImpl;

let mut ntlm = sspi::Ntlm::new();
let mut server_ntlm = sspi::Ntlm::new();

let mut client_output_buffer = vec![sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token)];
let mut server_output_buffer = vec![sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token)];

let identity = sspi::AuthIdentity {
    username: Username::parse("user").unwrap(),
    password: "password".to_string().into(),
};

let mut client_acq_cred_result = ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Outbound)
    .with_auth_data(&identity)
    .execute(&mut ntlm)
    .unwrap();

let mut server_acq_cred_result = server_ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Inbound)
    .with_auth_data(&identity)
    .execute(&mut server_ntlm)
    .unwrap();

loop {
    client_output_buffer[0].buffer.clear();

    let mut builder = ntlm.initialize_security_context()
        .with_credentials_handle(&mut client_acq_cred_result.credentials_handle)
        .with_context_requirements(
            sspi::ClientRequestFlags::CONFIDENTIALITY | sspi::ClientRequestFlags::ALLOCATE_MEMORY,
        )
        .with_target_data_representation(sspi::DataRepresentation::Native)
        .with_target_name("user")
        .with_input(&mut server_output_buffer)
        .with_output(&mut client_output_buffer);

    let _client_result = ntlm.initialize_security_context_impl(&mut builder)
        .unwrap()
        .resolve_to_result()
        .unwrap();

    let server_result = server_ntlm
        .accept_security_context()
        .with_credentials_handle(&mut server_acq_cred_result.credentials_handle)
        .with_context_requirements(sspi::ServerRequestFlags::ALLOCATE_MEMORY)
        .with_target_data_representation(sspi::DataRepresentation::Native)
        .with_input(&mut client_output_buffer)
        .with_output(&mut server_output_buffer)
        .execute(&mut server_ntlm)
        .unwrap();

    if server_result.status == sspi::SecurityStatus::CompleteAndContinue
        || server_result.status == sspi::SecurityStatus::CompleteNeeded
    {
        break;
    }
}

let _result = server_ntlm
    .complete_auth_token(&mut server_output_buffer)
    .unwrap();

let mut msg = [sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token),
    sspi::SecurityBuffer::new(Vec::from("This is a message".as_bytes()), sspi::SecurityBufferType::Data)];

let _result = server_ntlm
    .encrypt_message(sspi::EncryptionFlags::empty(), &mut msg, 0).unwrap();

let [mut token, mut data] = msg;

let mut msg_buffer = vec![
    sspi::DecryptBuffer::Token(&mut token.buffer),
    sspi::DecryptBuffer::Data(&mut data.buffer),
];

#[allow(unused_variables)]
let encryption_flags = ntlm
    .decrypt_message(&mut msg_buffer, 0)
    .unwrap();

println!("Decrypted message: {:?}", msg_buffer[1].data());
§MSDN
source

fn query_context_sizes(&mut self) -> Result<ContextSizes>

Retrieves information about the bounds of sizes of authentication information of the current security principal.

§Returns
  • ContextSizes upon success
  • Error on error
§Example
use sspi::Sspi;
let mut ntlm = sspi::Ntlm::new();
let sizes = ntlm.query_context_sizes().unwrap();
println!("Max token: {}", sizes.max_token);
println!("Max signature: {}", sizes.max_signature);
println!("Block: {}", sizes.block);
println!("Security trailer: {}", sizes.security_trailer);
§MSDN
source

fn query_context_names(&mut self) -> Result<ContextNames>

Retrieves the username of the credential associated to the context.

§Returns
  • ContextNames upon success
  • Error on error
§Example
use sspi::Sspi;
use sspi::Username;

let mut ntlm = sspi::Ntlm::new();
let identity = sspi::AuthIdentity {
    username: Username::parse("user").unwrap(),
    password: "password".to_string().into(),
};

let _acq_cred_result = ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Inbound)
    .with_auth_data(&identity)
    .execute(&mut ntlm).unwrap();

let names = ntlm.query_context_names().unwrap();
println!("Username: {:?}", names.username.account_name());
println!("Domain: {:?}", names.username.domain_name());
§MSDN
source

fn query_context_package_info(&mut self) -> Result<PackageInfo>

Retrieves information about the specified security package. This information includes the bounds of sizes of authentication information, credentials, and contexts.

§Returns
  • PackageInfo containing the information about the package
  • Error on error
§Example
use sspi::Sspi;
let mut ntlm = sspi::Ntlm::new();
let info = ntlm.query_context_package_info().unwrap();
println!("Package name: {:?}", info.name);
§MSDN
source

fn query_context_cert_trust_status(&mut self) -> Result<CertTrustStatus>

Retrieves the trust information of the certificate.

§Returns
  • CertTrustStatus on success
§Example
use sspi::Sspi;
let mut ntlm = sspi::Ntlm::new();
let cert_info = ntlm.query_context_package_info().unwrap();
§MSDN
source

fn change_password<'a>( &'a mut self, change_password: ChangePassword<'a> ) -> Result<GeneratorChangePassword<'_>>

Changes the password for a Windows domain account.

§Returns
  • () on success
§Example
use sspi::{Sspi, ChangePasswordBuilder};
let mut ntlm = sspi::Ntlm::new();
let mut output = [];
let cert_info = ntlm.query_context_package_info().unwrap();
let change_password = ChangePasswordBuilder::new()
    .with_domain_name("domain".into())
    .with_account_name("username".into())
    .with_old_password("old_password".into())
    .with_old_password("new_password".into())
    .with_output(&mut output)
    .build()
    .unwrap();
ntlm.change_password(change_password).unwrap();
§MSDN

Provided Methods§

source

fn acquire_credentials_handle<'a>( &mut self ) -> EmptyAcquireCredentialsHandle<'a, Self::CredentialsHandle, Self::AuthenticationData>

Acquires a handle to preexisting credentials of a security principal. The preexisting credentials are available only for sspi::winapi module. This handle is required by the initialize_security_context and accept_security_context functions. These can be either preexisting credentials, which are established through a system logon, or the caller can provide alternative credentials. Alternative credentials are always required to specify when using platform independent SSPs.

§Returns
  • AcquireCredentialsHandle builder
§Requirements for execution

These methods are required to be called before calling the execute method of the AcquireCredentialsHandle builder:

§Example
use sspi::Sspi;
use sspi::Username;

let mut ntlm = sspi::Ntlm::new();

let identity = sspi::AuthIdentity {
    username: Username::parse("user").unwrap(),
    password: "password".to_string().into(),
};

#[allow(unused_variables)]
let result = ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Outbound)
    .with_auth_data(&identity)
    .execute(&mut ntlm)
    .unwrap();
§MSDN
source

fn initialize_security_context<'a>( &mut self ) -> EmptyInitializeSecurityContext<'a, Self::CredentialsHandle>

Initiates the client side, outbound security context from a credential handle. The function is used to build a security context between the client application and a remote peer. The function returns a token that the client must pass to the remote peer, which the peer in turn submits to the local security implementation through the accept_security_context call.

§Returns
  • InitializeSecurityContext builder
§Requirements for execution

These methods are required to be called before calling the execute method

§Example
use sspi::Sspi;
use sspi::Username;
use sspi::builders::EmptyInitializeSecurityContext;
use sspi::SspiImpl;

let mut ntlm = sspi::Ntlm::new();

let identity = sspi::AuthIdentity {
    username: Username::new(&whoami::username(), Some(&whoami::hostname())).unwrap(),
    password: String::from("password").into(),
};

let mut acq_cred_result = ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Outbound)
    .with_auth_data(&identity)
    .execute(&mut ntlm)
    .unwrap();

let mut credentials_handle = acq_cred_result.credentials_handle;

let mut output_buffer = vec![sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token)];

#[allow(unused_variables)]
let mut builder = ntlm.initialize_security_context()
    .with_credentials_handle(&mut credentials_handle)
    .with_context_requirements(
        sspi::ClientRequestFlags::CONFIDENTIALITY | sspi::ClientRequestFlags::ALLOCATE_MEMORY,
    )
    .with_target_data_representation(sspi::DataRepresentation::Native)
    .with_output(&mut output_buffer);

let result = ntlm.initialize_security_context_impl(&mut builder)
        .unwrap()
        .resolve_to_result()
        .unwrap();
§MSDN
source

fn accept_security_context<'a>( &mut self ) -> EmptyAcceptSecurityContext<'a, Self::CredentialsHandle>

Lets the server component of a transport application establish a security context between the server and a remote client. The remote client calls the initialize_security_context function to start the process of establishing a security context. The server can require one or more reply tokens from the remote client to complete establishing the security context.

§Returns
  • AcceptSecurityContext builder
§Requirements for execution

These methods are required to be called before calling the execute method of the AcceptSecurityContext builder:

§Example
use sspi::Sspi;
use sspi::Username;
use sspi::builders::EmptyInitializeSecurityContext;
use sspi::SspiImpl;

let mut client_ntlm = sspi::Ntlm::new();

let identity = sspi::AuthIdentity {
    username: Username::parse("user").unwrap(),
    password: "password".to_string().into(),
};

let mut client_acq_cred_result = client_ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Outbound)
    .with_auth_data(&identity)
    .execute(&mut client_ntlm)
    .unwrap();

let mut client_output_buffer = vec![sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token)];

let mut builder = client_ntlm.initialize_security_context()
    .with_credentials_handle(&mut client_acq_cred_result.credentials_handle)
    .with_context_requirements(
        sspi::ClientRequestFlags::CONFIDENTIALITY | sspi::ClientRequestFlags::ALLOCATE_MEMORY,
    )
    .with_target_data_representation(sspi::DataRepresentation::Native)
    .with_target_name("user")
    .with_output(&mut client_output_buffer);

let _result = client_ntlm.initialize_security_context_impl(&mut builder)
        .unwrap()
        .resolve_to_result()
        .unwrap();

let mut ntlm = sspi::Ntlm::new();
let mut output_buffer = vec![sspi::SecurityBuffer::new(Vec::new(), sspi::SecurityBufferType::Token)];

let mut server_acq_cred_result = ntlm
    .acquire_credentials_handle()
    .with_credential_use(sspi::CredentialUse::Inbound)
    .with_auth_data(&identity)
    .execute(&mut ntlm)
    .unwrap();

let mut credentials_handle = server_acq_cred_result.credentials_handle;

#[allow(unused_variables)]
let result = ntlm
    .accept_security_context()
    .with_credentials_handle(&mut credentials_handle)
    .with_context_requirements(sspi::ServerRequestFlags::ALLOCATE_MEMORY)
    .with_target_data_representation(sspi::DataRepresentation::Native)
    .with_input(&mut client_output_buffer)
    .with_output(&mut output_buffer)
    .execute(&mut ntlm)
    .unwrap();
§MSDN
source

fn query_context_stream_sizes(&mut self) -> Result<StreamSizes>

Queries the sizes of the various parts of a stream used in the per-message functions. This function is implemented only for CredSSP security package.

§MSDN
source

fn query_context_remote_cert(&mut self) -> Result<CertContext>

Retrieves the information about the end certificate supplied by the server. This function is implemented only for CredSSP security package.

§Returns
  • CertContext on success
§MSDN
source

fn query_context_negotiation_package(&mut self) -> Result<PackageInfo>

Retrieves the information about the negotiated security package. This function is implemented only for CredSSP security package.

§Returns
  • PackageInfo on success
§MSDN
source

fn query_context_connection_info(&mut self) -> Result<ConnectionInfo>

Returns detailed information on the established connection. This function is implemented only for CredSSP security package.

§Returns
  • ConnectionInfo on success
§MSDN

Object Safety§

This trait is not object safe.

Implementors§