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
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
\fBip\fP
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,
we believe it's a bad idea.
.TP
\fBssl_ciphers\fP (override global ssl_default_ciphers)
OpenSSL cipher lists used for this network.
.TP
\fBname\fP
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
#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
#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
\ log log_system
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
\ log_sync_interval
syn keyword bipKeyword contained nextgroup=bipIPV ip
@ -64,7 +65,7 @@ syn keyword bipKeyword contained nextgroup=bipIPV ip
syn region bipNetwork contained matchgroup=Macro
\ start=/network\s*{\s*/ end=/};/
\ 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
" User block (level 1)
@ -85,7 +86,7 @@ syn region bipConnection contained matchgroup=Macro
\ start=/connection\s*{\s*/ end=/};/
\ contains=bipCoKeyword,bipChannel,bipComment,bipEndError,bipWhite
syn keyword bipCoKeyword contained nextgroup=bipBoolV follow_nick
\ ignore_first_nick
\ ignore_first_nick log
syn keyword bipCoKeyword contained nextgroup=bipStringV name user nick
\ network password vhost away_nick on_connect_send realname
\ no_client_away_msg ssl_check_mode

View File

@ -41,6 +41,8 @@ unsigned short conf_port;
int conf_css;
#ifdef HAVE_LIBSSL
char *conf_ssl_certfile;
char *conf_client_ciphers;
char *conf_server_default_ciphers;
#endif
int conf_daemonize;
char *conf_pid_file;
@ -358,6 +360,9 @@ static int add_network(bip_t *bip, list_t *data)
case LEX_SSL:
n->ssl = t->ndata;
break;
case LEX_CIPHERS:
MOVE_STRING(n->ciphers, t->pdata);
break;
#endif
case LEX_SERVER:
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);
}
#ifdef HAVE_LIBSSL
if (!n->ciphers) {
n->ciphers = conf_server_default_ciphers;
}
#endif
return 1;
}
@ -996,6 +1007,12 @@ int fireup(bip_t *bip, FILE *conf)
conf_reconn_timer = t->ndata;
break;
#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:
conf_css = t->ndata;
break;
@ -1003,7 +1020,9 @@ int fireup(bip_t *bip, FILE *conf)
MOVE_STRING(conf_ssl_certfile, t->pdata);
break;
#else
case LEX_DEFAULT_CIPHERS:
case LEX_CSS:
case LEX_CSS_CIPHERS:
case LEX_CSS_PEM:
mylog(LOG_WARN, "Found SSL option whereas bip is "
"not built with SSL support.");
@ -1191,6 +1210,8 @@ int main(int argc, char **argv)
conf_pid_file = NULL;
#ifdef HAVE_LIBSSL
conf_ssl_certfile = NULL;
conf_client_ciphers = NULL;
conf_server_default_ciphers = NULL;
#endif
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 {
int number;
@ -99,6 +99,8 @@ command:
| 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_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_SYSTEM LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_LOG_SYSTEM, $3); }
| LEX_LOG_SYNC_INTERVAL LEX_EQ LEX_INT { $$ = tuple_i_new(
@ -132,6 +134,7 @@ network:
net_command:
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_CIPHERS LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_CIPHERS, $3); }
| LEX_SERVER LEX_LBRA server LEX_RBRA {
$$ = tuple_l_new(LEX_SERVER, $3); }

View File

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

View File

@ -91,7 +91,7 @@ typedef struct connection {
} connection_t;
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);
connection_t *listen_new(char *hostname, int port, int ssl);
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->vhost, link->bind_port,
#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_client_certfile,
#else
0, 0, NULL, NULL,
0, NULL, 0, NULL, NULL,
#endif
CONNECT_TIMEOUT);
assert(conn);

View File

@ -93,6 +93,7 @@ struct network
char *name;
#ifdef HAVE_LIBSSL
int ssl;
char *ciphers;
#endif
int serverc;
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_store" { return LEX_SSL_CHECK_STORE; }
"ssl_client_certfile" { return LEX_SSL_CLIENT_CERTFILE; }
"ssl_default_ciphers" { return LEX_DEFAULT_CIPHERS; }
"ciphers" { return LEX_CIPHERS; }
"key" { return LEX_KEY; }
"autojoin_on_kick" { return LEX_AUTOJOIN_ON_KICK; }
"channel" { return LEX_CHANNEL; }
@ -108,6 +110,7 @@ list_t *parse_conf(FILE *file, int *err)
"pid_file" { return LEX_PID_FILE; }
"bip_use_notice" { return LEX_BIP_USE_NOTICE; }
"client_side_ssl_pem" { return LEX_CSS_PEM; }
"client_side_ciphers" { return LEX_CSS_CIPHERS; }
"ignore_server_capab" { return LEX_IGNORE_CAPAB; }
"reconn_timer" { return LEX_RECONN_TIMER; }
\"[^"]*\" {