1
0
forked from bip/bip

Add cipher specifications setting

Allow to configure cipher specifications for the listening bip
connection and for each outgoing IRC connection.

Closes #301
This commit is contained in:
Pierre-Louis Bonicoli 2016-04-13 01:04:33 +02:00
parent 20f39abc56
commit ab8e5eece1
10 changed files with 70 additions and 15 deletions

View File

@ -78,6 +78,14 @@ defined.
Set this to the full path of the cert/key pair bip should use to accept clients Set this to the full path of the cert/key pair bip should use to accept clients
SSL connections. SSL connections.
.TP
\fBclient_side_ciphers\fP
OpenSSL cipher lists used for clients SSL connections.
.TP
\fBssl_default_ciphers\fP
OpenSSL cipher lists used for server connections.
.TP .TP
\fBip\fP \fBip\fP
Ignored for the time being. Ignored for the time being.
@ -147,6 +155,10 @@ If true, BIP will connect to this network using SSL only. You cannot mix
SSL servers and non-SSL servers in the same network section. This is by choice, SSL servers and non-SSL servers in the same network section. This is by choice,
we believe it's a bad idea. we believe it's a bad idea.
.TP
\fBssl_ciphers\fP (override global ssl_default_ciphers)
OpenSSL cipher lists used for this network.
.TP .TP
\fBname\fP \fBname\fP
It's the network name used in the \fBconnection section\fP. Please note that It's the network name used in the \fBconnection section\fP. Please note that

View File

@ -20,6 +20,12 @@ client_side_ssl = false;
# serve SSL clients. If unset, it defaults to <bipdir>/bip.pem # serve SSL clients. If unset, it defaults to <bipdir>/bip.pem
#client_side_ssl_pem = "/path/to/pemfile"; #client_side_ssl_pem = "/path/to/pemfile";
# OpenSSL cipher lists used with SSL client connections.
#client_side_ciphers = "ECDHE-RSA-AES128-GCM-SHA256";
# Default OpenSSL cipher lists used with outgoing connections to IRC servers.
#ssl_default_ciphers = "ECDHE-RSA-AES128-GCM-SHA256";
# Define where the pidfile should be stored. Defaults to <bipdir>/bip.pid # Define where the pidfile should be stored. Defaults to <bipdir>/bip.pid
#pid_file="/var/run/bip/bip.pid"; #pid_file="/var/run/bip/bip.pid";

View File

@ -55,7 +55,8 @@ syn region bipMain start=/\%^/ end=/\%$/
syn keyword bipKeyword contained nextgroup=bipBoolV client_side_ssl syn keyword bipKeyword contained nextgroup=bipBoolV client_side_ssl
\ log log_system \ log log_system
syn keyword bipKeyword contained nextgroup=bipStringV log_root syn keyword bipKeyword contained nextgroup=bipStringV log_root
\ log_format pid_file client_side_ssl_pem \ log_format pid_file client_side_ssl_pem client_side_ciphers
\ ssl_default_ciphers
syn keyword bipKeyword contained nextgroup=bipNumericV port log_level syn keyword bipKeyword contained nextgroup=bipNumericV port log_level
\ log_sync_interval \ log_sync_interval
syn keyword bipKeyword contained nextgroup=bipIPV ip syn keyword bipKeyword contained nextgroup=bipIPV ip
@ -64,7 +65,7 @@ syn keyword bipKeyword contained nextgroup=bipIPV ip
syn region bipNetwork contained matchgroup=Macro syn region bipNetwork contained matchgroup=Macro
\ start=/network\s*{\s*/ end=/};/ \ start=/network\s*{\s*/ end=/};/
\ contains=bipNKeyword,bipServer,bipComment,bipEndError,bipWhite \ contains=bipNKeyword,bipServer,bipComment,bipEndError,bipWhite
syn keyword bipNKeyword contained nextgroup=bipStringV name syn keyword bipNKeyword contained nextgroup=bipStringV name ciphers
syn keyword bipNKeyword contained nextgroup=bipBoolV ssl syn keyword bipNKeyword contained nextgroup=bipBoolV ssl
" User block (level 1) " User block (level 1)
@ -85,7 +86,7 @@ syn region bipConnection contained matchgroup=Macro
\ start=/connection\s*{\s*/ end=/};/ \ start=/connection\s*{\s*/ end=/};/
\ contains=bipCoKeyword,bipChannel,bipComment,bipEndError,bipWhite \ contains=bipCoKeyword,bipChannel,bipComment,bipEndError,bipWhite
syn keyword bipCoKeyword contained nextgroup=bipBoolV follow_nick syn keyword bipCoKeyword contained nextgroup=bipBoolV follow_nick
\ ignore_first_nick \ ignore_first_nick log
syn keyword bipCoKeyword contained nextgroup=bipStringV name user nick syn keyword bipCoKeyword contained nextgroup=bipStringV name user nick
\ network password vhost away_nick on_connect_send realname \ network password vhost away_nick on_connect_send realname
\ no_client_away_msg ssl_check_mode \ no_client_away_msg ssl_check_mode

