//! # Keyring library
//!
//! Allows for setting and getting passwords on Linux, OSX, and Windows

// Configure for Linux
#[cfg(target_os = "linux")]
extern crate secret_service;
#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "linux")]
pub use linux::Keyring;

// Configure for Windows
#[cfg(target_os = "windows")]
extern crate winapi;
#[cfg(target_os = "windows")]
extern crate advapi32;
#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
pub use windows::Keyring;

// Configure for OSX
#[cfg(target_os = "macos")]
extern crate rustc_serialize;
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "macos")]
pub use macos::Keyring;

mod error;
pub use error::{KeyringError, Result};

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    #[should_panic]
    fn test_empty_password_input() {
        let pass = "";
        let keyring = Keyring::new("test", "test");
        match keyring.set_password(pass) {
            Ok(_) => (),
            Err(_) => {
                keyring.get_password().unwrap();
            },
        }
    }
}

//! # Keyring library
//!
//! Allows for setting and getting passwords on Linux, OSX, and Windows

// Configure for Linux
#[cfg(target_os = "linux")]
extern crate secret_service;
#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "linux")]
pub use linux::Keyring;

// Configure for Windows
#[cfg(target_os = "windows")]
extern crate winapi;
#[cfg(target_os = "windows")]
extern crate advapi32;
#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
pub use windows::Keyring;

// Configure for OSX
#[cfg(target_os = "macos")]
extern crate rustc_serialize;
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "macos")]
pub use macos::Keyring;

mod error;
pub use error::{KeyringError, Result};


--- 
+++ 
@@ -31,3 +31,20 @@
 mod error;
 pub use error::{KeyringError, Result};
 
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    #[should_panic]
+    fn test_empty_password_input() {
+        let pass = "";
+        let keyring = Keyring::new("test", "test");
+        match keyring.set_password(pass) {
+            Ok(_) => (),
+            Err(_) => {
+                keyring.get_password().unwrap();
+            },
+        }
+    }
+}
Add test for empty password

Handling empty passwords properly.

I don't have an explicit check for empty passwords in the keyring
library (front-end or any of the backends). Instead, I rely on the
system vaults (or as close as possible to that interface) to report back
errors. I don't want to up-front assume that blank passwords are
invalid (although I thought about doing it this way... and would have
missed a bug).

In the keyring library, the set_password fn for linux has a try! around
every single function call which returns a result (all of which are
basically wrappers around dbus secret-service calls).

So, I was a bit surprised to find that fuzzing the keyring library
caught a panic on empty string input! I expected a propagated error.

Turns out it was an error in the secret-service library, in a non-IO
call formatting the secret. I assumed that because there was no IO it
could safely be unwrapped, but it turns out that the dbus library would
return an empty array error when construting from an empty string! A
very unexpected error!

Anyways, now that error is no longer unwrapped, and is instead
propogated up.

This error was caught while fuzzing, although it would have been easy
enough if I had more basic tests.
