add callback functionality on certificate verification failure
Based on the differences to libmesode this functionality has been added. It allows a library-user to set a callback for cases where the TLS stack can't verify a received certificate and let the end-user decide what to do. examples/basic implements an example handler of said functionality. Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
This commit is contained in:
@@ -19,6 +19,20 @@
|
||||
#define KA_TIMEOUT 60
|
||||
#define KA_INTERVAL 1
|
||||
|
||||
static void print_tlscert(const xmpp_tlscert_t *cert)
|
||||
{
|
||||
const char *name;
|
||||
size_t n;
|
||||
for (n = 0; n < (unsigned)XMPP_CERT_ELEMENT_MAX; ++n) {
|
||||
printf("\t%32s: %s\n", xmpp_tlscert_get_description(n),
|
||||
xmpp_tlscert_get_string(cert, n));
|
||||
}
|
||||
n = 0;
|
||||
while ((name = xmpp_tlscert_get_dnsname(cert, n++)) != NULL)
|
||||
printf("\t%32s: %s\n", "dnsName", name);
|
||||
printf("PEM:\n%s\n", xmpp_tlscert_get_pem(cert));
|
||||
}
|
||||
|
||||
/* define a handler for connection events */
|
||||
static void conn_handler(xmpp_conn_t *conn,
|
||||
xmpp_conn_event_t status,
|
||||
@@ -37,6 +51,11 @@ static void conn_handler(xmpp_conn_t *conn,
|
||||
secured = xmpp_conn_is_secured(conn);
|
||||
fprintf(stderr, "DEBUG: connection is %s.\n",
|
||||
secured ? "secured" : "NOT secured");
|
||||
if (secured) {
|
||||
xmpp_tlscert_t *cert = xmpp_conn_get_peer_cert(conn);
|
||||
print_tlscert(cert);
|
||||
xmpp_tlscert_free(cert);
|
||||
}
|
||||
xmpp_disconnect(conn);
|
||||
} else {
|
||||
fprintf(stderr, "DEBUG: disconnected\n");
|
||||
@@ -44,6 +63,23 @@ static void conn_handler(xmpp_conn_t *conn,
|
||||
}
|
||||
}
|
||||
|
||||
static int certfail_handler(const xmpp_tlscert_t *cert,
|
||||
const char *const errormsg)
|
||||
{
|
||||
char read_char[16] = {0};
|
||||
printf("Received certificate can't be validated!\n");
|
||||
printf("Reason: %s\n", errormsg);
|
||||
print_tlscert(cert);
|
||||
printf("Do you agree to connect?\n[y(es)|n(o)]: ");
|
||||
fflush(stdout);
|
||||
if (fgets(read_char, sizeof(read_char), stdin) == NULL) {
|
||||
printf("fgets() failed\n");
|
||||
return 0;
|
||||
}
|
||||
printf("\n");
|
||||
return read_char[0] == 'y' || read_char[0] == 'Y';
|
||||
}
|
||||
|
||||
static void usage(int exit_code)
|
||||
{
|
||||
fprintf(stderr,
|
||||
@@ -52,10 +88,15 @@ static void usage(int exit_code)
|
||||
" --jid <jid> The JID to use to authenticate.\n"
|
||||
" --pass <pass> The password of the JID.\n"
|
||||
" --tls-cert <cert> Path to client certificate.\n"
|
||||
" --capath <path> Path to an additional CA trust store "
|
||||
"(directory).\n"
|
||||
" --cafile <path> Path to an additional CA trust store "
|
||||
"(single file).\n"
|
||||
" --tls-key <key> Path to private key.\n\n"
|
||||
" --disable-tls Disable TLS.\n"
|
||||
" --mandatory-tls Deny plaintext connection.\n"
|
||||
" --trust-tls Trust TLS certificate.\n"
|
||||
" --enable-certfail Enable certfail handler.\n"
|
||||
" --legacy-ssl Use old style SSL.\n"
|
||||
" --legacy-auth Allow legacy authentication.\n"
|
||||
" --verbose Increase the verbosity level.\n"
|
||||
@@ -71,9 +112,10 @@ int main(int argc, char **argv)
|
||||
xmpp_ctx_t *ctx;
|
||||
xmpp_conn_t *conn;
|
||||
xmpp_log_t *log;
|
||||
char *jid = NULL, *password = NULL, *cert = NULL, *key = NULL, *host = NULL;
|
||||
char *jid = NULL, *password = NULL, *cert = NULL, *key = NULL, *host = NULL,
|
||||
*capath = NULL, *cafile = NULL;
|
||||
long flags = 0;
|
||||
int tcp_keepalive = 0, verbosity = 0;
|
||||
int tcp_keepalive = 0, verbosity = 0, certfail = 0;
|
||||
int i;
|
||||
unsigned long port = 0;
|
||||
|
||||
@@ -95,6 +137,8 @@ int main(int argc, char **argv)
|
||||
verbosity++;
|
||||
else if (strcmp(argv[i], "--tcp-keepalive") == 0)
|
||||
tcp_keepalive = 1;
|
||||
else if (strcmp(argv[i], "--enable-certfail") == 0)
|
||||
certfail = 1;
|
||||
else if ((strcmp(argv[i], "--jid") == 0) && (++i < argc))
|
||||
jid = argv[i];
|
||||
else if ((strcmp(argv[i], "--pass") == 0) && (++i < argc))
|
||||
@@ -103,6 +147,10 @@ int main(int argc, char **argv)
|
||||
cert = argv[i];
|
||||
else if ((strcmp(argv[i], "--tls-key") == 0) && (++i < argc))
|
||||
key = argv[i];
|
||||
else if ((strcmp(argv[i], "--capath") == 0) && (++i < argc))
|
||||
capath = argv[i];
|
||||
else if ((strcmp(argv[i], "--cafile") == 0) && (++i < argc))
|
||||
cafile = argv[i];
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -147,6 +195,13 @@ int main(int argc, char **argv)
|
||||
if (password)
|
||||
xmpp_conn_set_pass(conn, password);
|
||||
|
||||
if (certfail)
|
||||
xmpp_conn_set_certfail_handler(conn, certfail_handler);
|
||||
if (capath)
|
||||
xmpp_conn_set_capath(conn, capath);
|
||||
if (cafile)
|
||||
xmpp_conn_set_cafile(conn, cafile);
|
||||
|
||||
/* initiate connection */
|
||||
if (xmpp_connect_client(conn, host, port, conn_handler, ctx) == XMPP_EOK) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user