This commit is contained in:
Vivian 2023-12-15 21:26:29 +01:00
commit cbf4e9d62f
4 changed files with 380 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/target
.idea/

230
Cargo.lock generated Normal file
View file

@ -0,0 +1,230 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "backtrace"
version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "cc"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "color-eyre"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204"
dependencies = [
"backtrace",
"color-spantrace",
"eyre",
"indenter",
"once_cell",
"owo-colors",
"tracing-error",
]
[[package]]
name = "color-spantrace"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2"
dependencies = [
"once_cell",
"owo-colors",
"tracing-core",
"tracing-error",
]
[[package]]
name = "eyre"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799"
dependencies = [
"indenter",
"once_cell",
]
[[package]]
name = "gimli"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "gnome-autounlock-keyring"
version = "0.1.0"
dependencies = [
"color-eyre",
]
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]]
name = "memchr"
version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "miniz_oxide"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
dependencies = [
"adler",
]
[[package]]
name = "object"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "owo-colors"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
name = "pin-project-lite"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
[[package]]
name = "rustc-demangle"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "thread_local"
version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "tracing"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-error"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
dependencies = [
"tracing",
"tracing-subscriber",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"sharded-slab",
"thread_local",
"tracing-core",
]
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"

9
Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "gnome-autounlock-keyring"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
color-eyre = "0.6.2"

139
src/main.rs Normal file
View file

@ -0,0 +1,139 @@
use color_eyre::eyre::{bail, eyre, WrapErr};
use std::env;
use std::io::{Read, Write};
use std::os::unix::net::UnixStream;
use std::path::{Path, PathBuf};
fn get_control_socket() -> Option<PathBuf> {
let gnome_var = env::var("GNOME_KEYRING_CONTROL")
.ok()
.map(|el| PathBuf::from(el).join("control"))
.and_then(|el| el.exists().then_some(el));
let xdg_var = env::var("XDG_RUNTIME_DIR")
.ok()
.map(|el| PathBuf::from(el).join("keyring").join("control"))
.and_then(|el| el.exists().then_some(el));
gnome_var.or(xdg_var)
}
enum ControlOp {
Initialize = 0,
Unlock = 1,
Change = 2,
Quit = 4,
}
impl ControlOp {
fn to_bytes(self) -> [u8; 4] {
(self as u32).to_be_bytes()
}
}
#[derive(Debug)]
enum ControlResult {
Ok = 0,
Denied = 1,
Failed = 2,
NoDaemon = 3,
}
impl ControlResult {
fn from_u32(n: u32) -> Option<ControlResult> {
match n {
0 => Some(ControlResult::Ok),
1 => Some(ControlResult::Denied),
2 => Some(ControlResult::Failed),
3 => Some(ControlResult::NoDaemon),
_ => None,
}
}
}
fn unlock_keyring(password: &str) -> color_eyre::Result<ControlResult> {
let socket = get_control_socket()
.ok_or_else(|| eyre!("Could not find gnome keyring control socket path"))?;
let mut stream = UnixStream::connect(socket)
.wrap_err("Could not connect to the gnome keyring unix socket")?;
let ret = stream
.write(&[0])
.wrap_err("could not write credential byte")?;
if ret != 1 {
bail!("writing cred byte failed")
}
// oplen is
// 8 = packet size + op code
// 4 size of length of pw byte
let oplen: u32 = 8 + 4 + password.len() as u32;
// write length
let ret = stream
.write(&oplen.to_be_bytes())
.wrap_err("could not write oplen")?;
if ret != 4 {
bail!("writing oplen failed")
}
// write unlock
let ret = stream
.write(&ControlOp::Unlock.to_bytes())
.wrap_err("could not write unlock")?;
if ret != 4 {
bail!("writing unlock failed")
}
// write pw len
let ret = stream
.write(&(password.len() as u32).to_be_bytes())
.wrap_err("could not write password length")?;
if ret != 4 {
bail!("writing pwlen failed")
}
let mut pw_buf = password.as_bytes();
while !pw_buf.is_empty() {
let ret = stream.write(pw_buf).wrap_err("writing password failed")?;
pw_buf = &pw_buf[ret..]
}
let mut buf = [0; 4];
let val = stream
.read(&mut buf)
.wrap_err("could not read response length")?;
if val != 4 {
bail!("invalid response length length")
}
let len = u32::from_be_bytes(buf);
if len != 8 {
bail!("invalid response length");
}
let val = stream.read(&mut buf).wrap_err("could not read response")?;
if val != 4 {
bail!("invalid response length (2)")
}
let resp = u32::from_be_bytes(buf);
let code = ControlResult::from_u32(resp).ok_or_else(|| eyre!("invalid resp"))?;
Ok(code)
}
fn main() -> color_eyre::Result<()> {
color_eyre::install().unwrap();
let res = unlock_keyring("example")?;
dbg!(res);
Ok(())
}