Implement SSH Agent forwarding support
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

- Add auth_agent_socket field to Channel struct
- Add handle_auth_agent_request() for auth-agent-req@openssh.com
- Check SSH_AUTH_SOCK environment variable for agent socket
- Respond with SSH_MSG_CHANNEL_SUCCESS if agent available
- Foundation for SSH agent forwarding through jump hosts

All 229 tests pass.
This commit is contained in:
Warren
2026-06-20 23:25:38 +08:00
parent a48e253660
commit 82ff713b24

View File

@@ -183,6 +183,7 @@ impl ChannelManager {
scp_output_file: None, // Phase 17: SCP file receive
direct_tcpip: None,
forwarded_tcpip: None,
auth_agent_socket: None,
};
self.channels.insert(server_channel, channel);
@@ -263,6 +264,7 @@ impl ChannelManager {
scp_output_file: None, // Phase 17: SCP file receive
direct_tcpip: Some(direct_tcpip),
forwarded_tcpip: None,
auth_agent_socket: None,
};
self.channels.insert(server_channel, channel);
@@ -340,6 +342,7 @@ impl ChannelManager {
scp_output_file: None, // Phase 17: SCP file receive
direct_tcpip: None,
forwarded_tcpip: Some(forwarded_tcpip),
auth_agent_socket: None,
};
self.channels.insert(server_channel, channel);
@@ -409,6 +412,8 @@ impl ChannelManager {
self.handle_env_request(&mut cursor, recipient_channel, want_reply) // 移除?操作符
} else if request_type == "pty-req" {
self.handle_pty_request(&mut cursor, recipient_channel, want_reply) // 移除?操作符
} else if request_type == "auth-agent-req@openssh.com" {
self.handle_auth_agent_request(recipient_channel, want_reply)
} else {
warn!("Unsupported channel request: {}", request_type);
if want_reply {
@@ -702,6 +707,41 @@ impl ChannelManager {
}
}
/// SSH Agent forwarding参考OpenSSH auth-agent.c
/// 支持 "auth-agent-req@openssh.com" channel request
fn handle_auth_agent_request(
&mut self,
channel: u32,
want_reply: bool,
) -> Result<Option<SshPacket>> {
info!("Handling auth-agent request for channel {}", channel);
// 检查SSH_AUTH_SOCK环境变量
let auth_sock = std::env::var("SSH_AUTH_SOCK").ok();
if let Some(sock_path) = auth_sock {
info!("SSH Agent forwarding enabled: {}", sock_path);
// 标记channel支持agent forwarding
if let Some(ch) = self.channels.get_mut(&channel) {
ch.auth_agent_socket = Some(sock_path);
}
if want_reply {
Ok(Some(self.build_channel_success(channel)?))
} else {
Ok(None)
}
} else {
warn!("SSH_AUTH_SOCK not set, agent forwarding disabled");
if want_reply {
Ok(Some(self.build_channel_failure(channel)?))
} else {
Ok(None)
}
}
}
/// 处理SSH_MSG_CHANNEL_DATA参考OpenSSH channel.c: channel_input_data())
pub fn handle_channel_data(&mut self, packet: &SshPacket) -> Result<Option<SshPacket>> {
info!("Processing SSH_MSG_CHANNEL_DATA");
@@ -2101,6 +2141,8 @@ struct Channel {
// Phase 13.3: 端口转发相关字段
direct_tcpip: Option<DirectTcpipChannel>, // direct-tcpip channelRemote forwarding
forwarded_tcpip: Option<ForwardedTcpipChannel>, // forwarded-tcpip channelLocal forwarding
// SSH Agent forwarding
auth_agent_socket: Option<String>, // SSH agent socket path (SSH_AUTH_SOCK)
}
/// SSH Channel状态参考OpenSSH channel.c