View File

@ -41,6 +41,8 @@ unsigned short conf_port;
int conf_css; int conf_css;
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
char *conf_ssl_certfile; char *conf_ssl_certfile;
char *conf_client_ciphers;
char *conf_server_default_ciphers;
#endif #endif
int conf_daemonize; int conf_daemonize;
char *conf_pid_file; char *conf_pid_file;
@ -358,6 +360,9 @@ static int add_network(bip_t *bip, list_t *data)
case LEX_SSL: case LEX_SSL:
n->ssl = t->ndata; n->ssl = t->ndata;
break; break;
case LEX_CIPHERS:
MOVE_STRING(n->ciphers, t->pdata);
break;
#endif #endif
case LEX_SERVER: case LEX_SERVER:
n->serverv = bip_realloc(n->serverv, (n->serverc + 1) n->serverv = bip_realloc(n->serverv, (n->serverc + 1)
@ -383,6 +388,12 @@ static int add_network(bip_t *bip, list_t *data)
free(t->pdata); free(t->pdata);
free(t); free(t);
} }
#ifdef HAVE_LIBSSL
if (!n->ciphers) {
n->ciphers = conf_server_default_ciphers;
}
#endif
return 1; return 1;
} }
@ -996,6 +1007,12 @@ int fireup(bip_t *bip, FILE *conf)
conf_reconn_timer = t->ndata; conf_reconn_timer = t->ndata;
break; break;
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
case LEX_DEFAULT_CIPHERS:
MOVE_STRING(conf_server_default_ciphers, t->pdata);
break;
case LEX_CSS_CIPHERS:
MOVE_STRING(conf_client_ciphers, t->pdata);
break;
case LEX_CSS: case LEX_CSS:
conf_css = t->ndata; conf_css = t->ndata;
break; break;
@ -1003,7 +1020,9 @@ int fireup(bip_t *bip, FILE *conf)
MOVE_STRING(conf_ssl_certfile, t->pdata); MOVE_STRING(conf_ssl_certfile, t->pdata);
break; break;
#else #else
case LEX_DEFAULT_CIPHERS:
case LEX_CSS: case LEX_CSS:
case LEX_CSS_CIPHERS:
case LEX_CSS_PEM: case LEX_CSS_PEM:
mylog(LOG_WARN, "Found SSL option whereas bip is " mylog(LOG_WARN, "Found SSL option whereas bip is "
"not built with SSL support."); "not built with SSL support.");
@ -1191,6 +1210,8 @@ int main(int argc, char **argv)
conf_pid_file = NULL; conf_pid_file = NULL;
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
conf_ssl_certfile = NULL; conf_ssl_certfile = NULL;
conf_client_ciphers = NULL;
conf_server_default_ciphers = NULL;
#endif #endif
while ((ch = getopt(argc, argv, "hvnf:s:")) != -1) { while ((ch = getopt(argc, argv, "hvnf:s:")) != -1) {

View File

@ -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_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_BLRESET_CONNECTION 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 LEX_AUTOJOIN_ON_KICK LEX_IGNORE_CAPAB LEX_RECONN_TIMER %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_CIPHERS LEX_CSS_CIPHERS LEX_DEFAULT_CIPHERS 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_BLRESET_CONNECTION 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 LEX_AUTOJOIN_ON_KICK LEX_IGNORE_CAPAB LEX_RECONN_TIMER
%union { %union {
int number; int number;
@ -99,6 +99,8 @@ command:
| LEX_PORT LEX_EQ LEX_INT { $$ = tuple_i_new(LEX_PORT, $3); } | LEX_PORT LEX_EQ LEX_INT { $$ = tuple_i_new(LEX_PORT, $3); }
| LEX_CSS LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_CSS, $3); } | LEX_CSS LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_CSS, $3); }
| LEX_CSS_PEM LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_CSS_PEM, $3); } | LEX_CSS_PEM LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_CSS_PEM, $3); }
| LEX_CSS_CIPHERS LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_CSS_CIPHERS, $3); }
| LEX_DEFAULT_CIPHERS LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_DEFAULT_CIPHERS, $3); }
| LEX_LOG LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_LOG, $3); } | LEX_LOG LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_LOG, $3); }
| LEX_LOG_SYSTEM LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_LOG_SYSTEM, $3); } | LEX_LOG_SYSTEM LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_LOG_SYSTEM, $3); }
| LEX_LOG_SYNC_INTERVAL LEX_EQ LEX_INT { $$ = tuple_i_new( | LEX_LOG_SYNC_INTERVAL LEX_EQ LEX_INT { $$ = tuple_i_new(
@ -132,6 +134,7 @@ network:
net_command: net_command:
LEX_NAME LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_NAME, $3); } LEX_NAME LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_NAME, $3); }
| LEX_SSL LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_SSL, $3); } | LEX_SSL LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_SSL, $3); }
| LEX_CIPHERS LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_CIPHERS, $3); }
| LEX_SERVER LEX_LBRA server LEX_RBRA { | LEX_SERVER LEX_LBRA server LEX_RBRA {
$$ = tuple_l_new(LEX_SERVER, $3); } $$ = tuple_l_new(LEX_SERVER, $3); }

