1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use super::{Exop, ExopParser};
use bytes::BytesMut;
use lber::common::TagClass;
use lber::parse::parse_tag;
use lber::structures::{ASNTag, OctetString, Sequence, Tag};
use lber::{write, IResult};
pub const PASSMOD_OID: &str = "1.3.6.1.4.1.4203.1.11.1";
#[derive(Clone, Debug)]
pub struct PasswordModify<'a> {
pub user_id: Option<&'a str>,
pub old_pass: Option<&'a str>,
pub new_pass: Option<&'a str>,
}
#[derive(Clone, Debug)]
pub struct PasswordModifyResp {
pub gen_pass: String,
}
impl<'a> From<PasswordModify<'a>> for Exop {
fn from(pm: PasswordModify<'a>) -> Exop {
let mut pm_vec = vec![];
if let Some(user_id) = pm.user_id {
pm_vec.push(Tag::OctetString(OctetString {
id: 0,
class: TagClass::Context,
inner: Vec::from(user_id.as_bytes()),
}));
}
if let Some(old_pass) = pm.old_pass {
pm_vec.push(Tag::OctetString(OctetString {
id: 1,
class: TagClass::Context,
inner: Vec::from(old_pass.as_bytes()),
}));
}
if let Some(new_pass) = pm.new_pass {
pm_vec.push(Tag::OctetString(OctetString {
id: 2,
class: TagClass::Context,
inner: Vec::from(new_pass.as_bytes()),
}));
}
let val = if pm_vec.is_empty() {
None
} else {
let pm_val = Tag::Sequence(Sequence {
inner: pm_vec,
..Default::default()
})
.into_structure();
let mut buf = BytesMut::new();
write::encode_into(&mut buf, pm_val).expect("encoded");
Some(Vec::from(&buf[..]))
};
Exop {
name: Some(PASSMOD_OID.to_owned()),
val,
}
}
}
impl ExopParser for PasswordModifyResp {
fn parse(val: &[u8]) -> PasswordModifyResp {
let tags = match parse_tag(val) {
IResult::Done(_, tag) => tag,
_ => panic!("failed to parse password modify return value"),
};
let mut tags = tags
.expect_constructed()
.expect("password modify sequence")
.into_iter();
let gen_pass = tags
.next()
.expect("element")
.match_class(TagClass::Context)
.and_then(|t| t.match_id(0))
.and_then(|t| t.expect_primitive())
.expect("generated password")
.as_slice()
.to_owned();
let gen_pass = String::from_utf8(gen_pass).expect("generated password not UTF-8");
PasswordModifyResp { gen_pass }
}
}