//! OpenMessage
//! Hides a message inside some text. Which can be recovered again by a key.
//!
//! Disclaimer: This programm does not cryptographically encrypt messages.
//! it only obfuscates a message using XOR, and should not be used
//! in any production environment.
//!
//! This project is only to experiment with permutations
//! and byte manipulation.
//!
//! Copyright (C) 2025 adam@p-trace.com GPG: key.p-trace.com
//!
//! This program is free software: you can redistribute it and/or modify
//! it under the terms of the GNU General Public License as published by
//! the Free Software Foundation, either version 3 of the License, or
//! any later version.
//!
//! This program is distributed in the hope that it will be useful,
//! but WITHOUT ANY WARRANTY; without even the implied warranty of
//! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//! GNU General Public License for more details.
//!
//! You should have received a copy of the GNU General Public License
//! along with this program. If not, see .
use std::fs::{self, read_to_string};
use std::process::exit;
use std::path::PathBuf;
use clap::{CommandFactory, Parser};
use obfuscator::Obfuscator;
mod obfuscator;
const CHUNK_SIZE: usize = 4;
const MAGIC: [u8; 8] = [0x4f, 0x4d, 0x66, 0x6d, 0x74, 0x0, 0x0, 0x0]; // OMfmt
const KEY_FN: &str = "key.om";
const OUT_FN: &str = "output.txt";
const CLI_ABOUT: &str = "Hides a message inside some text\n\
\n\
Encode:\n\
$ om container.txt -e message.txt\n\
\n\
Decode:\n\
$ om container.txt -d key.om";
#[derive(Parser)]
#[command(name = "OpenMessage")]
#[command(about = CLI_ABOUT)]
#[command(version, long_about = None)]
struct Cli {
/// File path to the text file for the 'container'.
/// Where the message should be encoded/decoded from
container: PathBuf,
/// Encodes the message; needs the file path to the text file of the message
#[arg(short, long)]
encode: Option,
/// Decodes the message; needs the file path to the keyfile.
/// from your current directory
#[arg(short, long)]
decode: Option,
/// Outputs the decrypted message to a text file
#[arg(short, long)]
output: bool,
/// Doesn't print the message output to the console
#[arg(short, long)]
silent: bool,
/// Prints some debug information
#[arg(short, long)]
verbose: bool,
}
fn main() {
let cli = Cli::parse();
let container = match read_to_string(cli.container) {
Ok(v) => v,
Err(e) => {
eprintln!("{e}");
exit(1);
}
};
if cli.encode.is_some() {
let message = match read_to_string(cli.encode.unwrap()) {
Ok(v) => v,
Err(e) => {
eprintln!("[Error]: {e}");
exit(1);
}
};
Obfuscator::new(Some(message), container, KEY_FN.into(), cli.verbose).encode();
exit(0);
}
if cli.decode.is_some() {
let message = Obfuscator::new(None, container, cli.decode.unwrap(), cli.verbose).decode();
if cli.output {
match fs::write(OUT_FN, &message) {
Ok(_) => println!("Saved decrypted message to your current directory as '{}'", OUT_FN),
Err(e) => {
eprintln!("[Error]: {e}");
exit(1);
}
}
}
if !cli.silent {
println!("{}", message);
}
exit(0);
}
println!("Some args are missing! Help:");
let _ = Cli::command().print_help();
println!();
exit(0);
}