Index: networkmanager/backends/NetworkManager/settings/802-1xdbus.cpp
===================================================================
--- networkmanager.orig/backends/NetworkManager/settings/802-1xdbus.cpp
+++ networkmanager/backends/NetworkManager/settings/802-1xdbus.cpp
@@ -32,6 +32,12 @@ void Security8021xDbus::fromMap(const QV
         if (map.contains(QLatin1String(NM_SETTING_802_1X_CA_PATH))) {
             setting->setCapath(map.value(QLatin1String(NM_SETTING_802_1X_CA_PATH)).value<QString>());
         }
+        if (map.contains(QLatin1String(NM_SETTING_802_1X_SUBJECT_MATCH))) {
+            setting->setSubjectmatch(map.value(QLatin1String(NM_SETTING_802_1X_SUBJECT_MATCH)).value<QString>());
+        }
+        if (map.contains(QLatin1String(NM_SETTING_802_1X_ALTSUBJECT_MATCHES))) {
+            setting->setAltsubjectmatches(map.value(QLatin1String(NM_SETTING_802_1X_ALTSUBJECT_MATCHES)).value<QString>());
+        }
         if (map.contains(QLatin1String(NM_SETTING_802_1X_CLIENT_CERT))) {
             setting->setClientcert(map.value(QLatin1String(NM_SETTING_802_1X_CLIENT_CERT)).value<QByteArray>());
         }
@@ -56,6 +62,12 @@ void Security8021xDbus::fromMap(const QV
         if (map.contains(QLatin1String(NM_SETTING_802_1X_PHASE2_CA_PATH))) {
             setting->setPhase2capath(map.value(QLatin1String(NM_SETTING_802_1X_PHASE2_CA_PATH)).value<QString>());
         }
+        if (map.contains(QLatin1String(NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH))) {
+            setting->setPhase2subjectmatch(map.value(QLatin1String(NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH)).value<QString>());
+        }
+        if (map.contains(QLatin1String(NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES))) {
+            setting->setPhase2altsubjectmatches(map.value(QLatin1String(NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES)).value<QString>());
+        }
         if (map.contains(QLatin1String(NM_SETTING_802_1X_PHASE2_CLIENT_CERT))) {
             setting->setPhase2clientcert(map.value(QLatin1String(NM_SETTING_802_1X_PHASE2_CLIENT_CERT)).value<QByteArray>());
         }
@@ -105,10 +117,17 @@ QVariantMap Security8021xDbus::toMap()
         }
         if (!setting->cacert().isEmpty()) {
             map.insert(QLatin1String(NM_SETTING_802_1X_CA_CERT), setting->cacert());
+            kDebug() << "cacert: " << setting->cacert();
         }
         if (!setting->capath().isEmpty()) {
             map.insert(QLatin1String(NM_SETTING_802_1X_CA_PATH), setting->capath());
         }
+        if (!setting->subjectmatch().isEmpty()) {
+            map.insert(QLatin1String(NM_SETTING_802_1X_SUBJECT_MATCH), setting->subjectmatch());
+        }
+        if (!setting->altsubjectmatches().isEmpty()) {
+            map.insert(QLatin1String(NM_SETTING_802_1X_ALTSUBJECT_MATCHES), setting->altsubjectmatches());
+        }
         if (!setting->clientcert().isEmpty()) {
             map.insert(QLatin1String(NM_SETTING_802_1X_CLIENT_CERT), setting->clientcert());
         }
@@ -178,6 +197,10 @@ QVariantMap Security8021xDbus::toMap()
             map.insert(QLatin1String(NM_SETTING_802_1X_PHASE2_CA_CERT), setting->phase2cacert());
         if (!setting->phase2capath().isEmpty())
             map.insert(QLatin1String(NM_SETTING_802_1X_PHASE2_CA_PATH), setting->phase2capath());
+        if (!setting->phase2subjectmatch().isEmpty())
+            map.insert(QLatin1String(NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH), setting->phase2subjectmatch());
+        if (!setting->phase2altsubjectmatches().isEmpty())
+            map.insert(QLatin1String(NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES), setting->phase2altsubjectmatches());
         if (!setting->phase2clientcert().isEmpty())
             map.insert(QLatin1String(NM_SETTING_802_1X_PHASE2_CLIENT_CERT), setting->phase2clientcert());
         if (!setting->phase2privatekey().isEmpty())
Index: networkmanager/libs/internals/settings/802-1x.h
===================================================================
--- networkmanager.orig/libs/internals/settings/802-1x.h
+++ networkmanager/libs/internals/settings/802-1x.h
@@ -113,7 +113,9 @@ class KNMINTERNALS_EXPORT Security8021xS
     {
         mCapath = v;
 
-        setCacert( getBytes(v));
+        QByteArray data = getBytes(v);
+        if (!data.isEmpty() || mCerthash.isEmpty())
+           setCacert( data );
     }
 
     /**
@@ -125,6 +127,51 @@ class KNMINTERNALS_EXPORT Security8021xS
     }
 
     /**
+      Set Subject
+    */
+    void setSubjectmatch( const QString & v )
+    {
+        mSubjectmatch = v;
+    }
+
+    /**
+      Get Subject
+    */
+    QString subjectmatch() const
+    {
+      return mSubjectmatch;
+    }
+
+    /**
+      Set Alt Subject
+    */
+    void setAltsubjectmatches( const QString & v )
+    {
+        mAltsubjectmatches = v;
+    }
+
+    /**
+      Get Alt Subject
+    */
+    QString altsubjectmatches() const
+    {
+      return mAltsubjectmatches;
+    }
+
+    QString certhash() const
+    {
+      return mCerthash;
+    }
+
+    void setCerthash( const QString & v )
+    {
+      mCerthash = v;
+      // We only set the certificate to use a hash if we don't have a real certificate
+      if ( !v.isEmpty() && mCapath.isEmpty() )
+         mCacert = (QString("hash://server/sha256/")+v).toLatin1();
+    }
+
+    /**
       Set Client Cert
     */
     void setClientcert( const QByteArray & v )
@@ -271,6 +318,38 @@ class KNMINTERNALS_EXPORT Security8021xS
     }
 
     /**
+      Set Phase2 Subject
+    */
+    void setPhase2subjectmatch( const QString & v )
+    {
+        mPhase2subjectmatch = v;
+    }
+
+    /**
+      Get Phase2 Subject
+    */
+    QString phase2subjectmatch() const
+    {
+      return mPhase2subjectmatch;
+    }
+
+    /**
+      Set Alt Subject
+    */
+    void setPhase2altsubjectmatches( const QString & v )
+    {
+        mPhase2altsubjectmatches = v;
+    }
+
+    /**
+      Get Alt Subject
+    */
+    QString phase2altsubjectmatches() const
+    {
+      return mPhase2altsubjectmatches;
+    }
+
+    /**
       Set Phase 2 client cert
     */
     void setPhase2clientcert( const QByteArray & v )
@@ -530,8 +609,11 @@ kDebug() << eap;
     QString mAnonymousidentity;
     QByteArray mCacert;
     QString mCapath;
+    QString mCerthash;
     QByteArray mClientcert;
     QString mClientcertpath;
+    QString mSubjectmatch;
+    QString mAltsubjectmatches;
     int mPhase1peapver;
     QString mPhase1peaplabel;
     QString mPhase1fastprovisioning;
@@ -539,6 +621,8 @@ kDebug() << eap;
     int mPhase2autheap;
     QByteArray mPhase2cacert;
     QString mPhase2capath;
+    QString mPhase2subjectmatch;
+    QString mPhase2altsubjectmatches;
     QByteArray mPhase2clientcert;
     QString mPhase2clientcertpath;
     QString mPassword;
