1extern crate asnom;
2
3extern crate futures;
4extern crate tokio_core;
5extern crate tokio_proto;
6extern crate tokio_service;
7
8extern crate byteorder;
9
10#[macro_use]
11extern crate log;
12
13use tokio_service::Service;
14
15use std::ops::Drop;
16use protocol::LdapProto;
17
18use std::io;
19use std::default::Default;
20use std::net::SocketAddr;
21
22use futures::Future;
23use tokio_core::reactor::Core;
24use tokio_core::net::TcpStream;
25use tokio_proto::TcpClient;
26use tokio_proto::multiplex::ClientService;
27
28use asnom::structures::*;
29use asnom::common::TagClass::*;
30
31mod protocol;
32
33pub struct LDAP {
34 inner: ClientService<TcpStream, LdapProto>,
35 core: Core
36}
37
38impl LDAP {
39 pub fn new(addr: &SocketAddr) -> Result<LDAP, io::Error> {
40 let mut core = Core::new().unwrap();
41
42 let handle = core.handle();
43
44 let client_fut = TcpClient::new(LdapProto).connect(addr, &handle);
45
46 let clientres = core.run(client_fut);
47
48 match clientres {
49 Ok(client) => {
50 Ok(LDAP {
51 inner: client,
52 core: core,
53 })
54 },
55 Err(e) => Err(e)
56 }
57 }
58
59 pub fn simple_bind(&self, dn: String, pw: String) -> Box<Future<Item = bool, Error = io::Error>> {
60 let req = Tag::Sequence(Sequence {
61 id: 0,
62 class: Application,
63 inner: vec![
64 Tag::Integer(Integer {
65 inner: 3,
66 .. Default::default()
67 }),
68 Tag::OctetString(OctetString {
69 inner: dn.into_bytes(),
70 .. Default::default()
71 }),
72 Tag::OctetString(OctetString {
73 id: 0,
74 class: Context,
75 inner: pw.into_bytes(),
76 })
77 ],
78 });
79
80 let fut = self.inner.call(req).and_then(|res|
81 match res {
82 Tag::StructureTag(tag) => {
83 if let Some(i) = tag.expect_constructed() {
84 return Ok(i[0] == Tag::Integer(Integer {
85 id: 10,
86 class: Universal,
87 inner: 0
88 }).into_structure())
89 } else {
90 return Ok(false)
91 }
92 }
93 _ => unimplemented!(),
94 }
95 );
96 Box::new(fut)
97 }
98
99 pub fn simple_bind_s(&mut self, dn: String, pw: String) -> Result<bool,io::Error> {
100 let fut = self.simple_bind(dn, pw);
101 self.core.run(fut)
102 }
103}
104
105impl Drop for LDAP {
106 fn drop(&mut self) {
107 let _ = self.core.run(self.inner.call(Tag::Null(Null {
108 id: 2,
109 class: Application,
110 inner: (),
111 })));
112 }
113}