<commit_before>// In pythons secretstorage, this is dhcrypto.py
//
// This module implements Secret Service Session,
// including crypto
//
// rand to get integer with 1024 random bits

//use crypto::digest::Digest;
//use crypto::sha2::Sha256;

use ss::{
    SS_DBUS_NAME,
    SS_PATH,
    SS_INTERFACE_SERVICE,
    ALGORITHM_PLAIN,
};

use dbus::{
    Connection,
    Message,
    Path,
    Error,
};
use dbus::MessageItem::{
    Variant,
    Str,
    ObjectPath,
};
use std::rc::Rc;

// helper enum
pub enum EncryptionType {
    Plain,
    Dh,
}

#[derive(Debug)]
pub struct Session {
    // TODO: Should session store encryption?
    // TODO: method for getting path
    pub object_path: Path,
    server_public_key: Option<Vec<u8>>,
    aes_key: Option<Vec<u8>>,
    encrypted: bool,
    my_private_key: Vec<u8>,
    my_public_key: Vec<u8>,
}

impl Session {
    pub fn new(bus: Rc<Connection>, encryption: EncryptionType) -> Result<Self, Error> {
        // Forming message, should not fail unless bug
        let m = match encryption {
            EncryptionType::Plain => {
                Message::new_method_call(
                    SS_DBUS_NAME,
                    SS_PATH,
                    SS_INTERFACE_SERVICE,
                    "OpenSession"
                ).unwrap()
                .append(Str(ALGORITHM_PLAIN.to_owned()))
                // this argument should be input for algorithm
                .append(Variant(Box::new(Str("".to_owned()))))
            },
            EncryptionType::Dh => {
                // TODO: Change this to encrypted!
                Message::new_method_call(
                    SS_DBUS_NAME,
                    SS_PATH,
                    SS_INTERFACE_SERVICE,
                    "OpenSession"
                ).unwrap()
                .append(Str(ALGORITHM_PLAIN.to_owned()))
                // this argument should be input for algorithm
                .append(Variant(Box::new(Str("".to_owned()))))
            },
        };

        let r = try!(bus.send_with_reply_and_block(m, 2000));

        let items = r.get_items();

        // check session output
        match items.get(0) {
            Some(o) if *o == Variant(Box::new(Str("".to_owned()))) => (),
            Some(_) => {
                return Err(Error::new_custom("SSError", "Error negotiating algorithm"));
            },
            _ => {
                return Err(Error::new_custom("SSError",  "Error: no output fromOpenSession"));
            },
        };

        let object_path = match items.get(1) {
            Some(&ObjectPath(ref path)) => path.clone(),
            _ => {
                return Err(Error::new_custom("SSError",  "Error: no output fromOpenSession"));
            },
        };

        Ok(Session {
            object_path: object_path,
            server_public_key: None,
            aes_key: None,
            encrypted: false,
            my_private_key: vec![],
            my_public_key: vec![],
        })
    }

//    pub fn set_server_public_key(&mut self, server_public_key: &[u8]) {
//        ()
//    }
//
//    pub fn set_object_path(&mut self, object_path: ObjectPath) {
//        self.object_path = object_path;
//    }
}

#[cfg(test)]
mod test {
    use std::rc::Rc;
    use super::*;
    use dbus::{Connection, BusType};

    #[test]
    fn should_create_plain_session() {
        let bus = Connection::get_private(BusType::Session).unwrap();
        Session::new(Rc::new(bus), EncryptionType::Plain).unwrap();
    }

    #[test]
    fn should_create_encrypted_session() {
        let bus = Connection::get_private(BusType::Session).unwrap();
        Session::new(Rc::new(bus), EncryptionType::Dh).unwrap();
    }
}
<commit_msg>Session handling<commit_after>// In pythons secretstorage, this is dhcrypto.py
//
// This module implements Secret Service Session,
// including crypto
//
// rand to get integer with 1024 random bits

//use crypto::digest::Digest;
//use crypto::sha2::Sha256;

use ss::{
    SS_DBUS_NAME,
    SS_PATH,
    SS_INTERFACE_SERVICE,
    ALGORITHM_PLAIN,
};

use dbus::{
    Connection,
    Message,
    MessageItem,
    Path,
    Error,
};
use dbus::MessageItem::{
    Variant,
    Str,
};
use std::rc::Rc;

