TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
9.9KB

  1. /* This file is part of the KDE project
  2. *
  3. * Copyright (C) 2000 George Staikos <staikos@kde.org>
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Library General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Library General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Library General Public License
  16. * along with this library; see the file COPYING.LIB. If not, write to
  17. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  18. * Boston, MA 02110-1301, USA.
  19. */
  20. #ifdef HAVE_CONFIG_H
  21. #include <config.h>
  22. #endif
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <stdlib.h>
  26. #include <pwd.h>
  27. #include <unistd.h>
  28. #include <tqfile.h>
  29. #include <tqsortedlist.h>
  30. #include "ksslsettings.h"
  31. #include <tdeglobal.h>
  32. #include <kstandarddirs.h>
  33. #include <kdebug.h>
  34. // this hack provided by Malte Starostik to avoid glibc/openssl bug
  35. // on some systems
  36. #ifdef KSSL_HAVE_SSL
  37. #define crypt _openssl_crypt
  38. #include <openssl/ssl.h>
  39. #undef crypt
  40. #endif
  41. #include <kopenssl.h>
  42. class CipherNode {
  43. public:
  44. CipherNode(const char *_name, int _keylen) :
  45. name(_name), keylen(_keylen) {}
  46. TQString name;
  47. int keylen;
  48. inline int operator==(CipherNode &x)
  49. { return ((x.keylen == keylen) && (x.name == name)); }
  50. inline int operator< (CipherNode &x) { return keylen < x.keylen; }
  51. inline int operator<=(CipherNode &x) { return keylen <= x.keylen; }
  52. inline int operator> (CipherNode &x) { return keylen > x.keylen; }
  53. inline int operator>=(CipherNode &x) { return keylen >= x.keylen; }
  54. };
  55. class KSSLSettingsPrivate {
  56. public:
  57. KSSLSettingsPrivate() {
  58. kossl = NULL; // try to delay this as long as possible
  59. }
  60. ~KSSLSettingsPrivate() {
  61. }
  62. KOSSL *kossl;
  63. bool m_bUseEGD;
  64. bool m_bUseEFile;
  65. TQString m_EGDPath;
  66. bool m_bSendX509;
  67. bool m_bPromptX509;
  68. };
  69. //
  70. // FIXME
  71. // Implementation note: for now, we only read cipher settings from disk,
  72. // and do not store them in memory. This should change.
  73. //
  74. KSSLSettings::KSSLSettings(bool readConfig) {
  75. d = new KSSLSettingsPrivate;
  76. m_cfg = new TDEConfig("cryptodefaults", false, false);
  77. if (!TDEGlobal::dirs()->addResourceType("kssl", TDEStandardDirs::kde_default("data") + "kssl")) {
  78. //kdDebug(7029) << "Error adding (kssl, share/apps/kssl)" << endl;
  79. }
  80. if (readConfig) load();
  81. }
  82. // we don't save settings incase it was a temporary object
  83. KSSLSettings::~KSSLSettings() {
  84. delete m_cfg;
  85. delete d;
  86. }
  87. bool KSSLSettings::sslv2() const {
  88. return m_bUseSSLv2;
  89. }
  90. bool KSSLSettings::sslv3() const {
  91. return m_bUseSSLv3;
  92. }
  93. bool KSSLSettings::tlsv1() const {
  94. return m_bUseTLSv1;
  95. }
  96. // FIXME: we should make a default list available if this fails
  97. // since OpenSSL seems to just choose any old thing if it's given an
  98. // empty list. This behavior is not confirmed though.
  99. TQString KSSLSettings::getCipherList() {
  100. TQString clist;
  101. #ifdef KSSL_HAVE_SSL
  102. TQString tcipher;
  103. bool firstcipher = true;
  104. SSL_METHOD *meth = 0L;
  105. TQPtrList<CipherNode> cipherList;
  106. cipherList.setAutoDelete(true);
  107. if (!d->kossl)
  108. d->kossl = KOSSL::self();
  109. if (m_bUseSSLv3 && m_bUseSSLv2)
  110. meth = d->kossl->TLS_client_method();
  111. else if(m_bUseSSLv3)
  112. meth = d->kossl->SSLv3_client_method();
  113. else if (m_bUseSSLv2)
  114. meth = d->kossl->SSLv2_client_method();
  115. SSL_CTX *ctx = d->kossl->SSL_CTX_new(meth);
  116. SSL* ssl = d->kossl->SSL_new(ctx);
  117. STACK_OF(SSL_CIPHER)* sk = d->kossl->SSL_get_ciphers(ssl);
  118. int cnt = d->kossl->OPENSSL_sk_num(sk);
  119. for (int i=0; i< cnt; i++) {
  120. SSL_CIPHER *sc = reinterpret_cast<SSL_CIPHER*>(d->kossl->OPENSSL_sk_value(sk,i));
  121. if (!sc)
  122. break;
  123. if(!strcmp("SSLv2", d->kossl->SSL_CIPHER_get_version(sc)))
  124. m_cfg->setGroup("SSLv2");
  125. else
  126. m_cfg->setGroup("SSLv3");
  127. tcipher.sprintf("cipher_%s", d->kossl->SSL_CIPHER_get_name(sc));
  128. int bits = d->kossl->SSL_CIPHER_get_bits(sc, NULL);
  129. if (m_cfg->readBoolEntry(tcipher, bits >= 56)) {
  130. CipherNode *xx = new CipherNode(d->kossl->SSL_CIPHER_get_name(sc),bits);
  131. if (!cipherList.contains(xx))
  132. cipherList.prepend(xx);
  133. else
  134. delete xx;
  135. }
  136. }
  137. d->kossl->SSL_free(ssl);
  138. d->kossl->SSL_CTX_free(ctx);
  139. // Remove any ADH ciphers as per RFC2246
  140. // Also remove NULL ciphers and 168bit ciphers
  141. for (unsigned int i = 0; i < cipherList.count(); i++) {
  142. CipherNode *j = 0L;
  143. while ((j = cipherList.at(i)) != 0L) {
  144. if (j->name.contains("ADH-") || j->name.contains("NULL-") || j->name.contains("DES-CBC3-SHA") || j->name.contains("FZA")) {
  145. cipherList.remove(j);
  146. } else {
  147. break;
  148. }
  149. }
  150. }
  151. // now assemble the list cipher1:cipher2:cipher3:...:ciphern
  152. while (!cipherList.isEmpty()) {
  153. if (firstcipher)
  154. firstcipher = false;
  155. else clist.append(":");
  156. clist.append(cipherList.getLast()->name);
  157. cipherList.removeLast();
  158. } // while
  159. kdDebug(7029) << "Cipher list is: " << clist << endl;
  160. #endif
  161. return clist;
  162. }
  163. // FIXME - sync these up so that we can use them with the control module!!
  164. void KSSLSettings::load() {
  165. m_cfg->reparseConfiguration();
  166. m_cfg->setGroup("TLS");
  167. m_bUseTLSv1 = m_cfg->readBoolEntry("Enabled", true);
  168. #if OPENSSL_VERSION_NUMBER >= 0x10100000L || defined(OPENSSL_NO_SSL2)
  169. m_bUseSSLv2 = false;
  170. #else
  171. m_cfg->setGroup("SSLv2");
  172. m_bUseSSLv2 = m_cfg->readBoolEntry("Enabled", false);
  173. #endif
  174. #if defined(OPENSSL_NO_SSL3)
  175. m_bUseSSLv3 = false;
  176. #else
  177. m_cfg->setGroup("SSLv3");
  178. m_bUseSSLv3 = m_cfg->readBoolEntry("Enabled", true);
  179. #endif
  180. m_cfg->setGroup("Warnings");
  181. m_bWarnOnEnter = m_cfg->readBoolEntry("OnEnter", false);
  182. m_bWarnOnLeave = m_cfg->readBoolEntry("OnLeave", true);
  183. m_bWarnOnUnencrypted = m_cfg->readBoolEntry("OnUnencrypted", true);
  184. m_bWarnOnMixed = m_cfg->readBoolEntry("OnMixed", true);
  185. m_cfg->setGroup("Validation");
  186. m_bWarnSelfSigned = m_cfg->readBoolEntry("WarnSelfSigned", true);
  187. m_bWarnExpired = m_cfg->readBoolEntry("WarnExpired", true);
  188. m_bWarnRevoked = m_cfg->readBoolEntry("WarnRevoked", true);
  189. m_cfg->setGroup("EGD");
  190. d->m_bUseEGD = m_cfg->readBoolEntry("UseEGD", false);
  191. d->m_bUseEFile = m_cfg->readBoolEntry("UseEFile", false);
  192. d->m_EGDPath = m_cfg->readPathEntry("EGDPath");
  193. m_cfg->setGroup("Auth");
  194. d->m_bSendX509 = ("send" == m_cfg->readEntry("AuthMethod", ""));
  195. d->m_bPromptX509 = ("prompt" == m_cfg->readEntry("AuthMethod", ""));
  196. #ifdef KSSL_HAVE_SSL
  197. #endif
  198. }
  199. void KSSLSettings::defaults() {
  200. m_bUseTLSv1 = true;
  201. m_bUseSSLv2 = false;
  202. m_bUseSSLv3 = true;
  203. m_bWarnOnEnter = false;
  204. m_bWarnOnLeave = true;
  205. m_bWarnOnUnencrypted = true;
  206. m_bWarnOnMixed = true;
  207. m_bWarnSelfSigned = true;
  208. m_bWarnExpired = true;
  209. m_bWarnRevoked = true;
  210. d->m_bUseEGD = false;
  211. d->m_bUseEFile = false;
  212. d->m_EGDPath = "";
  213. }
  214. void KSSLSettings::save() {
  215. m_cfg->setGroup("TLS");
  216. m_cfg->writeEntry("Enabled", m_bUseTLSv1);
  217. m_cfg->setGroup("SSLv2");
  218. m_cfg->writeEntry("Enabled", m_bUseSSLv2);
  219. m_cfg->setGroup("SSLv3");
  220. m_cfg->writeEntry("Enabled", m_bUseSSLv3);
  221. m_cfg->setGroup("Warnings");
  222. m_cfg->writeEntry("OnEnter", m_bWarnOnEnter);
  223. m_cfg->writeEntry("OnLeave", m_bWarnOnLeave);
  224. m_cfg->writeEntry("OnUnencrypted", m_bWarnOnUnencrypted);
  225. m_cfg->writeEntry("OnMixed", m_bWarnOnMixed);
  226. m_cfg->setGroup("Validation");
  227. m_cfg->writeEntry("WarnSelfSigned", m_bWarnSelfSigned);
  228. m_cfg->writeEntry("WarnExpired", m_bWarnExpired);
  229. m_cfg->writeEntry("WarnRevoked", m_bWarnRevoked);
  230. m_cfg->setGroup("EGD");
  231. m_cfg->writeEntry("UseEGD", d->m_bUseEGD);
  232. m_cfg->writeEntry("UseEFile", d->m_bUseEFile);
  233. m_cfg->writePathEntry("EGDPath", d->m_EGDPath);
  234. m_cfg->sync();
  235. // FIXME - ciphers
  236. #if 0
  237. #ifdef KSSL_HAVE_SSL
  238. m_cfg->setGroup("SSLv2");
  239. for (unsigned int i = 0; i < v2ciphers.count(); i++) {
  240. TQString ciphername;
  241. ciphername.sprintf("cipher_%s", v2ciphers[i].ascii());
  242. if (v2selectedciphers.contains(v2ciphers[i])) {
  243. m_cfg->writeEntry(ciphername, true);
  244. } else m_cfg->writeEntry(ciphername, false);
  245. }
  246. m_cfg->setGroup("SSLv3");
  247. for (unsigned int i = 0; i < v3ciphers.count(); i++) {
  248. TQString ciphername;
  249. ciphername.sprintf("cipher_%s", v3ciphers[i].ascii());
  250. if (v3selectedciphers.contains(v3ciphers[i])) {
  251. m_cfg->writeEntry(ciphername, true);
  252. } else m_cfg->writeEntry(ciphername, false);
  253. }
  254. #endif
  255. m_cfg->sync();
  256. // insure proper permissions -- contains sensitive data
  257. TQString cfgName(TDEGlobal::dirs()->findResource("config", "cryptodefaults"));
  258. if (!cfgName.isEmpty())
  259. ::chmod(TQFile::encodeName(cfgName), 0600);
  260. #endif
  261. }
  262. bool KSSLSettings::warnOnEnter() const { return m_bWarnOnEnter; }
  263. void KSSLSettings::setWarnOnEnter(bool x) { m_bWarnOnEnter = x; }
  264. bool KSSLSettings::warnOnUnencrypted() const { return m_bWarnOnUnencrypted; }
  265. void KSSLSettings::setWarnOnUnencrypted(bool x) { m_bWarnOnUnencrypted = x; }
  266. bool KSSLSettings::warnOnLeave() const { return m_bWarnOnLeave; }
  267. void KSSLSettings::setWarnOnLeave(bool x) { m_bWarnOnLeave = x; }
  268. bool KSSLSettings::warnOnMixed() const { return m_bWarnOnMixed; }
  269. bool KSSLSettings::warnOnSelfSigned() const { return m_bWarnSelfSigned; }
  270. bool KSSLSettings::warnOnRevoked() const { return m_bWarnRevoked; }
  271. bool KSSLSettings::warnOnExpired() const { return m_bWarnExpired; }
  272. bool KSSLSettings::useEGD() const { return d->m_bUseEGD; }
  273. bool KSSLSettings::useEFile() const { return d->m_bUseEFile; }
  274. bool KSSLSettings::autoSendX509() const { return d->m_bSendX509; }
  275. bool KSSLSettings::promptSendX509() const { return d->m_bPromptX509; }
  276. void KSSLSettings::setTLSv1(bool enabled) { m_bUseTLSv1 = enabled; }
  277. void KSSLSettings::setSSLv2(bool enabled) { m_bUseSSLv2 = enabled; }
  278. void KSSLSettings::setSSLv3(bool enabled) { m_bUseSSLv3 = enabled; }
  279. TQString& KSSLSettings::getEGDPath() { return d->m_EGDPath; }