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
114
115
116
117
118
119
120
121
122
123
124
125
|
use std::ffi::CString;
use std::marker;
use std::slice;
use std::str;
use {raw, Session, Error};
use util::{Binding, SessionBinding};
/// A structure representing a connection to an SSH agent.
///
/// Agents can be used to authenticate a session.
pub struct Agent<'sess> {
raw: *mut raw::LIBSSH2_AGENT,
sess: &'sess Session,
}
/// An iterator over the identities found in an SSH agent.
pub struct Identities<'agent> {
prev: *mut raw::libssh2_agent_publickey,
agent: &'agent Agent<'agent>,
}
/// A public key which is extracted from an SSH agent.
pub struct PublicKey<'agent> {
raw: *mut raw::libssh2_agent_publickey,
_marker: marker::PhantomData<&'agent [u8]>,
}
impl<'sess> Agent<'sess> {
/// Connect to an ssh-agent running on the system.
pub fn connect(&mut self) -> Result<(), Error> {
unsafe { self.sess.rc(raw::libssh2_agent_connect(self.raw)) }
}
/// Close a connection to an ssh-agent.
pub fn disconnect(&mut self) -> Result<(), Error> {
unsafe { self.sess.rc(raw::libssh2_agent_disconnect(self.raw)) }
}
/// Request an ssh-agent to list of public keys, and stores them in the
/// internal collection of the handle.
///
/// Call `identities` to get the public keys.
pub fn list_identities(&mut self) -> Result<(), Error> {
unsafe { self.sess.rc(raw::libssh2_agent_list_identities(self.raw)) }
}
/// Get an iterator over the identities of this agent.
pub fn identities(&self) -> Identities {
Identities { prev: 0 as *mut _, agent: self }
}
/// Attempt public key authentication with the help of ssh-agent.
pub fn userauth(&self, username: &str, identity: &PublicKey)
-> Result<(), Error>{
let username = try!(CString::new(username));
unsafe {
self.sess.rc(raw::libssh2_agent_userauth(self.raw,
username.as_ptr(),
identity.raw))
}
}
}
impl<'sess> SessionBinding<'sess> for Agent<'sess> {
type Raw = raw::LIBSSH2_AGENT;
unsafe fn from_raw(sess: &'sess Session,
raw: *mut raw::LIBSSH2_AGENT) -> Agent<'sess> {
Agent { raw: raw, sess: sess }
}
fn raw(&self) -> *mut raw::LIBSSH2_AGENT { self.raw }
}
impl<'a> Drop for Agent<'a> {
fn drop(&mut self) {
unsafe { raw::libssh2_agent_free(self.raw) }
}
}
impl<'agent> Iterator for Identities<'agent> {
type Item = Result<PublicKey<'agent>, Error>;
fn next(&mut self) -> Option<Result<PublicKey<'agent>, Error>> {
unsafe {
let mut next = 0 as *mut _;
match raw::libssh2_agent_get_identity(self.agent.raw,
&mut next,
self.prev) {
0 => { self.prev = next; Some(Ok(Binding::from_raw(next))) }
1 => None,
rc => Some(Err(self.agent.sess.rc(rc).err().unwrap())),
}
}
}
}
impl<'agent> PublicKey<'agent> {
/// Return the data of this public key.
pub fn blob(&self) -> &[u8] {
unsafe {
slice::from_raw_parts_mut((*self.raw).blob,
(*self.raw).blob_len as usize)
}
}
/// Returns the comment in a printable format
pub fn comment(&self) -> &str {
unsafe {
str::from_utf8(::opt_bytes(self, (*self.raw).comment).unwrap())
.unwrap()
}
}
}
impl<'agent> Binding for PublicKey<'agent> {
type Raw = *mut raw::libssh2_agent_publickey;
unsafe fn from_raw(raw: *mut raw::libssh2_agent_publickey)
-> PublicKey<'agent> {
PublicKey { raw: raw, _marker: marker::PhantomData }
}
fn raw(&self) -> *mut raw::libssh2_agent_publickey { self.raw }
}
|