Version 2.0.0, with added XEP-0027 PGP support
Some checks failed
moparisthebest/sendxmpp-rs/pipeline/head There was a failure building this commit
Some checks failed
moparisthebest/sendxmpp-rs/pipeline/head There was a failure building this commit
This commit is contained in:
parent
d12a548793
commit
209a0ae2a3
53
Cargo.lock
generated
53
Cargo.lock
generated
@ -1,5 +1,11 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
@ -262,9 +268,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "309f13e3f4be6d5917178c84db67c0b9a09177ac16d4f9a7313a767a68adaa77"
|
||||
checksum = "90fa4cc29d25b0687b8570b0da86eac698dcb525110ad8b938fe6712baa711ec"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -277,9 +283,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a3b03bd32f6ec7885edeb99acd1e47e20e34fd4dfd3c6deed6fcac8a9d28f6a"
|
||||
checksum = "31ebc390c6913de330e418add60e1a7e5af4cb5ec600d19111b339cafcdcc027"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@ -287,15 +293,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed8aeae2b6ab243ebabe6f54cd4cf53054d98883d5d326128af7d57a9ca5cd3d"
|
||||
checksum = "089bd0baf024d3216916546338fffe4fc8dfffdd901e33c278abb091e0d52111"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f7836b36b7533d16fd5937311d98ba8965ab81030de8b0024c299dd5d51fb9b"
|
||||
checksum = "d0cb59f15119671c94cd9cc543dc9a50b8d5edc468b4ff5f0bb8567f66c6b48a"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@ -304,15 +310,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d41234e71d5e8ca73d01563974ef6f50e516d71e18f1a2f1184742e31f5d469f"
|
||||
checksum = "3868967e4e5ab86614e2176c99949eeef6cbcacaee737765f6ae693988273997"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3520e0eb4e704e88d771b92d51273ee212997f0d8282f17f5d8ff1cb39104e42"
|
||||
checksum = "95778720c3ee3c179cd0d8fd5a0f9b40aa7d745c080f86a8f8bed33c4fd89758"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
@ -322,24 +328,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c72d188479368953c6c8c7140e40d7a4401674ab3b98a41e60e515d6cbdbe5de"
|
||||
checksum = "d4e0f6be0ec0357772fd58fb751958dd600bd0b3edfd429e77793e4282831360"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08944cea9021170d383287169859c0ca8147d9ec285978393109954448f33cc7"
|
||||
checksum = "868090f28a925db6cb7462938c51d807546e298fb314088239f0e52fb4338b96"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3dd206efbe2ca683b2ce138ccdf61e1b0a63f5816dcedc9d8654c500ba0cea6"
|
||||
checksum = "cad5e82786df758d407932aded1235e24d8e2eb438b6adafd37930c2462fb5d1"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -855,9 +861,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
|
||||
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
@ -1128,8 +1134,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sendxmpp"
|
||||
version = "1.0.1"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"die",
|
||||
"dirs",
|
||||
"gumdrop",
|
||||
@ -1354,9 +1361,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d258221f566b6c803c7b4714abadc080172b272090cdc5e244a6d4dd13c3a6bd"
|
||||
checksum = "0ca04cec6ff2474c638057b65798f60ac183e5e79d3448bb7163d36a39cff6ec"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libc",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "sendxmpp"
|
||||
version = "1.0.1"
|
||||
version = "2.0.0"
|
||||
authors = ["moparisthebest <admin@moparisthebest.com>"]
|
||||
|
||||
description = "Send XMPP messages from the command line."
|
||||
@ -25,3 +25,4 @@ tokio-xmpp = "3.0.0"
|
||||
tokio = { version = "1", features = ["net", "rt", "rt-multi-thread", "macros"] }
|
||||
xmpp-parsers = "0.18"
|
||||
die = "0.2.0"
|
||||
anyhow = "1.0"
|
||||
|
62
src/main.rs
62
src/main.rs
@ -1,6 +1,6 @@
|
||||
use std::env::args;
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, Read};
|
||||
use std::io::{stdin, Read, Write};
|
||||
use std::iter::Iterator;
|
||||
use std::path::Path;
|
||||
|
||||
@ -11,6 +11,9 @@ use serde_derive::Deserialize;
|
||||
use tokio_xmpp::SimpleClient as Client;
|
||||
use xmpp_parsers::message::{Body, Message};
|
||||
use xmpp_parsers::{Element, Jid};
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
use anyhow::{Result, bail, anyhow};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Config {
|
||||
@ -111,8 +114,27 @@ async fn main() {
|
||||
let mut client = Client::new(&cfg.jid, &cfg.password).await.die("could not connect to xmpp server");
|
||||
|
||||
for recipient in recipients {
|
||||
let reply = make_reply(recipient.clone(), &data);
|
||||
client.send_stanza(reply).await.unwrap();
|
||||
let reply = if opts.force_pgp || opts.attempt_pgp {
|
||||
let encrypted = gpg_encrypt(recipient.clone(), &data);
|
||||
if encrypted.is_err() {
|
||||
if opts.force_pgp {
|
||||
die!("pgp encryption to jid '{}' failed!", recipient);
|
||||
} else {
|
||||
make_reply(recipient.clone(), &data)
|
||||
}
|
||||
} else {
|
||||
let encrypted = encrypted.unwrap();
|
||||
let encrypted = encrypted.trim();
|
||||
let mut reply = make_reply(recipient.clone(), "pgp");
|
||||
let mut x = Element::bare("x", "jabber:x:encrypted");
|
||||
x.append_text_node(encrypted);
|
||||
reply.append_child(x);
|
||||
reply
|
||||
}
|
||||
} else {
|
||||
make_reply(recipient.clone(), &data)
|
||||
};
|
||||
client.send_stanza(reply).await.die("sending message failed");
|
||||
}
|
||||
|
||||
// Close client connection
|
||||
@ -125,3 +147,37 @@ fn make_reply(to: Jid, body: &str) -> Element {
|
||||
message.bodies.insert(String::new(), Body(body.to_owned()));
|
||||
message.into()
|
||||
}
|
||||
|
||||
fn gpg_encrypt(to: Jid, body: &str) -> Result<String> {
|
||||
let to: String = std::convert::From::from(to);
|
||||
let mut gpg_cmd = Command::new("gpg")
|
||||
.arg("--encrypt")
|
||||
.arg("--armor")
|
||||
.arg("-r")
|
||||
.arg(to)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
{
|
||||
let stdin = gpg_cmd.stdin.as_mut().ok_or_else(|| anyhow!("no gpg stdin"))?;
|
||||
stdin.write_all(body.as_bytes())?;
|
||||
}
|
||||
|
||||
let output = gpg_cmd.wait_with_output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
bail!("gpg exited with non-zero status code");
|
||||
}
|
||||
|
||||
let output = output.stdout;
|
||||
|
||||
if output.len() < (28+26+10) { // 10 is just a... fudge factor
|
||||
bail!("length {} returned by gpg too short to be valid", output.len());
|
||||
}
|
||||
|
||||
let start = 28; // length of -----BEGIN PGP MESSAGE----- is 28
|
||||
let end = output.len() - 26; // length of -----END PGP MESSAGE----- is 26
|
||||
|
||||
Ok(String::from_utf8((&output[start..end]).to_vec())?)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user