Handle SSL-client auth. Fix crash on del_conn when the link never got connected at all.
This commit is contained in:
parent
c90578103c
commit
f1cc6451f5
@ -246,6 +246,12 @@ allows a "ssh-like" private key generation scheme. Note that in basic mode:
|
|||||||
\fBssl_check_store\fP (default: \fBnot set\fP)
|
\fBssl_check_store\fP (default: \fBnot set\fP)
|
||||||
This repository is browsed by BIP when a SSL certificate or CA check is needed.
|
This repository is browsed by BIP when a SSL certificate or CA check is needed.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fBssl_client_certfile\fP (default: \fBnot set\fP)
|
||||||
|
Some networks (OFTC at least) allow you to authenticate to nickserv services
|
||||||
|
using a client side certificate. Make this variable point to the .pem file to
|
||||||
|
use this feature.
|
||||||
|
|
||||||
.SH CONNECTION SUB-SECTION
|
.SH CONNECTION SUB-SECTION
|
||||||
|
|
||||||
Each connection section associates a user to the networks he wants to connect
|
Each connection section associates a user to the networks he wants to connect
|
||||||
|
@ -85,8 +85,9 @@ user {
|
|||||||
# bipmkpw
|
# bipmkpw
|
||||||
password = "3880f2b39b3b9cb507b052b695d2680859bfc327";
|
password = "3880f2b39b3b9cb507b052b695d2680859bfc327";
|
||||||
|
|
||||||
# Set this to true if you want "bip4ever" to have admin privileges on bip
|
# Set this to true if you want "bip4ever" to have admin privileges on
|
||||||
# He'll be able to RELOAD bip and see all users' configuration (except pass)
|
# bip He'll be able to RELOAD bip and see all users' configuration
|
||||||
|
# (except pass)
|
||||||
admin = true;
|
admin = true;
|
||||||
|
|
||||||
# When bip_use_notice is true, bip will send internal messages like
|
# When bip_use_notice is true, bip will send internal messages like
|
||||||
@ -114,6 +115,12 @@ user {
|
|||||||
# `c_rehash .' in it
|
# `c_rehash .' in it
|
||||||
ssl_check_store = "/home/bip4ever/.bip/trustedcerts.txt";
|
ssl_check_store = "/home/bip4ever/.bip/trustedcerts.txt";
|
||||||
|
|
||||||
|
# Some networks (OFTC at least) allow you to authenticate to nickserv
|
||||||
|
# using client side certificates, see
|
||||||
|
# http://www.oftc.net/oftc/NickServ/CertFP
|
||||||
|
# This is where you put your user's certificate.
|
||||||
|
# ssl_client_certfile = "/home/bip4ever/.bip/bip4ever_client_auth.pem";
|
||||||
|
|
||||||
# These will be the default for each connections
|
# These will be the default for each connections
|
||||||
default_nick = "bip4ever";
|
default_nick = "bip4ever";
|
||||||
default_user = "bip4ever";
|
default_user = "bip4ever";
|
||||||
|
@ -684,6 +684,7 @@ static int add_user(bip_t *bip, list_t *data, struct historical_directives *hds)
|
|||||||
FREE(u->default_realname);
|
FREE(u->default_realname);
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
FREE(u->ssl_check_store);
|
FREE(u->ssl_check_store);
|
||||||
|
FREE(u->ssl_client_certfile);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,7 +754,11 @@ static int add_user(bip_t *bip, list_t *data, struct historical_directives *hds)
|
|||||||
case LEX_SSL_CHECK_STORE:
|
case LEX_SSL_CHECK_STORE:
|
||||||
MOVE_STRING(u->ssl_check_store, t->pdata);
|
MOVE_STRING(u->ssl_check_store, t->pdata);
|
||||||
break;
|
break;
|
||||||
|
case LEX_SSL_CLIENT_CERTFILE:
|
||||||
|
MOVE_STRING(u->ssl_client_certfile, t->pdata);
|
||||||
|
break;
|
||||||
#else
|
#else
|
||||||
|
case LEX_SSL_CLIENT_CERTFILE:
|
||||||
case LEX_SSL_CHECK_MODE:
|
case LEX_SSL_CHECK_MODE:
|
||||||
case LEX_SSL_CHECK_STORE:
|
case LEX_SSL_CHECK_STORE:
|
||||||
mylog(LOG_WARN, "Found SSL option whereas bip is "
|
mylog(LOG_WARN, "Found SSL option whereas bip is "
|
||||||
@ -878,6 +883,7 @@ void user_kill(bip_t *bip, struct user *user)
|
|||||||
|
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
MAYFREE(user->ssl_check_store);
|
MAYFREE(user->ssl_check_store);
|
||||||
|
MAYFREE(user->ssl_client_certfile);
|
||||||
#endif
|
#endif
|
||||||
free(user);
|
free(user);
|
||||||
}
|
}
|
||||||
@ -1522,6 +1528,9 @@ noroom:
|
|||||||
bip_notify(ic, "SSL check mode '%s', stored into '%s'",
|
bip_notify(ic, "SSL check mode '%s', stored into '%s'",
|
||||||
checkmode2text(u->ssl_check_mode),
|
checkmode2text(u->ssl_check_mode),
|
||||||
STRORNULL(u->ssl_check_store));
|
STRORNULL(u->ssl_check_store));
|
||||||
|
if (u->ssl_client_certfile)
|
||||||
|
bip_notify(ic, "SSL client certificate stored into '%s'",
|
||||||
|
u->ssl_client_certfile);
|
||||||
#endif
|
#endif
|
||||||
bip_notify(ic, "Defaults nick: %s, user: %s, realname: %s",
|
bip_notify(ic, "Defaults nick: %s, user: %s, realname: %s",
|
||||||
STRORNULL(u->default_nick), STRORNULL(u->default_username),
|
STRORNULL(u->default_nick), STRORNULL(u->default_username),
|
||||||
|
@ -68,7 +68,7 @@ struct tuple *tuple_l_new(int type, void *p)
|
|||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%token LEX_IP LEX_EQ LEX_PORT LEX_CSS LEX_SEMICOLON LEX_CONNECTION LEX_NETWORK LEX_LBRA LEX_RBRA LEX_USER LEX_NAME LEX_NICK LEX_SERVER LEX_PASSWORD LEX_SRCIP LEX_HOST LEX_VHOST LEX_SOURCE_PORT LEX_NONE LEX_COMMENT LEX_BUNCH LEX_REALNAME LEX_SSL LEX_SSL_CHECK_MODE LEX_SSL_CHECK_STORE LEX_CHANNEL LEX_KEY LEX_LOG_ROOT LEX_LOG_FORMAT LEX_LOG_LEVEL LEX_BACKLOG_LINES LEX_BACKLOG_NO_TIMESTAMP LEX_BACKLOG LEX_LOG LEX_LOG_SYSTEM LEX_LOG_SYNC_INTERVAL LEX_FOLLOW_NICK LEX_ON_CONNECT_SEND LEX_AWAY_NICK LEX_PID_FILE LEX_IGN_FIRST_NICK LEX_ALWAYS_BACKLOG LEX_BLRESET_ON_TALK LEX_DEFAULT_USER LEX_DEFAULT_NICK LEX_DEFAULT_REALNAME LEX_NO_CLIENT_AWAY_MSG LEX_BL_MSG_ONLY LEX_ADMIN LEX_BIP_USE_NOTICE LEX_CSS_PEM
|
%token LEX_IP LEX_EQ LEX_PORT LEX_CSS LEX_SEMICOLON LEX_CONNECTION LEX_NETWORK LEX_LBRA LEX_RBRA LEX_USER LEX_NAME LEX_NICK LEX_SERVER LEX_PASSWORD LEX_SRCIP LEX_HOST LEX_VHOST LEX_SOURCE_PORT LEX_NONE LEX_COMMENT LEX_BUNCH LEX_REALNAME LEX_SSL LEX_SSL_CHECK_MODE LEX_SSL_CHECK_STORE LEX_SSL_CLIENT_CERTFILE LEX_CHANNEL LEX_KEY LEX_LOG_ROOT LEX_LOG_FORMAT LEX_LOG_LEVEL LEX_BACKLOG_LINES LEX_BACKLOG_NO_TIMESTAMP LEX_BACKLOG LEX_LOG LEX_LOG_SYSTEM LEX_LOG_SYNC_INTERVAL LEX_FOLLOW_NICK LEX_ON_CONNECT_SEND LEX_AWAY_NICK LEX_PID_FILE LEX_IGN_FIRST_NICK LEX_ALWAYS_BACKLOG LEX_BLRESET_ON_TALK LEX_DEFAULT_USER LEX_DEFAULT_NICK LEX_DEFAULT_REALNAME LEX_NO_CLIENT_AWAY_MSG LEX_BL_MSG_ONLY LEX_ADMIN LEX_BIP_USE_NOTICE LEX_CSS_PEM
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
int number;
|
int number;
|
||||||
@ -150,6 +150,8 @@ usr_command:
|
|||||||
LEX_SSL_CHECK_MODE, $3); }
|
LEX_SSL_CHECK_MODE, $3); }
|
||||||
| LEX_SSL_CHECK_STORE LEX_EQ LEX_STRING { $$ = tuple_s_new(
|
| LEX_SSL_CHECK_STORE LEX_EQ LEX_STRING { $$ = tuple_s_new(
|
||||||
LEX_SSL_CHECK_STORE, $3); }
|
LEX_SSL_CHECK_STORE, $3); }
|
||||||
|
| LEX_SSL_CLIENT_CERTFILE LEX_EQ LEX_STRING { $$ = tuple_s_new(
|
||||||
|
LEX_SSL_CLIENT_CERTFILE, $3); }
|
||||||
| LEX_DEFAULT_USER LEX_EQ LEX_STRING {
|
| LEX_DEFAULT_USER LEX_EQ LEX_STRING {
|
||||||
$$ = tuple_s_new(LEX_DEFAULT_USER, $3); }
|
$$ = tuple_s_new(LEX_DEFAULT_USER, $3); }
|
||||||
| LEX_DEFAULT_NICK LEX_EQ LEX_STRING {
|
| LEX_DEFAULT_NICK LEX_EQ LEX_STRING {
|
||||||
|
@ -1057,6 +1057,14 @@ connection_t *accept_new(connection_t *cn)
|
|||||||
connection_free(conn);
|
connection_free(conn);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (!SSL_CTX_use_certificate_chain_file(sslctx,
|
||||||
|
conf_ssl_certfile))
|
||||||
|
mylog(LOG_WARN, "SSL: Unable to load "
|
||||||
|
"certificate file");
|
||||||
|
if (!SSL_CTX_use_PrivateKey_file(sslctx,
|
||||||
|
conf_ssl_certfile,
|
||||||
|
SSL_FILETYPE_PEM))
|
||||||
|
mylog(LOG_WARN, "SSL: Unable to load key file");
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->ssl_h = SSL_new(sslctx);
|
conn->ssl_h = SSL_new(sslctx);
|
||||||
@ -1154,14 +1162,8 @@ prng_end:
|
|||||||
|
|
||||||
/* allocated by function */
|
/* allocated by function */
|
||||||
ctx = SSL_CTX_new(SSLv23_method());
|
ctx = SSL_CTX_new(SSLv23_method());
|
||||||
if (!SSL_CTX_use_certificate_chain_file(ctx,conf_ssl_certfile))
|
|
||||||
mylog(LOG_WARN, "SSL: Unable to load certificate file");
|
|
||||||
if (!SSL_CTX_use_PrivateKey_file(ctx, conf_ssl_certfile,
|
|
||||||
SSL_FILETYPE_PEM))
|
|
||||||
mylog(LOG_WARN, "SSL: Unable to load key file");
|
|
||||||
|
|
||||||
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
|
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
|
||||||
SSL_CTX_set_timeout(ctx,(long)60);
|
SSL_CTX_set_timeout(ctx, (long)60);
|
||||||
SSL_CTX_set_options(ctx, SSL_OP_ALL);
|
SSL_CTX_set_options(ctx, SSL_OP_ALL);
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
@ -1321,7 +1323,7 @@ static int SSLize(connection_t *cn, int *nc)
|
|||||||
|
|
||||||
static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
|
static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
|
||||||
char *srchostname, char *srcport, int check_mode,
|
char *srchostname, char *srcport, int check_mode,
|
||||||
char *check_store, int timeout)
|
char *check_store, char *ssl_client_certfile, int timeout)
|
||||||
{
|
{
|
||||||
connection_t *conn;
|
connection_t *conn;
|
||||||
|
|
||||||
@ -1330,6 +1332,7 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
|
|||||||
mylog(LOG_ERROR, "SSL context initialization failed");
|
mylog(LOG_ERROR, "SSL context initialization failed");
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->cert = NULL;
|
conn->cert = NULL;
|
||||||
conn->ssl_check_mode = check_mode;
|
conn->ssl_check_mode = check_mode;
|
||||||
|
|
||||||
@ -1368,6 +1371,18 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
|
|||||||
fatal("Unknown SSL cert check mode.");
|
fatal("Unknown SSL cert check mode.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssl_client_certfile) {
|
||||||
|
if (!SSL_CTX_use_certificate_chain_file(conn->ssl_ctx_h,
|
||||||
|
ssl_client_certfile))
|
||||||
|
mylog(LOG_WARN, "SSL: Unable to load certificate file");
|
||||||
|
else if (!SSL_CTX_use_PrivateKey_file(conn->ssl_ctx_h,
|
||||||
|
ssl_client_certfile, SSL_FILETYPE_PEM))
|
||||||
|
mylog(LOG_WARN, "SSL: Unable to load key file");
|
||||||
|
else
|
||||||
|
mylog(LOG_INFO, "SSL: using %s pem file as client SSL "
|
||||||
|
"certificate", ssl_client_certfile);
|
||||||
|
}
|
||||||
|
|
||||||
conn->ssl_h = SSL_new(conn->ssl_ctx_h);
|
conn->ssl_h = SSL_new(conn->ssl_ctx_h);
|
||||||
if (conn->ssl_h == NULL) {
|
if (conn->ssl_h == NULL) {
|
||||||
mylog(LOG_ERROR, "Unable to allocate SSL structures");
|
mylog(LOG_ERROR, "Unable to allocate SSL structures");
|
||||||
@ -1392,7 +1407,7 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
|
|||||||
|
|
||||||
connection_t *connection_new(char *dsthostname, int dstport, char *srchostname,
|
connection_t *connection_new(char *dsthostname, int dstport, char *srchostname,
|
||||||
int srcport, int ssl, int ssl_check_mode, char *ssl_check_store,
|
int srcport, int ssl, int ssl_check_mode, char *ssl_check_store,
|
||||||
int timeout)
|
char *ssl_client_certfile, int timeout)
|
||||||
{
|
{
|
||||||
char dstportbuf[20], srcportbuf[20], *tmp;
|
char dstportbuf[20], srcportbuf[20], *tmp;
|
||||||
#ifndef HAVE_LIBSSL
|
#ifndef HAVE_LIBSSL
|
||||||
@ -1412,7 +1427,8 @@ connection_t *connection_new(char *dsthostname, int dstport, char *srchostname,
|
|||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
if (ssl)
|
if (ssl)
|
||||||
return _connection_new_SSL(dsthostname, dstportbuf, srchostname,
|
return _connection_new_SSL(dsthostname, dstportbuf, srchostname,
|
||||||
tmp, ssl_check_mode, ssl_check_store, timeout);
|
tmp, ssl_check_mode, ssl_check_store,
|
||||||
|
ssl_client_certfile, timeout);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
return _connection_new(dsthostname, dstportbuf, srchostname,
|
return _connection_new(dsthostname, dstportbuf, srchostname,
|
||||||
|
@ -92,7 +92,7 @@ typedef struct connection {
|
|||||||
|
|
||||||
connection_t *connection_new(char *dsthostname, int dstport, char *srchostname,
|
connection_t *connection_new(char *dsthostname, int dstport, char *srchostname,
|
||||||
int srcport, int ssl, int ssl_check_mode,
|
int srcport, int ssl, int ssl_check_mode,
|
||||||
char *ssl_check_store,int timeout);
|
char *ssl_check_store, char *ssl_client_certfile, int timeout);
|
||||||
connection_t *listen_new(char *hostname, int port, int ssl);
|
connection_t *listen_new(char *hostname, int port, int ssl);
|
||||||
connection_t *accept_new(connection_t *cn);
|
connection_t *accept_new(connection_t *cn);
|
||||||
void connection_free(connection_t *cn);
|
void connection_free(connection_t *cn);
|
||||||
|
10
src/irc.c
10
src/irc.c
@ -2053,6 +2053,7 @@ connection_t *irc_server_connect(struct link *link)
|
|||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
link->network->ssl, link->ssl_check_mode,
|
link->network->ssl, link->ssl_check_mode,
|
||||||
link->user->ssl_check_store,
|
link->user->ssl_check_store,
|
||||||
|
link->user->ssl_client_certfile,
|
||||||
#else
|
#else
|
||||||
0, 0, NULL,
|
0, 0, NULL,
|
||||||
#endif
|
#endif
|
||||||
@ -2470,9 +2471,12 @@ struct link *irc_link_new()
|
|||||||
|
|
||||||
void link_kill(bip_t *bip, struct link *link)
|
void link_kill(bip_t *bip, struct link *link)
|
||||||
{
|
{
|
||||||
list_remove(&bip->conn_list, CONN(link->l_server));
|
/* in case in never got connected */
|
||||||
server_cleanup(link->l_server);
|
if (link->l_server) {
|
||||||
irc_server_free(link->l_server);
|
list_remove(&bip->conn_list, CONN(link->l_server));
|
||||||
|
server_cleanup(link->l_server);
|
||||||
|
irc_server_free(link->l_server);
|
||||||
|
}
|
||||||
while (link->l_clientc) {
|
while (link->l_clientc) {
|
||||||
struct link_client *lc = link->l_clientv[0];
|
struct link_client *lc = link->l_clientv[0];
|
||||||
if (lc == bip->reloading_client)
|
if (lc == bip->reloading_client)
|
||||||
|
@ -88,6 +88,7 @@ struct user {
|
|||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
int ssl_check_mode;
|
int ssl_check_mode;
|
||||||
char *ssl_check_store;
|
char *ssl_check_store;
|
||||||
|
char *ssl_client_certfile;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hash_t connections;
|
hash_t connections;
|
||||||
|
@ -87,6 +87,7 @@ list_t *parse_conf(FILE *file, int *err)
|
|||||||
"ssl" { return LEX_SSL; }
|
"ssl" { return LEX_SSL; }
|
||||||
"ssl_check_mode" { return LEX_SSL_CHECK_MODE; }
|
"ssl_check_mode" { return LEX_SSL_CHECK_MODE; }
|
||||||
"ssl_check_store" { return LEX_SSL_CHECK_STORE; }
|
"ssl_check_store" { return LEX_SSL_CHECK_STORE; }
|
||||||
|
"ssl_client_certfile" { return LEX_SSL_CLIENT_CERTFILE; }
|
||||||
"key" { return LEX_KEY; }
|
"key" { return LEX_KEY; }
|
||||||
"channel" { return LEX_CHANNEL; }
|
"channel" { return LEX_CHANNEL; }
|
||||||
"log_level" { return LEX_LOG_LEVEL; }
|
"log_level" { return LEX_LOG_LEVEL; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user