Skip to content

Commit

Permalink
fix: 🚧 add log as workspace dependency, remove direct print to console
Browse files Browse the repository at this point in the history
  • Loading branch information
Jisu-Woniu committed Apr 2, 2024
1 parent 244d4e7 commit ed32e0a
Show file tree
Hide file tree
Showing 15 changed files with 147 additions and 115 deletions.
55 changes: 4 additions & 51 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ license = "Apache-2.0"
# clap requires Rust 1.74+ to work
rust-version = "1.74"

[workspace.dependencies]
log = "0.4.21"
rsjudge-utils = { version = "0.1.0", path = "crates/rsjudge-utils" }

[package]
name = "rsjudge"
version.workspace = true
Expand Down Expand Up @@ -131,6 +135,7 @@ dest = "/usr/lib/sysusers.d/rsjudge.conf"
# Workspace dependencies
rsjudge-judger = { version = "0.1.0", path = "crates/rsjudge-judger" }
rsjudge-runner = { version = "0.1.0", path = "crates/rsjudge-runner" }
rsjudge-utils.workspace = true

# Optional dependencies
rsjudge-grpc = { version = "0.1.0", path = "crates/rsjudge-grpc", optional = true }
Expand All @@ -140,9 +145,9 @@ anyhow = "1.0.80"
caps = "0.5.5"
clap = { version = "4.5.3", features = ["derive"] }
env_logger = "0.11.3"
log = "0.4.21"
log.workspace = true
mimalloc = "0.1.39"
tokio = { version = "1.36.0", features = ["fs", "rt-multi-thread", "macros"] }
tokio = { version = "1.37.0", features = ["fs", "rt-multi-thread", "macros"] }
toml = "0.8.12"

# Unused for now:
Expand Down
2 changes: 1 addition & 1 deletion crates/rsjudge-grpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ rust-version.workspace = true
[dependencies]
anyhow = "1.0.81"
futures = "0.3.30"
log.workspace = true
prost = "0.12.3"
prost-types = "0.12.3"
tokio = { version = "1.36.0", features = ["net"] }
tokio-stream = "0.1.15"
tonic = "0.11.0"
tonic-buf-build = "0.2.0"

[build-dependencies]
anyhow = "1.0.81"
Expand Down
2 changes: 2 additions & 0 deletions crates/rsjudge-grpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::print_stderr))]

use std::net::SocketAddr;

use tonic::transport::{Error, Server};
Expand Down
9 changes: 5 additions & 4 deletions crates/rsjudge-grpc/src/server.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use log::debug;
use tokio_stream::wrappers::ReceiverStream;
use tonic::{async_trait, Request, Response, Status};

Expand All @@ -17,8 +18,8 @@ impl JudgeService for JudgeServerImpl {
&self,
request: Request<SelfTestRequest>,
) -> Result<Response<Self::SelfTestStream>, Status> {
let _ = request;
todo!()
debug!("Received SelfTestRequest: {:?}", request.into_inner());
Err(Status::unimplemented("Not implemented yet"))
}

type SubmitStream = ReceiverStream<Result<SubmitResponse, Status>>;
Expand All @@ -27,7 +28,7 @@ impl JudgeService for JudgeServerImpl {
&self,
request: Request<SubmitRequest>,
) -> Result<Response<Self::SubmitStream>, Status> {
let _ = request;
todo!()
debug!("Received SubmitRequest: {:?}", request.into_inner());
Err(Status::unimplemented("Not implemented yet"))
}
}
2 changes: 2 additions & 0 deletions crates/rsjudge-judger/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::print_stderr))]

pub mod comparer;

pub use comparer::{default_comparer::DefaultComparer, CompareResult, Comparer};
7 changes: 4 additions & 3 deletions crates/rsjudge-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ rust-version.workspace = true
description = "Command runner for rsjudge"

[dependencies]
anyhow = "1.0.81"
caps = "0.5.5"
log.workspace = true
nix = { version = "0.28.0", features = ["user"] }
once_cell = "1.19.0"
rsjudge-utils.workspace = true
thiserror = "1.0.58"
uzers = "0.11.3"

[build-dependencies]
rustc_version = "0.4.0"

