This source file includes following definitions.
- debug_log
- remoted__read_handshake_data
- lrmd_remote_client_msg
- lrmd_remote_client_destroy
- lrmd_auth_timeout_cb
- lrmd_remote_listen
- tls_server_dropped
- lrmd_tls_server_key_cb
- bind_and_listen
- get_address_info
- lrmd_init_remote_tls_server
- execd_stop_tls_server
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <glib.h>
13 #include <unistd.h>
14
15 #include <crm/crm.h>
16 #include <crm/msg_xml.h>
17 #include <crm/crm.h>
18 #include <crm/msg_xml.h>
19 #include <crm/common/mainloop.h>
20 #include <crm/common/remote_internal.h>
21 #include <crm/lrmd_internal.h>
22
23 #include <netdb.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <netinet/ip.h>
27 #include <arpa/inet.h>
28
29 #include "pacemaker-execd.h"
30
31 #ifdef HAVE_GNUTLS_GNUTLS_H
32
33 # include <gnutls/gnutls.h>
34
35 # define LRMD_REMOTE_AUTH_TIMEOUT 10000
36 gnutls_psk_server_credentials_t psk_cred_s;
37 gnutls_dh_params_t dh_params;
38 static int ssock = -1;
39 extern int lrmd_call_id;
40
41 static void
42 debug_log(int level, const char *str)
43 {
44 fputs(str, stderr);
45 }
46
47
48
49
50
51
52
53
54
55 static int
56 remoted__read_handshake_data(pcmk__client_t *client)
57 {
58 int rc = pcmk__read_handshake_data(client);
59
60 if (rc == EAGAIN) {
61
62
63
64 return 0;
65 } else if (rc != pcmk_rc_ok) {
66 return -1;
67 }
68
69 if (client->remote->auth_timeout) {
70 g_source_remove(client->remote->auth_timeout);
71 }
72 client->remote->auth_timeout = 0;
73
74 pcmk__set_client_flags(client, pcmk__client_tls_handshake_complete);
75 crm_notice("Remote client connection accepted");
76
77
78
79
80 pcmk__set_client_flags(client, pcmk__client_privileged);
81
82
83 notify_of_new_client(client);
84 return 0;
85 }
86
87 static int
88 lrmd_remote_client_msg(gpointer data)
89 {
90 int id = 0;
91 int rc;
92 xmlNode *request = NULL;
93 pcmk__client_t *client = data;
94
95 if (!pcmk_is_set(client->flags,
96 pcmk__client_tls_handshake_complete)) {
97 return remoted__read_handshake_data(client);
98 }
99
100 switch (pcmk__remote_ready(client->remote, 0)) {
101 case pcmk_rc_ok:
102 break;
103 case ETIME:
104 return 0;
105 default:
106 crm_info("Remote client disconnected while polling it");
107 return -1;
108 }
109
110 rc = pcmk__read_remote_message(client->remote, -1);
111
112 request = pcmk__remote_message_xml(client->remote);
113 while (request) {
114 crm_element_value_int(request, F_LRMD_REMOTE_MSG_ID, &id);
115 crm_trace("Processing remote client request %d", id);
116 if (!client->name) {
117 const char *value = crm_element_value(request, F_LRMD_CLIENTNAME);
118
119 if (value) {
120 client->name = strdup(value);
121 }
122 }
123
124 lrmd_call_id++;
125 if (lrmd_call_id < 1) {
126 lrmd_call_id = 1;
127 }
128
129 crm_xml_add(request, F_LRMD_CLIENTID, client->id);
130 crm_xml_add(request, F_LRMD_CLIENTNAME, client->name);
131 crm_xml_add_int(request, F_LRMD_CALLID, lrmd_call_id);
132
133 process_lrmd_message(client, id, request);
134 free_xml(request);
135
136
137 request = pcmk__remote_message_xml(client->remote);
138 }
139
140 if (rc == ENOTCONN) {
141 crm_info("Remote client disconnected while reading from it");
142 return -1;
143 }
144
145 return 0;
146 }
147
148 static void
149 lrmd_remote_client_destroy(gpointer user_data)
150 {
151 pcmk__client_t *client = user_data;
152
153 if (client == NULL) {
154 return;
155 }
156
157 crm_notice("Cleaning up after remote client %s disconnected",
158 pcmk__client_name(client));
159
160 ipc_proxy_remove_provider(client);
161
162
163
164 if (pcmk__ipc_client_count() == 1) {
165 client_disconnect_cleanup(NULL);
166 }
167
168 if (client->remote->tls_session) {
169 void *sock_ptr;
170 int csock;
171
172 sock_ptr = gnutls_transport_get_ptr(*client->remote->tls_session);
173 csock = GPOINTER_TO_INT(sock_ptr);
174
175 gnutls_bye(*client->remote->tls_session, GNUTLS_SHUT_RDWR);
176 gnutls_deinit(*client->remote->tls_session);
177 gnutls_free(client->remote->tls_session);
178 close(csock);
179 }
180
181 lrmd_client_destroy(client);
182 return;
183 }
184
185 static gboolean
186 lrmd_auth_timeout_cb(gpointer data)
187 {
188 pcmk__client_t *client = data;
189
190 client->remote->auth_timeout = 0;
191
192 if (pcmk_is_set(client->flags,
193 pcmk__client_tls_handshake_complete)) {
194 return FALSE;
195 }
196
197 mainloop_del_fd(client->remote->source);
198 client->remote->source = NULL;
199 crm_err("Remote client authentication timed out");
200
201 return FALSE;
202 }
203
204
205 static int
206 lrmd_remote_listen(gpointer data)
207 {
208 int csock = -1;
209 gnutls_session_t *session = NULL;
210 pcmk__client_t *new_client = NULL;
211
212
213 static struct mainloop_fd_callbacks lrmd_remote_fd_cb = {
214 .dispatch = lrmd_remote_client_msg,
215 .destroy = lrmd_remote_client_destroy,
216 };
217
218 CRM_CHECK(ssock >= 0, return TRUE);
219
220 if (pcmk__accept_remote_connection(ssock, &csock) != pcmk_rc_ok) {
221 return TRUE;
222 }
223
224 session = pcmk__new_tls_session(csock, GNUTLS_SERVER, GNUTLS_CRD_PSK,
225 psk_cred_s);
226 if (session == NULL) {
227 close(csock);
228 return TRUE;
229 }
230
231 new_client = pcmk__new_unauth_client(NULL);
232 new_client->remote = calloc(1, sizeof(pcmk__remote_t));
233 pcmk__set_client_flags(new_client, pcmk__client_tls);
234 new_client->remote->tls_session = session;
235
236
237 new_client->remote->auth_timeout = g_timeout_add(LRMD_REMOTE_AUTH_TIMEOUT,
238 lrmd_auth_timeout_cb,
239 new_client);
240 crm_info("Remote client pending authentication "
241 CRM_XS " %p id: %s", new_client, new_client->id);
242
243 new_client->remote->source =
244 mainloop_add_fd("pacemaker-remote-client", G_PRIORITY_DEFAULT, csock,
245 new_client, &lrmd_remote_fd_cb);
246 return TRUE;
247 }
248
249 static void
250 tls_server_dropped(gpointer user_data)
251 {
252 crm_notice("TLS server session ended");
253 return;
254 }
255
256
257 static int
258 lrmd_tls_server_key_cb(gnutls_session_t session, const char *username, gnutls_datum_t * key)
259 {
260 return (lrmd__init_remote_key(key) == pcmk_rc_ok)? 0 : -1;
261 }
262
263 static int
264 bind_and_listen(struct addrinfo *addr)
265 {
266 int optval;
267 int fd;
268 int rc;
269 char buffer[INET6_ADDRSTRLEN] = { 0, };
270
271 pcmk__sockaddr2str(addr->ai_addr, buffer);
272 crm_trace("Attempting to bind to address %s", buffer);
273
274 fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
275 if (fd < 0) {
276 crm_perror(LOG_ERR, "Listener socket creation failed");
277 return -1;
278 }
279
280
281 optval = 1;
282 rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
283 if (rc < 0) {
284 crm_perror(LOG_ERR, "Local address reuse not allowed on %s", buffer);
285 close(fd);
286 return -1;
287 }
288
289 if (addr->ai_family == AF_INET6) {
290 optval = 0;
291 rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
292 if (rc < 0) {
293 crm_perror(LOG_INFO, "Couldn't disable IPV6-only on %s", buffer);
294 close(fd);
295 return -1;
296 }
297 }
298
299 if (bind(fd, addr->ai_addr, addr->ai_addrlen) != 0) {
300 crm_perror(LOG_ERR, "Cannot bind to %s", buffer);
301 close(fd);
302 return -1;
303 }
304
305 if (listen(fd, 10) == -1) {
306 crm_perror(LOG_ERR, "Cannot listen on %s", buffer);
307 close(fd);
308 return -1;
309 }
310 return fd;
311 }
312
313 static int
314 get_address_info(const char *bind_name, int port, struct addrinfo **res)
315 {
316 int rc;
317 char port_str[6];
318 struct addrinfo hints;
319
320 memset(&hints, 0, sizeof(struct addrinfo));
321 hints.ai_flags = AI_PASSIVE;
322 hints.ai_family = AF_UNSPEC;
323 hints.ai_socktype = SOCK_STREAM;
324 hints.ai_protocol = IPPROTO_TCP;
325
326 snprintf(port_str, sizeof(port_str), "%d", port);
327 rc = getaddrinfo(bind_name, port_str, &hints, res);
328 if (rc) {
329 crm_err("Unable to get IP address(es) for %s: %s",
330 (bind_name? bind_name : "local node"), gai_strerror(rc));
331 return -EADDRNOTAVAIL;
332 }
333 return pcmk_ok;
334 }
335
336 int
337 lrmd_init_remote_tls_server(void)
338 {
339 int filter;
340 int port = crm_default_remote_port();
341 struct addrinfo *res = NULL, *iter;
342 gnutls_datum_t psk_key = { NULL, 0 };
343 const char *bind_name = getenv("PCMK_remote_address");
344
345 static struct mainloop_fd_callbacks remote_listen_fd_callbacks = {
346 .dispatch = lrmd_remote_listen,
347 .destroy = tls_server_dropped,
348 };
349
350 CRM_CHECK(ssock == -1, return ssock);
351
352 crm_debug("Starting TLS listener on %s port %d",
353 (bind_name? bind_name : "all addresses on"), port);
354 crm_gnutls_global_init();
355 gnutls_global_set_log_function(debug_log);
356
357 if (pcmk__init_tls_dh(&dh_params) != pcmk_rc_ok) {
358 return -1;
359 }
360 gnutls_psk_allocate_server_credentials(&psk_cred_s);
361 gnutls_psk_set_server_credentials_function(psk_cred_s, lrmd_tls_server_key_cb);
362 gnutls_psk_set_server_dh_params(psk_cred_s, dh_params);
363
364
365
366
367
368
369 if (lrmd__init_remote_key(&psk_key) != pcmk_rc_ok) {
370 crm_warn("A cluster connection will not be possible until the key is available");
371 }
372 gnutls_free(psk_key.data);
373
374 if (get_address_info(bind_name, port, &res) != pcmk_ok) {
375 return -1;
376 }
377
378
379
380
381
382
383
384
385
386
387
388 iter = res;
389 filter = AF_INET6;
390 while (iter) {
391 if (iter->ai_family == filter) {
392 ssock = bind_and_listen(iter);
393 }
394 if (ssock != -1) {
395 break;
396 }
397
398 iter = iter->ai_next;
399 if (iter == NULL && filter == AF_INET6) {
400 iter = res;
401 filter = AF_INET;
402 }
403 }
404
405 if (ssock >= 0) {
406 mainloop_add_fd("pacemaker-remote-server", G_PRIORITY_DEFAULT, ssock,
407 NULL, &remote_listen_fd_callbacks);
408 crm_debug("Started TLS listener on %s port %d",
409 (bind_name? bind_name : "all addresses on"), port);
410 }
411 freeaddrinfo(res);
412 return ssock;
413 }
414
415 void
416 execd_stop_tls_server(void)
417 {
418 if (psk_cred_s) {
419 gnutls_psk_free_server_credentials(psk_cred_s);
420 psk_cred_s = 0;
421 }
422
423 if (ssock >= 0) {
424 close(ssock);
425 ssock = -1;
426 }
427 }
428 #endif