Index: networkmanager/settings/service/datamappings.cpp
===================================================================
--- networkmanager.orig/settings/service/datamappings.cpp
+++ networkmanager/settings/service/datamappings.cpp
@@ -79,6 +79,8 @@ void DataMappings::initKeyMappings()
     m_keyMappings.insert(QLatin1String("anonymousidentity"), QLatin1String(NM_SETTING_802_1X_ANONYMOUS_IDENTITY));
     m_keyMappings.insert(QLatin1String("cacert"), QLatin1String(NM_SETTING_802_1X_CA_CERT));
     m_keyMappings.insert(QLatin1String("capath"), QLatin1String(NM_SETTING_802_1X_CA_PATH));
+    m_keyMappings.insert(QLatin1String("subjectmatch"), QLatin1String(NM_SETTING_802_1X_SUBJECT_MATCH));
+    m_keyMappings.insert(QLatin1String("altsubjectmatches"), QLatin1String(NM_SETTING_802_1X_ALTSUBJECT_MATCHES));
     m_keyMappings.insert(QLatin1String("clientcert"), QLatin1String(NM_SETTING_802_1X_CLIENT_CERT));
     m_keyMappings.insert(QLatin1String("phase1peapver"), QLatin1String(NM_SETTING_802_1X_PHASE1_PEAPVER));
     m_keyMappings.insert(QLatin1String("phase1peaplabel"), QLatin1String(NM_SETTING_802_1X_PHASE1_PEAPLABEL));
@@ -87,6 +89,8 @@ void DataMappings::initKeyMappings()
     m_keyMappings.insert(QLatin1String("phase2autheap"), QLatin1String(NM_SETTING_802_1X_PHASE2_AUTHEAP));
     m_keyMappings.insert(QLatin1String("phase2cacert"), QLatin1String(NM_SETTING_802_1X_PHASE2_CA_CERT));
     m_keyMappings.insert(QLatin1String("phase2capath"), QLatin1String(NM_SETTING_802_1X_PHASE2_CA_PATH));
+    m_keyMappings.insert(QLatin1String("phase2subjectmatch"), QLatin1String(NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH));
+    m_keyMappings.insert(QLatin1String("phase2altsubjectmatches"), QLatin1String(NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES));
     m_keyMappings.insert(QLatin1String("phase2clientcert"), QLatin1String(NM_SETTING_802_1X_PHASE2_CLIENT_CERT));
     m_keyMappings.insert(QLatin1String("privatekey"), QLatin1String(NM_SETTING_802_1X_PRIVATE_KEY));
     m_keyMappings.insert(QLatin1String("phase2privatekey"), QLatin1String(NM_SETTING_802_1X_PHASE2_PRIVATE_KEY));
Index: networkmanager/backends/NetworkManager/introspection/nm-device-wifi.xml
===================================================================
--- /dev/null
+++ networkmanager/backends/NetworkManager/introspection/nm-device-wifi.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+  <interface name="org.freedesktop.NetworkManager.Device.Wireless">
+    <method name="GetAccessPoints">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_device_get_access_points"/>
+      <arg name="access_points" type="ao" direction="out">
+        <tp:docstring>
+          List of access point object paths
+        </tp:docstring>
+      </arg>
+      <tp:docstring>
+        Get the list of access points visible to this device.
+      </tp:docstring>
+    </method>
+
+    <method name="ProbeCaCert">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_device_probe_ca_cert"/>
+      <arg name="ssid" type="ay" direction="in">
+        <tp:docstring>
+          The SSID of the AP to be probed
+        </tp:docstring>
+      </arg>
+      <tp:docstring>
+        Probe the CA certificate of the RADIUS server.
+      </tp:docstring>
+    </method>
+
+    <property name="HwAddress" type="s" access="read">
+      <tp:docstring>
+        The hardware address of the device.
+      </tp:docstring>
+    </property>
+    <property name="Mode" type="u" access="read" tp:type="NM_802_11_MODE">
+      <tp:docstring>
+        The operating mode of the wireless device.
+      </tp:docstring>
+    </property>
+
+    <property name="Bitrate" type="u" access="read">
+      <tp:docstring>
+        The bit rate currently used by the wireless device, in kilobits/second (Kb/s).
+      </tp:docstring>
+    </property>
+    <property name="ActiveAccessPoint" type="o" access="read">
+      <tp:docstring>
+        Object path of the access point currently used by the wireless device.
+      </tp:docstring>
+    </property>
+    <property name="WirelessCapabilities" type="u" access="read" tp:type="NM_802_11_DEVICE_CAP">
+      <tp:docstring>
+        The capabilities of the wireless device.
+      </tp:docstring>
+    </property>
+
+    <signal name="PropertiesChanged">
+        <arg name="properties" type="a{sv}" tp:type="String_Variant_Map">
+          <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantMap"/>
+            <tp:docstring>
+                A dictionary containing the FIXME: check changed parameters.
+            </tp:docstring>
+        </arg>
+        <tp:docstring>
+            Emitted when the wireless device's properties changed.
+        </tp:docstring>
+    </signal>
+
+    <signal name="AccessPointAdded">
+        <arg name="access_point" type="o">
+            <tp:docstring>
+                The object path of the newly found access point.
+            </tp:docstring>
+        </arg>
+        <tp:docstring>
+            Emitted when a new access point is found by the device.
+        </tp:docstring>
+    </signal>
+
+    <signal name="AccessPointRemoved">
+      <arg name="access_point" type="o">
+            <tp:docstring>
+                The object path of the access point that has disappeared.
+            </tp:docstring>
+        </arg>
+        <tp:docstring>
+            Emitted when an access point disappears from view of the device.
+        </tp:docstring>
+    </signal>
+
+    <signal name="CaCertReceived">
+      <arg name="cert" type="a{ss}" tp:type="String_String_Map">
+          <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QStringMap"/>
+            <tp:docstring>
+              The certificate of the RADIUS server
+            </tp:docstring>
+      </arg>
+        <tp:docstring>
+            Emitted when wpa_supplicant replies the CA certificate of the RADIUS server.
+        </tp:docstring>
+    </signal>
+
+    <tp:flags name="NM_802_11_DEVICE_CAP" type="u">
+      <tp:docstring>
+        Flags describing the capabilities of a wireless device.
+      </tp:docstring>
+      <tp:flag suffix="NONE" value="0x0">
+        <tp:docstring>Null capability - syntactic sugar for no capabilities supported.  Do not AND this with other capabilities!</tp:docstring>
+      </tp:flag>
+      <tp:flag suffix="CIPHER_WEP40" value="0x1">
+        <tp:docstring>The device supports the 40-bit WEP cipher.</tp:docstring>
+      </tp:flag>
+      <tp:flag suffix="CIPHER_WEP104" value="0x2">
+        <tp:docstring>The device supports the 104-bit WEP cipher.</tp:docstring>
+      </tp:flag>
+      <tp:flag suffix="CIPHER_TKIP" value="0x4">
+        <tp:docstring>The device supports the TKIP cipher.</tp:docstring>
+      </tp:flag>
+      <tp:flag suffix="CIPHER_CCMP" value="0x8">
+        <tp:docstring>The device supports the CCMP cipher.</tp:docstring>
+      </tp:flag>
+      <tp:flag suffix="WPA" value="0x10">
+        <tp:docstring>The device supports the WPA encryption/authentication protocol.</tp:docstring>
+      </tp:flag>
+      <tp:flag suffix="RSN" value="0x20">
+        <tp:docstring>The device supports the RSN encryption/authentication protocol.</tp:docstring>
+      </tp:flag>
+    </tp:flags>
+  </interface>
+</node>
Index: networkmanager/libs/ui/nm-device-wifiinterface.cpp
===================================================================
--- /dev/null
+++ networkmanager/libs/ui/nm-device-wifiinterface.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -N -i types.h -p nm-device-wifiinterface introspection/nm-device-wifi.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "nm-device-wifiinterface.h"
+
+/*
+ * Implementation of interface class OrgFreedesktopNetworkManagerDeviceWirelessInterface
+ */
+
+OrgFreedesktopNetworkManagerDeviceWirelessInterface::OrgFreedesktopNetworkManagerDeviceWirelessInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+    : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+OrgFreedesktopNetworkManagerDeviceWirelessInterface::~OrgFreedesktopNetworkManagerDeviceWirelessInterface()
+{
+}
+
Index: networkmanager/libs/ui/nm-device-wifiinterface.h
===================================================================
--- /dev/null
+++ networkmanager/libs/ui/nm-device-wifiinterface.h
@@ -0,0 +1,80 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -N -i types.h -p nm-device-wifiinterface introspection/nm-device-wifi.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef NM_DEVICE_WIFIINTERFACE_H
+#define NM_DEVICE_WIFIINTERFACE_H
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+#include "types.h"
+
+/*
+ * Proxy class for interface org.freedesktop.NetworkManager.Device.Wireless
+ */
+class OrgFreedesktopNetworkManagerDeviceWirelessInterface: public QDBusAbstractInterface
+{
+    Q_OBJECT
+public:
+    static inline const char *staticInterfaceName()
+    { return "org.freedesktop.NetworkManager.Device.Wireless"; }
+
+public:
+    OrgFreedesktopNetworkManagerDeviceWirelessInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+    ~OrgFreedesktopNetworkManagerDeviceWirelessInterface();
+
+    Q_PROPERTY(QDBusObjectPath ActiveAccessPoint READ activeAccessPoint)
+    inline QDBusObjectPath activeAccessPoint() const
+    { return qvariant_cast< QDBusObjectPath >(property("ActiveAccessPoint")); }
+
+    Q_PROPERTY(uint Bitrate READ bitrate)
+    inline uint bitrate() const
+    { return qvariant_cast< uint >(property("Bitrate")); }
+
+    Q_PROPERTY(QString HwAddress READ hwAddress)
+    inline QString hwAddress() const
+    { return qvariant_cast< QString >(property("HwAddress")); }
+
+    Q_PROPERTY(uint Mode READ mode)
+    inline uint mode() const
+    { return qvariant_cast< uint >(property("Mode")); }
+
+    Q_PROPERTY(uint WirelessCapabilities READ wirelessCapabilities)
+    inline uint wirelessCapabilities() const
+    { return qvariant_cast< uint >(property("WirelessCapabilities")); }
+
+public Q_SLOTS: // METHODS
+    inline QDBusPendingReply<QList<QDBusObjectPath> > GetAccessPoints()
+    {
+        QList<QVariant> argumentList;
+        return asyncCallWithArgumentList(QLatin1String("GetAccessPoints"), argumentList);
+    }
+
+    inline QDBusPendingReply<> ProbeCaCert(const QByteArray &ssid)
+    {
+        QList<QVariant> argumentList;
+        argumentList << qVariantFromValue(ssid);
+        return asyncCallWithArgumentList(QLatin1String("ProbeCaCert"), argumentList);
+    }
+
+Q_SIGNALS: // SIGNALS
+//    void AccessPointAdded(const QDBusObjectPath &access_point);
+//    void AccessPointRemoved(const QDBusObjectPath &access_point);
+    void CaCertReceived(const QStringMap &cert);
+//    void PropertiesChanged(const QVariantMap &properties);
+};
+
+#endif
Index: networkmanager/libs/ui/security/eapmethodpeapbase.ui
===================================================================
--- networkmanager.orig/libs/ui/security/eapmethodpeapbase.ui
+++ networkmanager/libs/ui/security/eapmethodpeapbase.ui
@@ -30,6 +30,26 @@
       <widget class="KLineEdit" name="leAnonIdentity"/>
      </item>
      <item row="1" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>&amp;Subject:</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="buddy">
