1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#include <stdlib.h>
#include <assert.h>
#include <libssh/callbacks.h>
#include <libssh/server.h>
#include "server_ssh.h"
#include "log.h"
typedef struct ssh_data {
ssh_bind sshbind;
ssh_session session;
} ssh_data;
struct fwd_callbacks potd_ssh_callbacks = {
.on_listen = ssh_on_listen,
.on_shutdown = ssh_on_shutdown
};
static int set_default_keys(ssh_bind sshbind, int rsa_already_set,
int dsa_already_set, int ecdsa_already_set);
static int gen_default_keys(void);
static int gen_export_sshkey(enum ssh_keytypes_e type, int length, const char *path);
int ssh_init_cb(struct forward_ctx *ctx)
{
ctx->fwd_cbs = potd_ssh_callbacks;
if (ssh_init())
return 1;
ssh_data *d = (ssh_data *) calloc(1, sizeof(*d));
assert(d);
d->sshbind = ssh_bind_new();
d->session = ssh_new();
ctx->data = d;
if (!d->sshbind || !d->session)
return 1;
if (gen_default_keys())
return 1;
if (set_default_keys(d->sshbind, 0, 0, 0))
return 1;
return 0;
}
int ssh_on_listen(struct forward_ctx *ctx)
{
ssh_data *d = (ssh_data *) ctx->data;
if (ssh_bind_listen(d->sshbind) < 0) {
E("Error listening to SSH socket: %s", ssh_get_error(d->sshbind));
}
return 0;
}
int ssh_on_shutdown(struct forward_ctx *ctx)
{
return 0;
}
static int set_default_keys(ssh_bind sshbind, int rsa_already_set,
int dsa_already_set, int ecdsa_already_set)
{
if (!rsa_already_set) {
if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
"./ssh_host_rsa_key"))
return 1;
}
if (!dsa_already_set) {
if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
"./ssh_host_dsa_key"))
return 1;
}
if (!ecdsa_already_set) {
if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY,
"./ssh_host_ecdsa_key"))
return 1;
}
return 0;
}
static int gen_default_keys(void)
{
if (gen_export_sshkey(SSH_KEYTYPE_DSS, 1024, "./ssh_host_dsa_key"))
return 1;
if (gen_export_sshkey(SSH_KEYTYPE_RSA, 1024, "./ssh_host_rsa_key"))
return 1;
if (gen_export_sshkey(SSH_KEYTYPE_ECDSA, 1024, "./ssh_host_ecdsa_key"))
return 1;
return 0;
}
static int gen_export_sshkey(enum ssh_keytypes_e type, int length, const char *path)
{
ssh_key priv_key;
const char *type_str = NULL;
assert(path);
assert(length == 1024 || length == 2048 ||
length == 4096);
switch (type) {
case SSH_KEYTYPE_DSS:
type_str = "DSS";
break;
case SSH_KEYTYPE_RSA:
type_str = "RSA";
break;
case SSH_KEYTYPE_ECDSA:
type_str = "ECDSA";
break;
default:
return 1;
}
N2("Generating %s key with length %d bits and save it on disk: %s",
type_str, length, path);
if (ssh_pki_generate(type, length, &priv_key) != SSH_OK) {
E2("Generating %s key failed", type_str);
return 1;
}
errno = 0;
if (ssh_pki_export_privkey_file(priv_key, NULL, NULL,
NULL, path) != SSH_OK)
{
E_STRERR("SSH export to file");
return 1;
}
ssh_key_free(priv_key);
return 0;
}
|