diff --git a/AUTHORS b/AUTHORS index c83382afc..699c5ed6f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -93,6 +93,7 @@ The following submitted code, packages or analysis, and deserve special thanks: Aaron Bieber John West Jeroen Budts + Zed Jorarard Thanks to the following, who submitted detailed bug reports and excellent suggestions: diff --git a/NEWS b/NEWS index d7035b01c..7f47597f0 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,7 @@ New configuration options in taskwarrior 2.3.0 - 'taskd.key' specifies the task server key for encryption. - 'taskd.ca' specifies the task server CA. - 'taskd.trust' overrides certificate checking. + - 'taskd.ciphers' overrides default cipher selection. - 'debug.tls' shows TLS log information, for debugging. - The configuration file supports JSON encoding of unicode characters \uNNNN. diff --git a/doc/man/taskrc.5.in b/doc/man/taskrc.5.in index 937959f97..d479ea0dd 100644 --- a/doc/man/taskrc.5.in +++ b/doc/man/taskrc.5.in @@ -1375,11 +1375,19 @@ using a self-signed certificate. Optional. .TP .B taskd.trust=yes|no .RS -If you do not specify a CA certificate when your task server is usㄟng a self- +If you do not specify a CA certificate when your task server is using a self- signed certificate, you can override the certificate validation by setting this value to 'yes'. Default is not to trust a server certificate. .RE +.TP +.B taskd.ciphers=NORMAL +Override of the cipher selection. The set of ciphers used by TLS may be +controlled by both server and client. There must be some overlap between +client and server supported ciphers, or communication cannot occur. +Default is "NORMAL". See GnuTLS documentation for full details. +.RE + .SH "CREDITS & COPYRIGHTS" Copyright (C) 2006 \- 2013 P. Beckingham, F. Hernandez. diff --git a/src/Config.cpp b/src/Config.cpp index f3c32cf01..7b26a3a6f 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -301,6 +301,7 @@ std::string Config::_defaults = "#taskd.certificate \n" "#taskd.credentials //\n" "#taskd.server :\n" + "taskd.ciphers=NORMAL\n" "\n" "# Aliases - alternate names for commands\n" "alias.rm=delete # Alias for the delete command\n" diff --git a/src/TLSClient.cpp b/src/TLSClient.cpp index d1b75c8e6..c3973996e 100644 --- a/src/TLSClient.cpp +++ b/src/TLSClient.cpp @@ -154,6 +154,12 @@ void TLSClient::trust (bool value) } } +//////////////////////////////////////////////////////////////////////////////// +void TLSClient::ciphers (const std::string& cipher_list) +{ + _ciphers = cipher_list; +} + //////////////////////////////////////////////////////////////////////////////// void TLSClient::init ( const std::string& ca, @@ -181,9 +187,12 @@ void TLSClient::init ( #endif gnutls_init (&_session, GNUTLS_CLIENT); - // Use default priorities. + // Use default priorities unless overridden. + if (_ciphers == "") + _ciphers = "NORMAL"; + const char *err; - int ret = gnutls_priority_set_direct (_session, "NORMAL", &err); + int ret = gnutls_priority_set_direct (_session, _ciphers.c_str (), &err); if (ret < 0) { if (_debug && ret == GNUTLS_E_INVALID_REQUEST) diff --git a/src/TLSClient.h b/src/TLSClient.h index baccec7c5..bb6b5eedd 100644 --- a/src/TLSClient.h +++ b/src/TLSClient.h @@ -40,6 +40,7 @@ public: void limit (int); void debug (int); void trust (bool); + void ciphers (const std::string&); void init (const std::string&, const std::string&, const std::string&); void connect (const std::string&, const std::string&); void bye (); @@ -51,6 +52,7 @@ private: std::string _ca; std::string _cert; std::string _key; + std::string _ciphers; gnutls_certificate_credentials_t _credentials; gnutls_session_t _session; int _socket; diff --git a/src/commands/CmdDiagnostics.cpp b/src/commands/CmdDiagnostics.cpp index 36f835281..e9e4cb0b6 100644 --- a/src/commands/CmdDiagnostics.cpp +++ b/src/commands/CmdDiagnostics.cpp @@ -238,6 +238,10 @@ int CmdDiagnostics::execute (std::string& output) << context.config.get ("taskd.key") << "\n"; + out << " Ciphers: " + << context.config.get ("taskd.ciphers") + << "\n"; + // Get credentials, but mask out the key. std::string credentials = context.config.get ("taskd.credentials"); std::string::size_type last_slash = credentials.rfind ('/'); diff --git a/src/commands/CmdShow.cpp b/src/commands/CmdShow.cpp index b2fa840ac..8bba15d22 100644 --- a/src/commands/CmdShow.cpp +++ b/src/commands/CmdShow.cpp @@ -191,6 +191,7 @@ int CmdShow::execute (std::string& output) " taskd.server" " taskd.ca" " taskd.certificate" + " taskd.ciphers" " taskd.credentials" " taskd.key" " taskd.trust" diff --git a/src/commands/CmdSync.cpp b/src/commands/CmdSync.cpp index 4ec46bdab..e7f53957f 100644 --- a/src/commands/CmdSync.cpp +++ b/src/commands/CmdSync.cpp @@ -345,6 +345,7 @@ bool CmdSync::send ( client.debug (context.config.getInteger ("debug.tls")); client.trust (trust); + client.ciphers (context.config.get ("taskd.ciphers")); client.init (ca, certificate, key); client.connect (server, port); client.send (request.serialize () + "\n");