[dev-dependencies]
rsjudge-utils = { path = "../rsjudge-utils" }
anyhow = "1.0.81"
6 changes: 3 additions & 3 deletions crates/rsjudge-runner/examples/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ use rsjudge_runner::{
use uzers::{get_current_uid, get_user_by_uid};
fn main() -> anyhow::Result<()> {
let self_output = Command::new("id")
.run_as(&get_user_by_uid(get_current_uid()).ok_or(anyhow!("invalid user"))?)
.run_as(&get_user_by_uid(get_current_uid()).ok_or(anyhow!("invalid user"))?)?
.output()?;
println!("{}", String::from_utf8_lossy(&self_output.stdout));

let builder_output = Command::new("id").run_as(builder()?).output()?;
let builder_output = Command::new("id").run_as(builder()?)?.output()?;
println!("{}", String::from_utf8_lossy(&builder_output.stdout));

let runner_output = Command::new("id").run_as(runner()?).output()?;
let runner_output = Command::new("id").run_as(runner()?)?.output()?;
println!("{}", String::from_utf8_lossy(&runner_output.stdout));
Ok(())
}
4 changes: 2 additions & 2 deletions crates/rsjudge-runner/examples/exploit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ fn main() -> anyhow::Result<()> {

let exploit_inner = examples.join("exploit_inner");

let status = check_output(Command::new(dbg!(exploit_inner)).run_as(builder()?))?;
let status = check_output(Command::new(dbg!(exploit_inner)).run_as(builder()?)?)?;
println!("{}", String::from_utf8_lossy(&status.stdout));
println!("{}", String::from_utf8_lossy(&status.stderr));

let normal = examples.join("normal");
let status = check_output(Command::new(normal).run_as(builder()?))?;
let status = check_output(Command::new(normal).run_as(builder()?)?)?;
println!("{}", String::from_utf8_lossy(&status.stdout));
println!("{}", String::from_utf8_lossy(&status.stderr));

Expand Down
17 changes: 17 additions & 0 deletions crates/rsjudge-runner/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use caps::Capability;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum Error {
#[error("{cap} is required to run as another user.")]
CapsRequired { cap: Capability },
#[error("User '{name}' not found")]
UserNotFound { name: String },

#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("{0}")]
CapsError(#[from] caps::errors::CapsError),
}

pub type Result<T> = std::result::Result<T, Error>;
26 changes: 23 additions & 3 deletions crates/rsjudge-runner/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,35 @@
#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::print_stderr))]

use std::{os::unix::process::CommandExt as _, process::Command};

use caps::{has_cap, CapSet, Capability};
use nix::unistd::{setgroups, Gid};
use uzers::User;

use crate::error::{Error, Result};

pub mod error;
pub mod user;
pub trait RunAs {
fn run_as(&mut self, user: &User) -> &mut Command;
type Error;
fn run_as(&mut self, user: &User) -> Result<&mut Self>;
}

impl RunAs for Command {
fn run_as(&mut self, user: &User) -> &mut Self {
type Error = Error;
fn run_as(&mut self, user: &User) -> Result<&mut Self> {
if !has_cap(None, CapSet::Effective, Capability::CAP_SETUID)? {
Err(Error::CapsRequired {
cap: Capability::CAP_SETUID,
})?;
}

has_cap(None, CapSet::Effective, Capability::CAP_SETGID).map_err(|_| {
Error::CapsRequired {
cap: Capability::CAP_SETGID,
}
})?;

let uid = user.uid();
let gid = user.primary_group_id();

Expand Down Expand Up @@ -47,6 +67,6 @@ impl RunAs for Command {
self.groups(groups);
}

self
Ok(self)
}
}
33 changes: 22 additions & 11 deletions crates/rsjudge-runner/src/user.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
use anyhow::anyhow;
use once_cell::sync::Lazy;
use std::sync::OnceLock;

use uzers::{get_user_by_name, User};

pub static SUPERVISOR: Lazy<Option<User>> = Lazy::new(|| get_user_by_name("rsjudge-supervisor"));
pub static BUILDER: Lazy<Option<User>> = Lazy::new(|| get_user_by_name("rsjudge-builder"));
pub static RUNNER: Lazy<Option<User>> = Lazy::new(|| get_user_by_name("rsjudge-runner"));
use crate::error::{Error, Result};

pub static SUPERVISOR: OnceLock<Option<User>> = OnceLock::new();
pub static BUILDER: OnceLock<Option<User>> = OnceLock::new();
pub static RUNNER: OnceLock<Option<User>> = OnceLock::new();

pub fn supervisor<'a>() -> anyhow::Result<&'a User> {
pub fn supervisor<'a>() -> Result<&'a User> {
SUPERVISOR
.get_or_init(|| get_user_by_name("rsjudge-supervisor"))
.as_ref()
.ok_or_else(|| anyhow!("User `rsjudge-supervisor` not found"))
.ok_or_else(|| Error::UserNotFound {
name: "rsjudge-supervisor".to_string(),
})
}

pub fn builder<'a>() -> anyhow::Result<&'a User> {
pub fn builder<'a>() -> Result<&'a User> {
BUILDER
.get_or_init(|| get_user_by_name("rsjudge-builder"))
.as_ref()
.ok_or_else(|| anyhow!("User `rsjudge-builder` not found"))
.ok_or_else(|| Error::UserNotFound {
name: "rsjudge-builder".to_string(),
})
}

pub fn runner<'a>() -> anyhow::Result<&'a User> {
pub fn runner<'a>() -> Result<&'a User> {
RUNNER
.get_or_init(|| get_user_by_name("rsjudge-runner"))
.as_ref()
.ok_or_else(|| anyhow!("User `rsjudge-runner` not found"))
.ok_or_else(|| Error::UserNotFound {
name: "rsjudge-runner".to_string(),
})
}
2 changes: 2 additions & 0 deletions crates/rsjudge-utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![warn(clippy::print_stdout, clippy::print_stderr)]

//! A collection of utility functions for the rsjudge project.
#![warn(missing_docs)]
Expand Down
Loading

0 comments on commit ed32e0a

Please sign in to comment.