130 lines
4.2 KiB
Rust
130 lines
4.2 KiB
Rust
use std::error::Error;
|
|
|
|
use ed25519_dalek::{ed25519::signature::SignerMut, Signature};
|
|
use futures::prelude::*;
|
|
use libp2p::{
|
|
mdns,
|
|
request_response::{self, ProtocolSupport},
|
|
swarm::SwarmEvent,
|
|
};
|
|
use tracing_subscriber::EnvFilter;
|
|
|
|
use cll2v0::{
|
|
db, keys,
|
|
messages::{MyRequest, MyResponse, MyResult},
|
|
protocol::{mk_swarm, MyBehaviourEvent},
|
|
};
|
|
|
|
use clap::{Parser, Subcommand};
|
|
|
|
/// cll2v0 is a playground for rust libraries.
|
|
/// This is signing service.
|
|
#[derive(Parser)]
|
|
#[command(arg_required_else_help(true), version, about)]
|
|
struct Args {
|
|
#[command(subcommand)]
|
|
cmd: Option<Command>,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
enum Command {
|
|
/// Start server
|
|
Start(ServerParams),
|
|
}
|
|
|
|
#[derive(clap::Args, Debug)]
|
|
pub struct ServerParams {
|
|
/// Server listening address
|
|
#[arg(long, default_value = "/ip4/0.0.0.0/tcp/52321")]
|
|
pub listen_on: String,
|
|
/// Signing key of server libp2p part
|
|
#[arg(
|
|
long,
|
|
default_value = "deadbeef00000000000000000000000000000000000000000000000000000000"
|
|
)]
|
|
pub skey: String,
|
|
}
|
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
|
match Args::parse().cmd {
|
|
Some(Command::Start(params)) => tokio::runtime::Builder::new_multi_thread()
|
|
.enable_all()
|
|
.build()
|
|
.unwrap()
|
|
.block_on(start(params)),
|
|
_ => {
|
|
panic!("oops")
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn start(params: ServerParams) -> Result<(), Box<dyn Error>> {
|
|
let ServerParams {
|
|
skey: skey_hex,
|
|
listen_on,
|
|
} = params;
|
|
if true {
|
|
let _ = tracing_subscriber::fmt()
|
|
.with_env_filter(EnvFilter::from_default_env())
|
|
.try_init();
|
|
}
|
|
let keypair = keys::libp2p_kp_from_hex(skey_hex)?;
|
|
let peer_id = libp2p_identity::PublicKey::from(keypair.public()).to_peer_id();
|
|
println!("PEER_ID : {}", peer_id);
|
|
|
|
let (keychain, pool) = db::start_db().await?;
|
|
|
|
let mut swarm = mk_swarm(&keypair.clone().into(), ProtocolSupport::Inbound)?;
|
|
swarm.listen_on(listen_on.parse()?)?;
|
|
|
|
loop {
|
|
match swarm.select_next_some().await {
|
|
// MDNS BEHAVIOR
|
|
SwarmEvent::Behaviour(MyBehaviourEvent::Mdns(mdns::Event::Expired(list))) => {
|
|
for (peer_id, _multiaddr) in list {
|
|
println!("mDNS discover peer has expired: {peer_id}");
|
|
// swarm.behaviour_mut().gossipsub.remove_explicit_peer(&peer_id);
|
|
}
|
|
}
|
|
SwarmEvent::Behaviour(MyBehaviourEvent::ReqRes(request_response::Event::Message {
|
|
peer: _peer,
|
|
message:
|
|
libp2p::request_response::Message::Request {
|
|
request, channel, ..
|
|
},
|
|
})) => {
|
|
// println!("Req : {:?} {:?} {:?}", peer, channel, hex::encode(request.body.clone()), );
|
|
println!("REQSIG : {}", hex::encode(request.sig.clone()),);
|
|
let MyRequest { key, body, sig } = request;
|
|
|
|
// FIXME :: MAP ERROR.
|
|
let sig_arr: [u8; 64] = sig.clone().try_into().unwrap();
|
|
|
|
if let Ok(ekey) = keys::from_bytes(key.into()) {
|
|
if let Ok(_) = ekey.verify_strict(&body, &Signature::from_bytes(&sig_arr)) {
|
|
if let Ok(pkey) = db::get_persistent_key(&pool, &ekey).await {
|
|
if let Some(skey) = keychain.get(&pkey.to_bytes()) {
|
|
let _ = swarm.behaviour_mut().req_res.send_response(
|
|
channel,
|
|
MyResult::Okay(MyResponse {
|
|
sig: skey.clone().sign(&body).to_bytes().into(),
|
|
}),
|
|
);
|
|
} else {
|
|
println!("err0")
|
|
};
|
|
} else {
|
|
println!("err1");
|
|
}
|
|
} else {
|
|
println!("err2");
|
|
}
|
|
}
|
|
}
|
|
e => {
|
|
println!("OTHER {:?}", e)
|
|
}
|
|
}
|
|
}
|
|
}
|