+        <cstring>leSubject</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="KLineEdit" name="leSubject">
+       <property name="clickMessage">
+        <string>&lt;Probe the server to fill automatically&gt;</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0">
       <widget class="QLabel" name="label_3">
        <property name="text">
         <string>CA Certi&amp;ficate:</string>
@@ -42,10 +62,41 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
+     <item row="2" column="1">
       <widget class="KUrlRequester" name="kurCaCert"/>
      </item>
-     <item row="3" column="0">
+     <item row="3" column="1">
+      <widget class="QCheckBox" name="chkUseSystemCaCerts">
+       <property name="text">
+        <string>Use Syste&amp;m CA Certs</string>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="0" colspan="2">
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QLabel" name="labelHash">
+         <property name="text">
+          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note: &lt;/span&gt;Server hash is used instead of CA certificate&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QToolButton" name="btRemoveHash">
+         <property name="toolTip">
+          <string>Remove saved CA certificate hash</string>
+         </property>
+         <property name="text">
+          <string/>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item row="5" column="0">
       <widget class="QLabel" name="label_6">
        <property name="text">
         <string>PEAP &amp;Version:</string>
@@ -58,7 +109,7 @@
        </property>
       </widget>
      </item>
-     <item row="3" column="1">
+     <item row="5" column="1">
       <widget class="KComboBox" name="cboPeapVersion">
        <item>
         <property name="text">
@@ -77,13 +128,6 @@
        </item>
       </widget>
      </item>
-     <item row="2" column="1">
-      <widget class="QCheckBox" name="chkUseSystemCaCerts">
-       <property name="text">
-        <string>Use Syste&amp;m CA Certs</string>
-       </property>
-      </widget>
-     </item>
     </layout>
    </item>
    <item>
@@ -103,9 +147,9 @@
  </widget>
  <customwidgets>
   <customwidget>
-   <class>KUrlRequester</class>
-   <extends>QFrame</extends>
-   <header>kurlrequester.h</header>
+   <class>KComboBox</class>
+   <extends>QComboBox</extends>
+   <header>kcombobox.h</header>
   </customwidget>
   <customwidget>
    <class>KLineEdit</class>
@@ -113,14 +157,17 @@
    <header>klineedit.h</header>
   </customwidget>
   <customwidget>
-   <class>KComboBox</class>
-   <extends>QComboBox</extends>
-   <header>kcombobox.h</header>
+   <class>KUrlRequester</class>
+   <extends>QFrame</extends>
+   <header>kurlrequester.h</header>
   </customwidget>
  </customwidgets>
  <tabstops>
   <tabstop>leAnonIdentity</tabstop>
+  <tabstop>leSubject</tabstop>
   <tabstop>kurCaCert</tabstop>
+  <tabstop>chkUseSystemCaCerts</tabstop>
+  <tabstop>btRemoveHash</tabstop>
   <tabstop>cboPeapVersion</tabstop>
  </tabstops>
  <resources/>
@@ -132,12 +179,12 @@
    <slot>setDisabled(bool)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>222</x>
-     <y>83</y>
+     <x>356</x>
+     <y>106</y>
     </hint>
     <hint type="destinationlabel">
-     <x>221</x>
-     <y>54</y>
+     <x>355</x>
+     <y>81</y>
     </hint>
    </hints>
   </connection>
Index: networkmanager/libs/ui/security/peapwidget.cpp
===================================================================
--- networkmanager.orig/libs/ui/security/peapwidget.cpp
+++ networkmanager/libs/ui/security/peapwidget.cpp
@@ -21,6 +21,10 @@ along with this program.  If not, see <h
 
 #include "peapwidget.h"
 
+#include <KMessageBox>
+#include <KIcon>
+#include <QFileInfo>
+
 #include <nm-setting-8021x.h>
 #include <connection.h>
 
