author | Andrea Scarpino
<andrea@archlinux.org> 2015-01-04 09:15:04 UTC |
committer | Andrea Scarpino
<andrea@archlinux.org> 2015-01-04 09:15:04 UTC |
parent | e47212130b8b4d31667195336f35ac3be0a90686 |
PKGBUILD | +9 | -4 |
openconnect7.patch | +222 | -0 |
diff --git a/PKGBUILD b/PKGBUILD index 77614a7..3fbebb8 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -2,7 +2,7 @@ pkgname=plasma-nm pkgver=5.1.2 -pkgrel=1 +pkgrel=2 pkgdesc='Plasma applet written in QML for managing network connections' arch=('i686' 'x86_64') url='https://projects.kde.org/projects/kde/workspace/plasma-nm' @@ -11,16 +11,21 @@ depends=('plasma-workspace' 'libmm-qt5' 'libnm-qt5') makedepends=('extra-cmake-modules' 'kdoctools' 'openconnect' 'mobile-broadband-provider-info') optdepends=('mobile-broadband-provider-info: Database of mobile broadband service providers' 'openconnect: Cisco AnyConnect VPN plugin') groups=('plasma-next') -source=("http://download.kde.org/stable/plasma/${pkgver}/$pkgname-$pkgver.tar.xz") -md5sums=('85bcbb4dc40ff020a566413a209858ca') +source=("http://download.kde.org/stable/plasma/${pkgver}/$pkgname-$pkgver.tar.xz" + 'openconnect7.patch') +md5sums=('85bcbb4dc40ff020a566413a209858ca' + '1ce726ebf54031eb09763a45099962ed') prepare() { mkdir -p build + + cd ${pkgname}-${pkgver} + patch -p1 -i "${srcdir}"/openconnect7.patch } build() { cd build - cmake ../plasma-nm-$pkgver \ + cmake ../$pkgname-$pkgver \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_BUILD_TYPE=Release \ -DLIB_INSTALL_DIR=lib \ diff --git a/openconnect7.patch b/openconnect7.patch new file mode 100644 index 0000000..0e96079 --- /dev/null +++ b/openconnect7.patch @@ -0,0 +1,222 @@ +From: David Woodhouse <David.Woodhouse@intel.com> +Date: Wed, 03 Dec 2014 14:10:44 +0000 +Subject: Update OpenConnect support for library version 5 +X-Git-Url: http://quickgit.kde.org/?p=plasma-nm.git&a=commitdiff&h=66d9ab613c1ffd3f36df818f28cffe7750a36f6b +--- +Update OpenConnect support for library version 5 + +String ownership rules are now very simple: the library never takes ownership +of a string it's passed. It always takes its *own* copy and is responsible +for freeing that. Mostly driven by Windows DLL Hell where it's painful to +allocate in one library and free in another because they might actually be +using different heaps. + +Also adapt to the changes in server certificate hash handling. We are no +longer supposed to just compare strings, and must call the relevant function +to check a hash against the server's certificate. This gives better matching +and allows libopenconnect to upgrade the hash in future when it becomes +necessary. +--- + + +--- a/vpn/openconnect/CMakeLists.txt ++++ b/vpn/openconnect/CMakeLists.txt +@@ -25,6 +25,8 @@ + + if (${OPENCONNECT_VERSION} VERSION_GREATER ${MINIMUM_OPENCONNECT_VERSION_REQUIRED} OR + ${OPENCONNECT_VERSION} VERSION_EQUAL ${MINIMUM_OPENCONNECT_VERSION_REQUIRED}) ++ ++ include_directories(${OPENCONNECT_INCLUDE_DIRS}) + + set(openconnect_SRCS + openconnectui.cpp + +--- a/vpn/openconnect/openconnectauth.cpp ++++ b/vpn/openconnect/openconnectauth.cpp +@@ -165,7 +165,7 @@ + } + if (!dataMap[NM_OPENCONNECT_KEY_CACERT].isEmpty()) { + const QByteArray crt = QFile::encodeName(dataMap[NM_OPENCONNECT_KEY_CACERT]); +- openconnect_set_cafile(d->vpninfo, strdup(crt.data())); ++ openconnect_set_cafile(d->vpninfo, OC3DUP(crt.data())); + } + if (dataMap[NM_OPENCONNECT_KEY_CSD_ENABLE] == "yes") { + char *wrapper; +@@ -178,12 +178,12 @@ + } + if (!dataMap[NM_OPENCONNECT_KEY_PROXY].isEmpty()) { + const QByteArray proxy = QFile::encodeName(dataMap[NM_OPENCONNECT_KEY_PROXY]); +- openconnect_set_http_proxy(d->vpninfo, strdup(proxy.data())); ++ openconnect_set_http_proxy(d->vpninfo, OC3DUP(proxy.data())); + } + if (!dataMap[NM_OPENCONNECT_KEY_USERCERT].isEmpty()) { + const QByteArray crt = QFile::encodeName(dataMap[NM_OPENCONNECT_KEY_USERCERT]); + const QByteArray key = QFile::encodeName(dataMap[NM_OPENCONNECT_KEY_PRIVKEY]); +- openconnect_set_client_cert (d->vpninfo, strdup(crt.data()), strdup(key.data())); ++ openconnect_set_client_cert (d->vpninfo, OC3DUP(crt.data()), OC3DUP(key.data())); + + if (!crt.isEmpty() && dataMap[NM_OPENCONNECT_KEY_PEM_PASSPHRASE_FSID] == "yes") { + openconnect_passphrase_from_fsid(d->vpninfo); +@@ -280,10 +280,10 @@ + const VPNHost &host = d->hosts.at(i); + if (openconnect_parse_url(d->vpninfo, host.address.toAscii().data())) { + qWarning() << "Failed to parse server URL" << host.address; +- openconnect_set_hostname(d->vpninfo, strdup(host.address.toAscii().data())); ++ openconnect_set_hostname(d->vpninfo, OC3DUP(host.address.toAscii().data())); + } + if (!openconnect_get_urlpath(d->vpninfo) && !host.group.isEmpty()) +- openconnect_set_urlpath(d->vpninfo, strdup(host.group.toAscii().data())); ++ openconnect_set_urlpath(d->vpninfo, OC3DUP(host.group.toAscii().data())); + d->secrets["lasthost"] = host.name; + addFormInfo(QLatin1String("dialog-information"), i18n("Contacting host, please wait...")); + d->worker->start(); +@@ -305,9 +305,13 @@ + secrets.insert(QLatin1String(NM_OPENCONNECT_KEY_COOKIE), QLatin1String(openconnect_get_cookie(d->vpninfo))); + openconnect_clear_cookie(d->vpninfo); + ++#if OPENCONNECT_CHECK_VER(5,0) ++ const char *fingerprint = openconnect_get_peer_cert_hash(d->vpninfo); ++#else + OPENCONNECT_X509 *cert = openconnect_get_peer_cert(d->vpninfo); + char fingerprint[41]; + openconnect_get_cert_sha1(d->vpninfo, cert, fingerprint); ++#endif + secrets.insert(QLatin1String(NM_OPENCONNECT_KEY_GWCERT), QLatin1String(fingerprint)); + secrets.insert(QLatin1String("certsigs"), d->certificateFingerprints.join("\t")); + secrets.insert(QLatin1String("autoconnect"), d->ui.chkAutoconnect->isChecked() ? "yes" : "no"); +@@ -581,14 +585,16 @@ + const QString key = QString("form:%1:%2").arg(QLatin1String(form->auth_id)).arg(QLatin1String(opt->name)); + if (opt->type == OC_FORM_OPT_PASSWORD || opt->type == OC_FORM_OPT_TEXT) { + QLineEdit *le = qobject_cast<QLineEdit*>(widget); +- opt->value = qstrdup(le->text().toUtf8().constData()); +- if (opt->type == OC_FORM_OPT_PASSWORD) { ++ QByteArray text = le->text().toUtf8(); ++ openconnect_set_option_value(opt, text.data()); ++ if (opt->type == OC_FORM_OPT_TEXT) { + d->secrets.insert(key,le->text()); + } + } else if (opt->type == OC_FORM_OPT_SELECT) { + QComboBox *cbo = qobject_cast<QComboBox*>(widget); +- opt->value = qstrdup(cbo->currentData().toString().toUtf8().constData()); +- d->secrets.insert(key, cbo->currentData().toString()); ++ QByteArray text = cbo->itemData(cbo->currentIndex()).toString().toAscii(); ++ openconnect_set_option_value(opt, text.data()); ++ d->secrets.insert(key,cbo->itemData(cbo->currentIndex()).toString()); + } + } + } + +--- a/vpn/openconnect/openconnectauthworkerthread.cpp ++++ b/vpn/openconnect/openconnectauthworkerthread.cpp +@@ -43,6 +43,20 @@ + class OpenconnectAuthStaticWrapper + { + public: ++#if OPENCONNECT_CHECK_VER(5,0) ++ static int writeNewConfig(void *obj, const char *str, int num) ++ { ++ if (obj) ++ return static_cast<OpenconnectAuthWorkerThread*>(obj)->writeNewConfig(str, num); ++ return -1; ++ } ++ static int validatePeerCert(void *obj, const char *str) ++ { ++ if (obj) ++ return static_cast<OpenconnectAuthWorkerThread*>(obj)->validatePeerCert(NULL, str); ++ return -1; ++ } ++#else + static int writeNewConfig(void *obj, char *str, int num) + { + if (obj) +@@ -55,7 +69,8 @@ + return static_cast<OpenconnectAuthWorkerThread*>(obj)->validatePeerCert(cert, str); + return -1; + } +- static int processAuthForm(void *obj, struct oc_auth_form *form) ++#endif ++ static int processAuthForm(void *obj, struct oc_auth_form *form) + { + if (obj) + return static_cast<OpenconnectAuthWorkerThread*>(obj)->processAuthFormP(form); +@@ -108,7 +123,7 @@ + return m_openconnectInfo; + } + +-int OpenconnectAuthWorkerThread::writeNewConfig(char *buf, int buflen) ++int OpenconnectAuthWorkerThread::writeNewConfig(const char *buf, int buflen) + { + Q_UNUSED(buflen) + if (*m_userDecidedToQuit) +@@ -139,10 +154,16 @@ + } + #endif + +-int OpenconnectAuthWorkerThread::validatePeerCert(OPENCONNECT_X509 *cert, const char *reason) +-{ +- if (*m_userDecidedToQuit) +- return -EINVAL; ++int OpenconnectAuthWorkerThread::validatePeerCert(void *cert, const char *reason) ++{ ++ if (*m_userDecidedToQuit) ++ return -EINVAL; ++ ++#if OPENCONNECT_CHECK_VER(5,0) ++ (void)cert; ++ const char *fingerprint = openconnect_get_peer_cert_hash(m_openconnectInfo); ++ char *details = openconnect_get_peer_cert_details(m_openconnectInfo); ++#else + char fingerprint[41]; + int ret = 0; + +@@ -151,7 +172,7 @@ + return ret; + + char *details = openconnect_get_cert_details(m_openconnectInfo, cert); +- ++#endif + bool accepted = false; + m_mutex->lock(); + QString qFingerprint(fingerprint); +@@ -160,7 +181,7 @@ + emit validatePeerCert(qFingerprint, qCertinfo, qReason, &accepted); + m_waitForUserInput->wait(m_mutex); + m_mutex->unlock(); +- ::free(details); ++ openconnect_free_cert_info(m_openconnectInfo, details); + if (*m_userDecidedToQuit) + return -EINVAL; + + +--- a/vpn/openconnect/openconnectauthworkerthread.h ++++ b/vpn/openconnect/openconnectauthworkerthread.h +@@ -59,6 +59,17 @@ + #define OC_FORM_RESULT_NEWGROUP 2 + #endif + ++#if OPENCONNECT_CHECK_VER(4,0) ++#define OC3DUP(x) (x) ++#else ++#define openconnect_set_option_value(opt, val) do { \ ++ struct oc_form_opt *_o = (opt); \ ++ free(_o->value); _o->value = strdup(val); \ ++ } while (0) ++#define openconnect_free_cert_info(v, x) ::free(x) ++#define OC3DUP(x) strdup(x) ++#endif ++ + #include <QThread> + + class QMutex; +@@ -85,8 +96,8 @@ + void run(); + + private: +- int writeNewConfig(char *, int); +- int validatePeerCert(OPENCONNECT_X509 *, const char *); ++ int writeNewConfig(const char *, int); ++ int validatePeerCert(void *, const char *); + int processAuthFormP(struct oc_auth_form *); + void writeProgress(int level, const char *, va_list); + +