// helper enum
#[derive(Debug, PartialEq)]
pub enum EncryptionType {
    Plain,
    Dh,
}

#[derive(Debug)]
pub struct Session {
    // TODO: Should session store encryption? As bool or EncryptionType? also getter/setter
    pub object_path: Path,
    server_public_key: Option<Vec<u8>>,
    aes_key: Option<Vec<u8>>,
    encrypted: bool,
    my_private_key: Vec<u8>,
    my_public_key: Vec<u8>,
}

impl Session {
    pub fn new(bus: Rc<Connection>, encryption: EncryptionType) -> Result<Self, Error> {
        // Forming message, should not fail unless bug
        let m = match encryption {
            EncryptionType::Plain => {
                Message::new_method_call(
                    SS_DBUS_NAME,
                    SS_PATH,
                    SS_INTERFACE_SERVICE,
                    "OpenSession"
                ).unwrap()
                .append(Str(ALGORITHM_PLAIN.to_owned()))
                // this argument should be input for algorithm
                .append(Variant(Box::new(Str("".to_owned()))))
            },
            EncryptionType::Dh => {
                // TODO: Change this to encrypted!
                Message::new_method_call(
                    SS_DBUS_NAME,
                    SS_PATH,
                    SS_INTERFACE_SERVICE,
                    "OpenSession"
                ).unwrap()
                .append(Str(ALGORITHM_PLAIN.to_owned()))
                // this argument should be input for algorithm
                .append(Variant(Box::new(Str("".to_owned()))))
            },
        };

        let r = try!(bus.send_with_reply_and_block(m, 2000));
        let items = r.get_items();

        // check session output
        // Should this always be a Variant String?
        let session_output_dbus = try!(items
            .get(0)
            .ok_or(Error::new_custom("SSError",  "Error: no output from OpenSession"))
        );
        let session_output_variant_dbus: &MessageItem = session_output_dbus.inner().unwrap();

        let session_output = if encryption == EncryptionType::Plain {
            // plain encryption negotiation should result in empty string
            match session_output_variant_dbus.inner::<&str>().unwrap() {
                "" => vec![],
                _ => return Err(Error::new_custom("SSError", "Error negotiating algorithm")),
            }
        } else {
            // If not plain, Variant should be a vector of bytes
            let session_output_array_dbus: &Vec<_> = session_output_variant_dbus
                .inner()
                .expect("SSError, Algorithm negotiation expected Array");

            session_output_array_dbus
                .iter()
                .map(|byte_dbus| byte_dbus.inner::<u8>().unwrap())
                .collect::<Vec<_>>()
        };

        println!("{:?}", session_output);

        // get session path
        let object_path_dbus = try!(items
            .get(1)
            .ok_or(Error::new_custom("SSError",  "Error: no output from OpenSession"))
        );
        let object_path: &Path = object_path_dbus.inner().unwrap();


        Ok(Session {
            object_path: object_path.clone(),
            server_public_key: None,
            aes_key: None,
            encrypted: false,
            my_private_key: vec![],
            my_public_key: vec![],
        })
    }

    pub fn is_encrypted(&self) -> bool {
        self.encrypted
    }

//    pub fn set_server_public_key(&mut self, server_public_key: &[u8]) {
//        ()
//    }
//
//    pub fn set_object_path(&mut self, object_path: ObjectPath) {
//        self.object_path = object_path;
//    }
}

#[cfg(test)]
mod test {
    use std::rc::Rc;
    use super::*;
    use dbus::{Connection, BusType};

    #[test]
    fn should_create_plain_session() {
        let bus = Connection::get_private(BusType::Session).unwrap();
        let session = Session::new(Rc::new(bus), EncryptionType::Plain).unwrap();
        assert!(!session.is_encrypted());
    }

    #[test]
    fn should_create_encrypted_session() {
        let bus = Connection::get_private(BusType::Session).unwrap();
        let session = Session::new(Rc::new(bus), EncryptionType::Dh).unwrap();
        assert!(session.is_encrypted());
    }
}

{'fraction_non_alphanumeric': 0.1281716860327247, 'fraction_numerical': 0.004624140384159355, 'mean_word_length': 1.9638088545326775, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2918554', 'n_tokens_mistral': 2586, 'n_tokens_neox': 2515, 'n_words': 535}