git ssb

0+

cel / sslh



Tree: 21f524f71165538dcde9f8de32b9f69385ba0c87

Files: 21f524f71165538dcde9f8de32b9f69385ba0c87 / systemd-sslh-generator.c

4250 bytesRaw
1#include <libconfig.h>
2#include <stdio.h>
3#include <string.h>
4#include <stdlib.h>
5
6
7static char* resolve_listen(const char *hostname, const char *port) {
8 /* Need room in the strcat for \0 and :
9 * the format in the socket unit file is hostname:port */
10 char *conn = (char*)malloc(strlen(hostname)+strlen(port)+2);
11 strcpy(conn, hostname);
12 strcat(conn, ":");
13 strcat(conn, port);
14
15 return conn;
16
17}
18
19
20static int get_listen_from_conf(const char *filename, char **listen[]) {
21 config_t config;
22 config_setting_t *setting, *addr;
23 const char *hostname, *port;
24 int len = 0;
25
26 /* look up the listen stanzas in the config file so these
27 * can be used in the socket file generated */
28 config_init(&config);
29 if (config_read_file(&config, filename) == CONFIG_FALSE) {
30 /* we don't care if file is missing, skip it */
31 if (config_error_line(&config) != 0) {
32 fprintf(stderr, "%s:%d:%s\n",
33 filename,
34 config_error_line(&config),
35 config_error_text(&config));
36 return -1;
37 }
38 } else {
39 setting = config_lookup(&config, "listen");
40 if (setting) {
41 len = config_setting_length(setting);
42 *listen = malloc(len * sizeof(**listen));
43 for (int i = 0; i < len; i++) {
44 addr = config_setting_get_elem(setting, i);
45 if (! (config_setting_lookup_string(addr, "host", &hostname) &&
46 config_setting_lookup_string(addr, "port", &port))) {
47 fprintf(stderr,
48 "line %d:Incomplete specification (hostname and port required)\n",
49 config_setting_source_line(addr));
50 return -1;
51 } else {
52 (*listen)[i] = malloc(strlen(resolve_listen(hostname, port)));
53 strcpy((*listen)[i], resolve_listen(hostname, port));
54 }
55 }
56 }
57 }
58
59 return len;
60
61}
62
63static int write_socket_unit(FILE *socket, char *listen[], int num_addr, const char *source) {
64
65 fprintf(socket,
66 "# Automatically generated by systemd-sslh-generator\n\n"
67 "[Unit]\n"
68 "Before=sslh.service\n"
69 "SourcePath=%s\n"
70 "Documentation=man:sslh(8) man:systemd-sslh-generator(8)\n\n"
71 "[Socket]\n"
72 "FreeBind=true\n",
73 source);
74
75 for (int i = 0; i < num_addr; i++) {
76 fprintf(socket, "ListenStream=%s\n", listen[i]);
77 }
78
79 return 0;
80}
81
82static int gen_sslh_config(char *runtime_unit_dir) {
83 char *sslh_conf;
84 int num_addr;
85 FILE *config;
86 char **listen;
87 FILE *runtime_conf_fd = stdout;
88 const char *unit_file;
89
90 /* There are two default locations so check both with first given preference */
91 sslh_conf = "/etc/sslh.cfg";
92
93 config = fopen(sslh_conf, "r");
94 if (config == NULL) {
95 sslh_conf="/etc/sslh/sslh.cfg";
96 config = fopen(sslh_conf, "r");
97 if (config == NULL) {
98 return -1;
99 }
100 }
101
102 fclose(config);
103
104 num_addr = get_listen_from_conf(sslh_conf, &listen);
105 if (num_addr < 0)
106 return -1;
107
108 /* If this is run by systemd directly write to the location told to
109 * otherwise write to standard out so that it's trivial to check what
110 * will be written */
111 if (runtime_unit_dir != "") {
112 unit_file = "/sslh.socket";
113 size_t uf_len = strlen(unit_file);
114 size_t runtime_len = strlen(runtime_unit_dir) + uf_len + 1;
115 char *runtime_conf = malloc(runtime_len);
116 strcpy(runtime_conf, runtime_unit_dir);
117 strcat(runtime_conf, unit_file);
118 runtime_conf_fd = fopen(runtime_conf, "w");
119 }
120
121
122 return write_socket_unit(runtime_conf_fd, listen, num_addr, sslh_conf);
123}
124
125
126int main(int argc, char *argv[]){
127 int r = 0;
128 int k;
129 char *runtime_unit_dest = "";
130
131 if (argc > 1 && (argc != 4) ) {
132 printf("This program takes three or no arguments.\n");
133 return -1;
134 }
135
136 if (argc > 1)
137 runtime_unit_dest = argv[1];
138
139 k = gen_sslh_config(runtime_unit_dest);
140 if (k < 0)
141 r = k;
142
143 return r < 0 ? -1 : 0;
144}
145
146
147

Built with git-ssb-web