Skip to content

Commit

Permalink
Known host API implementation, tests and documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
pkittenis committed Jan 8, 2018
1 parent b995bf9 commit 99dcd6f
Show file tree
Hide file tree
Showing 16 changed files with 11,519 additions and 646 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ script:
- cd dist; pip install *; cd ..
jobs:
include:
- stage: OSX 10.12 wheel build
- stage: OSX wheel build
os: osx
if: tag IS present
before_install:
Expand All @@ -54,7 +54,7 @@ jobs:
fi
language: generic
python: skip
- stage: OSX 10.11 wheel build
- stage: OSX wheel build
os: osx
osx_image: xcode8
if: tag IS present
Expand All @@ -80,7 +80,7 @@ jobs:
fi
language: generic
python: skip
- stage: OSX 10.10 wheel build
- stage: OSX wheel build
os: osx
osx_image: xcode6.4
if: tag IS present
Expand Down
11 changes: 11 additions & 0 deletions Changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
Change Log
=============

0.8.0
++++++

Changes
---------

* Implemented known host API, all functions.
* Added `hostkey` method on `Session` class for retrieving server host key.
* Added server host key verification from known hosts file example.
* Added exceptions for all known host API errors.

0.7.0
++++++

Expand Down
1 change: 1 addition & 0 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ API Documentation
sftp_handle
pkey
listener
knownhost
exceptions
statinfo
fileinfo
7 changes: 7 additions & 0 deletions doc/knownhost.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ssh2.knownhost
===============

.. automodule:: ssh2.knownhost
:members:
:undoc-members:
:member-order: groupwise
58 changes: 58 additions & 0 deletions examples/example_host_key_verification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""Connect to localhost, verifying host by reading from ~/.ssh/known_hosts"""

from __future__ import print_function
import os
import socket

from ssh2.session import Session
from ssh2.session import LIBSSH2_HOSTKEY_HASH_SHA1, LIBSSH2_HOSTKEY_TYPE_RSA
from ssh2.knownhost import LIBSSH2_KNOWNHOST_TYPE_PLAIN, \
LIBSSH2_KNOWNHOST_KEYENC_RAW, LIBSSH2_KNOWNHOST_KEY_SSHRSA

# Connection settings
host = 'localhost'
user = os.getlogin()
known_hosts = os.sep.join([os.path.expanduser('~'), '.ssh', 'known_hosts'])

# Make socket, connect
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, 22))

# Initialise
session = Session()
session.handshake(sock)

host_key, key_type = session.hostkey()

server_key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA \
if key_type == LIBSSH2_HOSTKEY_TYPE_RSA \
else LIBSSH2_KNOWNHOST_KEY_SSHDSS

kh = session.knownhost_init()
_read_hosts = kh.readfile(known_hosts)
print("Read %s hosts from known hosts file at %s" % (_read_hosts, known_hosts))

# Verification
type_mask = LIBSSH2_KNOWNHOST_TYPE_PLAIN | \
LIBSSH2_KNOWNHOST_KEYENC_RAW | \
server_key_type
kh.checkp(host, 22, host_key, type_mask)
print("Host verification passed.")

# Verification passed, continue with authentication
session.agent_auth(user)

channel = session.open_session()
channel.execute('echo me')
channel.wait_eof()
channel.close()
channel.wait_closed()

# Get exit status
print("Exit status: %s" % channel.get_exit_status())

# Print output
size, data = channel.read()
while size > 0:
print(data)
size, data = channel.read()
37 changes: 35 additions & 2 deletions ssh2/c_ssh2.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ cdef extern from "libssh2.h" nogil:
LIBSSH2_CHANNEL_FLUSH_ALL
LIBSSH2_HOSTKEY_HASH_MD5
LIBSSH2_HOSTKEY_HASH_SHA1
LIBSSH2_HOSTKEY_TYPE_UNKNOWN
LIBSSH2_HOSTKEY_TYPE_RSA
LIBSSH2_HOSTKEY_TYPE_DSS

# ctypedef libssh2_uint64_t libssh2_struct_stat_size
ctypedef struct libssh2_struct_stat:
dev_t st_dev
Expand Down Expand Up @@ -336,8 +340,14 @@ cdef extern from "libssh2.h" nogil:
unsigned int *dest_len,
const char *src, unsigned int src_len)
const char *libssh2_version(int req_version_num)
ctypedef struct libssh2_knownhost:
pass

# Known host API
struct libssh2_knownhost:
unsigned int magic
void *node
char *name
char *key
int typemask
LIBSSH2_KNOWNHOSTS *libssh2_knownhost_init(LIBSSH2_SESSION *session)
int libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
const char *host,
Expand Down Expand Up @@ -377,6 +387,29 @@ cdef extern from "libssh2.h" nogil:
int libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts,
libssh2_knownhost **store,
libssh2_knownhost *prev)
enum:
LIBSSH2_KNOWNHOST_FILE_OPENSSH
LIBSSH2_KNOWNHOST_CHECK_MATCH
LIBSSH2_KNOWNHOST_CHECK_MISMATCH
LIBSSH2_KNOWNHOST_CHECK_NOTFOUND
LIBSSH2_KNOWNHOST_CHECK_FAILURE
LIBSSH2_KNOWNHOST_TYPE_MASK
LIBSSH2_KNOWNHOST_TYPE_PLAIN
LIBSSH2_KNOWNHOST_TYPE_SHA1
LIBSSH2_KNOWNHOST_TYPE_CUSTOM
LIBSSH2_KNOWNHOST_KEYENC_MASK
LIBSSH2_KNOWNHOST_KEYENC_RAW
LIBSSH2_KNOWNHOST_KEYENC_BASE64
LIBSSH2_KNOWNHOST_KEY_MASK
LIBSSH2_KNOWNHOST_KEY_SHIFT
LIBSSH2_KNOWNHOST_KEY_RSA1
LIBSSH2_KNOWNHOST_KEY_SSHRSA
LIBSSH2_KNOWNHOST_KEY_SSHDSS
IF EMBEDDED_LIB:
enum:
LIBSSH2_KNOWNHOST_KEY_UNKNOWN

# Public Key API
struct libssh2_agent_publickey:
unsigned int magic
void *node
Expand Down
Loading

0 comments on commit 99dcd6f

Please sign in to comment.