-
Notifications
You must be signed in to change notification settings - Fork 75
/
Copy pathpublickey.pyx
194 lines (160 loc) · 5.94 KB
/
publickey.pyx
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# This file is part of ssh2-python.
# Copyright (C) 2017-2020 Panos Kittenis
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation, version 2.1.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from libc.stdlib cimport malloc, free
from .session cimport Session
from .utils cimport to_bytes, handle_error_codes
from . cimport c_pkey
cdef object PyPublicKeyList(c_pkey.libssh2_publickey_list *_list):
cdef PublicKeyList key_list = PublicKeyList.__new__(PublicKeyList)
key_list.key_list = _list
return key_list
cdef class PublicKeyList:
cdef c_pkey.libssh2_publickey_list *key_list
cdef PublicKeySystem pkey_s
def __cinit__(self, PublicKeySystem pkey_s):
self.key_list = NULL
self.pkey_s = pkey_s
def __dealloc__(self):
with nogil:
c_pkey.libssh2_publickey_list_free(
self.pkey_s.pkey_s, self.key_list)
@property
def name(self):
return self.attr.name
@property
def name_len(self):
return self.attr.name_len
@property
def blob(self):
return self.attr.blob
@property
def blob_len(self):
return self.attr.blob_len
@property
def num_attrs(self):
return self.attr.num_attrs
cdef class PublicKeyAttribute:
"""Public key attributes"""
cdef c_pkey.libssh2_publickey_attribute attr
def __cinit__(self, bytes name, bytes value, char mandatory):
cdef char *_name = name
cdef char *_value = value
cdef unsigned long name_len = len(name)
cdef unsigned long value_len = len(value)
self.attr = c_pkey.libssh2_publickey_attribute(
_name, name_len, _value, value_len, mandatory)
@property
def name(self):
return self.attr.name
@property
def name_len(self):
return self.attr.name_len
@property
def value(self):
return self.attr.value
@property
def value_len(self):
return self.attr.value_len
@property
def mandatory(self):
return self.attr.mandatory
cdef c_pkey.libssh2_publickey_attribute * to_c_attr(list attrs):
cdef c_pkey.libssh2_publickey_attribute *_attrs
cdef size_t size = len(attrs)
cdef c_pkey.libssh2_publickey_attribute attr
with nogil:
_attrs = <c_pkey.libssh2_publickey_attribute *>malloc(
(size + 1) * sizeof(c_pkey.libssh2_publickey_attribute))
if _attrs is NULL:
with gil:
raise MemoryError
for i in range(size):
attr = attrs[i].attr
with nogil:
_attrs[i] = attr
return _attrs
cdef object PyPublicKeySystem(c_pkey.LIBSSH2_PUBLICKEY *_pkey_s,
Session session):
cdef PublicKeySystem pkey_s = PublicKeySystem.__new__(
PublicKeySystem, session)
pkey_s.pkey_s = _pkey_s
return pkey_s
cdef class PublicKeySystem:
"""Public Key subsystem. Methods for managing public keys on remote
server, like with the ``ssh-*-id`` utilities.
Not related to pkey authentication."""
cdef c_pkey.LIBSSH2_PUBLICKEY *pkey_s
cdef Session session
def __cinit__(self, Session session):
self.pkey_s = NULL
self.session = session
def __dealloc__(self):
if self.session is not None and self.session._session is not NULL and self.pkey_s is not NULL:
with nogil:
c_pkey.libssh2_publickey_shutdown(self.pkey_s)
self.pkey_s = NULL
def add(self, bytes name, bytes blob,
char overwrite,
list attrs):
cdef unsigned long name_len = len(name)
cdef unsigned long num_attrs = len(attrs)
cdef c_pkey.libssh2_publickey_attribute *_attrs = NULL
if num_attrs > 0:
_attrs = to_c_attr(attrs)
cdef const unsigned char *_name = name
cdef size_t blob_len = len(blob)
cdef const unsigned char *_blob = blob
with nogil:
rc = c_pkey.libssh2_publickey_add_ex(
self.pkey_s, _name, name_len, _blob,
blob_len, overwrite, num_attrs, _attrs)
if _attrs is not NULL:
free(_attrs)
return handle_error_codes(rc)
def remove(self, bytes name, bytes blob):
cdef unsigned long name_len = len(name)
cdef unsigned long blob_len = len(blob)
cdef const unsigned char *_name = name
cdef const unsigned char *_blob = blob
with nogil:
rc = c_pkey.libssh2_publickey_remove_ex(
self.pkey_s, _name, name_len, _blob, blob_len)
return handle_error_codes(rc)
def list_fetch(self):
cdef unsigned long num_keys = 0
cdef c_pkey.libssh2_publickey_list **pkey_list = NULL
cdef int rc
cdef list keys
with nogil:
rc = c_pkey.libssh2_publickey_list_fetch(
self.pkey_s, &num_keys, pkey_list)
if rc != 0:
return handle_error_codes(rc)
if num_keys < 1:
return []
keys = [PyPublicKeyList(pkey_list[i]) for i in range(num_keys)]
return keys
def list_free(self):
"""No-op - list_free called automatically by
:py:class:`ssh2.publickey.PublicKeyList` destructor"""
pass
def shutdown(self):
"""Shutdown public key subsystem.
Called automatically by object destructor"""
cdef int rc
with nogil:
rc = c_pkey.libssh2_publickey_shutdown(self.pkey_s)
return handle_error_codes(rc)