fakegreet: Dummy greetd backend
This commit is contained in:
51
Cargo.lock
generated
51
Cargo.lock
generated
@@ -85,6 +85,16 @@ dependencies = [
|
||||
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fakegreet"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"greetd_ipc 0.5.1",
|
||||
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.6"
|
||||
@@ -223,6 +233,17 @@ dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio-named-pipes"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio-uds"
|
||||
version = "0.6.7"
|
||||
@@ -244,6 +265,15 @@ dependencies = [
|
||||
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"socket2 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.33"
|
||||
@@ -363,6 +393,11 @@ dependencies = [
|
||||
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rpassword"
|
||||
version = "4.0.5"
|
||||
@@ -428,6 +463,17 @@ name = "slab"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.14"
|
||||
@@ -468,6 +514,7 @@ dependencies = [
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -578,8 +625,10 @@ dependencies = [
|
||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
"checksum memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223"
|
||||
"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
|
||||
"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3"
|
||||
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
|
||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||
"checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226"
|
||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||
"checksum nix 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb"
|
||||
"checksum nix 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
|
||||
@@ -594,6 +643,7 @@ dependencies = [
|
||||
"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
"checksum rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "99371657d3c8e4d816fb6221db98fa408242b0b53bac08f8676a41f8554fe99f"
|
||||
"checksum rust-ini 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c609fa8151080b18c38d39e09d1e55d6301d5610428ff804d0d59c4bac15cf7"
|
||||
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
|
||||
@@ -602,6 +652,7 @@ dependencies = [
|
||||
"checksum serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "eab8f15f15d6c41a154c1b128a22f2dfabe350ef53c40953d84e36155c91192b"
|
||||
"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
|
||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
"checksum socket2 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
|
||||
"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5"
|
||||
"checksum thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "205684fd018ca14432b12cce6ea3d46763311a571c3d294e71ba3f01adcf1aad"
|
||||
"checksum thiserror-impl 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57e4d2e50ca050ed44fb58309bdce3efa79948f84f9993ad1978de5eebdce5a7"
|
||||
|
@@ -9,4 +9,4 @@ incremental = false
|
||||
codegen-units = 1
|
||||
|
||||
[workspace]
|
||||
members = ["greetd_ipc", "greetd", "agreety"]
|
||||
members = ["greetd_ipc", "greetd", "agreety", "fakegreet"]
|
||||
|
2
fakegreet/.gitignore
vendored
Normal file
2
fakegreet/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/target
|
||||
**/*.rs.bk
|
14
fakegreet/Cargo.toml
Normal file
14
fakegreet/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "fakegreet"
|
||||
version = "0.5.0"
|
||||
authors = ["Kenny Levinsen"]
|
||||
edition = "2018"
|
||||
license = "GPL-3.0"
|
||||
homepage = "https://kl.wtf/projects/greetd"
|
||||
repository = "https://git.sr.ht/~kennylevinsen/greetd/"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
greetd_ipc = { path = "../greetd_ipc", features = ["tokio-codec"] }
|
||||
tokio = { version = "0.2", features = ["process"] }
|
||||
thiserror = "1.0"
|
56
fakegreet/src/error.rs
Normal file
56
fakegreet/src/error.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
use std::convert::From;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error as ThisError;
|
||||
|
||||
#[derive(Debug, ThisError, Clone, Deserialize, Serialize)]
|
||||
pub enum Error {
|
||||
#[error("{0}")]
|
||||
Error(String),
|
||||
|
||||
#[error("authentication error: {0}")]
|
||||
AuthError(String),
|
||||
|
||||
#[error("protocol error: {0}")]
|
||||
ProtocolError(String),
|
||||
|
||||
#[error("i/o error: {0}")]
|
||||
Io(String),
|
||||
|
||||
#[error("configuration error: {0}")]
|
||||
ConfigError(String),
|
||||
}
|
||||
|
||||
impl From<Box<dyn std::error::Error>> for Error {
|
||||
fn from(error: Box<dyn std::error::Error>) -> Self {
|
||||
Error::Error(format!("{}", error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
Error::Io(format!("{}", error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<greetd_ipc::codec::Error> for Error {
|
||||
fn from(error: greetd_ipc::codec::Error) -> Self {
|
||||
match error {
|
||||
greetd_ipc::codec::Error::Serialization(s) => Error::ProtocolError(s),
|
||||
greetd_ipc::codec::Error::Io(s) => Error::Io(s),
|
||||
greetd_ipc::codec::Error::Eof => Error::Io("EOF".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Error {
|
||||
fn from(error: String) -> Self {
|
||||
Error::Error(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Error {
|
||||
fn from(error: &str) -> Self {
|
||||
Error::Error(error.to_string())
|
||||
}
|
||||
}
|
191
fakegreet/src/main.rs
Normal file
191
fakegreet/src/main.rs
Normal file
@@ -0,0 +1,191 @@
|
||||
mod error;
|
||||
|
||||
use std::{cell::RefCell, env, rc::Rc, time::Duration};
|
||||
|
||||
use tokio::{
|
||||
net::{UnixListener, UnixStream},
|
||||
process::Command,
|
||||
task,
|
||||
time::delay_for,
|
||||
};
|
||||
|
||||
use crate::error::Error;
|
||||
use greetd_ipc::{
|
||||
codec::{Error as CodecError, TokioCodec},
|
||||
AuthMessageType, ErrorType, Request, Response,
|
||||
};
|
||||
|
||||
fn wrap_result<T>(res: Result<T, Error>) -> Response {
|
||||
match res {
|
||||
Ok(_) => Response::Success,
|
||||
Err(Error::AuthError(msg)) => Response::Error {
|
||||
error_type: ErrorType::AuthError,
|
||||
description: msg,
|
||||
},
|
||||
Err(e) => Response::Error {
|
||||
error_type: ErrorType::Error,
|
||||
description: format!("{}", e),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
struct InnerContext {
|
||||
user: Option<String>,
|
||||
password: Option<String>,
|
||||
ok: bool,
|
||||
}
|
||||
|
||||
struct Context {
|
||||
inner: RefCell<InnerContext>,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
fn new() -> Context {
|
||||
Context {
|
||||
inner: RefCell::new(InnerContext {
|
||||
user: None,
|
||||
password: None,
|
||||
ok: false,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_session(&self, username: String) -> Result<(), Error> {
|
||||
self.inner.borrow_mut().user = Some(username);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_question(&self) -> Result<Option<(AuthMessageType, String)>, Error> {
|
||||
let s = self.inner.borrow();
|
||||
if s.ok {
|
||||
Ok(None)
|
||||
} else if s.user.is_none() {
|
||||
Ok(Some((AuthMessageType::Visible, "User:".to_string())))
|
||||
} else if s.password.is_none() {
|
||||
Ok(Some((AuthMessageType::Secret, "Password:".to_string())))
|
||||
} else {
|
||||
Ok(Some((AuthMessageType::Visible, "7 + 2:".to_string())))
|
||||
}
|
||||
}
|
||||
|
||||
async fn post_response(&self, response: Option<String>) -> Result<(), Error> {
|
||||
let mut s = self.inner.borrow_mut();
|
||||
if s.ok {
|
||||
return Err(Error::Error("wat".to_string()));
|
||||
}
|
||||
if s.user.is_none() {
|
||||
s.user = response;
|
||||
} else if s.password.is_none() {
|
||||
s.password = response;
|
||||
} else {
|
||||
if s.user != Some("user".to_string())
|
||||
|| s.password != Some("password".to_string())
|
||||
|| response != Some("9".to_string())
|
||||
{
|
||||
delay_for(Duration::from_millis(2000)).await;
|
||||
return Err(Error::AuthError("nope".to_string()));
|
||||
}
|
||||
s.ok = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn start(&self, _cmd: Vec<String>) -> Result<(), Error> {
|
||||
if !self.inner.borrow().ok {
|
||||
return Err(Error::Error("not yet dammit".to_string()));
|
||||
}
|
||||
delay_for(Duration::from_millis(5000)).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn cancel(&self) -> Result<(), Error> {
|
||||
let mut s = self.inner.borrow_mut();
|
||||
s.user = None;
|
||||
s.password = None;
|
||||
s.ok = false;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
async fn client_get_question(ctx: &Context) -> Response {
|
||||
match ctx.get_question().await {
|
||||
Ok(Some((auth_message_type, auth_message))) => Response::AuthMessage {
|
||||
auth_message_type,
|
||||
auth_message,
|
||||
},
|
||||
res => wrap_result(res),
|
||||
}
|
||||
}
|
||||
|
||||
async fn client_handler(ctx: &Context, mut s: UnixStream) -> Result<(), Error> {
|
||||
loop {
|
||||
let req = match Request::read_from(&mut s).await {
|
||||
Ok(req) => req,
|
||||
Err(CodecError::Eof) => return Ok(()),
|
||||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
|
||||
println!("req: {:?}", req);
|
||||
let resp = match req {
|
||||
Request::CreateSession { username } => match ctx.create_session(username).await {
|
||||
Ok(()) => client_get_question(&ctx).await,
|
||||
res => wrap_result(res),
|
||||
},
|
||||
Request::PostAuthMessageResponse { response } => {
|
||||
match ctx.post_response(response).await {
|
||||
Ok(()) => client_get_question(&ctx).await,
|
||||
res => wrap_result(res),
|
||||
}
|
||||
}
|
||||
Request::StartSession { cmd } => wrap_result(ctx.start(cmd).await),
|
||||
Request::CancelSession => wrap_result(ctx.cancel().await),
|
||||
};
|
||||
|
||||
println!("resp: {:?}", resp);
|
||||
resp.write_to(&mut s).await?;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn server() -> Result<(), Error> {
|
||||
let path = "./greetd.sock";
|
||||
std::env::set_var("GREETD_SOCK", path);
|
||||
|
||||
let _ = std::fs::remove_file(path);
|
||||
let mut listener =
|
||||
UnixListener::bind(path).map_err(|e| format!("unable to open listener: {}", e))?;
|
||||
|
||||
let arg = env::args()
|
||||
.skip(1)
|
||||
.next()
|
||||
.expect("need argument")
|
||||
.to_string();
|
||||
let _ = Command::new("sh").arg("-c").arg(arg).spawn()?;
|
||||
|
||||
let ctx = Rc::new(Context::new());
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
stream = listener.accept() => match stream {
|
||||
Ok((stream, _)) => {
|
||||
let ctx = ctx.clone();
|
||||
task::spawn_local(async move {
|
||||
if let Err(e) = client_handler(&ctx, stream).await {
|
||||
eprintln!("client loop failed: {}", e);
|
||||
}
|
||||
});
|
||||
},
|
||||
Err(err) => return Err(format!("accept: {}", err).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let res = task::LocalSet::new()
|
||||
.run_until(async move { server().await })
|
||||
.await;
|
||||
if let Err(e) = res {
|
||||
eprintln!("error: {}", e);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user