KLdap

ber.cpp
1/*
2 This file is part of libkldap.
3 SPDX-FileCopyrightText: 2004-2006 Szombathelyi György <gyurco@freemail.hu>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "ber.h"
9#include "kldap_config.h"
10
11#include "ldap_core_debug.h"
12
13#include <QList>
14#include <QVarLengthArray>
15
16#include <cstdarg>
17
18#if LDAP_FOUND
19
20#ifdef Q_OS_SOLARIS // krazy:exclude=cpp
21#define BC31 1
22#endif
23
24#if !HAVE_WINLDAP_H
25#include <lber.h>
26#include <ldap.h>
27#else
28#include "w32-ldap-help.h"
29#endif
30
31#ifndef LBER_USE_DER
32#define LBER_USE_DER 1
33#endif
34
35#if !HAVE_BER_MEMFREE
36#if !HAVE_WINLDAP_H
37#define ber_memfree(x) ldap_memfree(x)
38#else
39#define ber_memfree(x) win_ldap_memfree(x)
40#endif
41#endif
42
43#endif
44
45using namespace KLDAPCore;
46
47class Q_DECL_HIDDEN Ber::BerPrivate
48{
49public:
50#if LDAP_FOUND
51 BerElement *mBer = nullptr;
52#endif
53};
54
55#if LDAP_FOUND
57 : d(new BerPrivate)
58{
59 d->mBer = ber_alloc_t(LBER_USE_DER);
60 Q_ASSERT(d->mBer);
61}
62
63Ber::Ber(const QByteArray &value)
64 : d(new BerPrivate)
65{
66 struct berval bv;
67 bv.bv_val = (char *)value.data();
68 bv.bv_len = value.size();
69 d->mBer = ber_init(&bv);
70 Q_ASSERT(d->mBer);
71}
72
74{
75 ber_free(d->mBer, 1);
76}
77
78Ber::Ber(const Ber &that)
79 : d(new BerPrivate)
80{
81 struct berval *bv;
82 if (ber_flatten(that.d->mBer, &bv) == 0) {
83 d->mBer = ber_init(bv);
84 ber_bvfree(bv);
85 }
86}
87
88Ber &Ber::operator=(const Ber &that)
89{
90 if (this == &that) {
91 return *this;
92 }
93
94 struct berval *bv;
95 if (ber_flatten(that.d->mBer, &bv) == 0) {
96 d->mBer = ber_init(bv);
97 ber_bvfree(bv);
98 }
99 return *this;
100}
101
103{
104 QByteArray ret;
105 struct berval *bv;
106 if (ber_flatten(d->mBer, &bv) == 0) {
107 ret = QByteArray(bv->bv_val, bv->bv_len);
108 ber_bvfree(bv);
109 }
110 return ret;
111}
112
113int Ber::printf(QString format, ...)
114{
115 char fmt[2];
116 va_list args;
117 va_start(args, format);
118 fmt[1] = '\0';
119
120 int i = 0;
121 int ret = 0;
122 while (i < format.length()) {
123 fmt[0] = format[i].toLatin1();
124 i++;
125 switch (fmt[0]) {
126 case 'b':
127 case 'e':
128 case 'i': {
129 ber_int_t v = va_arg(args, int);
130 ret = ber_printf(d->mBer, fmt, v);
131 break;
132 }
133 case 'B': {
134 // FIXME: QBitArray would be logical, but how to access the bits?
135 QByteArray *B = va_arg(args, QByteArray *);
136 int Bc = va_arg(args, int);
137 ret = ber_printf(d->mBer, fmt, B->data(), Bc);
138 break;
139 }
140 case 'o': {
141 QByteArray *o = va_arg(args, QByteArray *);
142 ret = ber_printf(d->mBer, fmt, o->data(), o->size());
143 break;
144 }
145 case 'O': {
146 QByteArray *O = va_arg(args, QByteArray *);
147 struct berval bv;
148 bv.bv_val = (char *)O->data();
149 bv.bv_len = O->size();
150 ret = ber_printf(d->mBer, fmt, &bv);
151 break;
152 }
153 case 's': {
154 QByteArray *s = va_arg(args, QByteArray *);
155 ret = ber_printf(d->mBer, fmt, s->data());
156 break;
157 break;
158 }
159 case 't': {
160 unsigned int t = va_arg(args, unsigned int);
161 ret = ber_printf(d->mBer, fmt, t);
162 break;
163 }
164 case 'v': {
165 QList<QByteArray> *v = va_arg(args, QList<QByteArray> *);
167 int j;
168 for (j = 0; j < v->count(); j++) {
169 l[j] = v->at(j).data();
170 }
171 l[j] = nullptr;
172 ret = ber_printf(d->mBer, fmt, l.data());
173 break;
174 }
175 case 'V': {
176 QList<QByteArray> *V = va_arg(args, QList<QByteArray> *);
179 int j;
180 for (j = 0; j < V->count(); j++) {
181 bvs[j].bv_val = (char *)V->at(j).data();
182 bvs[j].bv_len = V->at(j).size();
183 bv[j] = &bvs[j];
184 }
185 bv[V->count()] = nullptr;
186 ret = ber_printf(d->mBer, fmt, bv.data());
187 break;
188 }
189 case 'n':
190 case '{':
191 case '}':
192 case '[':
193 case ']':
194 ret = ber_printf(d->mBer, fmt);
195 break;
196 default:
197 qCWarning(LDAP_LOG) << "Invalid BER format parameter: '" << fmt << "'";
198 ret = -1;
199 }
200 qCDebug(LDAP_LOG) << "ber_printf format:" << fmt << "ret:" << ret;
201 if (ret == -1) {
202 break;
203 }
204 }
205 va_end(args);
206 return ret;
207}
208
209int Ber::scanf(QString format, ...)
210{
211 char fmt[2];
212 va_list args;
213 va_start(args, format);
214 fmt[1] = '\0';
215
216 int i = 0;
217 int ret = 0;
218 while (i < format.length()) {
219 fmt[0] = format[i].toLatin1();
220 i++;
221 switch (fmt[0]) {
222 case 'l':
223 case 'b':
224 case 'e':
225 case 'i': {
226 int *v = va_arg(args, int *);
227 ret = ber_scanf(d->mBer, fmt, v);
228 break;
229 }
230 case 'B': {
231 // FIXME: QBitArray would be logical, but how to access the bits?
232 QByteArray *B = va_arg(args, QByteArray *);
233 int *Bc = va_arg(args, int *);
234 char *c;
235 ret = ber_scanf(d->mBer, fmt, &c, Bc);
236 if (ret != -1) {
237 *B = QByteArray(c, (*Bc + 7) / 8);
238 ber_memfree(c);
239 }
240 break;
241 }
242 case 'o': {
243 QByteArray *o = va_arg(args, QByteArray *);
244 struct berval bv;
245 ret = ber_scanf(d->mBer, fmt, &bv);
246 if (ret != -1) {
247 *o = QByteArray(bv.bv_val, bv.bv_len);
248 ber_memfree(bv.bv_val);
249 }
250 break;
251 }
252 case 'O': {
253 QByteArray *O = va_arg(args, QByteArray *);
254 struct berval *bv;
255 ret = ber_scanf(d->mBer, fmt, &bv);
256 if (ret != -1) {
257 *O = QByteArray(bv->bv_val, bv->bv_len);
258 ber_bvfree(bv);
259 }
260 break;
261 }
262 case 'm': { // the same as 'O', just *bv should not be freed.
263 QByteArray *m = va_arg(args, QByteArray *);
264 struct berval *bv;
265 ret = ber_scanf(d->mBer, fmt, &bv);
266 if (ret != -1) {
267 *m = QByteArray(bv->bv_val, bv->bv_len);
268 }
269 break;
270 }
271 case 'a': {
272 QByteArray *a = va_arg(args, QByteArray *);
273 char *c;
274 ret = ber_scanf(d->mBer, fmt, &c);
275 if (ret != -1) {
276 *a = QByteArray(c);
277 ber_memfree(c);
278 }
279 break;
280 }
281
282 case 's': {
283 QByteArray *s = va_arg(args, QByteArray *);
284 char buf[255];
285 ber_len_t l = sizeof(buf);
286 ret = ber_scanf(d->mBer, fmt, &buf, &l);
287 if (ret != -1) {
288 *s = QByteArray(buf, l);
289 }
290 break;
291 }
292 case 't':
293 case 'T': {
294 unsigned int *t = va_arg(args, unsigned int *);
295 ret = ber_scanf(d->mBer, fmt, t);
296 break;
297 }
298 case 'v': {
299 QList<QByteArray> *v = va_arg(args, QList<QByteArray> *);
300 char **c;
301 char **c2;
302 ret = ber_scanf(d->mBer, fmt, &c);
303 if (ret != -1 && c) {
304 c2 = c;
305 while (*c) {
306 v->append(QByteArray(*c));
307 ber_memfree(*c);
308 c++;
309 }
310 ber_memfree((char *)c2);
311 }
312 break;
313 }
314 case 'V': {
315 QList<QByteArray> *v = va_arg(args, QList<QByteArray> *);
316 struct berval **bv;
317 struct berval **bv2;
318 ret = ber_scanf(d->mBer, fmt, &bv);
319 if (ret != -1 && bv) {
320 bv2 = bv;
321 while (*bv) {
322 v->append(QByteArray((*bv)->bv_val, (*bv)->bv_len));
323 bv++;
324 }
325 ber_bvecfree(bv2);
326 }
327 break;
328 }
329 case 'x':
330 case 'n':
331 case '{':
332 case '}':
333 case '[':
334 case ']':
335 ret = ber_scanf(d->mBer, fmt);
336 break;
337 default:
338 qCWarning(LDAP_LOG) << "Invalid BER format parameter: '" << fmt << "'";
339 ret = -1;
340 }
341
342 qCDebug(LDAP_LOG) << "ber_scanf format:" << fmt << "ret:" << ret;
343 if (ret == -1) {
344 break;
345 }
346 }
347 va_end(args);
348 return ret;
349}
350
351unsigned int Ber::peekTag(int &size)
352{
353 unsigned int ret;
354 ber_len_t len;
355 ret = ber_peek_tag(d->mBer, &len);
356 size = len;
357 return ret;
358}
359
360unsigned int Ber::skipTag(int &size)
361{
362 unsigned int ret;
363 ber_len_t len;
364 ret = ber_skip_tag(d->mBer, &len);
365 size = len;
366 return ret;
367}
368
369#else
370
372 : d(new BerPrivate)
373{
374 qCritical() << "LDAP support not compiled";
375}
376
378 : d(new BerPrivate)
379{
380 qCritical() << "LDAP support not compiled";
381}
382
384{
385}
386
387Ber::Ber(const Ber &)
388 : d(new BerPrivate)
389{
390 qCritical() << "LDAP support not compiled";
391}
392
393Ber &Ber::operator=(const Ber &that)
394{
395 if (this == &that) {
396 return *this;
397 }
398 qCritical() << "LDAP support not compiled";
399 return *this;
400}
401
403{
404 qCritical() << "LDAP support not compiled";
405 return QByteArray();
406}
407
408int Ber::printf(QString format, ...)
409{
410 Q_UNUSED(format)
411 qCritical() << "LDAP support not compiled";
412 return -1;
413}
414
415int Ber::scanf(QString format, ...)
416{
417 Q_UNUSED(format)
418 qCritical() << "LDAP support not compiled";
419 return -1;
420}
421
422unsigned int Ber::peekTag(int &size)
423{
424 Q_UNUSED(size)
425 qCritical() << "LDAP support not compiled";
426 return 0;
427}
428
429unsigned int Ber::skipTag(int &size)
430{
431 Q_UNUSED(size)
432 qCritical() << "LDAP support not compiled";
433 return 0;
434}
435
436#endif
This class allows encoding and decoding Qt structures using Basic Encoding Rules.
Definition ber.h:23
QByteArray flatten() const
Returns the Ber object as a flat QByteArray.
Definition ber.cpp:402
int printf(QString format,...)
Appends the data with the specified format to the Ber object.
Definition ber.cpp:408
Ber()
Constructs a Ber object.
Definition ber.cpp:371
~Ber()
Destroys the Ber object.
Definition ber.cpp:383
char * data()
qsizetype size() const const
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
qsizetype count() const const
qsizetype length() const const
QByteArray toLatin1() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:34 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.