---
cmd/hissh-agent/main.ha | 68 +++++++++++++++++++++++++---------------
cmd/hissh-export/main.ha | 13 ++++----
cmd/hissh-import/main.ha | 43 ++++++++++++++-----------
3 files changed, 72 insertions(+), 52 deletions(-)
diff --git a/cmd/hissh-agent/main.ha b/cmd/hissh-agent/main.ha
index c2ce119..8ce0344 100644
--- a/cmd/hissh-agent/main.ha
+++ b/cmd/hissh-agent/main.ha
@@ -8,6 +8,7 @@ use errors;
use fmt;
use format::ssh;
use fs;
+use himitsu::client;
use himitsu::query;
use io;
use log;
@@ -106,15 +107,24 @@ fn serve(conn: net::socket) void = {
};
fn handle_req_ident(agent: *agent::agent) (void | agent::error | net::error) = {
- const himitsu = himitsu_connect()?;
- defer io::close(himitsu)!;
- fmt::fprintln(himitsu, "query proto=ssh")?;
+ const conn = match (client::connect()) {
+ case let conn: net::socket =>
+ yield conn;
+ case let err: client::error =>
+ log::printfln("Error connecting to Himitsu: {}",
+ client::strerror(err));
+ return;
+ };
+ defer net::close(conn)!;
+
+ // TODO: Use himitsu::client::query to send request
+ fmt::fprintln(conn, "query proto=ssh")?;
let idents: agent::identities_answer = [];
defer free(idents);
for (true) {
- let buf = match (bufio::scanline(himitsu)?) {
+ let buf = match (bufio::scanline(conn)?) {
case io::EOF =>
log::println("Unexpected EOF from Himitsu");
break;
@@ -158,7 +168,7 @@ fn handle_req_ident(agent: *agent::agent) (void | agent::error | net::error) = {
yield key;
case void =>
log::printfln("Invalid SSH key: {}",
- strings::fromutf8(buf));
+ strings::fromutf8(buf)!);
continue;
};
@@ -168,7 +178,7 @@ fn handle_req_ident(agent: *agent::agent) (void | agent::error | net::error) = {
yield key;
case errors::invalid =>
log::printfln("Invalid SSH key: {}",
- strings::fromutf8(buf));
+ strings::fromutf8(buf)!);
continue;
};
@@ -179,11 +189,12 @@ fn handle_req_ident(agent: *agent::agent) (void | agent::error | net::error) = {
yield "";
};
- let edkey = ssh::ed25519key { ... };
- edkey.pubkey[..] = pkey[..];
+ const src = bufio::fixed(pkey, io::mode::READ);
+ let edkey = ssh::newed25519key();
+ ssh::key_decoderawpub(edkey, &src)!;
const sink = bufio::dynamic(io::mode::WRITE);
- ssh::encode_pubkey(&sink, &edkey)!;
+ ssh::encode_pubkey(&sink, edkey)!;
append(idents, agent::identity {
pubkey = bufio::buffer(&sink),
@@ -206,31 +217,41 @@ fn handle_sign_request(
) (void | agent::error | net::error) = {
const source = bufio::fixed(msg.key, io::mode::READ);
const key = match (ssh::decodepublic(&source)) {
- case let key: ssh::key =>
+ case let key: *ssh::key =>
yield key;
case ssh::error =>
const answer: agent::message = agent::agent_failure;
agent::writemsg(agent, &answer)!;
return;
};
- defer bytes::zero(key.privkey);
+ defer ssh::key_free(key);
+ // TODO: Use himitsu::client::query to send request
let req = bufio::dynamic(io::mode::WRITE);
defer io::close(&req)!;
fmt::fprint(&req, "query -d proto=ssh pkey=")?;
- base64::encode(&req, &base64::std_encoding, key.pubkey)!;
+ let enc = base64::newencoder(&base64::std_encoding, &req);
+ ssh::key_encoderawpub(key, &enc)?;
+ io::close(&enc)!;
fmt::fprintln(&req)!;
- const himitsu = himitsu_connect()?;
- defer io::close(himitsu)!;
- io::writeall(himitsu, bufio::buffer(&req))?;
+ const conn = match (client::connect()) {
+ case let conn: net::socket =>
+ yield conn;
+ case let err: client::error =>
+ log::printfln("Error connecting to Himitsu: {}",
+ client::strerror(err));
+ return;
+ };
+ defer net::close(conn)!;
+ io::writeall(conn, bufio::buffer(&req))?;
let comment = "";
defer free(comment);
let found = false;
for (true) {
- let buf = match (bufio::scanline(himitsu)?) {
+ let buf = match (bufio::scanline(conn)?) {
case io::EOF =>
log::println("Unexpected EOF from Himitsu");
break;
@@ -267,7 +288,7 @@ fn handle_sign_request(
yield key;
case void =>
log::printfln("Invalid SSH key: {}",
- strings::fromutf8(buf));
+ strings::fromutf8(buf)!);
continue;
};
defer bytes::zero(strings::toutf8(b64skey));
@@ -278,7 +299,7 @@ fn handle_sign_request(
yield key;
case errors::invalid =>
log::printfln("Invalid SSH key: {}",
- strings::fromutf8(buf));
+ strings::fromutf8(buf)!);
continue;
};
defer bytes::zero(skey);
@@ -290,7 +311,8 @@ fn handle_sign_request(
yield "";
};
- key.privkey[..] = skey[..];
+ const src = bufio::fixed(skey, io::mode::READ);
+ ssh::key_decoderawpriv(key, &src)!;
found = true;
break;
};
@@ -304,7 +326,7 @@ fn handle_sign_request(
let buf = bufio::dynamic(io::mode::WRITE);
defer io::close(&buf)!;
- ssh::sign(&buf, &key, msg.data)!;
+ ssh::sign(&buf, key, msg.data)!;
const answer: agent::message = agent::sign_response {
signature = bufio::buffer(&buf),
@@ -313,12 +335,6 @@ fn handle_sign_request(
log::printfln("Signed challenge with key {}", comment);
};
-fn himitsu_connect() (net::socket | net::error) = {
- let path = path::init();
- const sockpath = path::set(&path, dirs::runtime()!, "himitsu")!;
- return unix::connect(sockpath);
-};
-
// XXX: This really belongs in the himitsu library
// https://todo.sr.ht/~sircmpwn/himitsu/24
fn getkey(q: *query::query, name: str) (str | void) = {
diff --git a/cmd/hissh-export/main.ha b/cmd/hissh-export/main.ha
index 5f8b9fd..70f6cd7 100644
--- a/cmd/hissh-export/main.ha
+++ b/cmd/hissh-export/main.ha
@@ -84,19 +84,18 @@ fn encode(key: *query::query) void = {
const key = switch (keytype.value) {
case "ssh-ed25519" =>
- let key = ssh::ed25519key {
- comment = comment,
- ...
- };
- // XXX: We could validate the length here
- key.pubkey[..] = pkey[..];
+ let key = ssh::newed25519key();
+ key.comment = comment;
+ // TODO: Handle decode error gracefully
+ const src = bufio::fixed(pkey, io::mode::READ);
+ ssh::key_decoderawpub(key, &src)!;
yield key;
case =>
fmt::errorfln("Skipping unsupported key type {}", keytype)!;
return;
};
- ssh::encode_pubkeystr(os::stdout, &key)!;
+ ssh::encode_pubkeystr(os::stdout, key)!;
fmt::println()!;
};
diff --git a/cmd/hissh-import/main.ha b/cmd/hissh-import/main.ha
index ff384a5..5317aad 100644
--- a/cmd/hissh-import/main.ha
+++ b/cmd/hissh-import/main.ha
@@ -5,6 +5,7 @@ use encoding::base64;
use fmt;
use format::ssh;
use getopt;
+use himitsu::client;
use io;
use net::unix;
use net;
@@ -14,49 +15,53 @@ use shlex;
use unix::tty;
export fn main() void = {
- const key = match (ssh::decodesshprivate(os::stdin)) {
+ const privkey = match (ssh::decodesshprivate(os::stdin)) {
case let key: ssh::sshprivkey =>
yield key;
case let err: ssh::error =>
fmt::fatal("Error loading key:", ssh::strerror(err));
};
- if (ssh::isencrypted(&key)) {
- decrypt(&key);
+ if (ssh::isencrypted(&privkey)) {
+ decrypt(&privkey);
};
- const privkey = match (ssh::decodeprivate(&key)) {
- case let key: ssh::key =>
+ const key = match (ssh::decodeprivate(&privkey)) {
+ case let key: *ssh::key =>
yield key;
case let err: ssh::error =>
fmt::fatal("Error decoding private key:", ssh::strerror(err));
};
+ defer ssh::key_free(key);
// TODO: Support more key types
+ // TODO: Use himitsu::client::query to send request
let buf = bufio::dynamic(io::mode::WRITE);
defer io::close(&buf)!;
fmt::fprint(&buf, "add proto=ssh type=ssh-ed25519 pkey='")!;
- base64::encode(&buf, &base64::std_encoding, privkey.pubkey)!;
+ let enc = base64::newencoder(&base64::std_encoding, &buf);
+ ssh::key_encoderawpub(key, &enc)!;
+ io::close(&enc)!;
fmt::fprint(&buf, "' skey!='")!;
- base64::encode(&buf, &base64::std_encoding, privkey.privkey)!;
+ let enc = base64::newencoder(&base64::std_encoding, &buf);
+ ssh::key_encoderawpriv(key, &enc)!;
+ io::close(&enc)!;
fmt::fprint(&buf, "'")!;
- if (privkey.comment != "") {
+ let comment = ssh::key_comment(key);
+ if (comment != "") {
fmt::fprint(&buf, " comment=")!;
- shlex::quote(&buf, privkey.comment)!;
+ shlex::quote(&buf, comment)!;
};
fmt::fprintln(&buf)!;
- // TODO: It would be nice if himitsu (library) provided some tools for
- // connecting to and interacting with a Himitsu socket
- let path = path::init();
- const sockpath = path::set(&path, dirs::runtime()!, "himitsu")!;
- let conn = match (unix::connect(sockpath)) {
- case let s: net::socket =>
- yield s;
- case let e: net::error =>
- fmt::fatal("Error connecting to Himitsu:", net::strerror(e));
+ const conn = match (client::connect()) {
+ case let conn: net::socket =>
+ yield conn;
+ case let err: client::error =>
+ fmt::fatal("Error connecting to Himitsu:",
+ client::strerror(err));
};
- defer io::close(conn)!;
+ defer net::close(conn)!;
io::writeall(conn, bufio::buffer(&buf))!;
base-commit: 261519ad42384ce19f02d95c9c1eb1371441c301
--
2.39.1