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 110 111 112 113
extern crate asnom; extern crate futures; extern crate tokio_core; extern crate tokio_proto; extern crate tokio_service; extern crate byteorder; #[macro_use] extern crate log; use tokio_service::Service; use std::ops::Drop; use protocol::LdapProto; use std::io; use std::default::Default; use std::net::SocketAddr; use futures::Future; use tokio_core::reactor::Core; use tokio_core::net::TcpStream; use tokio_proto::TcpClient; use tokio_proto::multiplex::ClientService; use asnom::structures::*; use asnom::common::TagClass::*; mod protocol; pub struct LDAP { inner: ClientService<TcpStream, LdapProto>, core: Core } impl LDAP { pub fn new(addr: &SocketAddr) -> Result<LDAP, io::Error> { let mut core = Core::new().unwrap(); let handle = core.handle(); let client_fut = TcpClient::new(LdapProto).connect(addr, &handle); let clientres = core.run(client_fut); match clientres { Ok(client) => { Ok(LDAP { inner: client, core: core, }) }, Err(e) => Err(e) } } pub fn simple_bind(&self, dn: String, pw: String) -> Box<Future<Item = bool, Error = io::Error>> { let req = Tag::Sequence(Sequence { id: 0, class: Application, inner: vec![ Tag::Integer(Integer { inner: 3, .. Default::default() }), Tag::OctetString(OctetString { inner: dn.into_bytes(), .. Default::default() }), Tag::OctetString(OctetString { id: 0, class: Context, inner: pw.into_bytes(), }) ], }); let fut = self.inner.call(req).and_then(|res| match res { Tag::StructureTag(tag) => { if let Some(i) = tag.expect_constructed() { return Ok(i[0] == Tag::Integer(Integer { id: 10, class: Universal, inner: 0 }).into_structure()) } else { return Ok(false) } } _ => unimplemented!(), } ); Box::new(fut) } pub fn simple_bind_s(&mut self, dn: String, pw: String) -> Result<bool,io::Error> { let fut = self.simple_bind(dn, pw); self.core.run(fut) } } impl Drop for LDAP { fn drop(&mut self) { let _ = self.core.run(self.inner.call(Tag::Null(Null { id: 2, class: Application, inner: (), }))); } }