File indexing completed on 2025-01-26 04:52:12
0001 /* 0002 This file is part of libkdepim. 0003 0004 SPDX-FileCopyrightText: 2004 Tobias Koenig <tokoe@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "testkldap.h" 0010 0011 #include "ber.h" 0012 #include "ldapconnection.h" 0013 #include "ldapdn.h" 0014 #include "ldapoperation.h" 0015 #include "ldapsearch.h" 0016 #include "ldapserver.h" 0017 #include "ldapurl.h" 0018 #include "ldif.h" 0019 0020 #include <QDebug> 0021 #include <QFile> 0022 #include <QTest> 0023 QTEST_MAIN(KLdapTest) 0024 0025 KLdapTest::KLdapTest(QObject *parent) 0026 : QObject(parent) 0027 { 0028 } 0029 0030 void KLdapTest::initTestCase() 0031 { 0032 /* 0033 Read in the connection details of an LDAP server to use for testing. 0034 You should copy the file testurl.txt.tmpl to testurl.txt and specify a url in this file. 0035 The specified server should not be a production server in case we break anything here. 0036 You have been warned! 0037 */ 0038 const QString filename(QStringLiteral("testurl.txt")); 0039 QFile file(filename); 0040 if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { 0041 QTextStream stream(&file); 0042 stream >> m_url; 0043 file.close(); 0044 } 0045 0046 m_search = new LdapSearch; 0047 } 0048 0049 void KLdapTest::testBer() 0050 { 0051 Ber ber1; 0052 Ber ber2; 0053 Ber ber3; 0054 Ber ber4; 0055 Ber ber5; 0056 Ber ber6; 0057 Ber ber7; 0058 Ber bber; 0059 0060 int ainteger; 0061 QByteArray aoctetString1; 0062 QByteArray aoctetString2; 0063 QByteArray aoctetString3; 0064 QList<QByteArray> alist1; 0065 QList<QByteArray> alist2; 0066 0067 int binteger; 0068 QByteArray boctetString1; 0069 QByteArray boctetString2; 0070 QByteArray boctetString3; 0071 QList<QByteArray> blist1; 0072 QList<QByteArray> blist2; 0073 0074 aoctetString1 = "KDE"; 0075 aoctetString2 = "the"; 0076 aoctetString3 = "next generation"; 0077 0078 alist1.append(aoctetString1); 0079 alist1.append(aoctetString2); 0080 0081 alist2.append(aoctetString2); 0082 alist2.append(aoctetString3); 0083 alist2.append(aoctetString1); 0084 0085 ainteger = 23543; 0086 0087 ber1.printf(QStringLiteral("i"), ainteger); 0088 ber2.printf(QStringLiteral("o"), &aoctetString1); 0089 ber3.printf(QStringLiteral("O"), &aoctetString2); 0090 ber4.printf(QStringLiteral("s"), &aoctetString3); 0091 ber5.printf(QStringLiteral("{v}"), &alist1); 0092 ber6.printf(QStringLiteral("{V}"), &alist2); 0093 ber7.printf(QStringLiteral("oi{v}O"), &aoctetString1, ainteger, &alist2, &aoctetString2); 0094 0095 // test integer: 0096 bber = ber1; 0097 bber.scanf(QStringLiteral("i"), &binteger); 0098 QCOMPARE(ainteger, binteger); 0099 0100 // test octet strings: 0101 bber = ber2; 0102 bber.scanf(QStringLiteral("o"), &boctetString1); 0103 QCOMPARE(aoctetString1, boctetString1); 0104 bber = ber3; 0105 bber.scanf(QStringLiteral("o"), &boctetString2); 0106 QCOMPARE(aoctetString2, boctetString2); 0107 bber = ber4; 0108 bber.scanf(QStringLiteral("o"), &boctetString3); 0109 QCOMPARE(aoctetString3, boctetString3); 0110 0111 // test sequence of octet strings: 0112 bber = ber5; 0113 bber.scanf(QStringLiteral("v"), &blist1); 0114 QCOMPARE(alist1, blist1); 0115 0116 bber = ber6; 0117 bber.scanf(QStringLiteral("v"), &blist2); 0118 QCOMPARE(alist2, blist2); 0119 0120 // complex tests 0121 boctetString1 = boctetString2 = boctetString3 = QByteArray(); 0122 binteger = 0; 0123 blist1.clear(); 0124 blist2.clear(); 0125 0126 bber = ber7; 0127 bber.scanf(QStringLiteral("oivO"), &boctetString1, &binteger, &blist2, &boctetString2); 0128 QCOMPARE(aoctetString1, boctetString1); 0129 QCOMPARE(aoctetString2, boctetString2); 0130 QCOMPARE(alist2, blist2); 0131 QCOMPARE(ainteger, binteger); 0132 } 0133 0134 void KLdapTest::cleanupTestCase() 0135 { 0136 delete m_search; 0137 } 0138 0139 void KLdapTest::testLdapUrl() 0140 { 0141 // Test LdapUrl using some hardwired values so that we know what to compare to 0142 LdapUrl url; 0143 bool critical; 0144 0145 url.setUrl( 0146 QStringLiteral("ldap://cn=manager,dc=kde,dc=org:password@localhost:3999/" 0147 "dc=kde,dc=org?cn,mail?sub?(objectClass=*)?x-dir=base")); 0148 url.parseQuery(); 0149 0150 QCOMPARE(url.userName(), QStringLiteral("cn=manager,dc=kde,dc=org")); 0151 QCOMPARE(url.password(), QStringLiteral("password")); 0152 QCOMPARE(url.dn(), LdapDN(QStringLiteral("dc=kde,dc=org"))); 0153 QCOMPARE(url.scope(), LdapUrl::Sub); 0154 QCOMPARE(url.attributes().at(0), QStringLiteral("cn")); 0155 QCOMPARE(url.attributes().at(1), QStringLiteral("mail")); 0156 QCOMPARE(url.filter(), QStringLiteral("(objectClass=*)")); 0157 QCOMPARE(url.extension(QStringLiteral("x-dir"), critical), QStringLiteral("base")); 0158 QCOMPARE(url.query(), QStringLiteral("?cn,mail?sub??x-dir=base")); 0159 // For some reason the code removes the filter if it's (objectClass=*)... 0160 QCOMPARE(url.toString(), 0161 QStringLiteral("ldap://cn=manager,dc=kde,dc=org:password@localhost:3999/" 0162 "dc=kde,dc=org??cn,mail?sub??x-dir=base")); 0163 0164 // Now set a different filter 0165 url.setFilter(QStringLiteral("(objectclass=person)")); 0166 QCOMPARE(url.toDisplayString(), 0167 QStringLiteral("ldap://cn=manager,dc=kde,dc=org@localhost:3999/" 0168 "dc=kde,dc=org??cn,mail?sub?%28objectclass%3Dperson%29?x-dir=base")); 0169 QCOMPARE(url.filter(), QStringLiteral("(objectclass=person)")); 0170 0171 // And now a filter with non-ascii letters 0172 url.setFilter(QStringLiteral("(givenName=Valérie *)")); 0173 QCOMPARE(url.toDisplayString(), 0174 QString::fromUtf8("ldap://cn=manager,dc=kde,dc=org@localhost:3999/" 0175 "dc=kde,dc=org??cn,mail?sub?%28givenName%3DValérie %2A%29?x-dir=base")); 0176 QCOMPARE(url.filter(), QStringLiteral("(givenName=Valérie *)")); 0177 0178 // Test roundtrip via QUrl, as happens when sending it to kio_ldap 0179 const QUrl qurl(url); 0180 QCOMPARE(qurl.toDisplayString(), url.toDisplayString()); 0181 0182 const LdapUrl kiourl(qurl); 0183 QCOMPARE(kiourl.toString(), url.toString()); 0184 QCOMPARE(kiourl.toDisplayString(), url.toDisplayString()); 0185 QCOMPARE(kiourl.filter(), QStringLiteral("(givenName=Valérie *)")); 0186 } 0187 0188 void KLdapTest::testLdapConnection() 0189 { 0190 // Try to connect using an LdapUrl (read in from testurl.txt). 0191 LdapUrl url; 0192 url.setUrl(m_url); 0193 0194 LdapConnection conn; 0195 conn.setUrl(url); 0196 int ret; 0197 if ((ret = conn.connect())) { 0198 qDebug() << "Could not connect to LDAP server. Error was:" << conn.connectionError(); 0199 } 0200 QCOMPARE(ret, 0); 0201 0202 LdapOperation op(conn); 0203 // Now attempt to bind 0204 if ((ret = op.bind_s())) { 0205 qDebug() << "Could not bind to server. Error was:" << conn.ldapErrorString(); 0206 } 0207 QEXPECT_FAIL("", "Will fail since no server is available for testing", Abort); 0208 QCOMPARE(ret, 0); 0209 } 0210 0211 void KLdapTest::testLdapSearch() 0212 { 0213 // Lets try a search using the specified url 0214 LdapUrl url; 0215 url.setUrl(m_url); 0216 url.parseQuery(); 0217 connect(m_search, &LdapSearch::result, this, &KLdapTest::searchResult); 0218 connect(m_search, &LdapSearch::data, this, &KLdapTest::searchData); 0219 const bool success = m_search->search(url); 0220 QCoreApplication::processEvents(); 0221 0222 QEXPECT_FAIL("", "Will fail since no server is available for testing", Abort); 0223 QCOMPARE(success, true); 0224 0225 qDebug() << "Search found" << m_objects.size() << "matching entries"; 0226 } 0227 0228 void KLdapTest::searchResult(KLDAPCore::LdapSearch *search) 0229 { 0230 qDebug(); 0231 const int err = search->error(); 0232 if (err) { 0233 qDebug() << "Search returned the following error:" << search->errorString(); 0234 } 0235 QCOMPARE(err, 0); 0236 } 0237 0238 void KLdapTest::searchData(KLDAPCore::LdapSearch *search, const KLDAPCore::LdapObject &obj) 0239 { 0240 Q_UNUSED(search) 0241 // qDebug(); 0242 // qDebug() << "Object:"; 0243 // qDebug() << obj.toString(); 0244 m_objects.append(obj); 0245 } 0246 0247 void KLdapTest::testLdapDN() 0248 { 0249 const QString strDN(QStringLiteral("uid=Test\\+Person+ou=accounts\\,outgoing,dc=kde,dc=org")); 0250 const LdapDN dn(strDN); 0251 QCOMPARE(dn.isValid(), true); 0252 QCOMPARE(dn.rdnString(), QStringLiteral("uid=Test\\+Person+ou=accounts\\,outgoing")); 0253 } 0254 0255 void KLdapTest::testLdapModel() 0256 { 0257 // Use the user-supplied testing url 0258 LdapUrl url; 0259 url.setUrl(m_url); 0260 0261 // Create a connection to use and bind with it 0262 LdapConnection conn; 0263 conn.setUrl(url); 0264 int ret; 0265 if ((ret = conn.connect())) { 0266 qDebug() << "Could not connect to LDAP server. Error was:" << conn.connectionError(); 0267 } 0268 QCOMPARE(ret, 0); 0269 0270 LdapOperation op(conn); 0271 if ((ret = op.bind_s())) { 0272 qDebug() << "Could not bind to server. Error was:" << conn.ldapErrorString(); 0273 } 0274 QEXPECT_FAIL("", "Will fail since no server is available for testing", Abort); 0275 QCOMPARE(ret, 0); 0276 0277 QCoreApplication::processEvents(); 0278 } 0279 0280 /* 0281 void KLdapTest::testKLdap() 0282 { 0283 LdapUrl url; 0284 bool critical; 0285 0286 url.setUrl("ldap://cn=manager,dc=kde,dc=org:password@localhost:3999" 0287 "/dc=kde,dc=org?cn,mail?sub?(objectClass=*)?x-dir=base"); 0288 url.parseQuery(); 0289 0290 QCOMPARE( url.user(), QStringLiteral("cn=manager,dc=kde,dc=org") ); 0291 QCOMPARE( url.password(), QStringLiteral("password") ); 0292 QCOMPARE( url.dn(), QStringLiteral("dc=kde,dc=org") ); 0293 QCOMPARE( url.scope(), LdapUrl::Sub ); 0294 QCOMPARE( url.attributes().at(0), QStringLiteral("cn") ); 0295 QCOMPARE( url.attributes().at(1), QStringLiteral("mail") ); 0296 QCOMPARE( url.filter(), QStringLiteral("(objectClass=*)") ); 0297 QCOMPARE( url.extension(QStringLiteral("x-dir"), critical), QStringLiteral("base") ); 0298 0299 url.setDn("ou=People,dc=kde,dc=org"); 0300 QCOMPARE( url.dn(), QStringLiteral("ou=People,dc=kde,dc=org") ); 0301 url.setDn("/ou=People,dc=kde,dc=org"); 0302 QCOMPARE( url.dn(), QStringLiteral("ou=People,dc=kde,dc=org") ); 0303 0304 LdapServer server; 0305 // url.setUrl("ldaps://cn=manager,dc=kde,dc=org:passwor@localhost:3999/" 0306 "dc=kde,dc=org????x-timelimt=5,x-sizelimit=6,x=pagesize=7,binddn=cn=apple,ou=berry"); 0307 url.setUrl("ldaps://cn=manager,dc=kde,dc=org:password@localhost:3999/" 0308 "dc=kde,dc=org??base??x-timelimit=5"); 0309 url.parseQuery(); 0310 server.setUrl( url ); 0311 QCOMPARE( url.query(), QStringLiteral("??base??x-timelimit=5") ); 0312 QCOMPARE( url.url(), server.url().url() ); 0313 0314 LdapControl c1; 0315 c1.setControl( QStringLiteral("1.2.3.4.5.6"), QByteArray("abcdefg"), true ); 0316 //test copy constructor 0317 LdapControl c2(c1); 0318 QCOMPARE( c2.oid(), QStringLiteral("1.2.3.4.5.6") ); 0319 QCOMPARE( c2.value(), QByteArray("abcdefg") ); 0320 QCOMPARE( c2.critical(), true ); 0321 //test assignment operator 0322 LdapControl c3; 0323 c3 = c1; 0324 QCOMPARE( c3.oid(), QStringLiteral("1.2.3.4.5.6") ); 0325 QCOMPARE( c3.value(), QByteArray("abcdefg") ); 0326 QCOMPARE( c3.critical(), true ); 0327 */ 0328 // test Ber functions 0329 /* 0330 QByteArray left1("bertest"), right1; 0331 int left2 = 0, right2; 0332 int left3 = 1, right3; 0333 int left4 = 2, right4; 0334 int left5 = 3, right5; 0335 int left6 = 1, right6; 0336 QList<QByteArray> left7, right7; 0337 left7.append( "abcdefghij" ); 0338 left7.append( "123456789" ); 0339 left7.append( "1234\0\0\056789" ); 0340 0341 Ber ber; 0342 ber.printf("{seeiib}", &left1, left2, left3, left4, left5, left6 ); 0343 0344 // ber.printf("{ioOi{i}}", left3, &left1, &left2, left4, left4 ); 0345 Ber ber2 = ber; 0346 0347 unsigned int a; 0348 int b; 0349 a = ber2.skipTag( b ); 0350 qDebug() << "next tag:" << a << "size:" << b; 0351 a = ber2.skipTag( b ); 0352 qDebug() << "next tag:" << a << "size:" << b; 0353 a = ber2.skipTag( b ); 0354 qDebug() << "next tag:" << a << "size:" << b; 0355 a = ber2.skipTag( b ); 0356 qDebug() << "next tag:" << a << "size:" << b; 0357 a = ber2.skipTag( b ); 0358 qDebug() << "next tag:" << a << "size:" << b; 0359 a = ber2.skipTag( b ); 0360 qDebug() << "next tag:" << a << "size:" << b; 0361 a = ber2.skipTag( b ); 0362 qDebug() << "next tag:" << a << "size:" << b; 0363 a = ber2.skipTag( b ); 0364 qDebug() << "next tag:" << a << "size:" << b; 0365 0366 BerElement *_ber, *_ber2; 0367 _ber = ber_alloc_t( LBER_USE_DER ); 0368 0369 ber_len_t bl; 0370 ber_printf( _ber, "{i}", 5 ); 0371 qDebug() << "native"; 0372 _ber2 = ber_dup( _ber ); 0373 a = ber_skip_tag( _ber2, &bl ); 0374 qDebug() << "next tag:" << a << "size:" << bl; 0375 // ber_dump( _ber, 0 ); 0376 0377 // ber2.scanf("{v}", &right5 ); 0378 0379 // ber2.scanf("{inoOi{v}}", &right3, &right1, &right2, &right4, &right5 ); 0380 0381 // QCOMPARE( left1, right1 ); 0382 // QCOMPARE( left2, right2 ); 0383 // QCOMPARE( left3, right3 ); 0384 // QCOMPARE( left4, right4 ); 0385 // QCOMPARE( left5, right5 ); 0386 */ 0387 /* 0388 url.setUrl("ldap://localhost/dc=gyurco,dc=localdomain"); 0389 url.parseQuery(); 0390 server.setUrl( url ); 0391 LdapConnection conn( server ); 0392 int result = conn.connect(); 0393 qDebug() << "connect result" << result << conn.errorString(); 0394 0395 LdapOperation op( conn ); 0396 int msgid = op.search( "ou=People,dc=gyurco,dc=localdomain", LdapUrl::One, "", QStringList() ); 0397 qDebug() << "search msgid" << msgid; 0398 result = op.result( msgid ); 0399 qDebug() << "error code" << conn.ldapErrorCode() << "str:" << conn.ldapErrorString(); 0400 while ( result == LdapOperation::RES_SEARCH_ENTRY ) { 0401 qDebug() << op.object().toString(); 0402 result = op.result( msgid ); 0403 } 0404 qDebug() << "error code" << conn.ldapErrorCode() << "str:" << conn.ldapErrorString(); 0405 0406 msgid = op.del( "ou=People,dc=gyurco,dc=localdomain" ); 0407 qDebug() << "search msgid" << msgid; 0408 result = op.result( msgid ); 0409 qDebug() << "error code" << conn.ldapErrorCode() << "str:" << conn.ldapErrorString(); 0410 0411 msgid = op.compare( "ou=People,dc=gyurco,dc=localdomain", "objectClass", QByteArray("top") ); 0412 qDebug() << "search msgid" << msgid; 0413 result = op.result( msgid ); 0414 qDebug() << "error code" << conn.ldapErrorCode() << "str:" << conn.ldapErrorString(); 0415 0416 msgid = op.compare( "ou=People,dc=gyurco,dc=localdomain", "objectClass", 0417 QByteArray("inetOrgPerson") ); 0418 qDebug() << "search msgid" << msgid; 0419 result = op.result( msgid ); 0420 qDebug() << "error code" << conn.ldapErrorCode() << "str:" << conn.ldapErrorString(); 0421 0422 msgid = op.exop( "1.2.3.4.5.6.7.8", QByteArray("inetOrgPerson") ); 0423 qDebug() << "search msgid" << msgid; 0424 result = op.result( msgid ); 0425 qDebug() << "error code" << conn.ldapErrorCode() << "str:" << conn.ldapErrorString(); 0426 */ 0427 /* 0428 } 0429 */ 0430 0431 #include "moc_testkldap.cpp"