@@ -30,7 +34,7 @@ along with this program.  If not, see <h
 #include "settings/802-1x.h"
 
 PeapWidget::PeapWidget(Knm::Connection* connection, QWidget * parent)
-: EapMethodInnerAuth(connection, parent)
+: EapMethodInnerAuth(connection, parent), m_removeHash(false)
 {
     Q_D(EapMethodInnerAuth);
     setupUi(this);
@@ -39,9 +43,15 @@ PeapWidget::PeapWidget(Knm::Connection*
             i18nc("MSCHAPv2 inner auth method", "MSCHAPv2"));
     d->innerAuth->registerEapMethod(Knm::Security8021xSetting::EnumPhase2auth::md5, new EapMethodSimple(EapMethodSimple::MD5, connection, d->innerAuth),
             i18nc("MD5 inner auth method", "MD5"));
-    gridLayout->addWidget(d->innerAuth, 4, 0, 2, 2);
+    gridLayout->addWidget(d->innerAuth, gridLayout->rowCount(), 0, 2, 2);
 
     kurCaCert->setMode(KFile::LocalOnly);
+
+    btRemoveHash->setIcon( KIcon("edit-delete") );
+    connect(btRemoveHash, SIGNAL(clicked(bool)), this, SLOT(removeHash()));
+
+    connect(kurCaCert, SIGNAL(textChanged(const QString &)), this, SLOT(recalculateHashLabelVisibility()));
+    connect(chkUseSystemCaCerts, SIGNAL(toggled(bool)), this, SLOT(recalculateHashLabelVisibility()));
 }
 
 PeapWidget::~PeapWidget()
@@ -58,6 +68,7 @@ void PeapWidget::readConfig()
     Q_D(EapMethodInnerAuth);
 
     leAnonIdentity->setText(d->setting->anonymousidentity());
+    leSubject->setText(d->setting->subjectmatch());
 
     if (d->setting->useSystemCaCerts()) {
         chkUseSystemCaCerts->setChecked(true);
@@ -70,6 +81,8 @@ void PeapWidget::readConfig()
             kurCaCert->setUrl(capath);
     }
 
+    recalculateHashLabelVisibility();
+
     if (d->setting->phase2auth() != Knm::Security8021xSetting::EnumPhase2auth::none) {
         d->innerAuth->setCurrentEapMethod(d->setting->phase2auth());
     }
@@ -90,6 +103,11 @@ void PeapWidget::writeConfig()
     // PEAP specific config
     d->setting->setAnonymousidentity(leAnonIdentity->text());
 
+    d->setting->setSubjectmatch(leSubject->text());
+
+    if (m_removeHash)
+        d->setting->setCerthash("");
+
     if (chkUseSystemCaCerts->isChecked()) {
         d->setting->setUseSystemCaCerts(true);
         d->setting->setCapath("");
@@ -108,6 +126,45 @@ void PeapWidget::writeConfig()
     d->setting->setPhase1peapver(cboPeapVersion->currentIndex());
 }
 
