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

This commit is contained in:
Travis Burtrum 2021-01-15 01:05:15 -05:00
parent d12a548793
commit 209a0ae2a3
3 changed files with 91 additions and 27 deletions

53
Cargo.lock generated
View File

@ -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",

View File

@ -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"

View File

@ -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())?)
}