From: "Luis R. Rodriguez" <[email protected]> irssi supports letting you specify the client SSL password using the ssl_pass primitive on the configuration file. Its a terrible idea to be putting passwords on unencrypted files though so some security rational folks won't ever want to do this. If you currently don't supply one irssi goes on and assumes you do not want to use it, and depending on the server configuration it may or not fail on the SSL handshake and not allow any connection to go through... Freenode lets you authenticate your username with an SSL client certificate so this is not desirable behavior.
This adds support to irrsi so that if an SSL client certificate was supplied and if no password was set we prompt the user for one. Upon disconnects we won't have to re-enter the password but just in case for whatever reason SSL needs it we redraw the screen to the console screen should the user have to enter a password again. Users that do not have a password on the SSL client certificate can just either enter an empty password upon the prompt or set an empty password on the configuration file. Its a bad idea to be using passwordless client certificate files anyway, so let them do a bit more work. We only prompt for a password if and only if the client certificate was set, if you have different client certificate files or use the client certificate for different connections you'll be asked for a password for each server SSL connection. Signed-off-by: Luis R. Rodriguez <[email protected]> --- src/core/network-openssl.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 768fd54..23258c6 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -37,6 +37,8 @@ #include <validator/val_dane.h> #endif +void window_console(void); + /* ssl i/o channel object */ typedef struct { @@ -434,6 +436,7 @@ static int get_pem_password_callback(char *buffer, int max_length, int rwflag, v char *password; size_t length; + /* should not happen but better leave it */ if (pass == NULL) return 0; @@ -447,6 +450,35 @@ static int get_pem_password_callback(char *buffer, int max_length, int rwflag, v return length; } +static int prompt_pem_password_callback(char *buffer, int max_length, int rwflag, void *pem_cert) +{ + char *password, prompt[256]; + size_t length; + + window_console(); + + /* should not happen but better leave it */ + if (pem_cert == NULL) + return 0; + + snprintf(prompt, 256, "Enter Passphrase for %s:", (char *) pem_cert); + password = getpass(prompt); + + if (!password) + return 0; + + length = strlen(password); + + if (length > max_length) + return 0; + + strncpy(buffer, password, length); + irssi_redraw(); + + return length; +} + + static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_REC *server) { GIOSSLChannel *chan; @@ -476,8 +508,13 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_ return NULL; } SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); - SSL_CTX_set_default_passwd_cb(ctx, get_pem_password_callback); - SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)mypass); + if (mypass) { + SSL_CTX_set_default_passwd_cb(ctx, get_pem_password_callback); + SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)mypass); + } else if (mycert && *mycert) { + SSL_CTX_set_default_passwd_cb(ctx, prompt_pem_password_callback); + SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)mycert); + } if (mycert && *mycert) { char *scert = NULL, *spkey = NULL; -- 2.0.3
