ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
ssh_auth.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file ssh_auth.h
6 * @brief SSH user-authentication layer (RFC 4252).
7 *
8 * After NEWKEYS the client requests the "ssh-userauth" service; the server
9 * accepts it and then drives SSH_MSG_USERAUTH_REQUEST exchanges until a method
10 * succeeds (SSH_MSG_USERAUTH_SUCCESS) or the connection is dropped.
11 *
12 * This implementation supports the "password" method (RFC 4252 §8): the
13 * password travels inside the encrypted transport and is checked against an
14 * application-supplied callback. The "none" method is always answered with a
15 * failure that advertises "password" (RFC 4252 §5.2), which is how a client
16 * discovers the supported methods.
17 *
18 * @author Douglas Quigg (dstroy0)
19 * @date 2026
20 */
21
22#ifndef PROTOCORE_SSH_AUTH_H
23#define PROTOCORE_SSH_AUTH_H
24
25#include "protocore_config.h"
26#include <stddef.h>
27#include <stdint.h>
28
29/** @brief Parsed SSH_MSG_USERAUTH_REQUEST. */
31{
32 char user[SSH_AUTH_USER_MAX]; ///< User name, null-terminated.
33 char service[32]; ///< Requested service ("ssh-connection").
34 char method[24]; ///< Method name ("none", "password", "publickey", "keyboard-interactive").
35 char password[SSH_AUTH_PASS_MAX]; ///< Password (method == "password").
36 bool is_password; ///< True if a password method-request was parsed.
37 bool is_kbdint; ///< True if a keyboard-interactive method-request was parsed (RFC 4256).
38
39 // publickey method (RFC 4252 §7)
40 bool is_pubkey; ///< True if a publickey method-request was parsed.
41 bool has_signature; ///< True if the request carried a signature.
42 char pk_algo[20]; ///< Public-key algorithm name.
43 const uint8_t *pk_blob; ///< Public-key blob (points into the payload).
44 uint32_t pk_blob_len; ///< Length of pk_blob.
45 const uint8_t *signature; ///< Raw signature bytes (points into the payload).
46 uint32_t signature_len; ///< Length of signature.
47 const uint8_t *signed_prefix; ///< Bytes of the request that the signature covers.
48 size_t signed_prefix_len; ///< Length of signed_prefix (payload up to the signature).
49};
50
51/**
52 * @brief Application callback that validates a username/password pair.
53 * @return true to accept the credentials.
54 */
55typedef bool (*SshPasswordCb)(const char *user, const char *password);
56
57/** @brief Install the password-verification callback (nullptr → all fail). */
59
60/**
61 * @brief Application callback that decides whether a public key is authorized
62 * for @p user. @p blob is the "ssh-rsa" public-key blob.
63 * @return true if the key may authenticate this user.
64 */
65typedef bool (*SshPubkeyCb)(const char *user, const uint8_t *blob, size_t blob_len);
66
67/** @brief Install the publickey-authorization callback (nullptr → all fail). */
69
70/**
71 * @brief Handle SSH_MSG_SERVICE_REQUEST; emit SERVICE_ACCEPT for ssh-userauth.
72 * @return 0 and writes SERVICE_ACCEPT to @p out, or -1 if the service is not
73 * "ssh-userauth" or the message is malformed.
74 */
75int pc_ssh_auth_handle_service_request(const uint8_t *payload, size_t len, uint8_t *out, size_t *out_len, size_t cap);
76
77/**
78 * @brief Parse an SSH_MSG_USERAUTH_REQUEST into @p req.
79 * @return 0 on success, -1 if malformed.
80 */
81int pc_ssh_auth_parse_request(const uint8_t *payload, size_t len, SshAuthReq *req);
82
83/** @brief Build SSH_MSG_USERAUTH_FAILURE advertising "password". */
84int pc_ssh_auth_build_failure(uint8_t *out, size_t *out_len, size_t cap, bool partial);
85
86/** @brief Build SSH_MSG_USERAUTH_SUCCESS. */
87int pc_ssh_auth_build_success(uint8_t *out, size_t *out_len, size_t cap);
88
89/**
90 * @brief Handle a USERAUTH_REQUEST end-to-end for slot @p i.
91 *
92 * Parses the request, checks "password" credentials via the installed callback,
93 * and writes either USERAUTH_SUCCESS or USERAUTH_FAILURE to @p out. On success
94 * the session is marked authenticated and advanced to the connection phase.
95 *
96 * @return 0 if a response was produced (check the message type), -1 on parse
97 * error.
98 */
99int pc_ssh_auth_handle_request(uint8_t i, const uint8_t *payload, size_t len, uint8_t *out, size_t *out_len,
100 size_t cap);
101
102#if PC_ENABLE_SSH_KEYBOARD_INTERACTIVE
103/**
104 * @brief Handle an SSH_MSG_USERAUTH_INFO_RESPONSE (RFC 4256 §3.4) for slot @p i.
105 *
106 * The response to the single "Password:" prompt this server sends is verified through the installed
107 * password callback (keyboard-interactive is the challenge-response face of password auth here). Writes
108 * USERAUTH_SUCCESS or USERAUTH_FAILURE to @p out. Only valid while a keyboard-interactive exchange is
109 * pending for the slot (a prior USERAUTH_REQUEST selected it); otherwise fails.
110 *
111 * @return 0 if a response was produced (check the message type), -1 on parse error / no exchange pending.
112 */
113int pc_ssh_auth_handle_info_response(uint8_t i, const uint8_t *payload, size_t len, uint8_t *out, size_t *out_len,
114 size_t cap);
115#endif
116
117#endif // PROTOCORE_SSH_AUTH_H
User-facing configuration for ProtoCore.
#define SSH_AUTH_PASS_MAX
Max stored password length.
#define SSH_AUTH_USER_MAX
Max stored user name (RFC 4252 imposes no limit; we cap for BSS).
void pc_ssh_auth_set_pubkey_cb(SshPubkeyCb cb)
Install the publickey-authorization callback (nullptr → all fail).
Definition ssh_auth.cpp:48
int pc_ssh_auth_build_failure(uint8_t *out, size_t *out_len, size_t cap, bool partial)
Build SSH_MSG_USERAUTH_FAILURE advertising "password".
Definition ssh_auth.cpp:389
bool(* SshPasswordCb)(const char *user, const char *password)
Application callback that validates a username/password pair.
Definition ssh_auth.h:55
int pc_ssh_auth_build_success(uint8_t *out, size_t *out_len, size_t cap)
Build SSH_MSG_USERAUTH_SUCCESS.
Definition ssh_auth.cpp:414
void pc_ssh_auth_set_password_cb(SshPasswordCb cb)
Install the password-verification callback (nullptr → all fail).
Definition ssh_auth.cpp:43
int pc_ssh_auth_parse_request(const uint8_t *payload, size_t len, SshAuthReq *req)
Parse an SSH_MSG_USERAUTH_REQUEST into req.
Definition ssh_auth.cpp:294
bool(* SshPubkeyCb)(const char *user, const uint8_t *blob, size_t blob_len)
Application callback that decides whether a public key is authorized for user. blob is the "ssh-rsa" ...
Definition ssh_auth.h:65
int pc_ssh_auth_handle_service_request(const uint8_t *payload, size_t len, uint8_t *out, size_t *out_len, size_t cap)
Handle SSH_MSG_SERVICE_REQUEST; emit SERVICE_ACCEPT for ssh-userauth.
Definition ssh_auth.cpp:258
int pc_ssh_auth_handle_request(uint8_t i, const uint8_t *payload, size_t len, uint8_t *out, size_t *out_len, size_t cap)
Handle a USERAUTH_REQUEST end-to-end for slot i.
Definition ssh_auth.cpp:583
Parsed SSH_MSG_USERAUTH_REQUEST.
Definition ssh_auth.h:31
char method[24]
Method name ("none", "password", "publickey", "keyboard-interactive").
Definition ssh_auth.h:34
const uint8_t * signature
Raw signature bytes (points into the payload).
Definition ssh_auth.h:45
bool is_pubkey
True if a publickey method-request was parsed.
Definition ssh_auth.h:40
char pk_algo[20]
Public-key algorithm name.
Definition ssh_auth.h:42
bool is_password
True if a password method-request was parsed.
Definition ssh_auth.h:36
char password[SSH_AUTH_PASS_MAX]
Password (method == "password").
Definition ssh_auth.h:35
char user[SSH_AUTH_USER_MAX]
User name, null-terminated.
Definition ssh_auth.h:32
uint32_t pk_blob_len
Length of pk_blob.
Definition ssh_auth.h:44
char service[32]
Requested service ("ssh-connection").
Definition ssh_auth.h:33
bool is_kbdint
True if a keyboard-interactive method-request was parsed (RFC 4256).
Definition ssh_auth.h:37
size_t signed_prefix_len
Length of signed_prefix (payload up to the signature).
Definition ssh_auth.h:48
const uint8_t * pk_blob
Public-key blob (points into the payload).
Definition ssh_auth.h:43
const uint8_t * signed_prefix
Bytes of the request that the signature covers.
Definition ssh_auth.h:47
uint32_t signature_len
Length of signature.
Definition ssh_auth.h:46
bool has_signature
True if the request carried a signature.
Definition ssh_auth.h:41