mirror of
https://github.com/tmate-io/tmate-ssh-server.git
synced 2020-11-18 19:53:51 -08:00
Allow connections based on authorized_keys file.
When run with option `-a /path/to/authorized_keys`, tmate-slave will only authenticate public keys present in the file `/path/to/authorized_keys`. The expected format is the same as specified in sshd(8) manpage, section "AUTHORIZED_KEYS FILE FORMAT". See: tmate-io/tmate-slave#37 Closes #38
This commit is contained in:
parent
76ec591e91
commit
d6a76e0609
@ -33,14 +33,15 @@ extern int server_create_socket(void);
|
|||||||
extern int client_connect(struct event_base *base, const char *path, int start_server);
|
extern int client_connect(struct event_base *base, const char *path, int start_server);
|
||||||
|
|
||||||
struct tmate_settings _tmate_settings = {
|
struct tmate_settings _tmate_settings = {
|
||||||
.keys_dir = TMATE_SSH_DEFAULT_KEYS_DIR,
|
.keys_dir = TMATE_SSH_DEFAULT_KEYS_DIR,
|
||||||
.ssh_port = TMATE_SSH_DEFAULT_PORT,
|
.authorized_keys_path = NULL,
|
||||||
.proxy_hostname = NULL,
|
.ssh_port = TMATE_SSH_DEFAULT_PORT,
|
||||||
.bind_addr = NULL,
|
.proxy_hostname = NULL,
|
||||||
.proxy_port = TMATE_DEFAULT_PROXY_PORT,
|
.bind_addr = NULL,
|
||||||
.tmate_host = NULL,
|
.proxy_port = TMATE_DEFAULT_PROXY_PORT,
|
||||||
.log_level = LOG_NOTICE,
|
.tmate_host = NULL,
|
||||||
.use_syslog = false,
|
.log_level = LOG_NOTICE,
|
||||||
|
.use_syslog = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tmate_settings *tmate_settings = &_tmate_settings;
|
struct tmate_settings *tmate_settings = &_tmate_settings;
|
||||||
@ -102,7 +103,7 @@ void request_server_termination(void)
|
|||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "usage: tmate-slave [-b ip] [-h hostname] [-k keys_dir] [-p port] [-x proxy_hostname] [-q proxy_port] [-s] [-v]\n");
|
fprintf(stderr, "usage: tmate-slave [-b ip] [-h hostname] [-k keys_dir] [-a authorized_keys_path] [-p port] [-x proxy_hostname] [-q proxy_port] [-s] [-v]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* get_full_hostname(void)
|
static char* get_full_hostname(void)
|
||||||
@ -155,7 +156,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "b:h:k:p:x:q:sv")) != -1) {
|
while ((opt = getopt(argc, argv, "b:h:k:a:p:x:q:sv")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'b':
|
case 'b':
|
||||||
tmate_settings->bind_addr = xstrdup(optarg);
|
tmate_settings->bind_addr = xstrdup(optarg);
|
||||||
@ -166,6 +167,9 @@ int main(int argc, char **argv, char **envp)
|
|||||||
case 'k':
|
case 'k':
|
||||||
tmate_settings->keys_dir = xstrdup(optarg);
|
tmate_settings->keys_dir = xstrdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'a':
|
||||||
|
tmate_settings->authorized_keys_path = xstrdup(optarg);
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
tmate_settings->ssh_port = atoi(optarg);
|
tmate_settings->ssh_port = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <event.h>
|
#include <event.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@ -106,6 +107,61 @@ static ssh_channel channel_open_request_cb(ssh_session session, void *userdata)
|
|||||||
return client->channel;
|
return client->channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_authorized_keys(struct ssh_key_struct *client_pubkey) {
|
||||||
|
#define MAX_PUBKEY_SIZE 0x4000
|
||||||
|
|
||||||
|
const char *authorized_keys_path = tmate_settings->authorized_keys_path;
|
||||||
|
const char *token_delim = " ";
|
||||||
|
|
||||||
|
FILE *file;
|
||||||
|
char key_buf[MAX_PUBKEY_SIZE], *key_type, *key_content;
|
||||||
|
enum ssh_keytypes_e type;
|
||||||
|
ssh_key pkey;
|
||||||
|
|
||||||
|
if (authorized_keys_path == NULL)
|
||||||
|
return SSH_AUTH_SUCCESS;
|
||||||
|
|
||||||
|
file = fopen(authorized_keys_path, "rb");
|
||||||
|
if (file == NULL) {
|
||||||
|
tmate_fatal("Could not open authorized_keys file: \"%s\"", authorized_keys_path);
|
||||||
|
return SSH_AUTH_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets(key_buf, MAX_PUBKEY_SIZE, file)) {
|
||||||
|
if (key_buf[0] == '#' || key_buf[0] == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
key_type = strtok(key_buf, token_delim);
|
||||||
|
if (key_type == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
type = ssh_key_type_from_name(key_type);
|
||||||
|
if (type == SSH_KEYTYPE_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
key_content = strtok(NULL, token_delim);
|
||||||
|
if (key_content == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pkey = ssh_key_new();
|
||||||
|
if (ssh_pki_import_pubkey_base64(key_content, type, &pkey) != SSH_OK) {
|
||||||
|
ssh_key_free(pkey);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ssh_key_cmp(pkey, client_pubkey, SSH_KEY_CMP_PUBLIC)) {
|
||||||
|
ssh_key_free(pkey);
|
||||||
|
fclose(file);
|
||||||
|
return SSH_AUTH_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_key_free(pkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
return SSH_AUTH_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
static int auth_pubkey_cb(__unused ssh_session session,
|
static int auth_pubkey_cb(__unused ssh_session session,
|
||||||
const char *user,
|
const char *user,
|
||||||
struct ssh_key_struct *pubkey,
|
struct ssh_key_struct *pubkey,
|
||||||
@ -118,7 +174,8 @@ static int auth_pubkey_cb(__unused ssh_session session,
|
|||||||
client->username = xstrdup(user);
|
client->username = xstrdup(user);
|
||||||
if (ssh_pki_export_pubkey_base64(pubkey, &client->pubkey) != SSH_OK)
|
if (ssh_pki_export_pubkey_base64(pubkey, &client->pubkey) != SSH_OK)
|
||||||
tmate_fatal("error getting public key");
|
tmate_fatal("error getting public key");
|
||||||
return SSH_AUTH_SUCCESS;
|
|
||||||
|
return check_authorized_keys(pubkey);
|
||||||
case SSH_PUBLICKEY_STATE_NONE:
|
case SSH_PUBLICKEY_STATE_NONE:
|
||||||
return SSH_AUTH_SUCCESS;
|
return SSH_AUTH_SUCCESS;
|
||||||
default:
|
default:
|
||||||
|
1
tmate.h
1
tmate.h
@ -205,6 +205,7 @@ extern void tmate_ssh_server_main(struct tmate_session *session,
|
|||||||
|
|
||||||
struct tmate_settings {
|
struct tmate_settings {
|
||||||
const char *keys_dir;
|
const char *keys_dir;
|
||||||
|
const char *authorized_keys_path;
|
||||||
int ssh_port;
|
int ssh_port;
|
||||||
const char *proxy_hostname;
|
const char *proxy_hostname;
|
||||||
int proxy_port;
|
int proxy_port;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user