16#include <config-libkleo.h>
19#include "libkleo_debug.h"
23#include <KLazyLocalizedString>
29#define strcasecmp _stricmp
37 QStringLiteral(
"_X_"),
43class DNAttributeOrderStore
45 DNAttributeOrderStore()
46 : mAttributeOrder{defaultOrder}
51 static DNAttributeOrderStore *instance()
53 static DNAttributeOrderStore *self =
new DNAttributeOrderStore();
59 return mAttributeOrder.
empty() ? defaultOrder : mAttributeOrder;
64 mAttributeOrder = order;
72class Kleo::DN::Private
79 Private(
const Private &other)
80 : attributes(other.attributes)
81 , reorderedAttributes(other.reorderedAttributes)
93 if (--mRefCount <= 0) {
106 DN::Attribute::List attributes;
107 DN::Attribute::List reorderedAttributes;
123#define digitp(p) (*(p) >= '0' && *(p) <= '9')
124#define hexdigitp(a) (digitp(a) || (*(a) >= 'A' && *(a) <= 'F') || (*(a) >= 'a' && *(a) <= 'f'))
125#define xtoi_1(p) (*(p) <= '9' ? (*(p) - '0') : *(p) <= 'F' ? (*(p) - 'A' + 10) : (*(p) - 'a' + 10))
126#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p) + 1))
128static char *trim_trailing_spaces(
char *
string)
133 for (mark =
nullptr, p =
string; *p; p++) {
152static const unsigned char *parse_dn_part(DnPair *array,
const unsigned char *
string)
154 const unsigned char *s;
155 const unsigned char *s1;
160 for (s =
string + 1; *s && *s !=
'='; s++) {
170 p = (
char *)malloc(n + 1);
172 memcpy(p,
string, n);
174 trim_trailing_spaces((
char *)p);
176 if (
const char *name = Kleo::attributeNameForOID(p)) {
183 if (*
string ==
'#') {
186 for (s =
string; hexdigitp(s); s++)
193 array->value = p = (
char *)malloc(n + 1);
195 for (s1 =
string; n; s1 += 2, n--) {
201 for (n = 0, s =
string; *s; s++) {
205 if (*s ==
',' || *s ==
'=' || *s ==
'+' || *s ==
'<' || *s ==
'>' || *s ==
'#' || *s ==
';' || *s ==
'\\' || *s ==
'\"' || *s ==
' ') {
207 }
else if (hexdigitp(s) && hexdigitp(s + 1)) {
213 }
else if (*s ==
'\"') {
215 }
else if (*s ==
',' || *s ==
'=' || *s ==
'+' || *s ==
'<' || *s ==
'>' || *s ==
'#' || *s ==
';') {
222 array->value = p = (
char *)malloc(n + 1);
224 for (s =
string; n; s++, n--) {
253 while (*
string ==
' ') {
260 DnPair pair = {
nullptr,
nullptr};
261 string = parse_dn_part(&pair,
string);
265 if (pair.key && pair.value) {
271 while (*
string ==
' ') {
274 if (*
string && *
string !=
',' && *
string !=
';' && *
string !=
'+') {
289 return parse_dn((
const unsigned char *)dn.
toUtf8().
data());
295 for (
int i = 0, end = s.
length(); i != end; ++i) {
296 const QChar ch = s[i];
319 for (
const auto &attribute : dn) {
320 if (!attribute.name().isEmpty() && !attribute.value().isEmpty()) {
321 result.
push_back(attribute.name().trimmed() +
QLatin1Char(
'=') + dn_escape(attribute.value().trimmed()));
329 return listAttributes(dn).
join(sep);
334 const QStringList &attrOrder = Kleo::DN::attributeOrder();
343 if (!attrOrder.
contains((*it).name())) {
352 std::copy(unknownEntries.
begin(), unknownEntries.
end(), std::back_inserter(result));
353 unknownEntries.
clear();
356 if ((*dnit).name() == *oit) {
382 d->attributes = parse_dn(dn);
385Kleo::DN::DN(
const char *utf8DN)
390 d->attributes = parse_dn((
const unsigned char *)utf8DN);
394Kleo::DN::DN(
const DN &other)
409const Kleo::DN &Kleo::DN::operator=(
const DN &that)
411 if (this->d == that.d) {
430 return DNAttributeOrderStore::instance()->attributeOrder();
434void Kleo::DN::setAttributeOrder(
const QStringList &order)
436 DNAttributeOrderStore::instance()->setAttributeOrder(order);
450 if (d->reorderedAttributes.empty()) {
451 d->reorderedAttributes = reorder_dn(d->attributes);
453 return serialise(d->reorderedAttributes, QStringLiteral(
","));
462 if (d->reorderedAttributes.empty()) {
463 d->reorderedAttributes = reorder_dn(d->attributes);
465 return listAttributes(d->reorderedAttributes);
470 return d ? serialise(d->attributes, QStringLiteral(
",")) :
QString();
475 return d ? serialise(d->attributes, sep) :
QString();
481 return dn_escape(value);
484void Kleo::DN::detach()
487 d =
new Kleo::DN::Private();
489 }
else if (d->refCount() > 1) {
490 Kleo::DN::Private *d_save = d;
491 d =
new Kleo::DN::Private(*d);
497void Kleo::DN::append(
const Attribute &attr)
500 d->attributes.push_back(attr);
501 d->reorderedAttributes.clear();
511 if ((*it).name() == attrUpper) {
512 return (*it).value();
522 return d ? d->attributes.constBegin() : empty.constBegin();
527 return d ? d->attributes.constEnd() : empty.constEnd();
536 {QStringLiteral(
"CN"), kli18n(
"Common name") },
537 {QStringLiteral(
"SN"), kli18n(
"Surname") },
538 {QStringLiteral(
"GN"), kli18n(
"Given name") },
539 {QStringLiteral(
"L"), kli18n(
"Location") },
540 {QStringLiteral(
"T"), kli18n(
"Title") },
541 {QStringLiteral(
"OU"), kli18n(
"Organizational unit")},
542 {QStringLiteral(
"O"), kli18n(
"Organization") },
543 {QStringLiteral(
"PC"), kli18n(
"Postal code") },
544 {QStringLiteral(
"C"), kli18n(
"Country code") },
545 {QStringLiteral(
"SP"), kli18n(
"State or province") },
546 {QStringLiteral(
"DC"), kli18n(
"Domain component") },
547 {QStringLiteral(
"BC"), kli18n(
"Business category") },
548 {QStringLiteral(
"EMAIL"), kli18n(
"Email address") },
549 {QStringLiteral(
"MAIL"), kli18n(
"Mail address") },
550 {QStringLiteral(
"MOBILE"), kli18n(
"Mobile phone number")},
551 {QStringLiteral(
"TEL"), kli18n(
"Telephone number") },
552 {QStringLiteral(
"FAX"), kli18n(
"Fax number") },
553 {QStringLiteral(
"STREET"), kli18n(
"Street address") },
554 {QStringLiteral(
"UID"), kli18n(
"Unique ID") },
562 return attributeNamesAndLabels.keys();
568 const QString key{name.trimmed().toUpper()};
569 if (attributeNames().contains(key)) {
570 return attributeNamesAndLabels.value(key).toString();
572 qCWarning(LIBKLEO_LOG) <<
"Attribute " << key <<
" doesn't exit. Bug ?";
static QString escape(const QString &value)
QStringList prettyAttributes() const
Returns the non-empty attributes formatted as {NAME=value} and reordered according to the settings in...
void push_back(parameter_type value)
void reserve(qsizetype size)
qsizetype size() const const
QString fromUtf8(QByteArrayView str)
qsizetype length() const const
QString toUpper() const const
QByteArray toUtf8() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QString join(QChar separator) const const