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);
|
||||
|
||||
struct tmate_settings _tmate_settings = {
|
||||
.keys_dir = TMATE_SSH_DEFAULT_KEYS_DIR,
|
||||
.ssh_port = TMATE_SSH_DEFAULT_PORT,
|
||||
.proxy_hostname = NULL,
|
||||
.bind_addr = NULL,
|
||||
.proxy_port = TMATE_DEFAULT_PROXY_PORT,
|
||||
.tmate_host = NULL,
|
||||
.log_level = LOG_NOTICE,
|
||||
.use_syslog = false,
|
||||
.keys_dir = TMATE_SSH_DEFAULT_KEYS_DIR,
|
||||
.authorized_keys_path = NULL,
|
||||
.ssh_port = TMATE_SSH_DEFAULT_PORT,
|
||||
.proxy_hostname = NULL,
|
||||
.bind_addr = NULL,
|
||||
.proxy_port = TMATE_DEFAULT_PROXY_PORT,
|
||||
.tmate_host = NULL,
|
||||
.log_level = LOG_NOTICE,
|
||||
.use_syslog = false,
|
||||
};
|
||||
|
||||
struct tmate_settings *tmate_settings = &_tmate_settings;
|
||||
@ -102,7 +103,7 @@ void request_server_termination(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)
|
||||
@ -155,7 +156,7 @@ int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
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) {
|
||||
case 'b':
|
||||
tmate_settings->bind_addr = xstrdup(optarg);
|
||||
@ -166,6 +167,9 @@ int main(int argc, char **argv, char **envp)
|
||||
case 'k':
|
||||
tmate_settings->keys_dir = xstrdup(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
tmate_settings->authorized_keys_path = xstrdup(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
tmate_settings->ssh_port = atoi(optarg);
|
||||
break;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/wait.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <event.h>
|
||||
#include <arpa/inet.h>
|
||||
@ -106,6 +107,61 @@ static ssh_channel channel_open_request_cb(ssh_session session, void *userdata)
|
||||
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,
|
||||
const char *user,
|
||||
struct ssh_key_struct *pubkey,
|
||||
@ -118,7 +174,8 @@ static int auth_pubkey_cb(__unused ssh_session session,
|
||||
client->username = xstrdup(user);
|
||||
if (ssh_pki_export_pubkey_base64(pubkey, &client->pubkey) != SSH_OK)
|
||||
tmate_fatal("error getting public key");
|
||||
return SSH_AUTH_SUCCESS;
|
||||
|
||||
return check_authorized_keys(pubkey);
|
||||
case SSH_PUBLICKEY_STATE_NONE:
|
||||
return SSH_AUTH_SUCCESS;
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user