17 #include <sys/socket.h>
28 #ifdef HAVE_GNUTLS_GNUTLS_H
30 # include <gnutls/gnutls.h>
31 gnutls_anon_client_credentials_t anon_cred_c;
33 # define DEFAULT_CLIENT_HANDSHAKE_TIMEOUT 5000
35 const int kx_prio[] = {
40 static gboolean remote_gnutls_credentials_init = FALSE;
45 #include <arpa/inet.h>
52 typedef struct cib_remote_opaque_s {
73 xmlNode *
data, xmlNode ** output_data,
int call_options,
77 cib_remote_inputfd(
cib_t * cib)
81 return private->callback.tcp_socket;
85 cib_remote_set_connection_dnotify(
cib_t * cib,
void (*dnotify) (gpointer user_data))
87 return -EPROTONOSUPPORT;
91 cib_remote_register_notification(
cib_t * cib,
const char *callback,
int enabled)
105 cib_remote_new(
const char *server,
const char *user,
const char *passwd,
int port,
117 private->server = strdup(server);
121 private->user = strdup(user);
125 private->passwd = strdup(passwd);
128 private->port = port;
129 private->encrypted = encrypted;
145 cib_tls_close(
cib_t * cib)
149 #ifdef HAVE_GNUTLS_GNUTLS_H
150 if (private->encrypted) {
151 if (private->command.tls_session) {
152 gnutls_bye(*(private->command.tls_session), GNUTLS_SHUT_RDWR);
153 gnutls_deinit(*(private->command.tls_session));
154 gnutls_free(private->command.tls_session);
157 if (private->callback.tls_session) {
158 gnutls_bye(*(private->callback.tls_session), GNUTLS_SHUT_RDWR);
159 gnutls_deinit(*(private->callback.tls_session));
160 gnutls_free(private->callback.tls_session);
162 private->command.tls_session = NULL;
163 private->callback.tls_session = NULL;
164 if (remote_gnutls_credentials_init) {
165 gnutls_anon_free_client_credentials(anon_cred_c);
166 gnutls_global_deinit();
167 remote_gnutls_credentials_init = FALSE;
172 if (private->command.tcp_socket) {
173 shutdown(private->command.tcp_socket, SHUT_RDWR);
174 close(private->command.tcp_socket);
176 if (private->callback.tcp_socket) {
177 shutdown(private->callback.tcp_socket, SHUT_RDWR);
178 close(private->callback.tcp_socket);
180 private->command.tcp_socket = 0;
181 private->callback.tcp_socket = 0;
183 free(private->command.buffer);
184 free(private->callback.buffer);
185 private->command.buffer = NULL;
186 private->callback.buffer = NULL;
197 int disconnected = 0;
199 xmlNode *answer = NULL;
200 xmlNode *login = NULL;
209 #ifdef HAVE_GNUTLS_GNUTLS_H
210 connection->tls_session = NULL;
214 crm_perror(LOG_ERR,
"remote tcp connection to %s:%d failed", private->server,
221 if (private->encrypted) {
223 #ifdef HAVE_GNUTLS_GNUTLS_H
224 if (remote_gnutls_credentials_init == FALSE) {
225 crm_gnutls_global_init();
226 gnutls_anon_allocate_client_credentials(&anon_cred_c);
227 remote_gnutls_credentials_init = TRUE;
231 connection->tls_session = pcmk__new_tls_session(sock, GNUTLS_CLIENT,
234 if (connection->tls_session == NULL) {
239 if (crm_initiate_client_tls_handshake(connection, DEFAULT_CLIENT_HANDSHAKE_TIMEOUT) != 0) {
240 crm_err(
"Session creation for %s:%d failed", private->server, private->port);
242 gnutls_deinit(*connection->tls_session);
243 gnutls_free(connection->tls_session);
244 connection->tls_session = NULL;
249 return -EPROTONOSUPPORT;
272 if (answer == NULL) {
281 crm_err(
"Invalid registration message: %s", msg_type);
284 }
else if (tmp_ticket == NULL) {
288 connection->
token = strdup(tmp_ticket);
299 crm_trace(
"remote client connection established");
309 crm_err(
"Connection destroyed");
310 #ifdef HAVE_GNUTLS_GNUTLS_H
311 cib_tls_close(user_data);
319 int disconnected = 0;
320 cib_t *cib = user_data;
325 free(private->command.buffer);
326 private->command.buffer = NULL;
327 crm_err(
"received late reply for remote cib connection, discarding");
338 cib_t *cib = user_data;
342 int disconnected = 0;
344 crm_info(
"Message on callback channel");
381 if (private->passwd == NULL) {
382 struct termios settings;
384 rc = tcgetattr(0, &settings);
386 settings.c_lflag &= ~ECHO;
387 rc = tcsetattr(0, TCSANOW, &settings);
391 fprintf(stderr,
"Password: ");
392 private->passwd = calloc(1, 1024);
393 rc = scanf(
"%1023s", private->passwd);
394 fprintf(stderr,
"\n");
399 private->passwd = NULL;
402 settings.c_lflag |= ECHO;
403 rc = tcsetattr(0, TCSANOW, &settings);
406 if (private->server == NULL || private->user == NULL) {
411 rc = cib_tls_signon(cib, &(private->command), FALSE);
415 rc = cib_tls_signon(cib, &(private->callback), TRUE);
427 crm_notice(
"%s: Opened connection to %s:%d", name, private->server, private->port);
432 fprintf(stderr,
"%s: Connection to %s:%d failed: %s\n",
446 crm_debug(
"Disconnecting from the CIB manager");
447 #ifdef HAVE_GNUTLS_GNUTLS_H
468 free(private->server);
470 free(private->passwd);
482 xmlNode *
data, xmlNode ** output_data,
int call_options,
const char *name)
485 int disconnected = 0;
486 int remaining_time = 0;
489 xmlNode *op_msg = NULL;
490 xmlNode *op_reply = NULL;
498 if (output_data != NULL) {
503 crm_err(
"No operation specified");
519 if (op_msg == NULL) {
523 crm_trace(
"Sending %s message to the CIB manager", op);
539 crm_trace(
"Waiting for a synchronous reply");
541 start_time = time(NULL);
544 while (remaining_time > 0 && !disconnected) {
548 crm_remote_recv(&private->command, remaining_time * 1000, &disconnected);
557 if (reply_id == msg_id) {
560 }
else if (reply_id < msg_id) {
561 crm_debug(
"Received old reply: %d (wanted %d)", reply_id, msg_id);
564 }
else if ((reply_id - 10000) > msg_id) {
566 crm_debug(
"Received old reply: %d (wanted %d)", reply_id, msg_id);
569 crm_err(
"Received a __future__ reply:" " %d (wanted %d)", reply_id, msg_id);
576 remaining_time = time(NULL) - start_time;
586 crm_err(
"Disconnected while waiting for reply.");
588 }
else if (op_reply == NULL) {
589 crm_err(
"No reply message - empty");
605 if (rc ==
pcmk_ok || rc == -EPERM) {
614 if (output_data == NULL) {