Rust SSH认证代理库pageant的使用,pageant为Windows平台提供SSH密钥管理和身份验证功能

Rust SSH认证代理库pageant的使用,pageant为Windows平台提供SSH密钥管理和身份验证功能

安装

在项目目录中运行以下Cargo命令:

cargo add pageant

或者在Cargo.toml中添加以下行:

pageant = "0.0.3"

基本使用

pageant是一个为Windows平台提供SSH密钥管理和身份验证功能的Rust库。它允许Rust程序与Windows的Pageant SSH认证代理进行交互。

示例代码

use pageant::PageantClient;
use std::io;

fn main() -> io::Result<()> {
    // 创建Pageant客户端
    let mut client = PageantClient::new()?;
    
    // 获取Pageant中的密钥列表
    let identities = client.list_identities()?;
    println!("Available SSH identities:");
    for (i, identity) in identities.iter().enumerate() {
        println!("{}. {}", i + 1, identity.comment);
    }
    
    // 使用第一个密钥进行签名
    if !identities.is_empty() {
        let data = b"test data to sign";
        let signature = client.sign(&identities[0], data)?;
        println!("Signature: {:?}", signature);
    }
    
    Ok(())
}

代码说明

  1. PageantClient::new() - 创建一个新的Pageant客户端连接
  2. list_identities() - 获取Pageant中可用的SSH密钥列表
  3. sign() - 使用指定的密钥对数据进行签名

完整示例

use pageant::{PageantClient, Identity};
use std::io;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    // 初始化Pageant客户端
    let mut client = PageantClient::new()?;
    println!("Successfully connected to Pageant");
    
    // 列出所有可用身份
    let identities = client.list_identities()?;
    if identities.is_empty() {
        println!("No SSH identities found in Pageant");
        return Ok(());
    }
    
    // 打印所有可用密钥
    println!("Available SSH identities in Pageant:");
    for (index, identity) in identities.iter().enumerate() {
        println!("{}. {} ({} bits)", 
            index + 1, 
            identity.comment,
            identity.key_type.key_bits()
        );
    }
    
    // 选择第一个身份进行签名
    let selected_identity = &identities[0];
    println!("\nSelected identity: {}", selected_identity.comment);
    
    // 准备要签名的数据
    let data_to_sign = b"Important data that needs to be signed";
    println!("Data to sign: {:?}", data_to_sign);
    
    // 执行签名
    let signature = client.sign(selected_identity, data_to_sign)?;
    println!("Signature length: {} bytes", signature.len());
    println!("Signature data (first 16 bytes): {:?}", &signature[..16]);
    
    // 验证签名是否有效
    if !signature.is_empty() {
        println!("\nSignature successful!");
    } else {
        println!("\nSignature failed!");
    }
    
    Ok(())
}

特性

  • 与Windows Pageant代理无缝集成
  • 支持列出可用的SSH密钥
  • 支持使用密钥进行签名操作
  • 简单的API设计

依赖信息

  • 最新版本: 0.0.3
  • 许可证: Apache-2.0
  • 支持Rust版本: v1.75.0及以上

1 回复

Rust SSH认证代理库pageant的使用指南

概述

pageant是一个Rust库,专门为Windows平台提供SSH密钥管理和身份验证功能。它实现了与PuTTY的Pageant兼容的SSH认证代理协议,允许Rust程序与Pageant守护进程交互,使用存储在Pageant中的SSH密钥进行身份验证。

主要功能

  • 与Windows Pageant守护进程通信
  • 查询Pageant中可用的SSH密钥
  • 使用Pageant中的密钥进行SSH身份验证
  • 支持添加和删除Pageant中的密钥

安装方法

在Cargo.toml中添加依赖:

[dependencies]
pageant = "0.1"

基本使用方法

1. 检查Pageant是否运行

use pageant;

fn main() {
    if pageant::is_pageant_running() {
        println!("Pageant is running");
    } else {
        println!("Pageant is not running");
    }
}

2. 获取Pageant中的密钥列表

use pageant;

fn main() {
    if let Ok(keys) = pageant::list_keys() {
        println!("Found {} keys in Pageant:", keys.len());
        for (i, key) in keys.iter().enumerate() {
            println!("Key #{}: {}", i + 1, key.comment);
        }
    } else {
        eprintln!("Failed to list keys from Pageant");
    }
}

3. 使用Pageant进行SSH身份验证

use pageant;
use ssh2::Session;