View File

@ -24,8 +24,9 @@ static int ssl_cx_idx;
extern FILE *conf_global_log_file; extern FILE *conf_global_log_file;
static BIO *errbio = NULL; static BIO *errbio = NULL;
extern char *conf_ssl_certfile; extern char *conf_ssl_certfile;
extern char *conf_client_ciphers;
static int SSLize(connection_t *cn, int *nc); static int SSLize(connection_t *cn, int *nc);
static SSL_CTX *SSL_init_context(void); static SSL_CTX *SSL_init_context(char *ciphers);
/* SSH like trust management */ /* SSH like trust management */
int link_add_untrusted(void *ls, X509 *cert); int link_add_untrusted(void *ls, X509 *cert);
#endif #endif
@ -1240,7 +1241,7 @@ connection_t *accept_new(connection_t *cn)
mylog(LOG_DEBUG, "No SSL context available for " mylog(LOG_DEBUG, "No SSL context available for "
"accepted connections. " "accepted connections. "
"Initializing..."); "Initializing...");
if (!(sslctx = SSL_init_context())) { if (!(sslctx = SSL_init_context(conf_client_ciphers))) {
mylog(LOG_ERROR, "SSL context initialization " mylog(LOG_ERROR, "SSL context initialization "
"failed"); "failed");
connection_free(conn); connection_free(conn);
@ -1303,7 +1304,7 @@ static connection_t *_connection_new(char *dsthostname, char *dstport,
} }
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
static SSL_CTX *SSL_init_context(void) static SSL_CTX *SSL_init_context(char *ciphers)
{ {
int fd, flags, ret, rng; int fd, flags, ret, rng;
char buf[1025]; char buf[1025];
@ -1358,6 +1359,10 @@ prng_end:
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);
if (ciphers && !SSL_CTX_set_cipher_list(ctx, ciphers)) {
SSL_CTX_free(ctx);
return NULL;
}
return ctx; return ctx;
} }
@ -1518,13 +1523,13 @@ 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, char *ciphers, int check_mode,
char *check_store, char *ssl_client_certfile, int timeout) char *check_store, char *ssl_client_certfile, int timeout)
{ {
connection_t *conn; connection_t *conn;
conn = connection_init(1, 1, timeout, 0); conn = connection_init(1, 1, timeout, 0);
if (!(conn->ssl_ctx_h = SSL_init_context())) { if (!(conn->ssl_ctx_h = SSL_init_context(ciphers))) {
mylog(LOG_ERROR, "SSL context initialization failed"); mylog(LOG_ERROR, "SSL context initialization failed");
return conn; return conn;
} }
@ -1634,12 +1639,13 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
#endif #endif
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, char *ssl_ciphers, int ssl_check_mode,
char *ssl_client_certfile, int timeout) char *ssl_check_store, char *ssl_client_certfile, int timeout)
{ {
char dstportbuf[20], srcportbuf[20], *tmp; char dstportbuf[20], srcportbuf[20], *tmp;
#ifndef HAVE_LIBSSL #ifndef HAVE_LIBSSL
(void)ssl; (void)ssl;
(void)ssl_ciphers;
(void)ssl_check_mode; (void)ssl_check_mode;
(void)ssl_check_store; (void)ssl_check_store;
(void)ssl_client_certfile; (void)ssl_client_certfile;
@ -1656,7 +1662,7 @@ 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, tmp, ssl_ciphers, ssl_check_mode, ssl_check_store,
ssl_client_certfile, timeout); ssl_client_certfile, timeout);
else else
#endif #endif

