Compare commits
2 Commits
63cce3cbc1
...
1282848df3
Author | SHA1 | Date |
---|---|---|
~erin | 1282848df3 | |
~erin | d5d5841955 |
|
@ -0,0 +1,40 @@
|
||||||
|
# forge
|
||||||
|
A simple remote build system. Consists of a client (`forge-client`) and server (`forge-server`).
|
||||||
|
|
||||||
|
## Server
|
||||||
|
On first run, `forge-server` will create a configuration file for you in the default location (e.g. `~/.config/forge/config.toml`).
|
||||||
|
Use this to configure options, such as the IP & port to bind on, and whether to use authentication (along with a password).
|
||||||
|
|
||||||
|
Authentication will use *Argon2id* to hash and verify passwords.
|
||||||
|
|
||||||
|
Actually building stuff is a **WIP**.
|
||||||
|
|
||||||
|
## Client
|
||||||
|
Fully **WIP**. Right now it just sends test data.
|
||||||
|
|
||||||
|
Eventually, everything will be specified via command arguments, using [clap](https://lib.rs/crates/clap) for parsing.
|
||||||
|
|
||||||
|
```
|
||||||
|
Usage: forge-client [OPTIONS] [COMMAND]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-V, --version Print version info and exit
|
||||||
|
-H, --host Host IP to connect to (default 127.0.0.1)
|
||||||
|
-p, --port Host port to connect to (default 9134)
|
||||||
|
--json <FILE> Recieve information in JSON format (or read build command from JSON file)
|
||||||
|
|
||||||
|
--auth <PASSWD> Password for authentication
|
||||||
|
--profile Whether to profile the build
|
||||||
|
--prexec <CMD> Command(s) to run before building
|
||||||
|
--repo <URL> Remote git repository to clone from
|
||||||
|
--base <NAME> Basename of the git repo (used to cd into)
|
||||||
|
--build [cargo|make] Build system to use
|
||||||
|
--subcommand [run|build|install] Cargo/Make subcommand to use
|
||||||
|
--features <FEATURES> Comma-separated cargo features
|
||||||
|
--tag [release|debug] Optional cargo flag (default debug)
|
||||||
|
|
||||||
|
Command:
|
||||||
|
send Send a new build request
|
||||||
|
status Get status of a build request
|
||||||
|
fetch Fetch the binary result of a build request
|
||||||
|
```
|
|
@ -132,11 +132,9 @@ async fn build(msg: Message, address: SocketAddr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message {
|
impl Message {
|
||||||
async fn authenticate(&self, passwd: String) -> bool {
|
async fn authenticate(&self, passwd: String, salt: SaltString, argon2: Argon2<'_>) -> bool {
|
||||||
match &self.authentication {
|
match &self.authentication {
|
||||||
Some(auth) => {
|
Some(auth) => {
|
||||||
let salt = SaltString::generate(&mut OsRng);
|
|
||||||
let argon2 = Argon2::default();
|
|
||||||
let password_hash = argon2
|
let password_hash = argon2
|
||||||
.hash_password(auth.as_bytes(), &salt)
|
.hash_password(auth.as_bytes(), &salt)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -160,7 +158,13 @@ impl Message {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_socket(mut socket: TcpStream, address: SocketAddr, auth: AuthConfig) {
|
async fn process_socket(
|
||||||
|
mut socket: TcpStream,
|
||||||
|
address: SocketAddr,
|
||||||
|
auth: AuthConfig,
|
||||||
|
salt: SaltString,
|
||||||
|
argon2: Argon2<'_>,
|
||||||
|
) {
|
||||||
let (reader, writer) = socket.split();
|
let (reader, writer) = socket.split();
|
||||||
|
|
||||||
let mut reader = BufReader::new(reader);
|
let mut reader = BufReader::new(reader);
|
||||||
|
@ -183,7 +187,10 @@ async fn process_socket(mut socket: TcpStream, address: SocketAddr, auth: AuthCo
|
||||||
if auth.authenticate {
|
if auth.authenticate {
|
||||||
match &auth.password {
|
match &auth.password {
|
||||||
Some(pass) => {
|
Some(pass) => {
|
||||||
if json.authenticate(pass.clone()).await {
|
if json
|
||||||
|
.authenticate(pass.clone(), salt.clone(), argon2.clone())
|
||||||
|
.await
|
||||||
|
{
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
build(json, address).await;
|
build(json, address).await;
|
||||||
});
|
});
|
||||||
|
@ -206,12 +213,17 @@ async fn main() -> io::Result<()> {
|
||||||
let listener = TcpListener::bind(&addr).await?;
|
let listener = TcpListener::bind(&addr).await?;
|
||||||
info!("Listening on: <green>{}<//>", addr);
|
info!("Listening on: <green>{}<//>", addr);
|
||||||
|
|
||||||
|
let salt = SaltString::generate(&mut OsRng);
|
||||||
|
let argon2 = Argon2::default();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match listener.accept().await {
|
match listener.accept().await {
|
||||||
Ok((socket, addr)) => {
|
Ok((socket, addr)) => {
|
||||||
let auth = config.auth.clone();
|
let auth = config.auth.clone();
|
||||||
|
let m_salt = salt.clone();
|
||||||
|
let m_argon2 = argon2.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
process_socket(socket, addr, auth).await;
|
process_socket(socket, addr, auth, m_salt, m_argon2).await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err(e) => error!("couldn't get client: {:?}", e),
|
Err(e) => error!("couldn't get client: {:?}", e),
|
||||||
|
|
Loading…
Reference in New Issue