fn authenticate_with_pageant(session: &mut Session) -> Result<(), ssh2::Error> {
    let keys = pageant::list_keys().map_err(|_| ssh2::Error::from_errno(ssh2::ErrorCode::PUBLICKEY_UNVERIFIED))?;
    
    for key in keys {
        if session.userauth_agent("username", &key).is_ok() {
            return Ok(());
        }
    }
    
    Err(ssh2::Error::from_errno(ssh2::ErrorCode::PUBLICKEY_UNVERIFIED))
}

fn main() {
    let mut session = Session::new().unwrap();
    session.set_tcp_stream(tcp_stream);
    session.handshake().unwrap();
    
    if authenticate_with_pageant(&mut session).is_ok() {
        println!("Authentication successful!");
    } else {
        println!("Authentication failed");
    }
}

4. 向Pageant添加密钥

use pageant;
use ssh_key::PrivateKey;

fn add_key_to_pageant(key_path: &str) -> Result<(), Box<dyn std::error::Error>> {
    let key_data = std::fs::read(key_path)?;
    let private_key = PrivateKey::from_openssh(&key_data)?;
    
    pageant::add_key(&private_key.key_data(), "my-key-comment")?;
    Ok(())
}

高级用法

自定义连接超时

use pageant;
use std::time::Duration;

fn main() {
    let timeout = Duration::from_secs(5);
    let keys = pageant::list_keys_with_timeout(timeout).unwrap();
    // 处理密钥...
}

处理Pageant错误

use pageant;

fn handle_pageant_errors() {
    match pageant::list_keys() {
        Ok(keys) => println!("Got {} keys", keys.len()),
        Err(pageant::Error::PageantNotRunning) => eprintln!("Pageant is not running"),
        Err(pageant::Error::ConnectionFailed) => eprintln!("Failed to connect to Pageant"),
        Err(pageant::Error::ProtocolError) => eprintln!("Protocol error communicating with Pageant"),
        Err(_) => eprintln!("Unknown error"),
    }
}

注意事项

  1. 该库仅在Windows平台上有效,在其他平台上调用会返回错误
  2. 需要确保Pageant守护进程正在运行
  3. 对于生产环境,建议添加适当的错误处理和日志记录
  4. 密钥操作可能需要管理员权限

与SSH库集成

pageant库可以与ssh2thrussh等SSH库配合使用,为这些库提供身份验证后端。上面的示例已经展示了如何与ssh2库集成。

下面是一个完整的示例demo,展示如何使用pageant库进行SSH身份验证:

use pageant;
use ssh2::Session;
use std::net::TcpStream;
use std::error::Error;

// 检查Pageant是否运行并列出所有密钥
fn list_pageant_keys() -> Result<(), Box<dyn Error>> {
    if !pageant::is_pageant_running() {
        return Err("Pageant is not running".into());
    }

    let keys = pageant::list_keys()?;
    println!("Available SSH keys in Pageant:");
    for (i, key) in keys.iter().enumerate() {
        println!("{}. {}", i + 1, key.comment);
    }
    Ok(())
}

// 使用Pageant进行SSH身份验证
fn ssh_connect_with_pageant(host: &str, port: u16, username: &str) -> Result<(), Box<dyn Error>> {
    // 建立TCP连接
    let tcp = TcpStream::connect((host, port))?;
    
    // 创建SSH会话
    let mut sess = Session::new()?;
    sess.set_tcp_stream(tcp);
    sess.handshake()?;
    
    // 从Pageant获取密钥列表
    let keys = pageant::list_keys()?;
    
    // 尝试使用每个密钥进行身份验证
    for key in keys {
        if sess.userauth_agent(username, &key).is_ok() {
            println!("Successfully authenticated using key: {}", key.comment);
            return Ok(());
        }
    }
    
    Err("Authentication failed with all keys".into())
}

fn main() -> Result<(), Box<dyn Error>> {
    // 1. 检查Pageant状态
    list_pageant_keys()?;
    
    // 2. 使用Pageant进行SSH连接
    let host = "example.com";
    let port = 22;
    let username = "user";
    
    match ssh_connect_with_pageant(host, port, username) {
        Ok(_) => println!("SSH connection successful!"),
        Err(e) => eprintln!("SSH connection failed: {}", e),
    }
    
    Ok(())
}

这个完整示例展示了:

  1. 检查Pageant是否运行
  2. 列出Pageant中可用的SSH密钥
  3. 建立SSH连接并使用Pageant中的密钥进行身份验证
  4. 处理可能出现的错误

要运行此示例,你需要确保:

  1. Windows上已运行Pageant并加载了SSH密钥
  2. 添加了ssh2pageant依赖到Cargo.toml
  3. 替换示例中的主机、端口和用户名为你自己的SSH服务器信息
回到顶部