git ssb

0+

cel / sslh



Tree: b4cb91043812c7ff6fb13d369a65288adb6fbc8a

Files: b4cb91043812c7ff6fb13d369a65288adb6fbc8a / systemd-sslh-generator.c

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

Built with git-ssb-web