Skip to content

Commit 99dcd6f

Browse files
author
Pan
committed
Known host API implementation, tests and documentation.
1 parent b995bf9 commit 99dcd6f

16 files changed

+11519
-646
lines changed

.travis.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ script:
2929
- cd dist; pip install *; cd ..
3030
jobs:
3131
include:
32-
- stage: OSX 10.12 wheel build
32+
- stage: OSX wheel build
3333
os: osx
3434
if: tag IS present
3535
before_install:
@@ -54,7 +54,7 @@ jobs:
5454
fi
5555
language: generic
5656
python: skip
57-
- stage: OSX 10.11 wheel build
57+
- stage: OSX wheel build
5858
os: osx
5959
osx_image: xcode8
6060
if: tag IS present
@@ -80,7 +80,7 @@ jobs:
8080
fi
8181
language: generic
8282
python: skip
83-
- stage: OSX 10.10 wheel build
83+
- stage: OSX wheel build
8484
os: osx
8585
osx_image: xcode6.4
8686
if: tag IS present

Changelog.rst

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
Change Log
22
=============
33

4+
0.8.0
5+
++++++
6+
7+
Changes
8+
---------
9+
10+
* Implemented known host API, all functions.
11+
* Added `hostkey` method on `Session` class for retrieving server host key.
12+
* Added server host key verification from known hosts file example.
13+
* Added exceptions for all known host API errors.
14+
415
0.7.0
516
++++++
617

doc/api.rst

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ API Documentation
1010
sftp_handle
1111
pkey
1212
listener
13+
knownhost
1314
exceptions
1415
statinfo
1516
fileinfo

doc/knownhost.rst

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
ssh2.knownhost
2+
===============
3+
4+
.. automodule:: ssh2.knownhost
5+
:members:
6+
:undoc-members:
7+
:member-order: groupwise
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"""Connect to localhost, verifying host by reading from ~/.ssh/known_hosts"""
2+
3+
from __future__ import print_function
4+
import os
5+
import socket
6+
7+
from ssh2.session import Session
8+
from ssh2.session import LIBSSH2_HOSTKEY_HASH_SHA1, LIBSSH2_HOSTKEY_TYPE_RSA
9+
from ssh2.knownhost import LIBSSH2_KNOWNHOST_TYPE_PLAIN, \
10+
LIBSSH2_KNOWNHOST_KEYENC_RAW, LIBSSH2_KNOWNHOST_KEY_SSHRSA
11+
12+
# Connection settings
13+
host = 'localhost'
14+
user = os.getlogin()
15+
known_hosts = os.sep.join([os.path.expanduser('~'), '.ssh', 'known_hosts'])
16+
17+
# Make socket, connect
18+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
19+
sock.connect((host, 22))
20+
21+
# Initialise
22+
session = Session()
23+
session.handshake(sock)
24+
25+
host_key, key_type = session.hostkey()
26+
27+
server_key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA \
28+
if key_type == LIBSSH2_HOSTKEY_TYPE_RSA \
29+
else LIBSSH2_KNOWNHOST_KEY_SSHDSS
30+
31+
kh = session.knownhost_init()
32+
_read_hosts = kh.readfile(known_hosts)
33+
print("Read %s hosts from known hosts file at %s" % (_read_hosts, known_hosts))
34+
35+
# Verification
36+
type_mask = LIBSSH2_KNOWNHOST_TYPE_PLAIN | \
37+
LIBSSH2_KNOWNHOST_KEYENC_RAW | \
38+
server_key_type
39+
kh.checkp(host, 22, host_key, type_mask)
40+
print("Host verification passed.")
41+
42+
# Verification passed, continue with authentication
43+
session.agent_auth(user)
44+
45+
channel = session.open_session()
46+
channel.execute('echo me')
47+
channel.wait_eof()
48+
channel.close()
49+
channel.wait_closed()
50+
51+
# Get exit status
52+
print("Exit status: %s" % channel.get_exit_status())
53+
54+
# Print output
55+
size, data = channel.read()
56+
while size > 0:
57+
print(data)
58+
size, data = channel.read()

ssh2/c_ssh2.pxd

+35-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ cdef extern from "libssh2.h" nogil:
3636
LIBSSH2_CHANNEL_FLUSH_ALL
3737
LIBSSH2_HOSTKEY_HASH_MD5
3838
LIBSSH2_HOSTKEY_HASH_SHA1
39+
LIBSSH2_HOSTKEY_TYPE_UNKNOWN
40+
LIBSSH2_HOSTKEY_TYPE_RSA
41+
LIBSSH2_HOSTKEY_TYPE_DSS
42+
3943
# ctypedef libssh2_uint64_t libssh2_struct_stat_size
4044
ctypedef struct libssh2_struct_stat:
4145
dev_t st_dev
@@ -336,8 +340,14 @@ cdef extern from "libssh2.h" nogil:
336340
unsigned int *dest_len,
337341
const char *src, unsigned int src_len)
338342
const char *libssh2_version(int req_version_num)
339-
ctypedef struct libssh2_knownhost:
340-
pass
343+
344+
# Known host API
345+
struct libssh2_knownhost:
346+
unsigned int magic
347+
void *node
348+
char *name
349+
char *key
350+
int typemask
341351
LIBSSH2_KNOWNHOSTS *libssh2_knownhost_init(LIBSSH2_SESSION *session)
342352
int libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
343353
const char *host,
@@ -377,6 +387,29 @@ cdef extern from "libssh2.h" nogil:
377387
int libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts,
378388
libssh2_knownhost **store,
379389
libssh2_knownhost *prev)
390+
enum:
391+
LIBSSH2_KNOWNHOST_FILE_OPENSSH
392+
LIBSSH2_KNOWNHOST_CHECK_MATCH
393+
LIBSSH2_KNOWNHOST_CHECK_MISMATCH
394+
LIBSSH2_KNOWNHOST_CHECK_NOTFOUND
395+
LIBSSH2_KNOWNHOST_CHECK_FAILURE
396+
LIBSSH2_KNOWNHOST_TYPE_MASK
397+
LIBSSH2_KNOWNHOST_TYPE_PLAIN
398+
LIBSSH2_KNOWNHOST_TYPE_SHA1
399+
LIBSSH2_KNOWNHOST_TYPE_CUSTOM
400+
LIBSSH2_KNOWNHOST_KEYENC_MASK
401+
LIBSSH2_KNOWNHOST_KEYENC_RAW
402+
LIBSSH2_KNOWNHOST_KEYENC_BASE64
403+
LIBSSH2_KNOWNHOST_KEY_MASK
404+
LIBSSH2_KNOWNHOST_KEY_SHIFT
405+
LIBSSH2_KNOWNHOST_KEY_RSA1
406+
LIBSSH2_KNOWNHOST_KEY_SSHRSA
407+
LIBSSH2_KNOWNHOST_KEY_SSHDSS
408+
IF EMBEDDED_LIB:
409+
enum:
410+
LIBSSH2_KNOWNHOST_KEY_UNKNOWN
411+
412+
# Public Key API
380413
struct libssh2_agent_publickey:
381414
unsigned int magic
382415
void *node

0 commit comments

Comments
 (0)