add proxmox-tfa crate
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
2859858f59
commit
77dc52c047
@ -4,6 +4,7 @@ members = [
|
||||
"proxmox-api-macro",
|
||||
"proxmox-http",
|
||||
"proxmox-sortable-macro",
|
||||
"proxmox-tfa",
|
||||
]
|
||||
exclude = [
|
||||
"build",
|
||||
|
7
Makefile
7
Makefile
@ -1,6 +1,11 @@
|
||||
# Shortcut for common operations:
|
||||
|
||||
CRATES=proxmox proxmox-api-macro proxmox-http proxmox-sortable-macro
|
||||
CRATES = \
|
||||
proxmox \
|
||||
proxmox-api-macro \
|
||||
proxmox-http \
|
||||
proxmox-sortable-macro \
|
||||
proxmox-tfa
|
||||
|
||||
# By default we just run checks:
|
||||
.PHONY: all
|
||||
|
25
proxmox-tfa/Cargo.toml
Normal file
25
proxmox-tfa/Cargo.toml
Normal file
@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "proxmox-tfa"
|
||||
version = "1.0.0"
|
||||
authors = ["Proxmox Support Team <support@proxmox.com>"]
|
||||
edition = "2018"
|
||||
license = "AGPL-3"
|
||||
description = "tfa implementation for totp and u2f"
|
||||
|
||||
exclude = [ "debian" ]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
base32 = "0.4"
|
||||
base64 = "0.12"
|
||||
hex = "0.4"
|
||||
openssl = "0.10"
|
||||
percent-encoding = "2.1"
|
||||
serde = "1.0"
|
||||
serde_plain = "1.0"
|
||||
serde_json = { version = "1.0", optional = true }
|
||||
libc = { version = "0.2", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
u2f = [ "libc", "serde_json", "serde/derive" ]
|
5
proxmox-tfa/debian/changelog
Normal file
5
proxmox-tfa/debian/changelog
Normal file
@ -0,0 +1,5 @@
|
||||
rust-proxmox-tfa (1.0.0-1) stable; urgency=medium
|
||||
|
||||
* initial split out of `librust-proxmox-dev`
|
||||
|
||||
-- Proxmox Support Team <support@proxmox.com> Mon, 04 Oct 2021 11:38:53 +0200
|
97
proxmox-tfa/debian/control
Normal file
97
proxmox-tfa/debian/control
Normal file
@ -0,0 +1,97 @@
|
||||
Source: rust-proxmox-tfa
|
||||
Section: rust
|
||||
Priority: optional
|
||||
Build-Depends: debhelper (>= 12),
|
||||
dh-cargo (>= 24),
|
||||
cargo:native <!nocheck>,
|
||||
rustc:native <!nocheck>,
|
||||
libstd-rust-dev <!nocheck>,
|
||||
librust-anyhow-1+default-dev <!nocheck>,
|
||||
librust-base32-0.4+default-dev <!nocheck>,
|
||||
librust-base64-0.12+default-dev <!nocheck>,
|
||||
librust-hex-0.4+default-dev <!nocheck>,
|
||||
librust-openssl-0.10+default-dev <!nocheck>,
|
||||
librust-percent-encoding-2+default-dev (>= 2.1-~~) <!nocheck>,
|
||||
librust-serde-1+default-dev <!nocheck>,
|
||||
librust-serde-plain-1+default-dev <!nocheck>
|
||||
Maintainer: Proxmox Support Team <support@proxmox.com>
|
||||
Standards-Version: 4.5.1
|
||||
Vcs-Git: git://git.proxmox.com/git/proxmox.git
|
||||
Vcs-Browser: https://git.proxmox.com/?p=proxmox.git
|
||||
Rules-Requires-Root: no
|
||||
|
||||
Package: librust-proxmox-tfa-dev
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends:
|
||||
${misc:Depends},
|
||||
librust-anyhow-1+default-dev,
|
||||
librust-base32-0.4+default-dev,
|
||||
librust-base64-0.12+default-dev,
|
||||
librust-hex-0.4+default-dev,
|
||||
librust-openssl-0.10+default-dev,
|
||||
librust-percent-encoding-2+default-dev (>= 2.1-~~),
|
||||
librust-serde-1+default-dev,
|
||||
librust-serde-plain-1+default-dev
|
||||
Suggests:
|
||||
librust-proxmox-tfa+libc-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa+serde-json-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa+u2f-dev (= ${binary:Version})
|
||||
Provides:
|
||||
librust-proxmox-tfa+default-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1+default-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1.0-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1.0+default-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1.0.0-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1.0.0+default-dev (= ${binary:Version})
|
||||
Description: Tfa implementation for totp and u2f - Rust source code
|
||||
This package contains the source for the Rust proxmox-tfa crate, packaged by
|
||||
debcargo for use with cargo and dh-cargo.
|
||||
|
||||
Package: librust-proxmox-tfa+libc-dev
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends:
|
||||
${misc:Depends},
|
||||
librust-proxmox-tfa-dev (= ${binary:Version}),
|
||||
librust-libc-0.2+default-dev
|
||||
Provides:
|
||||
librust-proxmox-tfa-1+libc-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1.0+libc-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1.0.0+libc-dev (= ${binary:Version})
|
||||
Description: Tfa implementation for totp and u2f - feature "libc"
|
||||
This metapackage enables feature "libc" for the Rust proxmox-tfa crate, by
|
||||
pulling in any additional dependencies needed by that feature.
|
||||
|
||||
Package: librust-proxmox-tfa+serde-json-dev
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends:
|
||||
${misc:Depends},
|
||||
librust-proxmox-tfa-dev (= ${binary:Version}),
|
||||
librust-serde-json-1+default-dev
|
||||
Provides:
|
||||
librust-proxmox-tfa-1+serde-json-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1.0+serde-json-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1.0.0+serde-json-dev (= ${binary:Version})
|
||||
Description: Tfa implementation for totp and u2f - feature "serde_json"
|
||||
This metapackage enables feature "serde_json" for the Rust proxmox-tfa crate,
|
||||
by pulling in any additional dependencies needed by that feature.
|
||||
|
||||
Package: librust-proxmox-tfa+u2f-dev
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends:
|
||||
${misc:Depends},
|
||||
librust-proxmox-tfa-dev (= ${binary:Version}),
|
||||
librust-libc-0.2+default-dev,
|
||||
librust-serde-1+derive-dev,
|
||||
librust-serde-json-1+default-dev
|
||||
Provides:
|
||||
librust-proxmox-tfa-1+u2f-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1.0+u2f-dev (= ${binary:Version}),
|
||||
librust-proxmox-tfa-1.0.0+u2f-dev (= ${binary:Version})
|
||||
Description: Tfa implementation for totp and u2f - feature "u2f"
|
||||
This metapackage enables feature "u2f" for the Rust proxmox-tfa crate, by
|
||||
pulling in any additional dependencies needed by that feature.
|
16
proxmox-tfa/debian/copyright
Normal file
16
proxmox-tfa/debian/copyright
Normal file
@ -0,0 +1,16 @@
|
||||
Copyright (C) 2021 Proxmox Server Solutions GmbH
|
||||
|
||||
This software is written by Proxmox Server Solutions GmbH <support@proxmox.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
7
proxmox-tfa/debian/debcargo.toml
Normal file
7
proxmox-tfa/debian/debcargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
overlay = "."
|
||||
crate_src_path = ".."
|
||||
maintainer = "Proxmox Support Team <support@proxmox.com>"
|
||||
|
||||
[source]
|
||||
vcs_git = "git://git.proxmox.com/git/proxmox.git"
|
||||
vcs_browser = "https://git.proxmox.com/?p=proxmox.git"
|
@ -1,4 +1,4 @@
|
||||
//! Implementation of TOTP, U2F and other mechanisms.
|
||||
//! TOTP implementation.
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
@ -172,7 +172,7 @@ impl Totp {
|
||||
|
||||
/// Create a new OTP secret key builder using a secret specified in hexadecimal bytes.
|
||||
pub fn builder_from_hex(secret: &str) -> Result<TotpBuilder, Error> {
|
||||
crate::tools::hex_to_bin(secret).map(|secret| Self::builder().secret(secret))
|
||||
Ok(Self::builder().secret(hex::decode(secret)?))
|
||||
}
|
||||
|
||||
/// Get the secret key in binary form.
|
||||
@ -394,7 +394,7 @@ impl std::str::FromStr for Totp {
|
||||
}
|
||||
}
|
||||
|
||||
crate::forward_deserialize_to_from_str!(Totp);
|
||||
serde_plain::derive_deserialize_from_fromstr!(Totp, "valid TOTP url");
|
||||
|
||||
impl Serialize for Totp {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
@ -1,6 +1,7 @@
|
||||
//! U2F implementation.
|
||||
|
||||
use std::mem::MaybeUninit;
|
||||
use std::io;
|
||||
|
||||
use anyhow::{bail, format_err, Error};
|
||||
use openssl::ec::{EcGroup, EcKey, EcPoint};
|
||||
@ -10,8 +11,6 @@ use openssl::sha;
|
||||
use openssl::x509::X509;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::tools::serde::{bytes_as_base64, bytes_as_base64url_nopad};
|
||||
|
||||
const CHALLENGE_LEN: usize = 32;
|
||||
const U2F_VERSION: &str = "U2F_V2";
|
||||
|
||||
@ -318,10 +317,19 @@ fn decode(data: &str) -> Result<Vec<u8>, Error> {
|
||||
/// produce a challenge, which is just a bunch of random data
|
||||
fn challenge() -> Result<String, Error> {
|
||||
let mut data = MaybeUninit::<[u8; CHALLENGE_LEN]>::uninit();
|
||||
Ok(encode(&unsafe {
|
||||
crate::sys::linux::fill_with_random_data(&mut *data.as_mut_ptr())?;
|
||||
let data = unsafe {
|
||||
let buf: &mut [u8; CHALLENGE_LEN] = &mut *data.as_mut_ptr();
|
||||
let rc = libc::getrandom(buf.as_mut_ptr() as *mut libc::c_void, buf.len(), 0);
|
||||
if rc == -1 {
|
||||
return Err(io::Error::last_os_error().into());
|
||||
}
|
||||
if rc as usize != buf.len() {
|
||||
// `CHALLENGE_LEN` is small, so short reads cannot happen (see `getrandom(2)`)
|
||||
bail!("short getrandom call");
|
||||
}
|
||||
data.assume_init()
|
||||
}))
|
||||
};
|
||||
Ok(encode(&data))
|
||||
}
|
||||
|
||||
/// Used while parsing the binary registration response. The slices point directly into the
|
||||
@ -548,3 +556,37 @@ mod test {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub mod bytes_as_base64 {
|
||||
use serde::{Deserialize, Deserializer, Serializer};
|
||||
|
||||
pub fn serialize<S: Serializer>(data: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(&base64::encode(&data))
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
|
||||
use serde::de::Error;
|
||||
String::deserialize(deserializer).and_then(|string| {
|
||||
base64::decode(&string).map_err(|err| Error::custom(err.to_string()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub mod bytes_as_base64url_nopad {
|
||||
use serde::{Deserialize, Deserializer, Serializer};
|
||||
|
||||
pub fn serialize<S: Serializer>(data: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(&base64::encode_config(
|
||||
data.as_ref(),
|
||||
base64::URL_SAFE_NO_PAD,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
|
||||
use serde::de::Error;
|
||||
String::deserialize(deserializer).and_then(|string| {
|
||||
base64::decode_config(&string, base64::URL_SAFE_NO_PAD)
|
||||
.map_err(|err| Error::custom(err.to_string()))
|
||||
})
|
||||
}
|
||||
}
|
@ -20,7 +20,6 @@ nix = "0.19.1"
|
||||
unicode-width ="0.1.8"
|
||||
|
||||
# tools module:
|
||||
base32 = { version = "0.4", optional = true }
|
||||
base64 = "0.12"
|
||||
endian_trait = { version = "0.6", features = ["arrays"] }
|
||||
regex = "1.2"
|
||||
@ -38,7 +37,6 @@ futures = { version = "0.3", optional = true }
|
||||
http = "0.2"
|
||||
hyper = { version = "0.14", features = [ "full" ], optional = true }
|
||||
percent-encoding = "2.1"
|
||||
openssl = { version = "0.10", optional = true }
|
||||
rustyline = "7"
|
||||
textwrap = "0.11"
|
||||
tokio = { version = "1.0", features = [], optional = true }
|
||||
@ -51,7 +49,7 @@ proxmox-api-macro = { path = "../proxmox-api-macro", optional = true, version =
|
||||
proxmox-sortable-macro = { path = "../proxmox-sortable-macro", optional = true, version = "0.1.1" }
|
||||
|
||||
[features]
|
||||
default = [ "cli", "router", "tfa", "u2f" ]
|
||||
default = [ "cli", "router" ]
|
||||
sortable-macro = ["proxmox-sortable-macro"]
|
||||
|
||||
# api:
|
||||
@ -59,10 +57,8 @@ api-macro = ["proxmox-api-macro"]
|
||||
test-harness = []
|
||||
cli = [ "router", "hyper", "tokio" ]
|
||||
router = [ "futures", "hyper", "tokio" ]
|
||||
tfa = [ "openssl" ]
|
||||
u2f = [ "base32" ]
|
||||
|
||||
examples = ["tokio/macros", "u2f"]
|
||||
examples = ["tokio/macros"]
|
||||
|
||||
# tools:
|
||||
#valgrind = ["proxmox-tools/valgrind"]
|
||||
|
@ -22,9 +22,6 @@ pub mod uuid;
|
||||
pub mod vec;
|
||||
pub mod systemd;
|
||||
|
||||
#[cfg(feature = "tfa")]
|
||||
pub mod tfa;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use uuid::Uuid;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user