00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027
00028 #include <stdlib.h>
00029 #include <pwd.h>
00030 #include <unistd.h>
00031
00032 #include <qfile.h>
00033 #include <qsortedlist.h>
00034
00035 #include "ksslsettings.h"
00036 #include <kglobal.h>
00037 #include <kstandarddirs.h>
00038 #include <kdebug.h>
00039
00040
00041
00042 #ifdef KSSL_HAVE_SSL
00043 #define crypt _openssl_crypt
00044 #include <openssl/ssl.h>
00045 #undef crypt
00046 #endif
00047 #include <kopenssl.h>
00048
00049 #ifdef KSSL_HAVE_SSL
00050 #define sk_new d->kossl->sk_new
00051 #define sk_push d->kossl->sk_push
00052 #define sk_free d->kossl->sk_free
00053 #define sk_value d->kossl->sk_value
00054 #define sk_num d->kossl->sk_num
00055 #define sk_dup d->kossl->sk_dup
00056 #define sk_pop d->kossl->sk_pop
00057 #endif
00058
00059 class CipherNode {
00060 public:
00061 CipherNode(const char *_name, int _keylen) :
00062 name(_name), keylen(_keylen) {}
00063 QString name;
00064 int keylen;
00065 inline int operator==(CipherNode &x)
00066 { return ((x.keylen == keylen) && (x.name == name)); }
00067 inline int operator< (CipherNode &x) { return keylen < x.keylen; }
00068 inline int operator<=(CipherNode &x) { return keylen <= x.keylen; }
00069 inline int operator> (CipherNode &x) { return keylen > x.keylen; }
00070 inline int operator>=(CipherNode &x) { return keylen >= x.keylen; }
00071 };
00072
00073
00074 class KSSLSettingsPrivate {
00075 public:
00076 KSSLSettingsPrivate() {
00077 kossl = NULL;
00078 }
00079 ~KSSLSettingsPrivate() {
00080
00081 }
00082
00083 KOSSL *kossl;
00084 bool m_bUseEGD;
00085 bool m_bUseEFile;
00086 QString m_EGDPath;
00087 bool m_bSendX509;
00088 bool m_bPromptX509;
00089 };
00090
00091
00092
00093
00094
00095
00096
00097 KSSLSettings::KSSLSettings(bool readConfig) {
00098 d = new KSSLSettingsPrivate;
00099 m_cfg = new KConfig("cryptodefaults", false, false);
00100
00101 if (!KGlobal::dirs()->addResourceType("kssl", KStandardDirs::kde_default("data") + "kssl")) {
00102
00103 }
00104
00105 if (readConfig) load();
00106 }
00107
00108
00109
00110 KSSLSettings::~KSSLSettings() {
00111 delete m_cfg;
00112 delete d;
00113 }
00114
00115
00116 bool KSSLSettings::sslv2() const {
00117 return m_bUseSSLv2;
00118 }
00119
00120
00121 bool KSSLSettings::sslv3() const {
00122 return m_bUseSSLv3;
00123 }
00124
00125
00126 bool KSSLSettings::tlsv1() const {
00127 return m_bUseTLSv1;
00128 }
00129
00130
00131
00132
00133
00134 QString KSSLSettings::getCipherList() {
00135 QString clist;
00136 #ifdef KSSL_HAVE_SSL
00137 QString tcipher;
00138 bool firstcipher = true;
00139 SSL_METHOD *meth = 0L;
00140 QPtrList<CipherNode> cipherList;
00141
00142 cipherList.setAutoDelete(true);
00143
00144 if (!d->kossl)
00145 d->kossl = KOSSL::self();
00146
00147 if (m_bUseSSLv3 && m_bUseSSLv2)
00148 meth = d->kossl->SSLv23_client_method();
00149 else if(m_bUseSSLv3)
00150 meth = d->kossl->SSLv3_client_method();
00151 else if (m_bUseSSLv2)
00152 meth = d->kossl->SSLv2_client_method();
00153
00154 SSL_CTX *ctx = d->kossl->SSL_CTX_new(meth);
00155 SSL* ssl = d->kossl->SSL_new(ctx);
00156 STACK_OF(SSL_CIPHER)* sk = d->kossl->SSL_get_ciphers(ssl);
00157 int cnt = sk_SSL_CIPHER_num(sk);
00158 for (int i=0; i< cnt; i++) {
00159 SSL_CIPHER *sc = sk_SSL_CIPHER_value(sk,i);
00160 if (!sc)
00161 break;
00162
00163 if(!strcmp("SSLv2", d->kossl->SSL_CIPHER_get_version(sc)))
00164 m_cfg->setGroup("SSLv2");
00165 else
00166 m_cfg->setGroup("SSLv3");
00167
00168 tcipher.sprintf("cipher_%s", sc->name);
00169 int bits = d->kossl->SSL_CIPHER_get_bits(sc, NULL);
00170 if (m_cfg->readBoolEntry(tcipher, bits >= 56)) {
00171 CipherNode *xx = new CipherNode(sc->name,bits);
00172 if (!cipherList.contains(xx))
00173 cipherList.prepend(xx);
00174 else
00175 delete xx;
00176 }
00177 }
00178 d->kossl->SSL_free(ssl);
00179 d->kossl->SSL_CTX_free(ctx);
00180
00181
00182
00183 for (unsigned int i = 0; i < cipherList.count(); i++) {
00184 CipherNode *j = 0L;
00185 while ((j = cipherList.at(i)) != 0L) {
00186 if (j->name.contains("ADH-") || j->name.contains("NULL-") || j->name.contains("DES-CBC3-SHA") || j->name.contains("FZA")) {
00187 cipherList.remove(j);
00188 } else {
00189 break;
00190 }
00191 }
00192 }
00193
00194
00195 while (!cipherList.isEmpty()) {
00196 if (firstcipher)
00197 firstcipher = false;
00198 else clist.append(":");
00199 clist.append(cipherList.getLast()->name);
00200 cipherList.removeLast();
00201 }
00202
00203 kdDebug(7029) << "Cipher list is: " << clist << endl;
00204
00205 #endif
00206 return clist;
00207 }
00208
00209
00210 void KSSLSettings::load() {
00211 m_cfg->reparseConfiguration();
00212
00213 m_cfg->setGroup("TLS");
00214 m_bUseTLSv1 = m_cfg->readBoolEntry("Enabled", true);
00215
00216 m_cfg->setGroup("SSLv2");
00217 m_bUseSSLv2 = m_cfg->readBoolEntry("Enabled", false);
00218
00219 m_cfg->setGroup("SSLv3");
00220 m_bUseSSLv3 = m_cfg->readBoolEntry("Enabled", true);
00221
00222 m_cfg->setGroup("Warnings");
00223 m_bWarnOnEnter = m_cfg->readBoolEntry("OnEnter", false);
00224 m_bWarnOnLeave = m_cfg->readBoolEntry("OnLeave", true);
00225 m_bWarnOnUnencrypted = m_cfg->readBoolEntry("OnUnencrypted", true);
00226 m_bWarnOnMixed = m_cfg->readBoolEntry("OnMixed", true);
00227
00228 m_cfg->setGroup("Validation");
00229 m_bWarnSelfSigned = m_cfg->readBoolEntry("WarnSelfSigned", true);
00230 m_bWarnExpired = m_cfg->readBoolEntry("WarnExpired", true);
00231 m_bWarnRevoked = m_cfg->readBoolEntry("WarnRevoked", true);
00232
00233 m_cfg->setGroup("EGD");
00234 d->m_bUseEGD = m_cfg->readBoolEntry("UseEGD", false);
00235 d->m_bUseEFile = m_cfg->readBoolEntry("UseEFile", false);
00236 d->m_EGDPath = m_cfg->readPathEntry("EGDPath");
00237
00238 m_cfg->setGroup("Auth");
00239 d->m_bSendX509 = ("send" == m_cfg->readEntry("AuthMethod", ""));
00240 d->m_bPromptX509 = ("prompt" == m_cfg->readEntry("AuthMethod", ""));
00241
00242 #ifdef KSSL_HAVE_SSL
00243
00244
00245
00246 #endif
00247 }
00248
00249
00250 void KSSLSettings::defaults() {
00251 m_bUseTLSv1 = true;
00252 m_bUseSSLv2 = false;
00253 m_bUseSSLv3 = true;
00254 m_bWarnOnEnter = false;
00255 m_bWarnOnLeave = true;
00256 m_bWarnOnUnencrypted = true;
00257 m_bWarnOnMixed = true;
00258 m_bWarnSelfSigned = true;
00259 m_bWarnExpired = true;
00260 m_bWarnRevoked = true;
00261 d->m_bUseEGD = false;
00262 d->m_bUseEFile = false;
00263 d->m_EGDPath = "";
00264 }
00265
00266
00267 void KSSLSettings::save() {
00268 m_cfg->setGroup("TLS");
00269 m_cfg->writeEntry("Enabled", m_bUseTLSv1);
00270
00271 m_cfg->setGroup("SSLv2");
00272 m_cfg->writeEntry("Enabled", m_bUseSSLv2);
00273
00274 m_cfg->setGroup("SSLv3");
00275 m_cfg->writeEntry("Enabled", m_bUseSSLv3);
00276
00277 m_cfg->setGroup("Warnings");
00278 m_cfg->writeEntry("OnEnter", m_bWarnOnEnter);
00279 m_cfg->writeEntry("OnLeave", m_bWarnOnLeave);
00280 m_cfg->writeEntry("OnUnencrypted", m_bWarnOnUnencrypted);
00281 m_cfg->writeEntry("OnMixed", m_bWarnOnMixed);
00282
00283 m_cfg->setGroup("Validation");
00284 m_cfg->writeEntry("WarnSelfSigned", m_bWarnSelfSigned);
00285 m_cfg->writeEntry("WarnExpired", m_bWarnExpired);
00286 m_cfg->writeEntry("WarnRevoked", m_bWarnRevoked);
00287
00288 m_cfg->setGroup("EGD");
00289 m_cfg->writeEntry("UseEGD", d->m_bUseEGD);
00290 m_cfg->writeEntry("UseEFile", d->m_bUseEFile);
00291 m_cfg->writePathEntry("EGDPath", d->m_EGDPath);
00292
00293 m_cfg->sync();
00294
00295 #if 0
00296 #ifdef KSSL_HAVE_SSL
00297 m_cfg->setGroup("SSLv2");
00298 for (unsigned int i = 0; i < v2ciphers.count(); i++) {
00299 QString ciphername;
00300 ciphername.sprintf("cipher_%s", v2ciphers[i].ascii());
00301 if (v2selectedciphers.contains(v2ciphers[i])) {
00302 m_cfg->writeEntry(ciphername, true);
00303 } else m_cfg->writeEntry(ciphername, false);
00304 }
00305
00306 m_cfg->setGroup("SSLv3");
00307 for (unsigned int i = 0; i < v3ciphers.count(); i++) {
00308 QString ciphername;
00309 ciphername.sprintf("cipher_%s", v3ciphers[i].ascii());
00310 if (v3selectedciphers.contains(v3ciphers[i])) {
00311 m_cfg->writeEntry(ciphername, true);
00312 } else m_cfg->writeEntry(ciphername, false);
00313 }
00314 #endif
00315
00316 m_cfg->sync();
00317
00318
00319 QString cfgName(KGlobal::dirs()->findResource("config", "cryptodefaults"));
00320 if (!cfgName.isEmpty())
00321 ::chmod(QFile::encodeName(cfgName), 0600);
00322 #endif
00323 }
00324
00325
00326 bool KSSLSettings::warnOnEnter() const { return m_bWarnOnEnter; }
00327 void KSSLSettings::setWarnOnEnter(bool x) { m_bWarnOnEnter = x; }
00328 bool KSSLSettings::warnOnUnencrypted() const { return m_bWarnOnUnencrypted; }
00329 void KSSLSettings::setWarnOnUnencrypted(bool x) { m_bWarnOnUnencrypted = x; }
00330 bool KSSLSettings::warnOnLeave() const { return m_bWarnOnLeave; }
00331 void KSSLSettings::setWarnOnLeave(bool x) { m_bWarnOnLeave = x; }
00332 bool KSSLSettings::warnOnMixed() const { return m_bWarnOnMixed; }
00333 bool KSSLSettings::warnOnSelfSigned() const { return m_bWarnSelfSigned; }
00334 bool KSSLSettings::warnOnRevoked() const { return m_bWarnRevoked; }
00335 bool KSSLSettings::warnOnExpired() const { return m_bWarnExpired; }
00336 bool KSSLSettings::useEGD() const { return d->m_bUseEGD; }
00337 bool KSSLSettings::useEFile() const { return d->m_bUseEFile; }
00338 bool KSSLSettings::autoSendX509() const { return d->m_bSendX509; }
00339 bool KSSLSettings::promptSendX509() const { return d->m_bPromptX509; }
00340
00341 void KSSLSettings::setTLSv1(bool enabled) { m_bUseTLSv1 = enabled; }
00342 void KSSLSettings::setSSLv2(bool enabled) { m_bUseSSLv2 = enabled; }
00343 void KSSLSettings::setSSLv3(bool enabled) { m_bUseSSLv3 = enabled; }
00344
00345 QString& KSSLSettings::getEGDPath() { return d->m_EGDPath; }
00346
00347 #ifdef KSSL_HAVE_SSL
00348 #undef sk_new
00349 #undef sk_push
00350 #undef sk_free
00351 #undef sk_value
00352 #undef sk_num
00353 #undef sk_pop
00354 #undef sk_dup
00355 #endif
00356