#![allow(dead_code)]
#![allow(non_camel_case_types)]
use std::io::{Read, Write};
use num_derive::{FromPrimitive, ToPrimitive};
use super::{
deserialize, Deserialize, DeserializeEnum, DeserializeStruct, Serialize, SerializeEnum,
SerializeStruct,
};
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Default, FromPrimitive, ToPrimitive)]
#[repr(u32)]
pub enum auth_stat {
#[default]
AUTH_BADCRED = 1,
AUTH_REJECTEDCRED = 2,
AUTH_BADVERF = 3,
AUTH_REJECTEDVERF = 4,
AUTH_TOOWEAK = 5,
}
impl SerializeEnum for auth_stat {}
impl DeserializeEnum for auth_stat {}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, FromPrimitive, ToPrimitive)]
#[repr(u32)]
#[non_exhaustive]
pub enum auth_flavor {
AUTH_NULL = 0,
AUTH_UNIX = 1,
AUTH_SHORT = 2,
AUTH_DES = 3,
}
impl SerializeEnum for auth_flavor {}
impl DeserializeEnum for auth_flavor {}
#[allow(non_camel_case_types)]
#[derive(Clone, Debug, Default)]
pub struct auth_unix {
pub stamp: u32,
pub machinename: Vec<u8>,
pub uid: u32,
pub gid: u32,
pub gids: Vec<u32>,
}
DeserializeStruct!(auth_unix, stamp, machinename, uid, gid, gids);
SerializeStruct!(auth_unix, stamp, machinename, uid, gid, gids);
#[allow(non_camel_case_types)]
#[derive(Clone, Debug)]
pub struct opaque_auth {
pub flavor: auth_flavor,
pub body: Vec<u8>,
}
DeserializeStruct!(opaque_auth, flavor, body);
SerializeStruct!(opaque_auth, flavor, body);
impl Default for opaque_auth {
fn default() -> opaque_auth {
opaque_auth { flavor: auth_flavor::AUTH_NULL, body: Vec::new() }
}
}
#[allow(non_camel_case_types)]
#[derive(Clone, Debug, Default)]
pub struct rpc_msg {
pub xid: u32,
pub body: rpc_body,
}
DeserializeStruct!(rpc_msg, xid, body);
SerializeStruct!(rpc_msg, xid, body);
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Debug)]
#[repr(u32)]
pub enum rpc_body {
CALL(call_body),
REPLY(reply_body),
}
impl Default for rpc_body {
fn default() -> rpc_body {
rpc_body::CALL(call_body::default())
}
}
impl Serialize for rpc_body {
fn serialize<R: Write>(&self, dest: &mut R) -> std::io::Result<()> {
match self {
rpc_body::CALL(v) => {
0_u32.serialize(dest)?;
v.serialize(dest)?;
}
rpc_body::REPLY(v) => {
1_u32.serialize(dest)?;
v.serialize(dest)?;
}
}
Ok(())
}
}
impl Deserialize for rpc_body {
fn deserialize<R: Read>(&mut self, src: &mut R) -> std::io::Result<()> {
match deserialize::<u32>(src)? {
0 => *self = rpc_body::CALL(deserialize(src)?),
1 => *self = rpc_body::REPLY(deserialize(src)?),
msg_type => {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("Invalid message type in rpc_body: {msg_type}"),
))
}
}
Ok(())
}
}
#[allow(non_camel_case_types)]
#[derive(Clone, Debug, Default)]
pub struct call_body {
pub rpcvers: u32,
pub prog: u32,
pub vers: u32,
pub proc: u32,
pub cred: opaque_auth,
pub verf: opaque_auth,
}
DeserializeStruct!(call_body, rpcvers, prog, vers, proc, cred, verf);
SerializeStruct!(call_body, rpcvers, prog, vers, proc, cred, verf);
#[allow(non_camel_case_types)]
#[derive(Clone, Debug)]
pub enum reply_body {
MSG_ACCEPTED(accepted_reply),
MSG_DENIED(rejected_reply),
}
impl Default for reply_body {
fn default() -> reply_body {
reply_body::MSG_ACCEPTED(accepted_reply::default())
}
}
impl Serialize for reply_body {
fn serialize<R: Write>(&self, dest: &mut R) -> std::io::Result<()> {
match self {
reply_body::MSG_ACCEPTED(v) => {
0_u32.serialize(dest)?;
v.serialize(dest)?;
}
reply_body::MSG_DENIED(v) => {
1_u32.serialize(dest)?;
v.serialize(dest)?;
}
}
Ok(())
}
}
impl Deserialize for reply_body {
fn deserialize<R: Read>(&mut self, src: &mut R) -> std::io::Result<()> {
match deserialize::<u32>(src)? {
0 => *self = reply_body::MSG_ACCEPTED(deserialize(src)?),
1 => *self = reply_body::MSG_DENIED(deserialize(src)?),
reply_status => {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("Invalid reply status in reply_body: {reply_status}"),
))
}
}
Ok(())
}
}
#[allow(non_camel_case_types)]
#[derive(Clone, Debug, Default)]
pub struct mismatch_info {
pub low: u32,
pub high: u32,
}
DeserializeStruct!(mismatch_info, low, high);
SerializeStruct!(mismatch_info, low, high);
#[allow(non_camel_case_types)]
#[derive(Clone, Debug, Default)]
pub struct accepted_reply {
pub verf: opaque_auth,
pub reply_data: accept_body,
}
DeserializeStruct!(accepted_reply, verf, reply_data);
SerializeStruct!(accepted_reply, verf, reply_data);
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Debug, Default)]
#[repr(u32)]
pub enum accept_body {
#[default]
SUCCESS,
PROG_UNAVAIL,
PROG_MISMATCH(mismatch_info),
PROC_UNAVAIL,
GARBAGE_ARGS,
}
impl Serialize for accept_body {
fn serialize<R: Write>(&self, dest: &mut R) -> std::io::Result<()> {
match self {
accept_body::SUCCESS => {
0_u32.serialize(dest)?;
}
accept_body::PROG_UNAVAIL => {
1_u32.serialize(dest)?;
}
accept_body::PROG_MISMATCH(v) => {
2_u32.serialize(dest)?;
v.serialize(dest)?;
}
accept_body::PROC_UNAVAIL => {
3_u32.serialize(dest)?;
}
accept_body::GARBAGE_ARGS => {
4_u32.serialize(dest)?;
}
}
Ok(())
}
}
impl Deserialize for accept_body {
fn deserialize<R: Read>(&mut self, src: &mut R) -> std::io::Result<()> {
match deserialize::<u32>(src)? {
0 => *self = accept_body::SUCCESS,
1 => *self = accept_body::PROG_UNAVAIL,
2 => *self = accept_body::PROG_MISMATCH(deserialize(src)?),
3 => *self = accept_body::PROC_UNAVAIL,
4 => *self = accept_body::GARBAGE_ARGS,
accept_stat => {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("Invalid accept stat in accept_body: {accept_stat}"),
));
}
}
Ok(())
}
}
#[allow(non_camel_case_types)]
#[derive(Clone, Debug)]
pub enum rejected_reply {
RPC_MISMATCH(mismatch_info),
AUTH_ERROR(auth_stat),
}
impl Default for rejected_reply {
fn default() -> rejected_reply {
rejected_reply::AUTH_ERROR(auth_stat::default())
}
}
impl Serialize for rejected_reply {
fn serialize<R: Write>(&self, dest: &mut R) -> std::io::Result<()> {
match self {
rejected_reply::RPC_MISMATCH(v) => {
0_u32.serialize(dest)?;
v.serialize(dest)?;
}
rejected_reply::AUTH_ERROR(v) => {
1_u32.serialize(dest)?;
(*v as u32).serialize(dest)?;
}
}
Ok(())
}
}
impl Deserialize for rejected_reply {
fn deserialize<R: Read>(&mut self, src: &mut R) -> std::io::Result<()> {
match deserialize::<u32>(src)? {
0 => *self = rejected_reply::RPC_MISMATCH(deserialize(src)?),
1 => *self = rejected_reply::AUTH_ERROR(deserialize(src)?),
stat => {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("Invalid reject stat in rejected_reply: {stat}"),
))
}
}
Ok(())
}
}
pub fn proc_unavail_reply_message(xid: u32) -> rpc_msg {
let reply = reply_body::MSG_ACCEPTED(accepted_reply {
verf: opaque_auth::default(),
reply_data: accept_body::PROC_UNAVAIL,
});
rpc_msg { xid, body: rpc_body::REPLY(reply) }
}
pub fn prog_unavail_reply_message(xid: u32) -> rpc_msg {
let reply = reply_body::MSG_ACCEPTED(accepted_reply {
verf: opaque_auth::default(),
reply_data: accept_body::PROG_UNAVAIL,
});
rpc_msg { xid, body: rpc_body::REPLY(reply) }
}
pub fn prog_mismatch_reply_message(xid: u32, accepted_ver: u32) -> rpc_msg {
let reply = reply_body::MSG_ACCEPTED(accepted_reply {
verf: opaque_auth::default(),
reply_data: accept_body::PROG_MISMATCH(mismatch_info {
low: accepted_ver,
high: accepted_ver,
}),
});
rpc_msg { xid, body: rpc_body::REPLY(reply) }
}
pub fn garbage_args_reply_message(xid: u32) -> rpc_msg {
let reply = reply_body::MSG_ACCEPTED(accepted_reply {
verf: opaque_auth::default(),
reply_data: accept_body::GARBAGE_ARGS,
});
rpc_msg { xid, body: rpc_body::REPLY(reply) }
}
pub fn rpc_vers_mismatch(xid: u32) -> rpc_msg {
let reply = reply_body::MSG_DENIED(rejected_reply::RPC_MISMATCH(mismatch_info::default()));
rpc_msg { xid, body: rpc_body::REPLY(reply) }
}
pub fn make_success_reply(xid: u32) -> rpc_msg {
let reply = reply_body::MSG_ACCEPTED(accepted_reply {
verf: opaque_auth::default(),
reply_data: accept_body::SUCCESS,
});
rpc_msg { xid, body: rpc_body::REPLY(reply) }
}