+void PeapWidget::removeHash()
+{
+    Q_D(EapMethodInnerAuth);
+    int r = KMessageBox::questionYesNo(0L, QString("Are you sure you want knetworkmanager to forget the following saved certificate hash that was probed from the server?\n\n %1").arg(d->setting->certhash()));
+    if (r == KMessageBox::Yes)
+    {
+       labelHash->hide();
+       btRemoveHash->hide();
+       m_removeHash=true;
+    }
+}
+
+void PeapWidget::recalculateHashLabelVisibility()
+{
+    Q_D(EapMethodInnerAuth);
+    // To show the warning, there has to be a stored hash, the system checkbox
+    // has to be unchecked, capath empty or referencing an invalid path and
+    // the user shouldn't have chosen to remove the hash
+    QString capath=kurCaCert->text();
+    bool show = !d->setting->certhash().isEmpty() && !chkUseSystemCaCerts->isChecked() && !m_removeHash;
+
+    if (show && !capath.isEmpty())
+    {
+        QFileInfo info(capath);
+        if (info.isFile() && info.isReadable()) show = false;
+    }
+
+    if (show)
+    {
+        labelHash->show();
+        btRemoveHash->show();
+    }
+    else
+    {
+        labelHash->hide();
+        btRemoveHash->hide();
+    }
+}
+
 void PeapWidget::readSecrets()
 {
     Q_D(EapMethodInnerAuth);
Index: networkmanager/libs/ui/security/eapmethodtlsbase.ui
===================================================================
--- networkmanager.orig/libs/ui/security/eapmethodtlsbase.ui
+++ networkmanager/libs/ui/security/eapmethodtlsbase.ui
@@ -46,6 +46,26 @@
       <widget class="KUrlRequester" name="kurClientCert"/>
      </item>
      <item row="2" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>&amp;Subject:</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="buddy">
+        <cstring>leSubject</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="KLineEdit" name="leSubject">
+       <property name="clickMessage">
+        <string>&lt;Probe the server to fill automatically&gt;</string>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="0">
       <widget class="QLabel" name="label_3">
        <property name="text">
         <string>CA Certi&amp;ficate:</string>
@@ -58,10 +78,10 @@
        </property>
       </widget>
      </item>
-     <item row="2" column="1">
+     <item row="3" column="1">
       <widget class="KUrlRequester" name="kurCaCert"/>
      </item>
-     <item row="4" column="0">
+     <item row="6" column="0">
       <widget class="QLabel" name="label_4">
        <property name="text">
         <string>Private &amp;Key:</string>
@@ -74,10 +94,10 @@
        </property>
       </widget>
      </item>
-     <item row="4" column="1">
+     <item row="6" column="1">
       <widget class="KUrlRequester" name="kurPrivateKey"/>
      </item>
-     <item row="5" column="0">
+     <item row="7" column="0">
       <widget class="QLabel" name="label_5">
        <property name="text">
         <string>Private Key Pass&amp;word:</string>
@@ -90,20 +110,44 @@
        </property>
       </widget>
      </item>
-     <item row="5" column="1">
+     <item row="7" column="1">
       <widget class="KLineEdit" name="lePrivateKeyPassword">
        <property name="passwordMode">
         <bool>true</bool>
        </property>
       </widget>
      </item>
-     <item row="3" column="1">
+     <item row="4" column="1">
       <widget class="QCheckBox" name="chkUseSystemCaCerts">
        <property name="text">
         <string>Use Syste&amp;m CA Certs</string>
        </property>
       </widget>
      </item>
+     <item row="5" column="0" colspan="2">
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QLabel" name="labelHash">
+         <property name="text">
+          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note: &lt;/span&gt;Server hash is used instead of CA certificate&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QToolButton" name="btRemoveHash">
+         <property name="toolTip">
+          <string>Remove saved CA certificate hash</string>
+         </property>
+         <property name="text">
+          <string/>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
     </layout>
    </item>
    <item>
Index: networkmanager/libs/ui/security/eapmethodttlsbase.ui
===================================================================
--- networkmanager.orig/libs/ui/security/eapmethodttlsbase.ui
+++ networkmanager/libs/ui/security/eapmethodttlsbase.ui
@@ -30,6 +30,26 @@
       <widget class="KLineEdit" name="leAnonIdentity"/>
      </item>
      <item row="1" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>&amp;Subject:</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="buddy">
+        <cstring>leSubject</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="KLineEdit" name="leSubject">
+       <property name="clickMessage">
+        <string>&lt;Probe the server to fill automatically&gt;</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0">
       <widget class="QLabel" name="label_3">
        <property name="text">
         <string>CA Certi&amp;ficate:</string>
@@ -42,16 +62,40 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
+     <item row="2" column="1">
       <widget class="KUrlRequester" name="kurCaCert"/>
      </item>
-     <item row="2" column="1">
+     <item row="3" column="1">
       <widget class="QCheckBox" name="chkUseSystemCaCerts">
        <property name="text">
         <string>Use Syste&amp;m CA Certs</string>
        </property>
       </widget>
      </item>
+     <item row="4" column="0" colspan="2">
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QLabel" name="labelHash">
+         <property name="text">
+          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note: &lt;/span&gt;Server hash is used instead of CA certificate&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QToolButton" name="btRemoveHash">
+         <property name="toolTip">
+          <string>Remove saved CA certificate hash</string>
+         </property>
+         <property name="text">
+          <string/>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
     </layout>
    </item>
    <item>
Index: networkmanager/libs/ui/security/tlswidget.cpp
===================================================================
--- networkmanager.orig/libs/ui/security/tlswidget.cpp
+++ networkmanager/libs/ui/security/tlswidget.cpp
@@ -21,6 +21,10 @@ along with this program.  If not, see <h
 
 #include "tlswidget.h"
 
+#include <KMessageBox>
+#include <KIcon>
+#include <QFileInfo>
+
 #include "connection.h"
 #include "settings/802-1x.h"
 
@@ -41,6 +45,14 @@ TlsWidget::TlsWidget(bool isInnerMethod,
 : EapMethod(*new TlsWidgetPrivate(isInnerMethod), connection, parent)
 {
     setupUi(this);
+
+    kurCaCert->setMode(KFile::LocalOnly);
+
+    btRemoveHash->setIcon( KIcon("edit-delete") );
+    connect(btRemoveHash, SIGNAL(clicked(bool)), this, SLOT(removeHash()));
+
+    connect(kurCaCert, SIGNAL(textChanged(const QString &)), this, SLOT(recalculateHashLabelVisibility()));
+    connect(chkUseSystemCaCerts, SIGNAL(toggled(bool)), this, SLOT(recalculateHashLabelVisibility()));
 }
 
 TlsWidget::~TlsWidget()
@@ -56,6 +68,7 @@ void TlsWidget::readConfig()
 {
     Q_D(TlsWidget);
     leIdentity->setText(d->setting->identity());
+    leSubject->setText(d->setting->subjectmatch());
 
     QString value;
     if (d->setting->useSystemCaCerts()) {
@@ -73,6 +86,8 @@ void TlsWidget::readConfig()
             kurCaCert->setUrl(value);
     }
 
+    recalculateHashLabelVisibility();
+
     if (d->inner) {
         value = d->setting->phase2clientcertpath();
     } else {
@@ -101,6 +116,10 @@ void TlsWidget::writeConfig()
     // TLS specifics
     // nm-applet also writes this if TLS is inner, but it feels dodgy to me
     d->setting->setIdentity(leIdentity->text());
+    d->setting->setSubjectmatch(leSubject->text());
+
+    if (m_removeHash)
+        d->setting->setCerthash("");
 
     KUrl url;
     if (chkUseSystemCaCerts->isChecked()) {
@@ -160,4 +179,43 @@ void TlsWidget::setShowPasswords(bool on
     lePrivateKeyPassword->setPasswordMode(!on);
 }
 
+void TlsWidget::removeHash()
+{
+    Q_D(TlsWidget);
+    int r = KMessageBox::questionYesNo(0L, QString("Are you sure you want knetworkmanager to forget the following saved certificate hash that was probed from the server?\n\n %1").arg(d->setting->certhash()));
+    if (r == KMessageBox::Yes)
+    {
+       labelHash->hide();
+       btRemoveHash->hide();
+       m_removeHash=true;
+    }
+}
+
+void TlsWidget::recalculateHashLabelVisibility()
+{
+    Q_D(TlsWidget);
+    // To show the warning, there has to be a stored hash, the system checkbox
+    // has to be unchecked, capath empty or referencing an invalid path and
+    // the user shouldn't have chosen to remove the hash
+    QString capath=kurCaCert->text();
+    bool show = !d->setting->certhash().isEmpty() && !chkUseSystemCaCerts->isChecked() && !m_removeHash;
+
+    if (show && !capath.isEmpty())
+    {
+        QFileInfo info(capath);
+        if (info.isFile() && info.isReadable()) show = false;
+    }
+
+    if (show)
+    {
+        labelHash->show();
+        btRemoveHash->show();
+    }
+    else
+    {
+        labelHash->hide();
+        btRemoveHash->hide();
+    }
+}
+
 // vim: sw=4 sts=4 et tw=100
Index: networkmanager/libs/ui/security/ttlswidget.cpp
===================================================================
--- networkmanager.orig/libs/ui/security/ttlswidget.cpp
+++ networkmanager/libs/ui/security/ttlswidget.cpp
@@ -21,6 +21,10 @@ along with this program.  If not, see <h
 
 #include "ttlswidget.h"
 
+#include <KMessageBox>
+#include <KIcon>
+#include <QFileInfo>
+
 #include <nm-setting-8021x.h>
 
 #include <connection.h>
@@ -48,7 +52,15 @@ TtlsWidget::TtlsWidget(Knm::Connection*
     d->innerAuth->registerEapMethod(Knm::Security8021xSetting::EnumPhase2auth::chap,
             new EapMethodSimple(EapMethodSimple::Chap, connection, d->innerAuth),
             i18nc("CHAP inner auth method", "CHAP"));
-    gridLayout->addWidget(d->innerAuth, 3, 0, 2, 2);
+    gridLayout->addWidget(d->innerAuth, gridLayout->rowCount(), 0, 2, 2);
+
+    kurCaCert->setMode(KFile::LocalOnly);
+
+    btRemoveHash->setIcon( KIcon("edit-delete") );
+    connect(btRemoveHash, SIGNAL(clicked(bool)), this, SLOT(removeHash()));
+
+    connect(kurCaCert, SIGNAL(textChanged(const QString &)), this, SLOT(recalculateHashLabelVisibility()));
+    connect(chkUseSystemCaCerts, SIGNAL(toggled(bool)), this, SLOT(recalculateHashLabelVisibility()));
 }
 
 TtlsWidget::~TtlsWidget()
@@ -64,6 +76,7 @@ void TtlsWidget::readConfig()
 {
     Q_D(EapMethodInnerAuth);
     leAnonIdentity->setText(d->setting->anonymousidentity());
+    leSubject->setText(d->setting->subjectmatch());
 
     if (d->setting->useSystemCaCerts()) {
         chkUseSystemCaCerts->setChecked(true);
@@ -76,6 +89,8 @@ void TtlsWidget::readConfig()
             kurCaCert->setUrl(capath);
     }
 
+    recalculateHashLabelVisibility();
+
     if (d->setting->phase2autheap() != Knm::Security8021xSetting::EnumPhase2autheap::none) {
         d->innerAuth->setCurrentEapMethod(d->setting->phase2autheap());
     } else {
@@ -91,6 +106,10 @@ void TtlsWidget::writeConfig()
     d->setting->setEapFlags(Knm::Security8021xSetting::ttls);
     // TTLS specific config
     d->setting->setAnonymousidentity(leAnonIdentity->text());
+    d->setting->setSubjectmatch(leSubject->text());
+
+    if (m_removeHash)
+        d->setting->setCerthash("");
 
     KUrl url;
 
@@ -113,5 +132,43 @@ void TtlsWidget::readSecrets()
     d->innerAuth->readSecrets();
 }
 
+void TtlsWidget::removeHash()
+{
+    Q_D(EapMethodInnerAuth);
+    int r = KMessageBox::questionYesNo(0L, QString("Are you sure you want knetworkmanager to forget the following saved certificate hash that was probed from the server?\n\n %1").arg(d->setting->certhash()));
+    if (r == KMessageBox::Yes)
+    {
+       labelHash->hide();
+       btRemoveHash->hide();
+       m_removeHash=true;
+    }
+}
+
+void TtlsWidget::recalculateHashLabelVisibility()
+{
+    Q_D(EapMethodInnerAuth);
+    // To show the warning, there has to be a stored hash, the system checkbox
+    // has to be unchecked, capath empty or referencing an invalid path and
+    // the user shouldn't have chosen to remove the hash
+    QString capath=kurCaCert->text();
+    bool show = !d->setting->certhash().isEmpty() && !chkUseSystemCaCerts->isChecked() && !m_removeHash;
+
+    if (show && !capath.isEmpty())
+    {
+        QFileInfo info(capath);
+        if (info.isFile() && info.isReadable()) show = false;
+    }
+
+    if (show)
+    {
+        labelHash->show();
+        btRemoveHash->show();
+    }
+    else
+    {
+        labelHash->hide();
+        btRemoveHash->hide();
+    }
+}
 
 // vim: sw=4 sts=4 et tw=100
Index: networkmanager/libs/internals/settings/802-1xpersistence.cpp
===================================================================
--- networkmanager.orig/libs/internals/settings/802-1xpersistence.cpp
+++ networkmanager/libs/internals/settings/802-1xpersistence.cpp
@@ -24,7 +24,10 @@ void Security8021xPersistence::load()
   setting->setIdentity(m_config->readEntry("identity", ""));
   setting->setAnonymousidentity(m_config->readEntry("anonymousidentity", ""));
   setting->setCacert(m_config->readEntry("cacert", QByteArray()));
+  setting->setCerthash(m_config->readEntry("certhash", ""));
   setting->setCapath(m_config->readEntry("capath", ""));
+  setting->setSubjectmatch(m_config->readEntry("subjectmatch", ""));
+  setting->setAltsubjectmatches(m_config->readEntry("altsubjectmatches", ""));
   setting->setClientcert(m_config->readEntry("clientcert", QByteArray()));
   setting->setClientcertpath(m_config->readEntry("clientcertpath", ""));
   {
@@ -77,6 +80,8 @@ void Security8021xPersistence::load()
   }
   setting->setPhase2cacert(m_config->readEntry("phase2cacert", QByteArray()));
   setting->setPhase2capath(m_config->readEntry("phase2capath", ""));
+  setting->setPhase2subjectmatch(m_config->readEntry("phase2subjectmatch", ""));
+  setting->setPhase2altsubjectmatches(m_config->readEntry("phase2altsubjectmatches", ""));
   setting->setPhase2clientcert(m_config->readEntry("phase2clientcert", QByteArray()));
   setting->setPhase2clientcertpath(m_config->readEntry("phase2clientcertpath", ""));
   // SECRET
@@ -111,6 +116,9 @@ void Security8021xPersistence::save()
   m_config->writeEntry("anonymousidentity", setting->anonymousidentity());
   m_config->writeEntry("cacert", setting->cacert());
   m_config->writeEntry("capath", setting->capath());
+  m_config->writeEntry("certhash", setting->certhash());
+  m_config->writeEntry("subjectmatch", setting->subjectmatch());
+  m_config->writeEntry("altsubjectmatches", setting->altsubjectmatches());
   m_config->writeEntry("clientcert", setting->clientcert());
   m_config->writeEntry("clientcertpath", setting->clientcertpath());
   switch (setting->phase1peapver()) {
@@ -174,6 +182,8 @@ void Security8021xPersistence::save()
   }
   m_config->writeEntry("phase2cacert", setting->phase2cacert());
   m_config->writeEntry("phase2capath", setting->phase2capath());
+  m_config->writeEntry("phase2subjectmatch", setting->phase2subjectmatch());
+  m_config->writeEntry("phase2altsubjectmatches", setting->phase2altsubjectmatches());
   m_config->writeEntry("phase2clientcert", setting->phase2clientcert());
   m_config->writeEntry("phase2clientcertpath", setting->phase2clientcertpath());
   // SECRET
Index: networkmanager/backends/NetworkManager/nmdbussettingsservice.cpp
===================================================================
--- networkmanager.orig/backends/NetworkManager/nmdbussettingsservice.cpp
+++ networkmanager/backends/NetworkManager/nmdbussettingsservice.cpp
@@ -46,6 +46,7 @@ License along with this library.  If not
 #include "exportedconnectionsecrets.h"
 
 #include "nm-active-connectioninterface.h"
+#include "service/connectionlist.h"
 
 class NMDBusSettingsServicePrivate
 {
@@ -55,17 +56,19 @@ public:
     QHash<QDBusObjectPath, BusConnection *> pathToConnections;
     QHash<QUuid, BusConnection *> uuidToConnections;
     QHash<QUuid, QDBusObjectPath> uuidToPath;
+    ConnectionList *connectionList;
 };
 
 const QString NMDBusSettingsService::SERVICE_USER_SETTINGS = QLatin1String(NM_DBUS_SERVICE_USER_SETTINGS);
 const QString NMDBusSettingsService::SERVICE_SYSTEM_SETTINGS = QLatin1String(NM_DBUS_SERVICE_SYSTEM_SETTINGS);
 
-NMDBusSettingsService::NMDBusSettingsService(QObject * parent)
-: QObject(parent), d_ptr(new NMDBusSettingsServicePrivate)
+NMDBusSettingsService::NMDBusSettingsService(ConnectionList * connectionList)
+: QObject(connectionList), d_ptr(new NMDBusSettingsServicePrivate)
 {
     Q_D(NMDBusSettingsService);
     d->active = true;
     d->nextConnectionId = 0;
+    d->connectionList = connectionList;
 
     if ( !QDBusConnection::systemBus().interface()->registerService(SERVICE_USER_SETTINGS)) {
         // trouble;
@@ -175,6 +178,16 @@ void NMDBusSettingsService::handleAdd(Kn
                 ic->setProperty("NMDBusObjectPath", d->uuidToPath[ic->connectionUuid()].path());
             }
         }
+
+        if (ic)
+        {
+            Knm::Connection * connection = d->connectionList->findConnection(ic->connectionUuid());
+            if (connection)
+                connection->setDeviceUni(ic->deviceUni());
+            else
+                kDebug() << "Couldn't find connection for " << ic->connectionUuid() << " to set deviceUni to " << ic->deviceUni();
+        }
+
     }
 }
 
Index: networkmanager/backends/NetworkManager/nmdbussettingsservice.h
===================================================================
--- networkmanager.orig/backends/NetworkManager/nmdbussettingsservice.h
+++ networkmanager/backends/NetworkManager/nmdbussettingsservice.h
@@ -46,7 +46,7 @@ Q_OBJECT
 Q_CLASSINFO("D-Bus Interface", "org.freedesktop.NetworkManagerSettings")
 
 public:
-    NMDBusSettingsService(QObject * parent = 0);
+    NMDBusSettingsService(ConnectionList * connectionList);
     virtual ~NMDBusSettingsService();
     static const QString SERVICE_USER_SETTINGS;
     static const QString SERVICE_SYSTEM_SETTINGS;
Index: networkmanager/libs/internals/connection.cpp
===================================================================
--- networkmanager.orig/libs/internals/connection.cpp
+++ networkmanager/libs/internals/connection.cpp
@@ -285,4 +285,13 @@ void Connection::setType(Connection::Typ
     m_type = type;
 }
 
+QString Connection::deviceUni() const
+{
+    return m_deviceUni;
+}
+
+void Connection::setDeviceUni(const QString &device)
+{
+    m_deviceUni = device;
+}
 // vim: sw=4 sts=4 et tw=100
Index: networkmanager/libs/internals/connection.h
===================================================================
--- networkmanager.orig/libs/internals/connection.h
+++ networkmanager/libs/internals/connection.h
@@ -94,6 +94,9 @@ public:
      */
     bool secretsAvailable() const;
 
+
+    QString deviceUni() const;
+    void setDeviceUni(const QString &device);
 private:
     /**
      * Set up internal structure, including all settings specific to this connection type
@@ -115,6 +118,7 @@ private:
     QDateTime m_timestamp;
     QString m_origin;
     QList<Setting*> m_settings;
+    QString m_deviceUni;
 };
 } // namespace Knm
 
Index: networkmanager/libs/ui/connectionsecretsjob.cpp
===================================================================
--- networkmanager.orig/libs/ui/connectionsecretsjob.cpp
+++ networkmanager/libs/ui/connectionsecretsjob.cpp
@@ -41,6 +41,10 @@ along with this program.  If not, see <h
 #include <KLocale>
 #include <KServiceTypeTrader>
 #include <KStandardDirs>
+#include <KMessageBox>
+#include <KStandardGuiItem>
+#include <KGuiItem>
+#include <KPassivePopup>
 
 #include "802_11_wirelesswidget.h"
 #include "cdmawidget.h"
@@ -60,11 +64,17 @@ along with this program.  If not, see <h
 #include "connection.h"
 #include "vpnuiplugin.h"
 
+#include "settings/802-1x.h"
+#include "settings/802-11-wireless.h"
+#include "connectionpersistence.h"
+#include "nm-device-wifiinterface.h"
+
 ConnectionSecretsJob::ConnectionSecretsJob(Knm::Connection* connection, const QString &settingName,
                                            const QStringList& secrets, bool requestNew, const QDBusMessage& request)
     : m_connection(connection), m_connectionPersistence(0), mSettingName(settingName), mRequestNew(requestNew),
-      mRequest(request), m_askUserDialog(0), m_settingWidget(0)
+      mRequest(request), m_askUserDialog(0), m_settingWidget(0), m_caCertProbeTimer(0L), m_popup(0L), m_deviceWirelessIface(0L)
 {
+
     // record the secrets that we are looking for
     foreach (QString secretKey, secrets) {
         mSecrets.insert(secretKey, QVariant());
@@ -192,6 +202,29 @@ void ConnectionSecretsJob::dialogAccepte
     cp.save();
     m_settingWidget->deleteLater();
     m_askUserDialog->deleteLater();
+
+    if (caCertProbeNeeded(m_connection))
+    {
+       KGuiItem yes=KStandardGuiItem::yes();
+       KGuiItem no=KStandardGuiItem::no();
+       yes.setText("Edit Certificate");
+       yes.setIconName("document-edit");
+       yes.setToolTip("Go back to edit the certificate");
+       no.setText("Probe Certificate");
+       no.setIconName("network-wireless"); // or edit-find?
+       no.setToolTip("Probe the RADIUS server for the current CA certificate being used. This can take up to 30 seconds");
+       QString text=QString("<b>No Certificate Authority certificate chosen</b><P>Not using a Certificate Authority (CA) certificate can result in connections to insecure, forged wireless networks that might steal your credentials. Would you like to edit the CA certificate or probe the RADIUS server for the current CA certificate being used?");
+       int r=KMessageBox::questionYesNo(0L, text, "KNetworkManager security question", yes, no);
+       if (r==KMessageBox::Yes)
+          start();
+       else
+          startCaCertProbe(m_connection);
+
+       return;
+    }
+    else
+       kDebug() << "cacert probe not needed";
+
     emitResult();
 }
 
@@ -223,4 +256,169 @@ Knm::Connection * ConnectionSecretsJob::
     return m_connection;
 }
 
+bool ConnectionSecretsJob::caCertProbeNeeded(const Knm::Connection *connection)
+{
+   if (!connection) return false;
+   kDebug() << "connection deviceUNI: " << connection->deviceUni();
+
+   Knm::Security8021xSetting* setting8021x;
+   setting8021x = static_cast<Knm::Security8021xSetting *>(connection->setting(Knm::Setting::Security8021x));
+   if (!setting8021x) return false;
+
+   QStringList eapMethods = setting8021x->eap();
+   if ( !(   eapMethods.contains("ttls")
+          || eapMethods.contains("peap")
+          || eapMethods.contains("tls") ) ) return false;
+
+   QString subject = setting8021x->subjectmatch();
+   QString cahash = setting8021x->certhash();
+   QString capath = setting8021x->capath();
+
+   if (subject.isEmpty() || (cahash.isEmpty() && capath.isEmpty()))
+      return true;
+
+   return false;
+}
+
+bool ConnectionSecretsJob::startCaCertProbe(const Knm::Connection *connection)
+{
+    if (!connection) return false;
+    if (m_deviceWirelessIface)
+    {
+       kDebug() << "start CA Cert Probe requested, but there's a probe already running";
+       return false;
+    }
+    if (m_caCertProbeTimer)
+    {
+       kDebug() << "start CA Cert Probe requested, but there's a timer already running";
+       return false;
+    }
+
+    QString devicePath = connection->deviceUni();
+
+    Knm::WirelessSetting * wirelessSetting = dynamic_cast<Knm::WirelessSetting *>(connection->setting(Knm::Setting::Wireless));
+
+    m_deviceWirelessIface= new OrgFreedesktopNetworkManagerDeviceWirelessInterface("org.freedesktop.NetworkManager", devicePath, QDBusConnection::systemBus(), this);
+    connect(m_deviceWirelessIface, SIGNAL(CaCertReceived(const QStringMap&)), this, SLOT(handleCaCertReceived(const QStringMap&)));
+
+    m_deviceWirelessIface->setProperty("ssid", QVariant::fromValue(wirelessSetting->ssid()));
+    m_deviceWirelessIface->ProbeCaCert(wirelessSetting->ssid());
+    kDebug() << "cacert probe request sent for " << wirelessSetting->ssid();
+
+    m_popup=KPassivePopup::message("KNetworkManager", QString("Probing server CA certificate for network %1. This can take up to 30 seconds").arg(QString::fromLatin1(wirelessSetting->ssid())), QPixmap(), (QWidget *)0L, 30000);
+    m_popup->setAutoDelete(false);
+
+    m_caCertProbeTimer = new QTimer(this);
+    m_caCertProbeTimer->setSingleShot(true);
+    connect(m_caCertProbeTimer, SIGNAL(timeout()), this, SLOT(caCertProbeTimeout()));
+
+    m_caCertProbeTimer->start(30000);
+    return true;
+};
+
+void ConnectionSecretsJob::handleCaCertReceived(const QStringMap &cert)
+{
+   /**
+    * cert contains a map which either fills a value for "hash" or for "subject"
+    */
+   kDebug() << "NMDBusActiveConnectionMonitor::handleCaCertReceived";
+
+   delete m_caCertProbeTimer;
+   m_caCertProbeTimer=0L;
+   delete m_popup;
+   m_popup=0L;
+
+   Knm::Security8021xSetting* setting8021x;
+
+   //OrgFreedesktopNetworkManagerDeviceWirelessInterface *deviceWirelessIface= qobject_cast<OrgFreedesktopNetworkManagerDeviceWirelessInterface*>(sender());
+   if (!m_deviceWirelessIface)
+   {
+      kDebug() << "Signal sender was not a deviceWirelessIface object";
+      return;
+   }
+   disconnect(m_deviceWirelessIface, SIGNAL(CaCertReceived(const QStringMap&)), this, SLOT(handleCaCertReceived(const QStringMap&)));
+   m_deviceWirelessIface->deleteLater();
+
+   //Knm::Connection * connection = static_cast<Knm::Connection*>(deviceWirelessIface->property("connection").value<void *>());
+   if (!m_connection)
+   {
+      kDebug() << "No connection associated";
+      return;
+   }
+   QString ssid=m_deviceWirelessIface->property("ssid").toString();
+   setting8021x = static_cast<Knm::Security8021xSetting *>(m_connection->setting(Knm::Setting::Security8021x));
+   if (!setting8021x)
+   {
+      kDebug() << "Couldn't obtain settings object for connection " << m_connection->uuid();
+      return;
+   }
+
+   KGuiItem yes=KStandardGuiItem::yes();
+   KGuiItem no=KStandardGuiItem::no();
+   KGuiItem cancel=KStandardGuiItem::cancel();
+
+   yes.setText("Trust and remember");
+   yes.setToolTip("Trust the current connection and save the CA certificate subject and hash to validate future connections with them");
+   no.setText("Ignore");
+   no.setToolTip("Ignore the received data and continue connecting");
+   cancel.setText("Ignore and disconnect");
+   cancel.setToolTip("Ignore the received data and disconnect. Choose this if you're not sure if the current connection is right");
+   int r=KMessageBox::questionYesNoCancel(0L, QString("Server certificate data received for connection %1.\n  Subject: %2\n  Hash: %3\nDo you want to trust it and remember it for future connection validation?").arg(ssid).arg(cert["subject"]).arg(cert["hash"]), "KNetworkManager - Certificate data received", yes, no, cancel );
+   kDebug() << "user said: " << ((r == KMessageBox::Yes)? "Yes" : "No");
+   if (r==KMessageBox::Yes)
+   {
+      setting8021x->setSubjectmatch(cert["subject"]);
+      setting8021x->setCerthash(cert["hash"]);
+
+      /* Persist! */
+      QString configFile = KStandardDirs::locate("data",
+              Knm::ConnectionPersistence::CONNECTION_PERSISTENCE_PATH + m_connection->uuid());
+      Knm::ConnectionPersistence cp(m_connection,
+              KSharedConfig::openConfig(configFile, KConfig::NoGlobals),
+              (Knm::ConnectionPersistence::SecretStorageMode)KNetworkManagerServicePrefs::self()->secretStorageMode());
+      cp.save();
+   }
+   else if (r==KMessageBox::No)
+   {
+      yes.setText("Yes, I know it's the right network");
+      yes.setToolTip("Select this if you take the risk of sending your credentials to a possibly forged network");
+      no.setText("No, disconnect");
+      no.setToolTip("Select this if you want to be safe and disconnect from a possibly forged network. You should set a CA certificate for this connection to be safe");
+      QString warning;
+      if (ssid.isEmpty())
+        warning=QString("Warning: You didn't define any method to certify if the network you're connecting to is valid or it's a forged network that might steal your credentials. Are you sure you want to continue connecting?");
+      else
+        warning=QString("Warning: You didn't define any method to certify if the %1 network is really %2 or it's a forged network that might steal your credentials. Are you sure you want to continue connecting?").arg(ssid).arg(ssid);
+
+      int s=KMessageBox::questionYesNo(0L, warning, "KNetworkManager security warning", yes, no);
+      if (s==KMessageBox::No)
+         setError(EnumError::UserInputCancelled);
+   }
+   else if (r==KMessageBox::Cancel)
+   {
+      setError(EnumError::UserInputCancelled);
+   }
+
+   emitResult();
+}
+
+void ConnectionSecretsJob::caCertProbeTimeout()
+{
+   delete m_popup;
+   m_popup=0L;
+   if (m_deviceWirelessIface)
+   {
+      QString ssid=m_deviceWirelessIface->property("ssid").toString();
+      KPassivePopup::message("KNetworkManager", QString("Timeout probing the server CA certificate for network %1").arg(ssid), (QWidget *)0L );
+      delete m_deviceWirelessIface;
+      m_deviceWirelessIface=0L;
+   }
+   m_caCertProbeTimer->deleteLater();
+   m_caCertProbeTimer=0L;
+
+   start(); // restart the job
+}
+
+
+
 // vim: sw=4 sts=4 et tw=100
Index: networkmanager/libs/ui/connectionsecretsjob.h
===================================================================
--- networkmanager.orig/libs/ui/connectionsecretsjob.h
+++ networkmanager/libs/ui/connectionsecretsjob.h
@@ -31,7 +31,10 @@ along with this program.  If not, see <h
 #include "knm_export.h"
 
 class KDialog;
+class KPassivePopup;
 class SettingWidget;
+class OrgFreedesktopNetworkManagerDeviceWirelessInterface;
+typedef QMap <QString, QString> QStringMap;
 
 /**
  * A job that encapsulates looking up a specified set of Secrets from (secure) storage, ask the user
@@ -64,6 +67,8 @@ public Q_SLOTS:
     void doWork();
     void dialogAccepted();
     void dialogRejected();
+    void handleCaCertReceived(const QStringMap &cert);
+    void caCertProbeTimeout();
 
 protected Q_SLOTS:
     void gotPersistedSecrets(uint);
@@ -72,6 +77,14 @@ private:
     void doAskUser();
     QString keyForEntry(const QString & entry) const;
 
+    // Requests a cacert probe to NetworkManager via dbus for the @p ic connection.
+    // @returns if the request was done or there was a problem requesting it.
+    bool startCaCertProbe(const Knm::Connection *connection);
+
+    // @Returns if a cacert probe is needed for the @p ic connection
+    bool caCertProbeNeeded(const Knm::Connection *connection);
+
+
     Knm::Connection * m_connection;
     Knm::ConnectionPersistence * m_connectionPersistence;
 
@@ -81,6 +94,9 @@ private:
     QDBusMessage mRequest;
     KDialog * m_askUserDialog;
     SettingWidget * m_settingWidget;
+    QTimer *m_caCertProbeTimer;
+    KPassivePopup *m_popup;
+    OrgFreedesktopNetworkManagerDeviceWirelessInterface *m_deviceWirelessIface;
 };
 
 #endif // CONNECTIONSECRETSJOB_H
Index: networkmanager/libs/ui/CMakeLists.txt
===================================================================
--- networkmanager.orig/libs/ui/CMakeLists.txt
+++ networkmanager/libs/ui/CMakeLists.txt
@@ -66,6 +66,9 @@ set(knmui_SRCS
    simpleipv4addressvalidator.cpp
    listvalidator.cpp
    editlistdialog.cpp
+
+   #org.freedesktop.NetworkManager.Device.Wireless
+   nm-device-wifiinterface.cpp
    )
 
 kde4_add_ui_files(knmui_SRCS
Index: networkmanager/libs/ui/security/peapwidget.h
===================================================================
--- networkmanager.orig/libs/ui/security/peapwidget.h
+++ networkmanager/libs/ui/security/peapwidget.h
@@ -41,6 +41,12 @@ public:
     void writeConfig();
     void readSecrets();
 
+public slots:
+    void removeHash();
+    void recalculateHashLabelVisibility();
+
+private:
+    bool m_removeHash;
 };
 
 #endif
Index: networkmanager/libs/ui/security/tlswidget.h
===================================================================
--- networkmanager.orig/libs/ui/security/tlswidget.h
+++ networkmanager/libs/ui/security/tlswidget.h
@@ -50,6 +50,11 @@ public:
     void readSecrets();
 public Q_SLOTS:
     void setShowPasswords(bool b = true);
+    void removeHash();
+    void recalculateHashLabelVisibility();
+
+private:
+    bool m_removeHash;
 };
 
 #endif
Index: networkmanager/libs/ui/security/ttlswidget.h
===================================================================
--- networkmanager.orig/libs/ui/security/ttlswidget.h
+++ networkmanager/libs/ui/security/ttlswidget.h
@@ -40,6 +40,13 @@ public:
     void readConfig();
     void writeConfig();
     void readSecrets();
+
+public slots:
+    void removeHash();
+    void recalculateHashLabelVisibility();
+
+private:
+    bool m_removeHash;
 };
 
 #endif
