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