View File

@ -91,7 +91,7 @@ typedef struct connection {
} connection_t; } connection_t;
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, char *ssl_ciphers, int ssl_check_mode,
char *ssl_check_store, char *ssl_client_certfile, 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);

View File

@ -2171,11 +2171,13 @@ connection_t *irc_server_connect(struct link *link)
link->network->serverv[link->cur_server].port, link->network->serverv[link->cur_server].port,
link->vhost, link->bind_port, link->vhost, link->bind_port,
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
link->network->ssl, link->ssl_check_mode, link->network->ssl,
link->network->ciphers,
link->ssl_check_mode,
link->user->ssl_check_store, link->user->ssl_check_store,
link->user->ssl_client_certfile, link->user->ssl_client_certfile,
#else #else
0, 0, NULL, NULL, 0, NULL, 0, NULL, NULL,
#endif #endif
CONNECT_TIMEOUT); CONNECT_TIMEOUT);
assert(conn); assert(conn);

View File

@ -93,6 +93,7 @@ struct network
char *name; char *name;
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
int ssl; int ssl;
char *ciphers;
#endif #endif
int serverc; int serverc;
struct server *serverv; struct server *serverv;

View File

@ -81,6 +81,8 @@ list_t *parse_conf(FILE *file, int *err)
"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; } "ssl_client_certfile" { return LEX_SSL_CLIENT_CERTFILE; }
"ssl_default_ciphers" { return LEX_DEFAULT_CIPHERS; }
"ciphers" { return LEX_CIPHERS; }
"key" { return LEX_KEY; } "key" { return LEX_KEY; }
"autojoin_on_kick" { return LEX_AUTOJOIN_ON_KICK; } "autojoin_on_kick" { return LEX_AUTOJOIN_ON_KICK; }
"channel" { return LEX_CHANNEL; } "channel" { return LEX_CHANNEL; }
@ -108,6 +110,7 @@ list_t *parse_conf(FILE *file, int *err)
"pid_file" { return LEX_PID_FILE; } "pid_file" { return LEX_PID_FILE; }
"bip_use_notice" { return LEX_BIP_USE_NOTICE; } "bip_use_notice" { return LEX_BIP_USE_NOTICE; }
"client_side_ssl_pem" { return LEX_CSS_PEM; } "client_side_ssl_pem" { return LEX_CSS_PEM; }
"client_side_ciphers" { return LEX_CSS_CIPHERS; }
"ignore_server_capab" { return LEX_IGNORE_CAPAB; } "ignore_server_capab" { return LEX_IGNORE_CAPAB; }
"reconn_timer" { return LEX_RECONN_TIMER; } "reconn_timer" { return LEX_RECONN_TIMER; }
\"[^"]*\" { \"[^"]*\" {