25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * CDDL HEADER START
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen *
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * The contents of this file are subject to the terms of the
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Common Development and Distribution License (the "License").
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * You may not use this file except in compliance with the License.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen *
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * or http://www.opensolaris.org/os/licensing.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * See the License for the specific language governing permissions
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * and limitations under the License.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen *
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * When distributing Covered Code, include this CDDL HEADER in each
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * If applicable, add the following below this CDDL HEADER, with the
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * fields enclosed by brackets "[]" replaced with your own identifying
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * information: Portions Copyright [yyyy] [name of copyright owner]
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen *
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * CDDL HEADER END
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen * ldom_xmpp_client.c Extensible Messaging and Presence Protocol (XMPP)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen *
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Implement an xmpp client to subscribe for domain events from the ldmd.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Notify fmd module clients upon receiving the events.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen *
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include "ldom_xmpp_client.h"
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include "ldom_alloc.h"
e6590bdc0d540003c7df26f1d3b66db7cae9be2cVuong Nguyen#include "ldom_utils.h"
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <stdio.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <signal.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <strings.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <unistd.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <errno.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <netdb.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <dlfcn.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <fcntl.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <sys/socket.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <sys/types.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <sys/stat.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <libxml/parser.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <openssl/ssl.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef enum conn_state {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen CONN_STATE_UNKNOWN,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen CONN_STATE_TLS,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen CONN_STATE_FEATURE,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen CONN_STATE_LDM_INTERFACE,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen CONN_STATE_LDM_EVENT,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen CONN_STATE_DONE,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen CONN_STATE_FAILURE,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen CONN_STATE_MAX
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen} conn_state_t;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef struct xmpp_conn {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int fd;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int state;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen boolean_t tls_started;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen SSL *ssl;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlParserCtxtPtr parser;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen} xmpp_conn_t;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/* Forward declaration */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic int iowrite(xmpp_conn_t *conn, char *buf, int size);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void start_element(void *state, const xmlChar *name,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen const xmlChar **attrs);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void end_element(void *state, const xmlChar *name);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void error_func(void *state, const char *msg, ...);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void xmpp_close(xmpp_conn_t *conn);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic int start_tls(xmpp_conn_t *conn);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void handle_ldm_resp(xmpp_conn_t *conn, char *buf, size_t buf_size);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void handle_ldm_event(xmpp_conn_t *conn, char *buf, size_t buf_size);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic int xmpp_enable = 0;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyenstatic int xmpp_notify_pipe[2];
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic pthread_t xmpp_tid = 0;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic pthread_mutex_t xmpp_tid_lock = PTHREAD_MUTEX_INITIALIZER;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic client_list_t clt_list = { NULL, NULL, PTHREAD_MUTEX_INITIALIZER };
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#define FUNCTION_ADD(_function, _pointer, _lib, _func_name, _ret) \
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen _function = (_pointer)dlsym(_lib, _func_name); \
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (_function == NULL) { \
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen _ret += -1; \
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Prototypes and pointers to functions needed from libssl.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef void (*SSL_load_error_strings_pt)(void);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef int (*SSL_library_init_pt)(void);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef SSL_CTX *(*SSL_CTX_new_pt)(const SSL_METHOD *method);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef SSL_METHOD *(*SSLv23_client_method_pt)(void);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef int (*SSL_write_pt)(SSL *ssl, const void *buf, int num);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef int (*SSL_CTX_use_PrivateKey_file_pt)(SSL_CTX *ctx, const char *file,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int type);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef void (*RAND_seed_pt)(const void *buf, int num);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef int (*SSL_get_error_pt)(const SSL *ssl, int ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef long (*ERR_get_error_pt)(void);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef char *(*ERR_error_string_pt)(unsigned long e, char *buf);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef int (*SSL_connect_pt)(SSL *ssl);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef int (*SSL_CTX_use_certificate_chain_file_pt)(SSL_CTX *ctx,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen const char *file);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef int (*SSL_set_fd_pt)(SSL *ssl, int fd);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef void (*SSL_free_pt)(SSL *ssl);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef int (*SSL_read_pt)(SSL *ssl, void *buf, int num);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef SSL *(*SSL_new_pt)(SSL_CTX *ctx);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef SSL_CTX *(*SSL_get_SSL_CTX_pt)(const SSL *ssl);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyentypedef void (*SSL_CTX_free_pt)(SSL_CTX *ctx);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_load_error_strings_pt SSL_load_error_strings_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_library_init_pt SSL_library_init_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_CTX_new_pt SSL_CTX_new_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSLv23_client_method_pt SSLv23_client_method_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_write_pt SSL_write_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_CTX_use_PrivateKey_file_pt SSL_CTX_use_PrivateKey_file_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic RAND_seed_pt RAND_seed_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_get_error_pt SSL_get_error_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic ERR_get_error_pt ERR_get_error_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic ERR_error_string_pt ERR_error_string_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_connect_pt SSL_connect_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_CTX_use_certificate_chain_file_pt
25351652d920ae27c5a56c199da581033ce763f6Vuong NguyenSSL_CTX_use_certificate_chain_file_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_set_fd_pt SSL_set_fd_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_free_pt SSL_free_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_read_pt SSL_read_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_new_pt SSL_new_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_get_SSL_CTX_pt SSL_get_SSL_CTX_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic SSL_CTX_free_pt SSL_CTX_free_f = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void *xmpp_dl = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic ldom_event_info_t event_table[] = {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen { LDOM_EVENT_UNKNOWN, "unknown" },
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen { LDOM_EVENT_ADD, "add-domain" },
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen { LDOM_EVENT_REMOVE, "remove-domain" },
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen { LDOM_EVENT_BIND, "bind-domain" },
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen { LDOM_EVENT_UNBIND, "unbind-domain" },
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen { LDOM_EVENT_START, "start-domain" },
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen { LDOM_EVENT_STOP, "stop-domain" },
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen { LDOM_EVENT_RESET, "domain-reset" },
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen { LDOM_EVENT_PANIC, "panic-domain" },
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen { LDOM_EVENT_MAX, NULL }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen};
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic int event_table_size = \
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen sizeof (event_table) / sizeof (ldom_event_info_t);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic xmlSAXHandler xml_handler = {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* internalSubsetSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* isStandaloneSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* hasInternalSubsetSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* hasExternalSubsetSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* resolveEntitySAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* getEntitySAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* entityDeclSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* notationDeclSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* attributeDeclSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* elementDeclSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* unparsedEntityDeclSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* setDocumentLocatorSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* startDocumentSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* endDocumentSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen start_element, /* startElementSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen end_element, /* endElementSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* referenceSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* charactersSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* ignorableWhitespaceSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* processingInstructionSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* commentSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* warningSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen error_func, /* errorSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* fatalErrorSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* getParameterEntitySAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* cdataBlockSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* externalSubsetSAXFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen 0, /* unsigned int */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* void * _private */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* startElementNsSAX2Func */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, /* endElementNsSAX2Func */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL /* xmlStructuredErrorFunc */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen};
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenend_element(void *state, const xmlChar *name)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmpp_conn_t *conn = (xmpp_conn_t *)state;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (xmlStrcmp(name, STREAM_NODE) == 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_DONE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else if (xmlStrcmp(name, STARTTLS_NODE) == 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) iowrite(conn, START_TLS, strlen(START_TLS));
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else if (xmlStrcmp(name, PROCEED_NODE) == 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (start_tls(conn)) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_FAILURE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else if (xmlStrcmp(name, FEATURE_NODE) == 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (conn->state == CONN_STATE_TLS) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_FEATURE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) iowrite(conn, (char *)LDM_REG_DOMAIN_EVENTS,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen strlen((char *)LDM_REG_DOMAIN_EVENTS));
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else if (xmlStrcmp(name, XML_LDM_INTERFACE) == 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_LDM_INTERFACE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else if (xmlStrcmp(name, XML_LDM_EVENT) == 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_LDM_EVENT;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else if (xmlStrcmp(name, XML_FAILURE) == 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_FAILURE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*ARGSUSED*/
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstart_element(void *state, const xmlChar *name, const xmlChar **attrs)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*ARGSUSED*/
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenerror_func(void *state, const char *msg, ...)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic int
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenxmpp_connect(xmpp_conn_t *conn)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int sock;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen struct sockaddr_in serveraddr;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen serveraddr.sin_family = AF_INET;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen serveraddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen serveraddr.sin_port = htons(XMPP_DEFAULT_PORT);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (connect(sock, (struct sockaddr *)(&serveraddr),
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen sizeof (struct sockaddr_in)) < 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) bzero(conn, sizeof (xmpp_conn_t));
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->fd = sock;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->tls_started = B_FALSE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->parser = xmlCreatePushParserCtxt(&xml_handler, (void *) conn,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL, NULL, NULL);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (conn->parser == NULL) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (0);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenxmpp_close(xmpp_conn_t *conn)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) close(conn->fd);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->fd = -1;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_UNKNOWN;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (conn->parser != NULL) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlFreeParserCtxt(conn->parser);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->parser = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (conn->tls_started) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen SSL_free_f(conn->ssl);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->ssl = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->tls_started = B_FALSE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic int
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenioread(xmpp_conn_t *conn, char *buf, int size)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int count;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (conn->tls_started) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen count = SSL_read_f(conn->ssl, buf, size);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen count = read(conn->fd, buf, size);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (count <= 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_FAILURE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (count);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic int
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyeniowrite(xmpp_conn_t *conn, char *buf, int size)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int count;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (conn->tls_started) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen count = SSL_write_f(conn->ssl, buf, size);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen count = send(conn->fd, buf, size, 0);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (count <= 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_FAILURE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (count);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * notify_event()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Description:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Notify all clients an event by going through the client list and invoke
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * the callback functions.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyennotify_event(ldom_event_t event, char *ldom_name)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen client_info_t *p;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_lock(&clt_list.lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen for (p = clt_list.head; p != NULL; p = p->next) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen p->cb(ldom_name, event, p->data);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_unlock(&clt_list.lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * xmpp_client_thr()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Description:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * The main entry fo the xmpp client thread.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*ARGSUSED*/
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic void *
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenxmpp_client_thr(void *data)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int rc = 0;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int cnt;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen char buf[XMPP_BUF_SIZE];
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmpp_conn_t conn;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pollfd_t pollfd[2];
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen struct pollfd *pipe_fd = &pollfd[0];
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen struct pollfd *recv_fd = &pollfd[1];
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen while (xmpp_enable) {
e6590bdc0d540003c7df26f1d3b66db7cae9be2cVuong Nguyen /* clear the conn struct */
e6590bdc0d540003c7df26f1d3b66db7cae9be2cVuong Nguyen bzero(&conn, sizeof (xmpp_conn_t));
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* keep making a connection until successfully */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen do {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (rc = xmpp_connect(&conn))
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) sleep(XMPP_SLEEP);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } while (rc != 0 && xmpp_enable);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* write the stream node */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen cnt = iowrite(&conn, (char *)STREAM_START,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen strlen((char *)STREAM_START));
e6590bdc0d540003c7df26f1d3b66db7cae9be2cVuong Nguyen if (cnt != strlen((char *)STREAM_START)) {
e6590bdc0d540003c7df26f1d3b66db7cae9be2cVuong Nguyen xmpp_close(&conn);
e6590bdc0d540003c7df26f1d3b66db7cae9be2cVuong Nguyen (void) sleep(XMPP_SLEEP);
e6590bdc0d540003c7df26f1d3b66db7cae9be2cVuong Nguyen continue;
e6590bdc0d540003c7df26f1d3b66db7cae9be2cVuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pipe_fd->fd = xmpp_notify_pipe[1]; /* notification pipe */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pipe_fd->events = POLLIN;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen recv_fd->fd = conn.fd; /* XMPP connection */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen recv_fd->events = POLLIN;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* process input */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen while ((conn.state != CONN_STATE_FAILURE) &&
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (conn.state != CONN_STATE_DONE) && xmpp_enable) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen /* Wait for xmpp input or the notification */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pipe_fd->revents = 0;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen recv_fd->revents = 0;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen if (poll(pollfd, 2, -1) <= 0) {
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen break;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen } else if (pipe_fd->revents & POLLIN) {
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen /* Receive a notification to exit */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen xmpp_close(&conn);
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pthread_exit((void *)NULL);
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen }
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Assume the document size of a ldmd response is
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * less than 1KB. This assumption is valid with the
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * current ldmd implementation.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Should the document size exceeds 1KB, the buffer
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * size should be revisited accordingly.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) memset(buf, 0, XMPP_BUF_SIZE);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen cnt = ioread(&conn, buf, XMPP_BUF_SIZE);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (cnt <= 0)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen break;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (rc = xmlParseChunk(conn.parser, buf, cnt, 0)) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn.state = CONN_STATE_FAILURE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen switch (conn.state) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen case CONN_STATE_LDM_INTERFACE:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen handle_ldm_resp(&conn, buf, cnt);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen break;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen case CONN_STATE_LDM_EVENT:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen handle_ldm_event(&conn, buf, cnt);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen break;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen default:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen break;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * For now, the parser is reset after every read.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * It should only be reset once after the ssl is opened
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * in the start_tls().
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) xmlCtxtResetPush(conn.parser, NULL, NULL, NULL,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen NULL);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmpp_close(&conn);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) sleep(XMPP_SLEEP);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (NULL);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * find_client()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Description:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Walk to the list to find a libldom client
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic client_info_t *
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenfind_client(ldom_hdl_t *lhp)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen client_info_t *p;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen for (p = clt_list.head; p != NULL; p = p->next) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (p->lhp == lhp)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (p);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (NULL);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * xmpp_add_client()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Description:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Add a libldom client from the client list.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenint
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenxmpp_add_client(ldom_hdl_t *lhp, ldom_reg_cb_t cb, ldom_cb_arg_t data)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen client_info_t *clt;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_lock(&clt_list.lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (find_client(lhp)) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* already exists */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_unlock(&clt_list.lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* new client */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt = (client_info_t *)ldom_alloc(sizeof (client_info_t));
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt->lhp = lhp;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt->cb = cb;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt->data = data;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt->next = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt->prev = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (clt_list.head == NULL && clt_list.tail == NULL) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt_list.head = clt;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt_list.tail = clt;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* append to the list */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt->prev = clt_list.tail;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt_list.tail->next = clt;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt_list.tail = clt;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_unlock(&clt_list.lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (0);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * xmpp_remove_client()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Description:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Remove a libldom client from the client list.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenint
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenxmpp_remove_client(ldom_hdl_t *lhp)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen client_info_t *p;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_lock(&clt_list.lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((p = find_client(lhp)) == NULL) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* not present */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_unlock(&clt_list.lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (clt_list.head == p && clt_list.tail == p) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* single item list */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt_list.head = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt_list.tail = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else if (clt_list.head == p) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* delete the head */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt_list.head = p->next;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt_list.head->prev = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else if (clt_list.tail == p) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* delete the tail */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt_list.tail = p->prev;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen clt_list.tail->next = NULL;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* delete a middle node */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen p->next->prev = p->prev;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen p->prev->next = p->next;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen ldom_free(p, sizeof (client_info_t));
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_unlock(&clt_list.lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (0);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * xmpp_stop()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Description:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Stop the xmpp client thread
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*ARGSUSED*/
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenvoid
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenxmpp_stop(void)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_lock(&xmpp_tid_lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmpp_enable = 0;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (xmpp_tid) {
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen /*
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen * Write a byte to the pipe to notify the xmpp thread to exit.
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen * Then wait for it to exit.
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen (void) write(xmpp_notify_pipe[0], "1", 1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_join(xmpp_tid, NULL);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmpp_tid = 0;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_unlock(&xmpp_tid_lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * xmpp_start()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Description:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Start the xmpp client thread if have not done so.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenvoid
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenxmpp_start(void)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmpp_conn_t conn;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* Check if the xmmp thread has already started */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_lock(&xmpp_tid_lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (xmpp_tid != 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_unlock(&xmpp_tid_lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* Check if the ldmd supports xmpp by opening a connection */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (xmpp_connect(&conn)) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_unlock(&xmpp_tid_lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmpp_close(&conn);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmpp_enable = 1;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /*
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen * create xmpp client thread for receiving domain events.
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen * The notification pipe is for stopping the thread.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen (void) notify_setup(xmpp_notify_pipe);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_create(&xmpp_tid, NULL, xmpp_client_thr, NULL);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) pthread_mutex_unlock(&xmpp_tid_lock);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Register a function to stop the above thread upon a termination
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) atexit(xmpp_stop);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * This routine will run through the first time we get a remote XMPP
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * connection. After that we will not need to do this again. It cannot be run
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * from main thread at start as we need to alert remote users if the TLS
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * handshake failed.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic int
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenload_SSL_lib()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int ret = 0;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* If we have already opened the library no need to do it again. */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (xmpp_dl != NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (0);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen /*
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen * If the libssl.so in not in the default path, attempt to open it
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen * under /usr/sfw/lib.
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen */
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen xmpp_dl = dlopen("libssl.so", RTLD_NOW);
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen if (xmpp_dl == NULL) {
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen xmpp_dl = dlopen("/usr/sfw/lib/libssl.so", RTLD_NOW);
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen if (xmpp_dl == NULL)
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen return (-1);
c95876f50441415f3e5c0424ecdbb7fb6db06f74Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_load_error_strings_f, SSL_load_error_strings_pt,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmpp_dl, "SSL_load_error_strings", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_library_init_f, SSL_library_init_pt, xmpp_dl,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen "SSL_library_init", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_CTX_new_f, SSL_CTX_new_pt, xmpp_dl,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen "SSL_CTX_new", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSLv23_client_method_f, SSLv23_client_method_pt, xmpp_dl,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen "SSLv23_client_method", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_write_f, SSL_write_pt, xmpp_dl, "SSL_write", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_CTX_use_PrivateKey_file_f,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen SSL_CTX_use_PrivateKey_file_pt, xmpp_dl,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen "SSL_CTX_use_PrivateKey_file", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(RAND_seed_f, RAND_seed_pt, xmpp_dl, "RAND_seed", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_get_error_f, SSL_get_error_pt, xmpp_dl,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen "SSL_get_error", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(ERR_get_error_f, ERR_get_error_pt, xmpp_dl,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen "ERR_get_error", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(ERR_error_string_f, ERR_error_string_pt, xmpp_dl,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen "ERR_error_string", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_connect_f, SSL_connect_pt, xmpp_dl, "SSL_connect",
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_CTX_use_certificate_chain_file_f,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen SSL_CTX_use_certificate_chain_file_pt, xmpp_dl,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen "SSL_CTX_use_certificate_chain_file", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_set_fd_f, SSL_set_fd_pt, xmpp_dl, "SSL_set_fd", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_free_f, SSL_free_pt, xmpp_dl, "SSL_free", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_read_f, SSL_read_pt, xmpp_dl, "SSL_read", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_new_f, SSL_new_pt, xmpp_dl, "SSL_new", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_get_SSL_CTX_f, SSL_get_SSL_CTX_pt, xmpp_dl,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen "SSL_get_SSL_CTX", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen FUNCTION_ADD(SSL_CTX_free_f, SSL_CTX_free_pt, xmpp_dl,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen "SSL_CTX_free", ret);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (ret < 0)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen else
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (0);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * start_tls()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Description:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Load the libssl.so if has not done so and open a ssl connection.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * It is assumed that there is one xmpp thread to use the ssl connection.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * If multi-thread xmpp clients use the ssl connection, addtional work is
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * needed to ensure the usage of the ssl be thread-safe.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstatic int
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenstart_tls(xmpp_conn_t *conn)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int rv, urand_fd;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen SSL_CTX *ssl_ctx;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen char rand_buf[RAND_BUF_SIZE];
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen rv = load_SSL_lib();
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (rv == -1) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (rv);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen urand_fd = open("/dev/random", O_RDONLY);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (urand_fd == -1) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) read(urand_fd, rand_buf, RAND_BUF_SIZE);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen SSL_library_init_f();
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen RAND_seed_f(rand_buf, RAND_BUF_SIZE);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen ssl_ctx = SSL_CTX_new_f(SSLv23_client_method_f());
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (ssl_ctx == NULL) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->ssl = SSL_new_f(ssl_ctx);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen rv = SSL_set_fd_f(conn->ssl, conn->fd);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (rv == 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen rv = SSL_connect_f(conn->ssl);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (rv != 1) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->tls_started = B_TRUE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_TLS;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) iowrite(conn, STREAM_START, strlen(STREAM_START));
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (0);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Find and return the first-level subnode (if any) of 'node' which has name
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * 'name'.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong NguyenxmlNodePtr
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenxml_find_subnode(xmlNodePtr node, const xmlChar *name)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlNodePtr subnode;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (node == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (NULL);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen subnode = node->xmlChildrenNode;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen while (subnode != NULL) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (((char *)subnode->name != NULL) &&
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (xmlStrcmp(subnode->name, name) == 0))
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen break;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen subnode = subnode->next;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (subnode);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * handle_ldm_resp()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Description:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Parse the ldmd response of the domain event registration for the failure
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * status. If found, set the connection to failure so that it will be
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * closed and a new xmpp connection is established.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenvoid
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenhandle_ldm_resp(xmpp_conn_t *conn, char *buf, size_t buf_size)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlDocPtr xml_output;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlNodePtr root, resp, status, cmd, action;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen char *status_str, *action_str;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((xml_output = xmlParseMemory((const char *)buf, buf_size)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((root = xmlDocGetRootElement(xml_output)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* get the cmd node */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((cmd = xml_find_subnode(root, XML_CMD)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (strcmp((char *)cmd->name, (char *)XML_CMD) != 0)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* get the action node and make sure it is the reg-domain-events */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((action = xml_find_subnode(cmd, XML_ACTION)) == NULL) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((action_str = (char *)xmlNodeGetContent(action)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (strcmp(action_str, XML_REGISTER_ACTION) != 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlFree(action_str);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlFree(action_str);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* check the status of the response */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((resp = xml_find_subnode(cmd, XML_RESPONSE)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((status = xml_find_subnode(resp, XML_STATUS)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((status_str = (char *)xmlNodeGetContent(status)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (strcmp(status_str, (char *)XML_FAILURE) == 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen conn->state = CONN_STATE_FAILURE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlFree(status_str);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * handle_ldm_event()
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Description:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Parse the LDM_event for the ldom name and domain action. Then invokes
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * the clients's callback to notify them the event.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen/*ARGSUSED*/
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenvoid
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenhandle_ldm_event(xmpp_conn_t *conn, char *buf, size_t buf_size)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int i;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlDocPtr xml_output;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlNodePtr root, cmd, action, data, envelope, content;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen char *action_str, *ldom_name;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen ldom_event_t event = LDOM_EVENT_UNKNOWN;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((xml_output = xmlParseMemory((const char *)buf, buf_size)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((root = xmlDocGetRootElement(xml_output)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* get the action such as bind-domain, unbind-domain, etc. */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((cmd = xml_find_subnode(root, XML_CMD)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((action = xml_find_subnode(cmd, XML_ACTION)) == NULL) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((action_str = (char *)xmlNodeGetContent(action)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen for (i = 0; i < event_table_size; i++) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (event_table[i].name != NULL &&
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen strcasecmp(event_table[i].name, action_str) == 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen event = event_table[i].id;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen break;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlFree(action_str);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* get the ldom name */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen data = xml_find_subnode(cmd, XML_DATA);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen envelope = xml_find_subnode(data, XML_ENVELOPE);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen content = xml_find_subnode(envelope, XML_CONTENT);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((ldom_name = (char *)xmlGetProp(content, XML_ATTR_ID)) == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* Notifies all the clients the event */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (VALID_LDOM_EVENT(event)) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen notify_event(event, ldom_name);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen xmlFree(ldom_name);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}