Merge lp:~online-accounts/signon-plugin-sasl/packaging into lp:signon-plugin-sasl
- packaging
- Merge into trunk
Proposed by
Alberto Mardegan
Status: | Merged |
---|---|
Approved by: | David Barth |
Approved revision: | 12 |
Merged at revision: | 12 |
Proposed branch: | lp:~online-accounts/signon-plugin-sasl/packaging |
Merge into: | lp:signon-plugin-sasl |
Diff against target: |
1609 lines (+671/-717) 15 files modified
.bzr-builddeb/default.conf (+2/-0) .gitignore (+8/-0) .qmake.conf (+2/-0) common-project-config.pri (+6/-16) debian/changelog (+3/-2) debian/control (+4/-2) signon-plugin-sasl.pro (+0/-10) src/sasldata.h (+11/-2) src/saslplugin.cpp (+9/-6) src/saslplugin.h (+2/-1) src/src.pro (+4/-2) tests/saslplugintest.cpp (+0/-559) tests/saslplugintest.h (+0/-100) tests/tests.pro (+9/-17) tests/tst_plugin.cpp (+611/-0) |
To merge this branch: | bzr merge lp:~online-accounts/signon-plugin-sasl/packaging |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Online Accounts | Pending | ||
Review via email: mp+278412@code.launchpad.net |
Commit message
No change rebuild
Description of the change
No change rebuild
To post a comment you must log in.
- 12. By Alberto Mardegan
-
Rebase on trunk
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory '.bzr-builddeb' |
2 | === added file '.bzr-builddeb/default.conf' |
3 | --- .bzr-builddeb/default.conf 1970-01-01 00:00:00 +0000 |
4 | +++ .bzr-builddeb/default.conf 2015-12-03 07:31:19 +0000 |
5 | @@ -0,0 +1,2 @@ |
6 | +[BUILDDEB] |
7 | +split = True |
8 | |
9 | === added file '.gitignore' |
10 | --- .gitignore 1970-01-01 00:00:00 +0000 |
11 | +++ .gitignore 2015-12-03 07:31:19 +0000 |
12 | @@ -0,0 +1,8 @@ |
13 | +*.moc |
14 | +*.o |
15 | +.*.swp |
16 | +Makefile |
17 | +moc_* |
18 | +src/libsaslplugin.so |
19 | +tests/tst_plugin |
20 | + |
21 | |
22 | === added file '.qmake.conf' |
23 | --- .qmake.conf 1970-01-01 00:00:00 +0000 |
24 | +++ .qmake.conf 2015-12-03 07:31:19 +0000 |
25 | @@ -0,0 +1,2 @@ |
26 | +TOP_SRC_DIR = $$PWD |
27 | +TOP_BUILD_DIR = $$shadowed($$PWD) |
28 | |
29 | === modified file 'common-project-config.pri' |
30 | --- common-project-config.pri 2012-03-27 12:29:57 +0000 |
31 | +++ common-project-config.pri 2015-12-03 07:31:19 +0000 |
32 | @@ -10,11 +10,13 @@ |
33 | # Disable RTTI |
34 | QMAKE_CXXFLAGS += -fno-exceptions -fno-rtti |
35 | |
36 | -TOP_SRC_DIR = $$PWD |
37 | -TOP_BUILD_DIR = $${TOP_SRC_DIR}/$(BUILD_DIR) |
38 | +!defined(TOP_SRC_DIR, var) { |
39 | + TOP_SRC_DIR = $$PWD |
40 | + TOP_BUILD_DIR = $${TOP_SRC_DIR}/$(BUILD_DIR) |
41 | +} |
42 | |
43 | DEFINES += DEBUG_ENABLED |
44 | -EFINES += SIGNON_TRACE |
45 | +DEFINES += SIGNON_TRACE |
46 | |
47 | #----------------------------------------------------------------------------- |
48 | # setup the installation prefix |
49 | @@ -32,18 +34,7 @@ |
50 | message("==== install prefix set to `$${INSTALL_PREFIX}'") |
51 | } |
52 | |
53 | -# Setup the library installation directory |
54 | -exists( meego-release ) { |
55 | - ARCH = $$system(tail -n1 meego-release) |
56 | -} else { |
57 | - ARCH = $$system(uname -m) |
58 | -} |
59 | - |
60 | -contains( ARCH, x86_64 ) { |
61 | - INSTALL_LIBDIR = $${INSTALL_PREFIX}/lib64 |
62 | -} else { |
63 | - INSTALL_LIBDIR = $${INSTALL_PREFIX}/lib |
64 | -} |
65 | +INSTALL_LIBDIR = $${INSTALL_PREFIX}/lib |
66 | |
67 | # default library directory can be overriden by defining LIBDIR when |
68 | # running qmake |
69 | @@ -64,4 +55,3 @@ |
70 | } else { |
71 | SIGNON_PLUGINS_DIR = $$_PLUGINS |
72 | } |
73 | -SIGNON_PLUGINS_DIR_QUOTED = \\\"$$SIGNON_PLUGINS_DIR\\\" |
74 | |
75 | === modified file 'debian/changelog' |
76 | --- debian/changelog 2015-10-15 14:31:54 +0000 |
77 | +++ debian/changelog 2015-12-03 07:31:19 +0000 |
78 | @@ -1,5 +1,6 @@ |
79 | -signon-plugin-sasl (0.1-0ubuntu1) UNRELEASED; urgency=medium |
80 | +signon-plugin-sasl (0.1-0ubuntu2) vivid; urgency=medium |
81 | |
82 | * Initial release. |
83 | + * No change build for CI. |
84 | |
85 | - -- Alberto Mardegan <alberto.mardegan@canonical.com> Thu, 15 Oct 2015 17:22:15 +0300 |
86 | + -- Alberto Mardegan <alberto.mardegan@canonical.com> Tue, 24 Nov 2015 09:53:39 +0200 |
87 | |
88 | === modified file 'debian/control' |
89 | --- debian/control 2015-10-15 14:31:54 +0000 |
90 | +++ debian/control 2015-12-03 07:31:19 +0000 |
91 | @@ -5,22 +5,24 @@ |
92 | Build-Depends: dbus-test-runner, |
93 | debhelper (>= 9), |
94 | libsasl2-dev, |
95 | + libsasl2-modules, |
96 | libsignon-qt5-dev, |
97 | pkg-config, |
98 | qt5-default, |
99 | signon-plugins-dev (>> 8.57+14.10.20140827-0ubuntu1), |
100 | xvfb, |
101 | -Standards-Version: 3.9.4 |
102 | +Standards-Version: 3.9.6 |
103 | Homepage: https://gitlab.com/accounts-sso/signon-plugin-sasl |
104 | # If you aren't a member of ~online-accounts but need to upload packaging changes, |
105 | # just go ahead. ~online-accounts will notice and sync up the code again. |
106 | -Vcs-Bzr: https://code.launchpad.net/~online-accounts/signon-plugin-sasl/trunk |
107 | +Vcs-Bzr: lp:signon-plugin-sasl |
108 | |
109 | Package: signon-plugin-sasl |
110 | Architecture: any |
111 | Section: libs |
112 | Depends: ${shlibs:Depends}, |
113 | ${misc:Depends}, |
114 | + libsasl2-modules, |
115 | Description: Single Signon SASL plugin |
116 | SASL plugin for the Single Signon framework |
117 | |
118 | |
119 | === modified file 'signon-plugin-sasl.pro' |
120 | --- signon-plugin-sasl.pro 2015-09-18 13:52:42 +0000 |
121 | +++ signon-plugin-sasl.pro 2015-12-03 07:31:19 +0000 |
122 | @@ -8,13 +8,3 @@ |
123 | include( common-installs-config.pri ) |
124 | |
125 | #include( doc/doc.pri ) |
126 | - |
127 | -DISTNAME = $${PROJECT_NAME}-$${PROJECT_VERSION} |
128 | -EXCLUDES = \ |
129 | - --exclude-vcs \ |
130 | - --exclude=.* \ |
131 | - --exclude=$${DISTNAME}.tar.bz2 \ |
132 | - --exclude-from .gitignore |
133 | -dist.commands = "tar -cvjf $${DISTNAME}.tar.bz2 $$EXCLUDES --transform='s,^,$$DISTNAME/,' *" |
134 | -dist.depends = distclean |
135 | -QMAKE_EXTRA_TARGETS += dist |
136 | |
137 | === modified file 'src/sasldata.h' |
138 | --- src/sasldata.h 2012-03-16 08:53:07 +0000 |
139 | +++ src/sasldata.h 2015-12-03 07:31:19 +0000 |
140 | @@ -2,8 +2,9 @@ |
141 | * This file is part of signon |
142 | * |
143 | * Copyright (C) 2009-2010 Nokia Corporation. |
144 | + * Copyright (C) 2015 Canonical Ltd. |
145 | * |
146 | - * Contact: Alberto Mardegan <alberto.mardegan@nokia.com> |
147 | + * Contact: Alberto Mardegan <alberto.mardegan@canonical.com> |
148 | * |
149 | * This library is free software; you can redistribute it and/or |
150 | * modify it under the terms of the GNU Lesser General Public License |
151 | @@ -47,6 +48,14 @@ |
152 | CONTINUE, /*!< Authentication in progress */ |
153 | }; |
154 | |
155 | + SaslData(const QVariantMap &data = QVariantMap()) { m_data = data; } |
156 | + |
157 | + /*! |
158 | + * The list of mechanisms received from the remote server, separated with |
159 | + * whitespace or punctuation characters. |
160 | + */ |
161 | + SIGNON_SESSION_DECLARE_PROPERTY(QByteArray, MechList); |
162 | + |
163 | /*! |
164 | * The challenge received from the remote server. |
165 | */ |
166 | @@ -60,7 +69,7 @@ |
167 | /*! |
168 | * SASL authentication name. |
169 | */ |
170 | - SIGNON_SESSION_DECLARE_PROPERTY(QString, Authname); |
171 | + SIGNON_SESSION_DECLARE_PROPERTY(QString, AuthName); |
172 | |
173 | /*! |
174 | * SASL realm. |
175 | |
176 | === modified file 'src/saslplugin.cpp' |
177 | --- src/saslplugin.cpp 2015-09-18 14:35:00 +0000 |
178 | +++ src/saslplugin.cpp 2015-12-03 07:31:19 +0000 |
179 | @@ -2,8 +2,9 @@ |
180 | * This file is part of signon |
181 | * |
182 | * Copyright (C) 2009-2010 Nokia Corporation. |
183 | + * Copyright (C) 2015 Canonical Ltd. |
184 | * |
185 | - * Contact: Alberto Mardegan <alberto.mardegan@nokia.com> |
186 | + * Contact: Alberto Mardegan <alberto.mardegan@canonical.com> |
187 | * |
188 | * This library is free software; you can redistribute it and/or |
189 | * modify it under the terms of the GNU Lesser General Public License |
190 | @@ -169,7 +170,7 @@ |
191 | |
192 | using SignOn::Error; |
193 | |
194 | - if (!check_and_fix_parameters(d->m_input)) { |
195 | + if (!check_and_fix_parameters(d->m_input, mechanism.toUtf8())) { |
196 | TRACE() << "missing parameters"; |
197 | emit error(Error::MissingData); |
198 | return; |
199 | @@ -208,7 +209,7 @@ |
200 | } |
201 | |
202 | res = sasl_client_start(d->m_conn, |
203 | - mechanism.toUtf8().constData(), |
204 | + d->m_input.MechList().constData(), |
205 | NULL, |
206 | &data, |
207 | &len, |
208 | @@ -306,7 +307,7 @@ |
209 | *len = self->d->m_username.count(); |
210 | break; |
211 | case SASL_CB_AUTHNAME: |
212 | - self->d->m_authname = self->d->m_input.Authname().toUtf8(); |
213 | + self->d->m_authname = self->d->m_input.AuthName().toUtf8(); |
214 | *result = self->d->m_authname.constData(); |
215 | if (len) |
216 | *len = self->d->m_authname.count(); |
217 | @@ -432,7 +433,8 @@ |
218 | |
219 | } |
220 | |
221 | -bool SaslPlugin::check_and_fix_parameters(SaslData &input) |
222 | +bool SaslPlugin::check_and_fix_parameters(SaslData &input, |
223 | + const QByteArray &mechanism) |
224 | { |
225 | TRACE(); |
226 | if (input.UserName().isEmpty()) |
227 | @@ -440,7 +442,7 @@ |
228 | |
229 | //set default parameters |
230 | if (input.Service().isEmpty()) input.setService(QByteArray("default")); |
231 | - if (input.Authname().isEmpty()) input.setAuthname(input.UserName()); |
232 | + if (input.AuthName().isEmpty()) input.setAuthName(input.UserName()); |
233 | if (input.Fqdn().isEmpty()) { |
234 | if (!input.Realm().isEmpty()) |
235 | input.setFqdn(input.Realm()); |
236 | @@ -449,6 +451,7 @@ |
237 | } |
238 | if (input.IpLocal().isEmpty()) input.setIpLocal(QByteArray("127.0.0.1")); |
239 | if (input.IpRemote().isEmpty()) input.setIpRemote(QByteArray("127.0.0.1")); |
240 | + if (input.MechList().isEmpty()) input.setMechList(mechanism); |
241 | |
242 | return true; |
243 | } |
244 | |
245 | === modified file 'src/saslplugin.h' |
246 | --- src/saslplugin.h 2012-03-16 08:53:07 +0000 |
247 | +++ src/saslplugin.h 2015-12-03 07:31:19 +0000 |
248 | @@ -66,7 +66,8 @@ |
249 | int id, sasl_secret_t **psecret); |
250 | static int sasl_log(void *context, int priority, const char *message); |
251 | void set_callbacks(); |
252 | - bool check_and_fix_parameters(SaslData &input); |
253 | + bool check_and_fix_parameters(SaslData &input, |
254 | + const QByteArray &mechanism); |
255 | Private *d; // Owned. |
256 | }; |
257 | |
258 | |
259 | === modified file 'src/src.pro' |
260 | --- src/src.pro 2015-09-18 13:52:42 +0000 |
261 | +++ src/src.pro 2015-12-03 07:31:19 +0000 |
262 | @@ -10,8 +10,10 @@ |
263 | link_pkgconfig |
264 | DEFINES += SIGNON_PLUGIN_TRACE |
265 | |
266 | -public_headers += sasldata.h saslplugin.h |
267 | -private_headers = |
268 | +public_headers += \ |
269 | + sasldata.h |
270 | +private_headers += \ |
271 | + saslplugin.h |
272 | HEADERS += $$public_headers $$private_headers |
273 | |
274 | SOURCES += saslplugin.cpp |
275 | |
276 | === removed file 'tests/saslplugintest.cpp' |
277 | --- tests/saslplugintest.cpp 2015-09-18 14:35:00 +0000 |
278 | +++ tests/saslplugintest.cpp 1970-01-01 00:00:00 +0000 |
279 | @@ -1,559 +0,0 @@ |
280 | -/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
281 | -/* |
282 | - * This file is part of signon |
283 | - * |
284 | - * Copyright (C) 2009-2010 Nokia Corporation. |
285 | - * |
286 | - * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com> |
287 | - * Contact: Alberto Mardegan <alberto.mardegan@nokia.com> |
288 | - * |
289 | - * This library is free software; you can redistribute it and/or |
290 | - * modify it under the terms of the GNU Lesser General Public License |
291 | - * version 2.1 as published by the Free Software Foundation. |
292 | - * |
293 | - * This library is distributed in the hope that it will be useful, but |
294 | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
295 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
296 | - * Lesser General Public License for more details. |
297 | - * |
298 | - * You should have received a copy of the GNU Lesser General Public |
299 | - * License along with this library; if not, write to the Free Software |
300 | - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA |
301 | - * 02110-1301 USA |
302 | - */ |
303 | - |
304 | - |
305 | -#include <QtTest/QtTest> |
306 | -#include <sasl/sasl.h> |
307 | - |
308 | -#include "saslplugin.h" |
309 | -#include "sasldata.h" |
310 | -#include "saslplugin.cpp" |
311 | - |
312 | -#include "saslplugintest.h" |
313 | - |
314 | -using namespace SaslPluginNS; |
315 | - |
316 | -void SaslPluginTest::initTestCase() |
317 | -{ |
318 | - qRegisterMetaType<SignOn::SessionData>(); |
319 | -} |
320 | - |
321 | -void SaslPluginTest::cleanupTestCase() |
322 | -{ |
323 | - sasl_done(); |
324 | -} |
325 | - |
326 | -//prepare each test by creating new plugin |
327 | -void SaslPluginTest::init() |
328 | -{ |
329 | - m_testPlugin = new SaslPlugin(); |
330 | -} |
331 | - |
332 | -//finnish each test by deleting plugin |
333 | -void SaslPluginTest::cleanup() |
334 | -{ |
335 | - delete m_testPlugin; |
336 | - m_testPlugin=NULL; |
337 | -} |
338 | - |
339 | -//slot for receiving result |
340 | -void SaslPluginTest::result(const SignOn::SessionData& data) |
341 | -{ |
342 | - qDebug() << "got result"; |
343 | - m_response = data; |
344 | - m_loop.exit(); |
345 | -} |
346 | - |
347 | -//slot for receiving error |
348 | -void SaslPluginTest::pluginError(const SignOn::Error &error) |
349 | -{ |
350 | - qDebug() << "got error" << error.type(); |
351 | - m_errorType = error.type(); |
352 | - m_loop.exit(); |
353 | -} |
354 | - |
355 | -//test cases |
356 | - |
357 | -void SaslPluginTest::testPlugin() |
358 | -{ |
359 | - QVERIFY(m_testPlugin); |
360 | -} |
361 | - |
362 | -void SaslPluginTest::testPluginType() |
363 | -{ |
364 | - QCOMPARE(m_testPlugin->type(), QString("sasl")); |
365 | -} |
366 | - |
367 | -void SaslPluginTest::testPluginMechanisms() |
368 | -{ |
369 | - QStringList mechs = m_testPlugin->mechanisms(); |
370 | - QVERIFY(!mechs.isEmpty()); |
371 | - QVERIFY(mechs.contains(QString("PLAIN"))); |
372 | -} |
373 | - |
374 | -void SaslPluginTest::testPluginCancel() |
375 | -{ |
376 | - //no functionality to test |
377 | -} |
378 | - |
379 | -void SaslPluginTest::testPluginProcess() |
380 | -{ |
381 | - using SignOn::Error; |
382 | - |
383 | - SaslData info; |
384 | - |
385 | - QObject::connect(m_testPlugin, SIGNAL(result(const SignOn::SessionData&)), |
386 | - this, SLOT(result(const SignOn::SessionData&)),Qt::QueuedConnection); |
387 | - QObject::connect(m_testPlugin, SIGNAL(error(const SignOn::Error&)), |
388 | - this, SLOT(pluginError(const SignOn::Error&)),Qt::QueuedConnection); |
389 | - QTimer::singleShot(10*1000, &m_loop, SLOT(quit())); |
390 | - |
391 | - //try without username |
392 | - m_testPlugin->process(info, QString("ANONYMOUS")); |
393 | - m_loop.exec(); |
394 | - QVERIFY(m_errorType == Error::MissingData); |
395 | - |
396 | - //try without mechanism |
397 | - info.setUserName(QString("test")); |
398 | - m_testPlugin->process(info); |
399 | - m_loop.exec(); |
400 | - QVERIFY(m_errorType == Error::MechanismNotAvailable); |
401 | - |
402 | - //rest of process is tested with real authentication mechanisms |
403 | -} |
404 | - |
405 | -void SaslPluginTest::testPluginChallengePlain() |
406 | -{ |
407 | - SaslData info; |
408 | - |
409 | - QObject::connect(m_testPlugin, SIGNAL(result(const SignOn::SessionData&)), |
410 | - this, SLOT(result(const SignOn::SessionData&)),Qt::QueuedConnection); |
411 | - QObject::connect(m_testPlugin, SIGNAL(error(const SignOn::Error & )), |
412 | - this, SLOT(pluginError(const SignOn::Error & )),Qt::QueuedConnection); |
413 | - QTimer::singleShot(10*1000, &m_loop, SLOT(quit())); |
414 | - |
415 | - info.setUserName(QString("idmtestuser")); |
416 | - info.setSecret(QString("abc123")); |
417 | - info.setAuthname(QString("authn")); |
418 | - |
419 | - //give challenge to plugin |
420 | - m_testPlugin->process(info, QString("PLAIN")); |
421 | - m_loop.exec(); |
422 | - |
423 | - //test response here |
424 | - SaslData result = m_response.data<SaslData>(); |
425 | - QByteArray token=result.Response(); |
426 | - token.replace('\0',':'); |
427 | - QCOMPARE(result.Response(), QByteArray("idmtestuser\0authn\0abc123",11+5+6+2)); |
428 | - |
429 | - |
430 | - //create connection to server to get initial challenge |
431 | - SaslServer* server = new SaslServer(); |
432 | - QByteArray reply; |
433 | - server->init(QString("PLAIN"),reply); |
434 | - |
435 | - //check that authentication server is happy about answer |
436 | - int retval=server->step(result.Response()); |
437 | - QCOMPARE(retval, SASL_NOUSER); |
438 | - |
439 | - delete server; |
440 | -} |
441 | - |
442 | -void SaslPluginTest::testPluginChallengeDigestMd5() |
443 | -{ |
444 | - SaslData info; |
445 | - |
446 | - QObject::connect(m_testPlugin, SIGNAL(result(const SignOn::SessionData&)), |
447 | - this, SLOT(result(const SignOn::SessionData&)),Qt::QueuedConnection); |
448 | - QObject::connect(m_testPlugin, SIGNAL(error(const SignOn::Error & )), |
449 | - this, SLOT(pluginError(const SignOn::Error & )),Qt::QueuedConnection); |
450 | - QTimer::singleShot(10*1000, &m_loop, SLOT(quit())); |
451 | - |
452 | - info.setUserName(QString("idmtestuser")); |
453 | - info.setSecret(QString("abc123")); |
454 | - info.setAuthname(QString("authn")); |
455 | - info.setRealm(QString("realm")); |
456 | - info.setService(QByteArray("sample")); |
457 | - |
458 | - //create connection to server to get initial challenge |
459 | - SaslServer* server = new SaslServer(); |
460 | - |
461 | - QByteArray challenge; |
462 | - server->init(QString("DIGEST-MD5"), challenge); |
463 | - info.setChallenge(challenge); |
464 | - |
465 | - //give challenge to plugin |
466 | - m_testPlugin->process(info, QString("DIGEST-MD5")); |
467 | - m_loop.exec(); |
468 | - |
469 | - //test response here |
470 | - SaslData result = m_response.data<SaslData>(); |
471 | - |
472 | - int retval=server->step(result.Response()); |
473 | - QCOMPARE(retval, SASL_NOUSER); |
474 | - |
475 | - delete server; |
476 | -} |
477 | - |
478 | -void SaslPluginTest::testPluginChallengeCramMd5() |
479 | -{ |
480 | - SaslData info; |
481 | - |
482 | - QObject::connect(m_testPlugin, SIGNAL(result(const SignOn::SessionData&)), |
483 | - this, SLOT(result(const SignOn::SessionData&)),Qt::QueuedConnection); |
484 | - QObject::connect(m_testPlugin, SIGNAL(error(const SignOn::Error & )), |
485 | - this, SLOT(pluginError(const SignOn::Error & )),Qt::QueuedConnection); |
486 | - QTimer::singleShot(10*1000, &m_loop, SLOT(quit())); |
487 | - |
488 | - info.setUserName(QString("idmtestuser")); |
489 | - info.setSecret(QString("abc123")); |
490 | - info.setAuthname(QString("authn")); |
491 | - info.setRealm(QString("realm")); |
492 | - info.setService(QByteArray("sample")); |
493 | - |
494 | - //create connection to server to get initial challenge |
495 | - SaslServer *server = new SaslServer(); |
496 | - |
497 | - QByteArray challenge; |
498 | - int serret = server->init(QString("CRAM-MD5"), challenge); //fails sometimes |
499 | - if (serret!=SASL_OK) |
500 | - { |
501 | - QSKIP("sasl server init for CRAM-MD5 failed",SkipSingle); |
502 | - } |
503 | - |
504 | - qDebug() <<challenge; |
505 | - info.setChallenge(challenge); |
506 | - |
507 | - //give challenge to plugin |
508 | - m_testPlugin->process(info, QString("CRAM-MD5")); |
509 | - m_loop.exec(); |
510 | - |
511 | - //test response here |
512 | - SaslData result = m_response.data<SaslData>(); |
513 | - |
514 | - int retval=server->step(result.Response()); //fails, check server impl. |
515 | - QCOMPARE(retval, SASL_NOUSER); |
516 | - |
517 | - delete server; |
518 | -} |
519 | - |
520 | -//private funcs |
521 | - |
522 | -void SaslPluginTest::testPluginsasl_callback() |
523 | -{ |
524 | - int ret=0; |
525 | - const char* res; |
526 | - unsigned len; |
527 | - ret=m_testPlugin->sasl_callback(NULL,0,&res,&len); |
528 | - QVERIFY(ret==SASL_BADPARAM); |
529 | - ret=m_testPlugin->sasl_callback(m_testPlugin,0,NULL,&len); |
530 | - QVERIFY(ret==SASL_BADPARAM); |
531 | - |
532 | - m_testPlugin->d->m_input.setUserName(QString("user")); |
533 | - |
534 | - ret=m_testPlugin->sasl_callback(m_testPlugin,SASL_CB_USER,&res,&len); |
535 | - QVERIFY(ret==SASL_OK); |
536 | - QCOMPARE(QByteArray(res),QByteArray("user")); |
537 | - QVERIFY(len == 4); |
538 | - |
539 | - m_testPlugin->d->m_input.setAuthname(QString("auth")); |
540 | - |
541 | - ret=m_testPlugin->sasl_callback(m_testPlugin,SASL_CB_AUTHNAME,&res,&len); |
542 | - QVERIFY(ret==SASL_OK); |
543 | - QCOMPARE(QByteArray(res),QByteArray("auth")); |
544 | - QVERIFY(len == 4); |
545 | - |
546 | - ret=m_testPlugin->sasl_callback(m_testPlugin,SASL_CB_LANGUAGE,&res,&len); |
547 | - QVERIFY(ret==SASL_OK); |
548 | - QVERIFY(res == NULL); |
549 | - QVERIFY(len == 0); |
550 | - |
551 | - ret=m_testPlugin->sasl_callback(m_testPlugin,45643,&res,&len); |
552 | - QVERIFY(ret==SASL_BADPARAM); |
553 | -} |
554 | - |
555 | -void SaslPluginTest::testPluginsasl_get_realm() |
556 | -{ |
557 | - int ret=0; |
558 | - const char* res; |
559 | - |
560 | - ret=m_testPlugin->sasl_get_realm(NULL, 0, NULL, NULL); |
561 | - QVERIFY(ret==SASL_FAIL); |
562 | - ret=m_testPlugin->sasl_get_realm(NULL, SASL_CB_GETREALM, NULL, NULL); |
563 | - QVERIFY(ret==SASL_BADPARAM); |
564 | - ret=m_testPlugin->sasl_get_realm(m_testPlugin, SASL_CB_GETREALM, NULL, NULL); |
565 | - QVERIFY(ret==SASL_BADPARAM); |
566 | - |
567 | - ret=m_testPlugin->sasl_get_realm(m_testPlugin, SASL_CB_GETREALM, NULL, &res); |
568 | - QVERIFY(ret==SASL_OK); |
569 | - |
570 | - m_testPlugin->d->m_input.setRealm(QString("real")); |
571 | - |
572 | - ret=m_testPlugin->sasl_get_realm(m_testPlugin, SASL_CB_GETREALM, NULL, &res); |
573 | - QVERIFY(ret==SASL_OK); |
574 | - QCOMPARE(QByteArray(res),QByteArray("real")); |
575 | -} |
576 | - |
577 | -void SaslPluginTest::testPluginsasl_get_secret() |
578 | -{ |
579 | - int ret=0; |
580 | - sasl_secret_t *secret=NULL; |
581 | - |
582 | - ret=m_testPlugin->sasl_get_secret(m_testPlugin->d->m_conn,NULL,0, &secret); |
583 | - QVERIFY(ret==SASL_BADPARAM); |
584 | - |
585 | - m_testPlugin->d->m_input.setSecret(QString("password")); |
586 | - |
587 | - ret=m_testPlugin->sasl_get_secret(m_testPlugin->d->m_conn,m_testPlugin,SASL_CB_PASS, NULL); |
588 | - QVERIFY(ret==SASL_BADPARAM); |
589 | - ret=m_testPlugin->sasl_get_secret(m_testPlugin->d->m_conn,m_testPlugin,SASL_CB_PASS, &secret); |
590 | - qDebug("err: %d",ret); |
591 | - QVERIFY(ret==SASL_OK); |
592 | - QCOMPARE(QByteArray("password"),QByteArray((const char*)secret->data,(int)secret->len)); |
593 | -} |
594 | - |
595 | -void SaslPluginTest::testPluginsasl_log() |
596 | -{ |
597 | - int ret=0; |
598 | - |
599 | - ret=m_testPlugin->sasl_log(m_testPlugin, 0, NULL); |
600 | - QVERIFY(ret==SASL_BADPARAM); |
601 | - |
602 | - ret=m_testPlugin->sasl_log(m_testPlugin, 0, "test debug"); |
603 | - QVERIFY(ret==SASL_OK); |
604 | -} |
605 | - |
606 | -void SaslPluginTest::testPluginset_callbacks() |
607 | -{ |
608 | - m_testPlugin->set_callbacks(); |
609 | - sasl_callback_t *callback; |
610 | - callback = m_testPlugin->d->m_callbacks; |
611 | - QVERIFY(callback != NULL); |
612 | - QVERIFY(callback->id == SASL_CB_LOG); |
613 | - QVERIFY(callback->context == m_testPlugin); |
614 | - ++callback; |
615 | - QVERIFY(callback != NULL); |
616 | - QVERIFY(callback->id == SASL_CB_USER); |
617 | - QVERIFY(callback->context == m_testPlugin); |
618 | - ++callback; |
619 | - QVERIFY(callback != NULL); |
620 | - QVERIFY(callback->id == SASL_CB_AUTHNAME); |
621 | - QVERIFY(callback->context == m_testPlugin); |
622 | - ++callback; |
623 | - QVERIFY(callback != NULL); |
624 | - QVERIFY(callback->id == SASL_CB_PASS); |
625 | - QVERIFY(callback->context == m_testPlugin); |
626 | - ++callback; |
627 | - QVERIFY(callback != NULL); |
628 | - QVERIFY(callback->id == SASL_CB_GETREALM); |
629 | - QVERIFY(callback->context == m_testPlugin); |
630 | - ++callback; |
631 | - QVERIFY(callback != NULL); |
632 | - QVERIFY(callback->id == SASL_CB_LIST_END); |
633 | - QVERIFY(callback->context == NULL); |
634 | -} |
635 | - |
636 | -void SaslPluginTest::testPlugincheck_and_fix_parameters() |
637 | -{ |
638 | - bool ret; |
639 | - SaslData input; |
640 | - ret=m_testPlugin->check_and_fix_parameters(input); |
641 | - QVERIFY(ret==false); //m_user not defined |
642 | - QVERIFY(input.Service().isEmpty()); |
643 | - input.setUserName(QString("user")); |
644 | - |
645 | - ret=m_testPlugin->check_and_fix_parameters(input); |
646 | - QVERIFY(ret); //user valid |
647 | - QCOMPARE(input.UserName(), QString("user")); |
648 | - QCOMPARE(input.Service(), QString("default")); |
649 | - QCOMPARE(input.Fqdn(), QString("default")); |
650 | - QCOMPARE(input.IpLocal(), QString("127.0.0.1")); |
651 | - QCOMPARE(input.IpRemote(), QString("127.0.0.1")); |
652 | -} |
653 | - |
654 | -// sasl server implementation for response verification |
655 | - |
656 | -int sasl_log(void *context, |
657 | - int priority, |
658 | - const char *message) |
659 | -{ |
660 | - Q_UNUSED(context); |
661 | - Q_UNUSED(priority); |
662 | - if (! message) |
663 | - return SASL_BADPARAM; |
664 | - |
665 | - TRACE() << message; |
666 | - return SASL_OK; |
667 | -} |
668 | - |
669 | -static sasl_callback_t callbacks[] = { |
670 | - { |
671 | - SASL_CB_LOG, (int(*)())(&sasl_log), NULL |
672 | - }, { |
673 | - SASL_CB_LIST_END, NULL, NULL |
674 | - } |
675 | -}; |
676 | - |
677 | -void saslfail(int why, const char *what, const char *errstr) |
678 | -{ |
679 | - qDebug() << why << what << errstr; |
680 | -} |
681 | - |
682 | -#define SAMPLE_SEC_BUF_SIZE (2048) |
683 | - |
684 | -char buf[SAMPLE_SEC_BUF_SIZE]; |
685 | - |
686 | -SaslServer::SaslServer() |
687 | -{ |
688 | - service="sample"; |
689 | - localdomain="loc"; |
690 | - userdomain="realm"; |
691 | - iplocal="127.0.0.1"; |
692 | - ipremote="127.0.0.1"; |
693 | - searchpath="."; |
694 | - memset(&buf, 0L, SAMPLE_SEC_BUF_SIZE); |
695 | -} |
696 | - |
697 | -SaslServer::~SaslServer() |
698 | -{ |
699 | - sasl_dispose(&conn); |
700 | - //sasl_done(); //cannot be called, as plugin also runs this |
701 | -} |
702 | - |
703 | -int SaslServer::init(const QString &mech, QByteArray &challenge) |
704 | -{ |
705 | - const char *ext_authid = NULL; |
706 | - |
707 | - /* Init defaults... */ |
708 | - memset(&secprops, 0L, sizeof(secprops)); |
709 | - secprops.maxbufsize = SAMPLE_SEC_BUF_SIZE; |
710 | - secprops.max_ssf = UINT_MAX; |
711 | - |
712 | - result = sasl_server_init(callbacks, "sample"); |
713 | - if (result != SASL_OK) |
714 | - saslfail(result, "Initializing libsasl", NULL); |
715 | - |
716 | - result = sasl_server_new(service, |
717 | - localdomain, |
718 | - userdomain, |
719 | - iplocal, |
720 | - ipremote, |
721 | - NULL, |
722 | - serverlast, |
723 | - &conn); |
724 | - if (result != SASL_OK) |
725 | - saslfail(result, "Allocating sasl connection state", NULL); |
726 | - |
727 | - if (!mech.isEmpty()) { |
728 | - printf("Forcing use of mechanism %s\n", mech.toLatin1().constData()); |
729 | - data = strdup(mech.toLatin1().constData()); |
730 | - len = (unsigned) strlen(data); |
731 | - count = 1; |
732 | - } else { |
733 | - puts("Generating client mechanism list..."); |
734 | - result = sasl_listmech(conn, |
735 | - ext_authid, |
736 | - NULL, |
737 | - " ", |
738 | - NULL, |
739 | - &data, |
740 | - &len, |
741 | - (int*)&count); |
742 | - if (result != SASL_OK) |
743 | - saslfail(result, "Generating client mechanism list", NULL); |
744 | - } |
745 | - |
746 | - printf("Sending list of %d mechanism(s)\n", count); |
747 | - |
748 | - if (!mech.isEmpty()) { |
749 | - free((void *)data); |
750 | - } |
751 | - |
752 | - puts("Waiting for client mechanism..."); |
753 | - strcpy(buf, mech.toLatin1().constData()); |
754 | - len=strlen(buf); |
755 | - |
756 | - if (!mech.isEmpty() && strcasecmp(mech.toLatin1().constData(), buf)) |
757 | - { |
758 | - qDebug("Client chose something other than the mandatory mechanism"); |
759 | - return SASL_FAIL; |
760 | - } |
761 | - |
762 | - if (strlen(buf) < len) { |
763 | - qDebug(" Hmm, there's an initial response here "); |
764 | - data = buf + strlen(buf) + 1; |
765 | - len = len - strlen(buf) - 1; |
766 | - } else { |
767 | - qDebug("no initial data"); |
768 | - data = NULL; |
769 | - len = 0; |
770 | - } |
771 | - qDebug("start"); |
772 | - result = sasl_server_start(conn, |
773 | - buf, |
774 | - data, |
775 | - len, |
776 | - &data, |
777 | - &len); |
778 | - if (result != SASL_OK && result != SASL_CONTINUE) |
779 | - { |
780 | - saslfail(result, "Starting SASL negotiation", sasl_errstring(result,NULL,NULL)); |
781 | - return result; |
782 | - } |
783 | - if (len) { |
784 | - qDebug("gotl data"); |
785 | - qDebug()<< data; |
786 | - challenge=QByteArray(data,len); |
787 | - qDebug()<< challenge; |
788 | - } |
789 | - return result; |
790 | -} |
791 | - |
792 | -int SaslServer::step(const QByteArray &response) |
793 | -{ |
794 | - if (data) { |
795 | - puts("Sending response..."); |
796 | - } else { |
797 | - qDebug("No data to send--something's wrong"); |
798 | - } |
799 | - puts("Waiting for client reply..."); |
800 | - QByteArray resp=response; |
801 | - resp.replace('\0',':'); |
802 | - |
803 | - qDebug()<<resp; |
804 | - qDebug()<<response; |
805 | - qDebug()<<response.count(); |
806 | - |
807 | - for(int i=0; i<response.count(); i++) buf[i]=(char)(response.constData()[i]); |
808 | - len=response.count(); |
809 | - buf[len]=0; |
810 | - |
811 | - data = NULL; |
812 | - result = sasl_server_step(conn, buf, len, |
813 | - &data, &len); |
814 | - if (result != SASL_OK && result != SASL_CONTINUE) |
815 | - { |
816 | - saslfail(result, "Performing SASL negotiation", sasl_errstring(result,NULL,NULL)); |
817 | - return result; |
818 | - } |
819 | - |
820 | - if(result == SASL_CONTINUE) { |
821 | - qDebug("continue"); |
822 | - return result; |
823 | - } |
824 | - |
825 | - puts("Negotiation complete"); |
826 | - |
827 | - if(serverlast&&data) { |
828 | - printf("might need additional send:\n"); |
829 | - } |
830 | - |
831 | - result = sasl_getprop(conn, SASL_USERNAME, (const void **)&data); |
832 | - |
833 | - return SASL_OK; |
834 | -} |
835 | - |
836 | -//end test cases |
837 | - |
838 | -QTEST_MAIN(SaslPluginTest) |
839 | |
840 | === removed file 'tests/saslplugintest.h' |
841 | --- tests/saslplugintest.h 2015-09-18 13:33:21 +0000 |
842 | +++ tests/saslplugintest.h 1970-01-01 00:00:00 +0000 |
843 | @@ -1,100 +0,0 @@ |
844 | -/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
845 | -/* |
846 | - * This file is part of signon |
847 | - * |
848 | - * Copyright (C) 2009-2010 Nokia Corporation. |
849 | - * |
850 | - * Contact: Alberto Mardegan <alberto.mardegan@nokia.com> |
851 | - * |
852 | - * This library is free software; you can redistribute it and/or |
853 | - * modify it under the terms of the GNU Lesser General Public License |
854 | - * version 2.1 as published by the Free Software Foundation. |
855 | - * |
856 | - * This library is distributed in the hope that it will be useful, but |
857 | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
858 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
859 | - * Lesser General Public License for more details. |
860 | - * |
861 | - * You should have received a copy of the GNU Lesser General Public |
862 | - * License along with this library; if not, write to the Free Software |
863 | - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA |
864 | - * 02110-1301 USA |
865 | - */ |
866 | - |
867 | -#ifndef SASL_PLUGINS_TEST |
868 | -#define SASL_PLUGINS_TEST |
869 | - |
870 | -#include <sasl/sasl.h> |
871 | -#include <QString> |
872 | -#include "saslplugin.h" |
873 | -#include "SignOn/authpluginif.h" |
874 | - |
875 | -using namespace SaslPluginNS; |
876 | - |
877 | -class SaslPluginTest : public QObject |
878 | -{ |
879 | - Q_OBJECT |
880 | - |
881 | -public slots: |
882 | - void result(const SignOn::SessionData& data); |
883 | - void pluginError(const SignOn::Error &error); |
884 | - |
885 | -private slots: |
886 | - void initTestCase(); |
887 | - void cleanupTestCase(); |
888 | - void init(); |
889 | - void cleanup(); |
890 | - |
891 | - //test cases |
892 | - void testPlugin(); |
893 | - void testPluginType(); |
894 | - void testPluginMechanisms(); |
895 | - void testPluginCancel(); |
896 | - void testPluginProcess(); |
897 | - void testPluginChallengePlain(); |
898 | - void testPluginChallengeDigestMd5(); |
899 | - void testPluginChallengeCramMd5(); |
900 | - void testPluginsasl_callback(); |
901 | - void testPluginsasl_get_realm(); |
902 | - void testPluginsasl_get_secret(); |
903 | - void testPluginsasl_log(); |
904 | - void testPluginset_callbacks(); |
905 | - void testPlugincheck_and_fix_parameters(); |
906 | - //end test cases |
907 | - |
908 | -private: |
909 | - SaslPlugin* m_testPlugin; |
910 | - int m_errorType; |
911 | - SignOn::SessionData m_response; |
912 | - QEventLoop m_loop; |
913 | -}; |
914 | - |
915 | -class SaslServer { |
916 | -public: |
917 | - SaslServer(); |
918 | - ~SaslServer(); |
919 | - int init(const QString& mech, QByteArray &challenge); |
920 | - int step(const QByteArray &response); |
921 | - |
922 | - int c; |
923 | - int errflag ; |
924 | - int result; |
925 | - sasl_security_properties_t secprops; |
926 | - sasl_ssf_t extssf ; |
927 | - char *options, *value; |
928 | - unsigned len, count; |
929 | - const char *data; |
930 | - int serverlast ; |
931 | - sasl_ssf_t *ssf; |
932 | - |
933 | - const char *mech, |
934 | - *iplocal , |
935 | - *ipremote , |
936 | - *searchpath, |
937 | - *service , |
938 | - *localdomain , |
939 | - *userdomain ; |
940 | - sasl_conn_t *conn ; |
941 | -}; |
942 | - |
943 | -#endif //SASL_PLUGINS_TEST |
944 | |
945 | === modified file 'tests/tests.pro' |
946 | --- tests/tests.pro 2015-09-18 14:35:00 +0000 |
947 | +++ tests/tests.pro 2015-12-03 07:31:19 +0000 |
948 | @@ -1,36 +1,28 @@ |
949 | include( ../common-project-config.pri ) |
950 | include( ../common-vars.pri ) |
951 | |
952 | -QMAKE_EXTRA_TARGETS += check |
953 | - |
954 | -TARGET = signon-saslplugin-tests |
955 | +TARGET = tst_plugin |
956 | |
957 | QT += \ |
958 | core \ |
959 | testlib |
960 | QT -= gui |
961 | -CONFIG += qtestlib \ |
962 | +CONFIG += \ |
963 | link_pkgconfig \ |
964 | |
965 | -SOURCES += saslplugintest.cpp |
966 | - |
967 | -HEADERS += saslplugintest.h \ |
968 | - $${TOP_SRC_DIR}/src/saslplugin.h |
969 | - |
970 | -INCLUDEPATH += $${TOP_SRC_DIR}/src |
971 | +SOURCES += tst_plugin.cpp |
972 | + |
973 | +HEADERS += \ |
974 | + $${TOP_SRC_DIR}/src/saslplugin.h |
975 | + |
976 | +INCLUDEPATH += . \ |
977 | + $${TOP_SRC_DIR}/src |
978 | |
979 | PKGCONFIG += \ |
980 | libsasl2 \ |
981 | libsignon-qt5 \ |
982 | signon-plugins |
983 | |
984 | -QMAKE_CXXFLAGS += -fno-exceptions \ |
985 | - -fno-rtti |
986 | - |
987 | -target.path = /usr/bin |
988 | - |
989 | -INSTALLS += target |
990 | - |
991 | check.depends = $$TARGET |
992 | check.commands = ./$$TARGET |
993 | QMAKE_EXTRA_TARGETS += check |
994 | |
995 | === added file 'tests/tst_plugin.cpp' |
996 | --- tests/tst_plugin.cpp 1970-01-01 00:00:00 +0000 |
997 | +++ tests/tst_plugin.cpp 2015-12-03 07:31:19 +0000 |
998 | @@ -0,0 +1,611 @@ |
999 | +/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
1000 | +/* |
1001 | + * This file is part of signon |
1002 | + * |
1003 | + * Copyright (C) 2009-2010 Nokia Corporation. |
1004 | + * Copyright (C) 2015 Canonical Ltd. |
1005 | + * |
1006 | + * Contact: Alberto Mardegan <alberto.mardegan@canonical.com> |
1007 | + * |
1008 | + * This library is free software; you can redistribute it and/or |
1009 | + * modify it under the terms of the GNU Lesser General Public License |
1010 | + * version 2.1 as published by the Free Software Foundation. |
1011 | + * |
1012 | + * This library is distributed in the hope that it will be useful, but |
1013 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
1014 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1015 | + * Lesser General Public License for more details. |
1016 | + * |
1017 | + * You should have received a copy of the GNU Lesser General Public |
1018 | + * License along with this library; if not, write to the Free Software |
1019 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA |
1020 | + * 02110-1301 USA |
1021 | + */ |
1022 | + |
1023 | +#include "saslplugin.h" |
1024 | +#include "sasldata.h" |
1025 | +#include "saslplugin.cpp" |
1026 | + |
1027 | +#include <QJsonDocument> |
1028 | +#include <QJsonObject> |
1029 | +#include <QSignalSpy> |
1030 | +#include <QTest> |
1031 | +#include <sasl/sasl.h> |
1032 | + |
1033 | +using namespace SaslPluginNS; |
1034 | + |
1035 | +namespace QTest { |
1036 | +template<> char *toString(const QVariantMap &map) |
1037 | +{ |
1038 | + QJsonDocument doc(QJsonObject::fromVariantMap(map)); |
1039 | + return qstrdup(doc.toJson(QJsonDocument::Compact).data()); |
1040 | +} |
1041 | +} // QTest namespace |
1042 | + |
1043 | +// sasl server implementation for response verification |
1044 | + |
1045 | +class SaslServer { |
1046 | +public: |
1047 | + SaslServer(); |
1048 | + ~SaslServer(); |
1049 | + int init(const QString &mech, QByteArray &challenge); |
1050 | + int step(const QByteArray &response); |
1051 | + |
1052 | + int c; |
1053 | + int errflag; |
1054 | + int result; |
1055 | + sasl_security_properties_t secprops; |
1056 | + sasl_ssf_t extssf; |
1057 | + char *options, *value; |
1058 | + unsigned len, count; |
1059 | + const char *data; |
1060 | + int serverlast; |
1061 | + sasl_ssf_t *ssf; |
1062 | + |
1063 | + const char *mech; |
1064 | + const char *iplocal; |
1065 | + const char *ipremote; |
1066 | + const char *searchpath; |
1067 | + const char *service; |
1068 | + const char *localdomain; |
1069 | + const char *userdomain; |
1070 | + sasl_conn_t *conn; |
1071 | +}; |
1072 | + |
1073 | +int sasl_log(void *context, int priority, const char *message) |
1074 | +{ |
1075 | + Q_UNUSED(context); |
1076 | + Q_UNUSED(priority); |
1077 | + if (!message) |
1078 | + return SASL_BADPARAM; |
1079 | + |
1080 | + TRACE() << message; |
1081 | + return SASL_OK; |
1082 | +} |
1083 | + |
1084 | +static sasl_callback_t callbacks[] = { |
1085 | + { |
1086 | + SASL_CB_LOG, (int(*)())(&sasl_log), NULL |
1087 | + }, { |
1088 | + SASL_CB_LIST_END, NULL, NULL |
1089 | + } |
1090 | +}; |
1091 | + |
1092 | +void saslfail(int why, const char *what, const char *errstr) |
1093 | +{ |
1094 | + qDebug() << why << what << errstr; |
1095 | +} |
1096 | + |
1097 | +#define SAMPLE_SEC_BUF_SIZE (2048) |
1098 | + |
1099 | +char buf[SAMPLE_SEC_BUF_SIZE]; |
1100 | + |
1101 | +SaslServer::SaslServer() |
1102 | +{ |
1103 | + service = "sample"; |
1104 | + localdomain = "loc"; |
1105 | + userdomain = "realm"; |
1106 | + iplocal = "127.0.0.1"; |
1107 | + ipremote = "127.0.0.1"; |
1108 | + searchpath = "."; |
1109 | + memset(&buf, 0L, SAMPLE_SEC_BUF_SIZE); |
1110 | +} |
1111 | + |
1112 | +SaslServer::~SaslServer() |
1113 | +{ |
1114 | + sasl_dispose(&conn); |
1115 | + //sasl_done(); //cannot be called, as plugin also runs this |
1116 | +} |
1117 | + |
1118 | +int SaslServer::init(const QString &mech, QByteArray &challenge) |
1119 | +{ |
1120 | + const char *ext_authid = NULL; |
1121 | + |
1122 | + /* Init defaults... */ |
1123 | + memset(&secprops, 0L, sizeof(secprops)); |
1124 | + secprops.maxbufsize = SAMPLE_SEC_BUF_SIZE; |
1125 | + secprops.max_ssf = UINT_MAX; |
1126 | + |
1127 | + result = sasl_server_init(callbacks, "sample"); |
1128 | + if (result != SASL_OK) |
1129 | + saslfail(result, "Initializing libsasl", NULL); |
1130 | + |
1131 | + result = sasl_server_new(service, |
1132 | + localdomain, |
1133 | + userdomain, |
1134 | + iplocal, |
1135 | + ipremote, |
1136 | + NULL, |
1137 | + 0, |
1138 | + &conn); |
1139 | + if (result != SASL_OK) |
1140 | + saslfail(result, "Allocating sasl connection state", NULL); |
1141 | + |
1142 | + if (!mech.isEmpty()) { |
1143 | + data = strdup(mech.toLatin1().constData()); |
1144 | + len = (unsigned) strlen(data); |
1145 | + count = 1; |
1146 | + } else { |
1147 | + result = sasl_listmech(conn, |
1148 | + ext_authid, |
1149 | + NULL, |
1150 | + " ", |
1151 | + NULL, |
1152 | + &data, |
1153 | + &len, |
1154 | + (int*)&count); |
1155 | + if (result != SASL_OK) |
1156 | + saslfail(result, "Generating client mechanism list", NULL); |
1157 | + } |
1158 | + |
1159 | + if (!mech.isEmpty()) { |
1160 | + free((void *)data); |
1161 | + } |
1162 | + |
1163 | + strcpy(buf, mech.toLatin1().constData()); |
1164 | + len = strlen(buf); |
1165 | + |
1166 | + if (!mech.isEmpty() && strcasecmp(mech.toLatin1().constData(), buf)) |
1167 | + { |
1168 | + qDebug("Client chose something other than the mandatory mechanism"); |
1169 | + return SASL_FAIL; |
1170 | + } |
1171 | + |
1172 | + if (strlen(buf) < len) { |
1173 | + data = buf + strlen(buf) + 1; |
1174 | + len = len - strlen(buf) - 1; |
1175 | + } else { |
1176 | + data = NULL; |
1177 | + len = 0; |
1178 | + } |
1179 | + result = sasl_server_start(conn, buf, data, len, |
1180 | + &data, &len); |
1181 | + if (result != SASL_OK && result != SASL_CONTINUE) { |
1182 | + saslfail(result, "Starting SASL negotiation", |
1183 | + sasl_errstring(result, NULL, NULL)); |
1184 | + return result; |
1185 | + } |
1186 | + if (len) { |
1187 | + challenge = QByteArray(data, len); |
1188 | + } |
1189 | + return result; |
1190 | +} |
1191 | + |
1192 | +int SaslServer::step(const QByteArray &response) |
1193 | +{ |
1194 | + if (!data) { |
1195 | + qDebug("No data to send--something's wrong"); |
1196 | + } |
1197 | + QByteArray resp = response; |
1198 | + resp.replace('\0', ':'); |
1199 | + |
1200 | + for (int i = 0; i < response.count(); i++) { |
1201 | + buf[i] = (char)(response.constData()[i]); |
1202 | + } |
1203 | + len = response.count(); |
1204 | + buf[len] = 0; |
1205 | + |
1206 | + data = NULL; |
1207 | + result = sasl_server_step(conn, buf, len, |
1208 | + &data, &len); |
1209 | + if (result != SASL_OK && result != SASL_CONTINUE) { |
1210 | + saslfail(result, "Performing SASL negotiation", |
1211 | + sasl_errstring(result, NULL, NULL)); |
1212 | + return result; |
1213 | + } |
1214 | + |
1215 | + if (result == SASL_CONTINUE) { |
1216 | + return result; |
1217 | + } |
1218 | + |
1219 | + result = sasl_getprop(conn, SASL_USERNAME, (const void **)&data); |
1220 | + |
1221 | + return SASL_OK; |
1222 | +} |
1223 | +class SaslPluginTest: public QObject |
1224 | +{ |
1225 | + Q_OBJECT |
1226 | + |
1227 | +private Q_SLOTS: |
1228 | + void initTestCase(); |
1229 | + void cleanupTestCase(); |
1230 | + void init(); |
1231 | + void cleanup(); |
1232 | + |
1233 | + //test cases |
1234 | + void testPlugin(); |
1235 | + void testPluginType(); |
1236 | + void testPluginMechanisms(); |
1237 | + void testProcess(); |
1238 | + void testChallengePlain(); |
1239 | + void testChallengeDigestMd5(); |
1240 | + void testChallengeCramMd5(); |
1241 | + void testPluginsasl_callback(); |
1242 | + void testPluginsasl_get_realm(); |
1243 | + void testPluginsasl_get_secret(); |
1244 | + void testPluginsasl_log(); |
1245 | + void testPluginset_callbacks(); |
1246 | + void testParameters_data(); |
1247 | + void testParameters(); |
1248 | + //end test cases |
1249 | + |
1250 | +private: |
1251 | + SaslPlugin *m_testPlugin; |
1252 | +}; |
1253 | + |
1254 | +void SaslPluginTest::initTestCase() |
1255 | +{ |
1256 | + qRegisterMetaType<SignOn::SessionData>(); |
1257 | +} |
1258 | + |
1259 | +void SaslPluginTest::cleanupTestCase() |
1260 | +{ |
1261 | + sasl_done(); |
1262 | +} |
1263 | + |
1264 | +void SaslPluginTest::init() |
1265 | +{ |
1266 | + m_testPlugin = new SaslPlugin(); |
1267 | +} |
1268 | + |
1269 | +void SaslPluginTest::cleanup() |
1270 | +{ |
1271 | + delete m_testPlugin; |
1272 | + m_testPlugin = 0; |
1273 | +} |
1274 | + |
1275 | +void SaslPluginTest::testPlugin() |
1276 | +{ |
1277 | + QVERIFY(m_testPlugin); |
1278 | +} |
1279 | + |
1280 | +void SaslPluginTest::testPluginType() |
1281 | +{ |
1282 | + QCOMPARE(m_testPlugin->type(), QString("sasl")); |
1283 | +} |
1284 | + |
1285 | +void SaslPluginTest::testPluginMechanisms() |
1286 | +{ |
1287 | + QStringList mechs = m_testPlugin->mechanisms(); |
1288 | + QVERIFY(!mechs.isEmpty()); |
1289 | + QVERIFY(mechs.contains(QString("PLAIN"))); |
1290 | +} |
1291 | + |
1292 | +void SaslPluginTest::testProcess() |
1293 | +{ |
1294 | + SaslData info; |
1295 | + |
1296 | + QSignalSpy resultSpy(m_testPlugin, |
1297 | + SIGNAL(result(const SignOn::SessionData&))); |
1298 | + QSignalSpy errorSpy(m_testPlugin, SIGNAL(error(const SignOn::Error&))); |
1299 | + |
1300 | + //try without username |
1301 | + m_testPlugin->process(info, QString("ANONYMOUS")); |
1302 | + QCOMPARE(errorSpy.count(), 1); |
1303 | + QCOMPARE(errorSpy.at(0).at(0).value<SignOn::Error>().type(), |
1304 | + int(SignOn::Error::MissingData)); |
1305 | + QCOMPARE(resultSpy.count(), 0); |
1306 | + |
1307 | + //try without mechanism |
1308 | + errorSpy.clear(); |
1309 | + info.setUserName(QString("test")); |
1310 | + m_testPlugin->process(info); |
1311 | + QCOMPARE(errorSpy.count(), 1); |
1312 | + QCOMPARE(errorSpy.at(0).at(0).value<SignOn::Error>().type(), |
1313 | + int(SignOn::Error::MechanismNotAvailable)); |
1314 | + QCOMPARE(resultSpy.count(), 0); |
1315 | +} |
1316 | + |
1317 | +void SaslPluginTest::testChallengePlain() |
1318 | +{ |
1319 | + SaslData info; |
1320 | + |
1321 | + QSignalSpy resultSpy(m_testPlugin, |
1322 | + SIGNAL(result(const SignOn::SessionData&))); |
1323 | + QSignalSpy errorSpy(m_testPlugin, SIGNAL(error(const SignOn::Error&))); |
1324 | + |
1325 | + info.setUserName(QString("idmtestuser")); |
1326 | + info.setSecret(QString("abc123")); |
1327 | + info.setAuthName(QString("authn")); |
1328 | + |
1329 | + //give challenge to plugin |
1330 | + m_testPlugin->process(info, QString("PLAIN")); |
1331 | + |
1332 | + //test response here |
1333 | + QCOMPARE(errorSpy.count(), 0); |
1334 | + QCOMPARE(resultSpy.count(), 1); |
1335 | + SaslData result = |
1336 | + resultSpy.at(0).at(0).value<SignOn::SessionData>().data<SaslData>(); |
1337 | + QByteArray token=result.Response(); |
1338 | + token.replace('\0',':'); |
1339 | + QCOMPARE(result.Response(), QByteArray("idmtestuser\0authn\0abc123",11+5+6+2)); |
1340 | + |
1341 | + //create connection to server to get initial challenge |
1342 | + SaslServer *server = new SaslServer(); |
1343 | + QByteArray reply; |
1344 | + server->init(QString("PLAIN"), reply); |
1345 | + |
1346 | + //check that authentication server is happy about answer |
1347 | + int retval = server->step(result.Response()); |
1348 | + QCOMPARE(retval, SASL_NOUSER); |
1349 | + |
1350 | + delete server; |
1351 | +} |
1352 | + |
1353 | +void SaslPluginTest::testChallengeDigestMd5() |
1354 | +{ |
1355 | + SaslData info; |
1356 | + |
1357 | + QSignalSpy resultSpy(m_testPlugin, |
1358 | + SIGNAL(result(const SignOn::SessionData&))); |
1359 | + QSignalSpy errorSpy(m_testPlugin, SIGNAL(error(const SignOn::Error&))); |
1360 | + |
1361 | + info.setUserName(QString("idmtestuser")); |
1362 | + info.setSecret(QString("abc123")); |
1363 | + info.setAuthName(QString("authn")); |
1364 | + info.setRealm(QString("realm")); |
1365 | + info.setService(QByteArray("sample")); |
1366 | + |
1367 | + //create connection to server to get initial challenge |
1368 | + SaslServer *server = new SaslServer(); |
1369 | + |
1370 | + QByteArray challenge; |
1371 | + server->init(QString("DIGEST-MD5"), challenge); |
1372 | + info.setChallenge(challenge); |
1373 | + |
1374 | + //give challenge to plugin |
1375 | + m_testPlugin->process(info, QString("DIGEST-MD5")); |
1376 | + |
1377 | + //test response here |
1378 | + QCOMPARE(errorSpy.count(), 0); |
1379 | + QCOMPARE(resultSpy.count(), 1); |
1380 | + SaslData result = |
1381 | + resultSpy.at(0).at(0).value<SignOn::SessionData>().data<SaslData>(); |
1382 | + |
1383 | + int retval = server->step(result.Response()); |
1384 | + QCOMPARE(retval, SASL_NOUSER); |
1385 | + |
1386 | + delete server; |
1387 | +} |
1388 | + |
1389 | +void SaslPluginTest::testChallengeCramMd5() |
1390 | +{ |
1391 | + SaslData info; |
1392 | + |
1393 | + QSignalSpy resultSpy(m_testPlugin, |
1394 | + SIGNAL(result(const SignOn::SessionData&))); |
1395 | + QSignalSpy errorSpy(m_testPlugin, SIGNAL(error(const SignOn::Error&))); |
1396 | + |
1397 | + info.setUserName(QString("idmtestuser")); |
1398 | + info.setSecret(QString("abc123")); |
1399 | + info.setAuthName(QString("authn")); |
1400 | + info.setRealm(QString("realm")); |
1401 | + info.setService(QByteArray("sample")); |
1402 | + |
1403 | + //create connection to server to get initial challenge |
1404 | + SaslServer *server = new SaslServer(); |
1405 | + |
1406 | + QByteArray challenge; |
1407 | + int serret = server->init(QString("CRAM-MD5"), challenge); //fails sometimes |
1408 | + if (serret != SASL_OK) { |
1409 | + QSKIP("sasl server init for CRAM-MD5 failed", SkipSingle); |
1410 | + } |
1411 | + |
1412 | + info.setChallenge(challenge); |
1413 | + |
1414 | + //give challenge to plugin |
1415 | + m_testPlugin->process(info, QString("CRAM-MD5")); |
1416 | + |
1417 | + //test response here |
1418 | + QCOMPARE(errorSpy.count(), 0); |
1419 | + QCOMPARE(resultSpy.count(), 1); |
1420 | + SaslData result = |
1421 | + resultSpy.at(0).at(0).value<SignOn::SessionData>().data<SaslData>(); |
1422 | + |
1423 | + int retval = server->step(result.Response()); //fails, check server impl. |
1424 | + QCOMPARE(retval, SASL_NOUSER); |
1425 | + |
1426 | + delete server; |
1427 | +} |
1428 | + |
1429 | +//private funcs |
1430 | + |
1431 | +void SaslPluginTest::testPluginsasl_callback() |
1432 | +{ |
1433 | + int ret; |
1434 | + const char *res; |
1435 | + unsigned len; |
1436 | + ret = m_testPlugin->sasl_callback(NULL, 0, &res, &len); |
1437 | + QCOMPARE(ret, SASL_BADPARAM); |
1438 | + ret = m_testPlugin->sasl_callback(m_testPlugin, 0, NULL, &len); |
1439 | + QCOMPARE(ret, SASL_BADPARAM); |
1440 | + |
1441 | + m_testPlugin->d->m_input.setUserName(QString("user")); |
1442 | + |
1443 | + ret = m_testPlugin->sasl_callback(m_testPlugin, SASL_CB_USER, &res, &len); |
1444 | + QCOMPARE(ret, SASL_OK); |
1445 | + QCOMPARE(QByteArray(res), QByteArray("user")); |
1446 | + QCOMPARE(len, uint(4)); |
1447 | + |
1448 | + m_testPlugin->d->m_input.setAuthName(QString("auth")); |
1449 | + |
1450 | + ret = m_testPlugin->sasl_callback(m_testPlugin, SASL_CB_AUTHNAME, &res, &len); |
1451 | + QCOMPARE(ret, SASL_OK); |
1452 | + QCOMPARE(QByteArray(res), QByteArray("auth")); |
1453 | + QCOMPARE(len, uint(4)); |
1454 | + |
1455 | + ret = m_testPlugin->sasl_callback(m_testPlugin, SASL_CB_LANGUAGE, &res, &len); |
1456 | + QCOMPARE(ret, SASL_OK); |
1457 | + QVERIFY(!res); |
1458 | + QCOMPARE(len, uint(0)); |
1459 | + |
1460 | + ret = m_testPlugin->sasl_callback(m_testPlugin, 45643, &res, &len); |
1461 | + QCOMPARE(ret, SASL_BADPARAM); |
1462 | +} |
1463 | + |
1464 | +void SaslPluginTest::testPluginsasl_get_realm() |
1465 | +{ |
1466 | + int ret; |
1467 | + const char *res; |
1468 | + |
1469 | + ret = m_testPlugin->sasl_get_realm(NULL, 0, NULL, NULL); |
1470 | + QCOMPARE(ret, SASL_FAIL); |
1471 | + ret = m_testPlugin->sasl_get_realm(NULL, SASL_CB_GETREALM, NULL, NULL); |
1472 | + QCOMPARE(ret, SASL_BADPARAM); |
1473 | + ret = m_testPlugin->sasl_get_realm(m_testPlugin, SASL_CB_GETREALM, NULL, NULL); |
1474 | + QCOMPARE(ret, SASL_BADPARAM); |
1475 | + |
1476 | + ret = m_testPlugin->sasl_get_realm(m_testPlugin, SASL_CB_GETREALM, NULL, &res); |
1477 | + QCOMPARE(ret, SASL_OK); |
1478 | + |
1479 | + m_testPlugin->d->m_input.setRealm(QString("real")); |
1480 | + |
1481 | + ret = m_testPlugin->sasl_get_realm(m_testPlugin, SASL_CB_GETREALM, NULL, &res); |
1482 | + QCOMPARE(ret, SASL_OK); |
1483 | + QCOMPARE(QByteArray(res), QByteArray("real")); |
1484 | +} |
1485 | + |
1486 | +void SaslPluginTest::testPluginsasl_get_secret() |
1487 | +{ |
1488 | + int ret; |
1489 | + sasl_secret_t *secret = 0; |
1490 | + |
1491 | + ret = m_testPlugin->sasl_get_secret(m_testPlugin->d->m_conn, NULL, |
1492 | + 0, &secret); |
1493 | + QCOMPARE(ret, SASL_BADPARAM); |
1494 | + |
1495 | + m_testPlugin->d->m_input.setSecret(QString("password")); |
1496 | + |
1497 | + ret = m_testPlugin->sasl_get_secret(m_testPlugin->d->m_conn, m_testPlugin, |
1498 | + SASL_CB_PASS, NULL); |
1499 | + QCOMPARE(ret, SASL_BADPARAM); |
1500 | + ret = m_testPlugin->sasl_get_secret(m_testPlugin->d->m_conn, m_testPlugin, |
1501 | + SASL_CB_PASS, &secret); |
1502 | + QCOMPARE(ret, SASL_OK); |
1503 | + QCOMPARE(QByteArray("password"), |
1504 | + QByteArray((const char*)secret->data, (int)secret->len)); |
1505 | +} |
1506 | + |
1507 | +void SaslPluginTest::testPluginsasl_log() |
1508 | +{ |
1509 | + int ret; |
1510 | + |
1511 | + ret = m_testPlugin->sasl_log(m_testPlugin, 0, NULL); |
1512 | + QCOMPARE(ret, SASL_BADPARAM); |
1513 | + |
1514 | + ret = m_testPlugin->sasl_log(m_testPlugin, 0, "test debug"); |
1515 | + QCOMPARE(ret, SASL_OK); |
1516 | +} |
1517 | + |
1518 | +void SaslPluginTest::testPluginset_callbacks() |
1519 | +{ |
1520 | + m_testPlugin->set_callbacks(); |
1521 | + sasl_callback_t *callback; |
1522 | + callback = m_testPlugin->d->m_callbacks; |
1523 | + QVERIFY(callback != NULL); |
1524 | + QVERIFY(callback->id == SASL_CB_LOG); |
1525 | + QVERIFY(callback->context == m_testPlugin); |
1526 | + ++callback; |
1527 | + QVERIFY(callback != NULL); |
1528 | + QVERIFY(callback->id == SASL_CB_USER); |
1529 | + QVERIFY(callback->context == m_testPlugin); |
1530 | + ++callback; |
1531 | + QVERIFY(callback != NULL); |
1532 | + QVERIFY(callback->id == SASL_CB_AUTHNAME); |
1533 | + QVERIFY(callback->context == m_testPlugin); |
1534 | + ++callback; |
1535 | + QVERIFY(callback != NULL); |
1536 | + QVERIFY(callback->id == SASL_CB_PASS); |
1537 | + QVERIFY(callback->context == m_testPlugin); |
1538 | + ++callback; |
1539 | + QVERIFY(callback != NULL); |
1540 | + QVERIFY(callback->id == SASL_CB_GETREALM); |
1541 | + QVERIFY(callback->context == m_testPlugin); |
1542 | + ++callback; |
1543 | + QVERIFY(callback != NULL); |
1544 | + QVERIFY(callback->id == SASL_CB_LIST_END); |
1545 | + QVERIFY(callback->context == NULL); |
1546 | +} |
1547 | + |
1548 | +void SaslPluginTest::testParameters_data() |
1549 | +{ |
1550 | + qDebug() << "Called!"; |
1551 | + QTest::addColumn<QVariantMap>("parameters"); |
1552 | + QTest::addColumn<QString>("mechanism"); |
1553 | + QTest::addColumn<bool>("isValid"); |
1554 | + QTest::addColumn<QVariantMap>("expectedParams"); |
1555 | + |
1556 | + QVariantMap parameters; |
1557 | + QVariantMap expectedParams; |
1558 | + QTest::newRow("empty") << |
1559 | + parameters << QString() << false << expectedParams; |
1560 | + |
1561 | + parameters["UserName"] = "user"; |
1562 | + expectedParams["AuthName"] = "user"; |
1563 | + expectedParams["UserName"] = "user"; |
1564 | + expectedParams["Service"] = "default"; |
1565 | + expectedParams["Fqdn"] = "default"; |
1566 | + expectedParams["IpLocal"] = "127.0.0.1"; |
1567 | + expectedParams["IpRemote"] = "127.0.0.1"; |
1568 | + expectedParams["MechList"] = "PLAIN"; |
1569 | + QTest::newRow("only user") << |
1570 | + parameters << |
1571 | + "PLAIN" << |
1572 | + true << |
1573 | + expectedParams; |
1574 | + parameters.clear(); |
1575 | + expectedParams.clear(); |
1576 | + |
1577 | + parameters["UserName"] = "user"; |
1578 | + parameters["MechList"] = "MECH1 MECH2"; |
1579 | + expectedParams["AuthName"] = "user"; |
1580 | + expectedParams["UserName"] = "user"; |
1581 | + expectedParams["Service"] = "default"; |
1582 | + expectedParams["Fqdn"] = "default"; |
1583 | + expectedParams["IpLocal"] = "127.0.0.1"; |
1584 | + expectedParams["IpRemote"] = "127.0.0.1"; |
1585 | + expectedParams["MechList"] = "MECH1 MECH2"; |
1586 | + QTest::newRow("with mechlist") << |
1587 | + parameters << |
1588 | + "PLAIN" << |
1589 | + true << |
1590 | + expectedParams; |
1591 | +} |
1592 | + |
1593 | +void SaslPluginTest::testParameters() |
1594 | +{ |
1595 | + QFETCH(QVariantMap, parameters); |
1596 | + QFETCH(QString, mechanism); |
1597 | + QFETCH(bool, isValid); |
1598 | + QFETCH(QVariantMap, expectedParams); |
1599 | + |
1600 | + SaslData input(parameters); |
1601 | + bool ret = |
1602 | + m_testPlugin->check_and_fix_parameters(input, mechanism.toUtf8()); |
1603 | + QCOMPARE(ret, isValid); |
1604 | + |
1605 | + QCOMPARE(input.toMap(), expectedParams); |
1606 | +} |
1607 | + |
1608 | +QTEST_MAIN(SaslPluginTest) |
1609 | +#include "tst_plugin.moc" |