
Research
Security News
The Landscape of Malicious Open Source Packages: 2025 Mid‑Year Threat Report
A look at the top trends in how threat actors are weaponizing open source packages to deliver malware and persist across the software supply chain.
A high-performance SSH and SFTP client for network automation, built with LibSSH2 and OpenSSL. Inspired by Paramiko. Focused on performance and non-blocking operations.
Jimiko similar high-performance C++ implementation bundled in python:
# No prerequisites required
pip install jimiko
Platform Compatibility:
Python Version | Required OpenSSL | Linux Support | macOS Support |
---|---|---|---|
Python 3.9-3.11 | OpenSSL 1.1.1 | ✅ | ❌ |
Python 3.12+ | OpenSSL 3.0+ | ✅ | ✅ |
Parameter | Type | Default | Description |
---|---|---|---|
ip | string | required | IP address or hostname of the SSH server |
username | string | "" | Username for authentication |
password | string | "" | Password for authentication |
prompt | string | "" | Expected prompt pattern (regex) |
auth | bool | False | Whether to authenticate (set to True for regular SSH) |
port | int | 22 | SSH server port |
command_timeout_ms | int | 2000 | Timeout for command execution in milliseconds |
read_timeout_ms | int | 2000 | Timeout for reading responses in milliseconds |
pty_type | string | "vt100" | Terminal type to use for PTY requests |
use_pty | bool | True | Whether to request PTY allocation |
Method | Parameters | Return | Description |
---|---|---|---|
connect() | None | bool | Establishes connection to the server |
disconnect() | None | None | Closes the connection |
send(command, command_timeout_ms, read_timeout_ms, prompt) | string, uint32, uint32, string | string | Sends a command and returns output |
get_initial_output(timeout_ms) | uint32 | string | Captures initial banner output |
When using shell connections, the SSH client uses a PTY (Pseudo Terminal). The available terminal types include:
Different network devices may require different terminal types for optimal compatibility.
Default "vt100"
Parameter | Type | Default | Description |
---|---|---|---|
ip | string | Required | IP address or hostname of the remote server |
username | string | Required | Username for authentication |
password | string | Required | Password for authentication |
port | int | 22 | SSH port number |
operation_timeout_ms | uint32 | 30000 | Operation timeout in milliseconds |
Method | Parameters | Return | Description |
---|---|---|---|
connect() | None | bool | Establishes SFTP connection |
disconnect() | None | None | Closes the connection |
put(local_path, remote_path, mode) | string, string, int | bool | Uploads file to remote server |
get(remote_path, local_path) | string, string | bool | Downloads file from remote server |
list_dir(path) | string | vector | Lists directory contents |
file_exists(path) | string | bool | Checks if file exists |
file_info(path) | string | SFTPFileInfo | Gets file information |
make_dir(path, mode) | string, int | bool | Creates a directory |
remove_file(path) | string | bool | Deletes a file |
remove_dir(path) | string | bool | Removes a directory |
rename(old_path, new_path) | string, string | bool | Renames a file or directory |
from jimiko import PyJimikoClient
# Create SSH client with authentication
client = PyJimikoClient(
ip="192.168.1.1",
username="admin",
password="password123",
prompt="#", # Expected prompt
auth=True, # Enable authentication
port=22,
command_timeout_ms=5000, # 5 second timeout
read_timeout_ms=2000, # 2 second read timeout
pty_type="vt100"
)
# Connect to device
if client.connect():
# Basic command - uses the default prompt
result = client.send("show version")
print(result)
# Configure command with custom prompt
config_result = client.send("configure terminal", prompt="\\(config\\)#")
interface_result = client.send("interface GigabitEthernet0/1", prompt="\\(config-if\\)#")
# Return to enable mode
client.send("end", prompt="#")
# Command with longer timeout
result = client.send("show tech-support", command_timeout_ms=60000)
print(result)
# Disconnect when done
client.disconnect()
from jimiko import PyJimikoClient
# Create SSH client without authentication (for legacy devices)
client = PyJimikoClient(
ip="192.168.1.2",
auth=False,
port=22,
pty_type="vt100" # Using vt100 terminal type
)
# Connect to device
if client.connect():
# Get initial banner/login prompt
initial_output = client.get_initial_output(timeout_ms=5000)
print(initial_output)
# Send login credentials
if "login:" in initial_output:
result = client.send("admin")
result = client.send("password123")
# Now send commands as normal
result = client.send("rtrv-hdr:::;")
print(result)
# Disconnect when done
client.disconnect()
from jimiko import PyJimikoSFTPClient
import os
# Create SFTP client
sftp = PyJimikoSFTPClient(
ip="127.0.0.1",
username="admin",
password="password123",
port=22,
operation_timeout_ms=30000 # 30 second timeout
)
# Connect to server
if sftp.connect():
# Upload a file (with mode 0644)
sftp.put("local_file.txt", "/remote/path/file.txt", 0o644)
# Download a file
sftp.get("/remote/path/file.txt", "downloaded_file.txt")
# List directory contents
files = sftp.list_dir("/remote/path")
for file_info in files:
print(f"Name: {file_info.name}, Size: {file_info.size} bytes")
# Check if file exists
if sftp.file_exists("/remote/path/file.txt"):
# Get file info
info = sftp.file_info("/remote/path/file.txt")
print(f"File size: {info.size}, Modified: {info.mtime}")
# Create directory
sftp.make_dir("/remote/path/new_dir", 0o755)
# Rename file
sftp.rename("/remote/path/file.txt", "/remote/path/new_file.txt")
# Delete file
sftp.remove_file("/remote/path/new_file.txt")
# Remove directory
sftp.remove_dir("/remote/path/new_dir")
# Disconnect when done
sftp.disconnect()
git clone https://github.com/jameshill/jimiko.git
cd jimiko
pip install -r requirements-dev.txt
python setup.py build_ext --inplace
# Using vcpkg
vcpkg install libssh2:x64-windows openssl:x64-windows
# Using Homebrew
brew install libssh2 openssl@3
sudo apt-get install libssh2-1-dev libssl-dev
sudo yum install libssh2-devel openssl-devel
# Set VCPKG_ROOT environment variable
# See github workflow
set VCPKG_ROOT=C:\vcpkg\installed\x64-windows
python setup.py build
This section describes how to build Jimiko using Docker containers for maximum compatibility across Linux distributions.
Different Python versions require specific OpenSSL versions for compatibility:
Python Version | Required OpenSSL | Build Script |
---|---|---|
Python 3.8.x, 3.9.x, 3.10.x, 3.11.x | OpenSSL 1.1.1 | build_ssl111.sh |
Python 3.12.x, 3.13.x | OpenSSL 3.0 | build_ssl300.sh |
The build system automatically uses the appropriate OpenSSL version based on the Python version being built.
Jimiko uses a hybrid approach for library dependencies:
This approach ensures that:
The easiest way to build Jimiko for all supported Python versions is to use the sequential build script:
# From the project root directory
./docker/manylinux/build_sequential.sh
This script:
output/jimiko_py{version}/
build_summary.txt
To build for a specific Python version only:
# Build only for Python 3.8.20
./docker/manylinux/build_sequential.sh 3.8.20
The build process is managed by several scripts:
build_sequential.sh
: Main entry point that orchestrates the entire build processbuild_ssl102.sh
: Builds Jimiko for Python 3.6-3.7 with OpenSSL 1.0.2build_ssl111.sh
: Builds Jimiko for Python 3.8-3.11 with OpenSSL 1.1.1build_ssl300.sh
: Builds Jimiko for Python 3.12-3.13 with OpenSSL 3.0build.sh
: The core build script that runs inside the Docker containerFor macOS, use the included build script:
# Build for latest Python versions installed via pyenv
./build_macos.sh
Important Note: The bundled macOS version only supports Python 3.12 and 3.13. This is because these Python versions require OpenSSL 3.0, which is bundled with the wheel. For older Python versions on macOS, users will need to install the appropriate system dependencies (via Homebrew) and build from source.
The macOS build uses the system's dynamic linker with @rpath to find bundled libraries, similar to the Linux approach.
If you need to customize the build process:
docker/manylinux/Dockerfile_*
for container configurationbuild.sh
script for changes to the build process inside the containerbuild.sh
match the actual paths in the container.The build process creates several artifacts:
dist/
directorydist/
)src/jimiko/
named _jimiko_wrapper.cpython-<python-version>-manylinux2014_x86_64.so
The extracted binary file is used when creating a universal wheel that includes binaries for multiple platforms.
Disable PTY allocation:
# Connect to device without PTY allocation
client = PyJimikoClient(
ip="192.168.1.1",
username="admin",
password="password123",
prompt="#",
use_pty=False # Skip PTY allocation entirely
)
Adjust timeouts:
client = PyJimikoClient(
ip="192.168.1.1",
username="admin",
password="password123",
prompt="#",
command_timeout_ms=60000, # 60 seconds
read_timeout_ms=30000 # 30 seconds
)
Disable pagination on devices:
client.connect()
client.send("terminal length 0")
Try different terminal types if PTY is required:
client = PyJimikoClient(
ip="192.168.1.1",
username="admin",
password="password123",
prompt="#",
pty_type="vanilla" # Try alternative terminal types
)
By default, the SSH client uses the prompt pattern specified during initialization to detect when a command has completed. However, for specific commands, you can override this behavior:
Default prompt handling: The prompt pattern from the constructor is used to detect command completion:
client = PyJimikoClient(
ip="192.168.1.1",
username="admin",
password="password123",
prompt="#", # This will be used for all commands by default
)
Per-command prompt override: For special commands that have different output patterns, you can specify a command-specific prompt:
# Use the default prompt
result = client.send("show version")
# Use a custom prompt for a specific command
result = client.send("configure terminal", prompt="\\(config\\)#")
# Use a specific prompt for a yes/no prompt
result = client.send("reload", prompt="\\[yes/no\\]")
Prompt matching: Both default and override prompts support:
MIT License
FAQs
High-performance SSH and SFTP client for network automation
We found that jimiko demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A look at the top trends in how threat actors are weaponizing open source packages to deliver malware and persist across the software supply chain.
Security News
ESLint now supports HTML linting with 48 new rules, expanding its language plugin system to cover more of the modern web development stack.
Security News
CISA is discontinuing official RSS support for KEV and cybersecurity alerts, shifting updates to email and social media, disrupting automation workflows.