File indexing completed on 2024-05-12 05:48:35

0001 #include <QRegularExpression>
0002 
0003 #include <libaudit.h>
0004 
0005 #include <fcntl.h>
0006 #include <grp.h>
0007 #include <linux/prctl.h>
0008 #include <netdb.h>
0009 #include <pwd.h>
0010 #include <sys/personality.h>
0011 #include <sys/stat.h>
0012 
0013 #include "maps.h"
0014 
0015 #include "auditConvertor.h"
0016 
0017 AuditConvertor::AuditConvertor()
0018     : m_a0(-1)
0019     , m_a1(-1)
0020 {
0021     m_paramMap = {{QStringLiteral("arch"), &AuditConvertor::convertArch},
0022                   {QStringLiteral("exit"), &AuditConvertor::convertExit},
0023                   {QStringLiteral("uid"), &AuditConvertor::convertUid},
0024                   {QStringLiteral("auid"), &AuditConvertor::convertUid},
0025                   {QStringLiteral("old-auid"), &AuditConvertor::convertUid},
0026                   {QStringLiteral("euid"), &AuditConvertor::convertUid},
0027                   {QStringLiteral("suid"), &AuditConvertor::convertUid},
0028                   {QStringLiteral("fsuid"), &AuditConvertor::convertUid},
0029                   {QStringLiteral("ouid"), &AuditConvertor::convertUid},
0030                   {QStringLiteral("gid"), &AuditConvertor::convertGid},
0031                   {QStringLiteral("egid"), &AuditConvertor::convertGid},
0032                   {QStringLiteral("sgid"), &AuditConvertor::convertGid},
0033                   {QStringLiteral("fsgid"), &AuditConvertor::convertGid},
0034                   {QStringLiteral("ogid"), &AuditConvertor::convertGid},
0035                   {QStringLiteral("mode"), &AuditConvertor::convertMode},
0036                   {QStringLiteral("a2"), &AuditConvertor::convertA2},
0037                   {QStringLiteral("a3"), &AuditConvertor::convertA3}};
0038 }
0039 
0040 QString AuditConvertor::getParam(const QString &message, const QString &name)
0041 {
0042     const QRegularExpression re(QStringLiteral("\\s%1=([^\\s]*)").arg(name));
0043     const QRegularExpressionMatch match = re.match(message);
0044 
0045     if (match.hasMatch()) {
0046         return match.captured(1);
0047     } else {
0048         return QString();
0049     }
0050 }
0051 
0052 QString AuditConvertor::replaceParam(const QString &message, const QString &name, const QString &value)
0053 {
0054     const QRegularExpression re(QStringLiteral("\\s%1=[^\\s]*").arg(name));
0055     QString newMessage = message;
0056 
0057     return newMessage.replace(re, QStringLiteral(" %1=%2").arg(name).arg(value));
0058 }
0059 
0060 QString AuditConvertor::convertMessage(const QString &message)
0061 {
0062     QString newMessage = message;
0063 
0064     const QString proctitleParam = QStringLiteral("proctitle");
0065     QString proctitle = getParam(message, proctitleParam);
0066 
0067     if (!proctitle.isEmpty()) {
0068         proctitle = convertProcTitle(proctitle);
0069         return replaceParam(newMessage, proctitleParam, proctitle);
0070     }
0071 
0072     const QString syscallParam = QStringLiteral("syscall");
0073     QString syscall = getParam(message, syscallParam);
0074 
0075     if (!syscall.isEmpty()) {
0076         syscall = convertSysCall(syscall);
0077         newMessage = replaceParam(newMessage, syscallParam, syscall);
0078         m_syscall = syscall;
0079     } else {
0080         m_syscall.clear();
0081     }
0082 
0083     m_a0 = -1;
0084     m_a1 = -1;
0085 
0086     bool ok = false;
0087 
0088     if (!m_syscall.isEmpty()) {
0089         const QString a0Param = QStringLiteral("a0");
0090         QString a0 = getParam(message, a0Param);
0091 
0092         if (!a0.isEmpty()) {
0093             m_a0 = a0.toULong(&ok, 16);
0094             a0 = convertA0(a0);
0095             newMessage = replaceParam(newMessage, a0Param, a0);
0096         }
0097 
0098         const QString a1Param = QStringLiteral("a1");
0099         QString a1 = getParam(message, a1Param);
0100 
0101         if (!a1.isEmpty()) {
0102             m_a1 = a1.toULong(&ok, 16);
0103             a1 = convertA1(a1);
0104             newMessage = replaceParam(newMessage, a1Param, a1);
0105         }
0106     }
0107 
0108     convertParamFunc func = nullptr;
0109     QString name;
0110     QString value;
0111 
0112     auto it = m_paramMap.constBegin();
0113 
0114     while (it != m_paramMap.constEnd()) {
0115         func = it.value();
0116         name = it.key();
0117         value = getParam(message, name);
0118 
0119         if (!value.isEmpty()) {
0120             value = (this->*func)(value);
0121             newMessage = replaceParam(newMessage, name, value);
0122         }
0123 
0124         ++it;
0125     }
0126 
0127     return newMessage;
0128 }
0129 
0130 QString AuditConvertor::convertProcTitle(const QString &proctitle)
0131 {
0132     QString newProcTitle = proctitle;
0133 
0134     if (proctitle[0] == QChar::fromLatin1('\"')) {
0135         return newProcTitle.remove(QChar::fromLatin1('\"'));
0136     }
0137 
0138     newProcTitle.replace(QLatin1String("00"), QLatin1String("20"));
0139 
0140     QByteArray arr;
0141     QString str;
0142     bool ok;
0143 
0144     for (int i = 0; i < proctitle.size(); i += 2) {
0145         str = newProcTitle.mid(i, 2);
0146         arr.append(char(str.toShort(&ok, 16)));
0147     }
0148 
0149     return QString::fromLatin1(arr);
0150 }
0151 
0152 QString AuditConvertor::convertArch(const QString &arch)
0153 {
0154     bool ok = false;
0155 
0156     unsigned int machine = arch.toUInt(&ok, 16);
0157     machine = audit_elf_to_machine(machine);
0158 
0159     const char *name = audit_machine_to_name(machine);
0160 
0161     return QString::fromLatin1(name);
0162 }
0163 
0164 QString AuditConvertor::convertSysCall(const QString &syscall)
0165 {
0166     int machine = audit_detect_machine();
0167     const char *name = audit_syscall_to_name(syscall.toInt(), machine);
0168 
0169     return QString::fromLatin1(name);
0170 }
0171 
0172 QString AuditConvertor::convertExit(const QString &exit)
0173 {
0174     long long ival = exit.toLongLong();
0175 
0176     if (ival < 0) {
0177         const char *name = audit_errno_to_name(-ival);
0178         return QStringLiteral("%1(%2)").arg(QString::fromLocal8Bit(name)).arg(QString::fromLocal8Bit(strerror(-ival)));
0179     } else {
0180         return exit;
0181     }
0182 }
0183 
0184 QString AuditConvertor::convertUid(const QString &uid, int base)
0185 {
0186     bool ok = false;
0187     int val = uid.toInt(&ok, base);
0188 
0189     if (val == -1) {
0190         return QStringLiteral("unset");
0191     } else if (val == 0) {
0192         return QStringLiteral("root");
0193     }
0194 
0195     struct passwd *pw = getpwuid(val);
0196 
0197     if (pw) {
0198         return QString::fromLatin1(pw->pw_name);
0199     } else {
0200         return QStringLiteral("unknown(%1)").arg(uid);
0201     }
0202 }
0203 
0204 QString AuditConvertor::convertUid(const QString &uid)
0205 {
0206     return convertUid(uid, 10);
0207 }
0208 
0209 QString AuditConvertor::convertGid(const QString &gid, int base)
0210 {
0211     bool ok = false;
0212     int val = gid.toInt(&ok, base);
0213 
0214     if (val == -1) {
0215         return QStringLiteral("unset");
0216     } else if (val == 0) {
0217         return QStringLiteral("root");
0218     }
0219 
0220     struct group *gr = getgrgid(val);
0221 
0222     if (gr) {
0223         return QString::fromLatin1(gr->gr_name);
0224     } else {
0225         return QStringLiteral("unknown(%1)").arg(gid);
0226     }
0227 }
0228 
0229 QString AuditConvertor::convertGid(const QString &gid)
0230 {
0231     return convertGid(gid, 10);
0232 }
0233 
0234 QString AuditConvertor::convertMode(const QString &mode, int base)
0235 {
0236     bool ok = false;
0237     unsigned int ival = mode.toULong(&ok, base);
0238     const char *name;
0239     QString newMode;
0240 
0241     name = audit_ftype_to_name(ival & S_IFMT);
0242 
0243     if (name) {
0244         newMode = QString::fromLatin1(name);
0245     } else {
0246         unsigned first_ifmt_bit = S_IFMT & ~(S_IFMT - 1);
0247         newMode = QStringLiteral("0%1").arg((ival & S_IFMT) / first_ifmt_bit, 3, 8, QLatin1Char('0'));
0248     }
0249 
0250     if (S_ISUID & ival) {
0251         newMode += QLatin1String(",suid");
0252     }
0253     if (S_ISGID & ival) {
0254         newMode += QLatin1String(",sgid");
0255     }
0256     if (S_ISVTX & ival) {
0257         newMode += QLatin1String(",sticky");
0258     }
0259 
0260     newMode += QStringLiteral(",0%1").arg((S_IRWXU | S_IRWXG | S_IRWXO) & ival, 3, 8, QLatin1Char('0'));
0261 
0262     return newMode;
0263 }
0264 
0265 QString AuditConvertor::convertMode(const QString &mode)
0266 {
0267     return convertMode(mode, 8);
0268 }
0269 
0270 QString AuditConvertor::convertA0(const QString &a0)
0271 {
0272     if (m_syscall == QLatin1String("rt_sigaction")) {
0273         return convertSignals(a0, 16);
0274     } else if ((m_syscall == QLatin1String("renameat")) || (m_syscall == QLatin1String("readlinkat")) || (m_syscall == QLatin1String("mkdirat"))
0275                || (m_syscall == QLatin1String("mknodat")) || (m_syscall == QLatin1String("fchownat")) || (m_syscall == QLatin1String("futimesat"))
0276                || (m_syscall == QLatin1String("fchmodat")) || (m_syscall == QLatin1String("faccessat")) || (m_syscall == QLatin1String("futimensat"))
0277                || (m_syscall == QLatin1String("unlinkat")) || (m_syscall == QLatin1String("utimensat")) || (m_syscall == QLatin1String("linkat"))
0278                || (m_syscall == QLatin1String("newfstatat")) || (m_syscall == QLatin1String("openat"))) {
0279         return convertDirFd(a0);
0280     } else if ((m_syscall == QLatin1String("clone")) || (m_syscall == QLatin1String("unshare"))) {
0281         return convertCloneFlags(a0);
0282     } else if (m_syscall == QLatin1String("clock_settime")) {
0283         return convertClockId(a0);
0284     } else if (m_syscall == QLatin1String("personality")) {
0285         return convertPersonality(a0);
0286     } else if (m_syscall == QLatin1String("ptrace")) {
0287         return convertPtrace(a0);
0288     } else if (m_syscall == QLatin1String("prctl")) {
0289         return convertPrctlOpt(a0);
0290     } else if ((m_syscall == QLatin1String("getrlimit")) || (m_syscall == QLatin1String("setrlimit"))) {
0291         return convertRlimit(a0);
0292     } else if ((m_syscall == QLatin1String("setuid")) || (m_syscall == QLatin1String("setreuid")) || (m_syscall == QLatin1String("setresuid"))
0293                || (m_syscall == QLatin1String("setfsuid"))) {
0294         return convertUid(a0, 16);
0295     } else if ((m_syscall == QLatin1String("setgid")) || (m_syscall == QLatin1String("setregid")) || (m_syscall == QLatin1String("setresgid"))
0296                || (m_syscall == QLatin1String("setfsgid"))) {
0297         return convertGid(a0, 16);
0298     } else if (m_syscall == QLatin1String("socket")) {
0299         return convertSocketDomain(a0);
0300     } else if (m_syscall == QLatin1String("socketcall")) {
0301         return convertSocketCall(a0, 16);
0302     } else if (m_syscall == QLatin1String("ipccall")) {
0303         return convertIpcCall(a0, 16);
0304     } else if ((m_syscall == QLatin1String("exit")) || (m_syscall == QLatin1String("exit_group"))) {
0305         return convertExitSysCall(a0);
0306     } else if (m_syscall == QLatin1String("bpf")) {
0307         return convertBpf(a0);
0308     } else {
0309         return QStringLiteral("0x") + a0;
0310     }
0311 }
0312 
0313 QString AuditConvertor::convertA1(const QString &a1)
0314 {
0315     if ((m_syscall == QLatin1String("fchmod")) || (m_syscall == QLatin1String("chmod")) || (m_syscall == QLatin1String("creat"))
0316         || (m_syscall == QLatin1String("mkdir"))) {
0317         return convertModeShort(a1, 16);
0318     } else if (m_syscall.indexOf(QLatin1String("fcntl")) == 0) {
0319         return convertFcntlCmd(a1);
0320     } else if ((m_syscall == QLatin1String("chown")) || (m_syscall == QLatin1String("setreuid")) || (m_syscall == QLatin1String("setresuid"))) {
0321         return convertUid(a1, 16);
0322     } else if (m_syscall == QLatin1String("etsockopt")) {
0323         return convertSockOptLevel(a1);
0324     } else if ((m_syscall == QLatin1String("setregid")) || (m_syscall == QLatin1String("setresgid"))) {
0325         return convertGid(a1, 16);
0326     } else if (m_syscall == QLatin1String("socket")) {
0327         return convertSocketType(a1);
0328     } else if (m_syscall == QLatin1String("setns")) {
0329         return convertCloneFlags(a1);
0330     } else if (m_syscall == QLatin1String("sched_setscheduler")) {
0331         return convertSched(a1);
0332     } else if (m_syscall == QLatin1String("mknod")) {
0333         return convertMode(a1, 16);
0334     } else if ((m_syscall == QLatin1String("mq_open")) || (m_syscall == QLatin1String("open"))) {
0335         return convertOpenFlags(a1);
0336     } else if (m_syscall == QLatin1String("access")) {
0337         return convertAccess(a1);
0338     } else if (m_syscall == QLatin1String("epoll_ctl")) {
0339         return convertEpollCtl(a1);
0340     } else if ((m_syscall == QLatin1String("kill")) || (m_syscall == QLatin1String("tkill"))) {
0341         return convertSignals(a1, 16);
0342     } else if (m_syscall == QLatin1String("prctl")) {
0343         if (m_a0 == PR_CAPBSET_READ || m_a0 == PR_CAPBSET_DROP) {
0344             return convertCapabilities(a1, 16);
0345         } else if (m_a0 == PR_SET_PDEATHSIG) {
0346             return convertSignals(a1, 16);
0347         }
0348     } else if (m_syscall == QLatin1String("umount2")) {
0349         return convertUmount(a1);
0350     } else if (m_syscall == QLatin1String("ioctl")) {
0351         return convertIoctlReq(a1);
0352     }
0353 
0354     return QStringLiteral("0x") + a1;
0355 }
0356 
0357 QString AuditConvertor::convertA2(const QString &a2)
0358 {
0359     if (m_syscall.indexOf(QLatin1String("fcntl")) == 0) {
0360         return convertFcntl(a2);
0361     } else if (m_syscall.indexOf(QLatin1String("etsockopt")) == 1) {
0362         if (m_a1 == IPPROTO_IP) {
0363             return convertIpOptName(a2);
0364         } else if (m_a1 == SOL_SOCKET) {
0365             return convertSockOptName(a2);
0366         } else if (m_a1 == IPPROTO_TCP) {
0367             return convertTcpOptName(a2);
0368         } else if (m_a1 == IPPROTO_UDP) {
0369             return convertUdpOptName(a2);
0370         } else if (m_a1 == IPPROTO_IPV6) {
0371             return convertIp6OptName(a2);
0372         } else if (m_a1 == SOL_PACKET) {
0373             return convertPktOptName(a2);
0374         }
0375     } else if (m_syscall == QLatin1String("openat")) {
0376         return convertOpenFlags(a2);
0377     } else if ((m_syscall == QLatin1String("open")) && (m_a1 & O_CREAT)) {
0378         return convertModeShort(a2, 16);
0379     } else if ((m_syscall == QLatin1String("fchmodat")) || (m_syscall == QLatin1String("mkdirat")) || (m_syscall == QLatin1String("mknodat"))) {
0380         return convertModeShort(a2, 16);
0381     } else if (m_syscall == QLatin1String("faccessat")) {
0382         return convertAccess(a2);
0383     } else if (m_syscall == QLatin1String("setresuid")) {
0384         return convertUid(a2, 16);
0385     } else if ((m_syscall == QLatin1String("setresgid")) || (m_syscall == QLatin1String("chown"))) {
0386         return convertGid(a2, 16);
0387     } else if (m_syscall == QLatin1String("socket")) {
0388         return convertSocketProto(a2);
0389     } else if ((m_syscall == QLatin1String("sendmsg")) || (m_syscall == QLatin1String("recvmsg"))) {
0390         return convertRecv(a2);
0391     } else if (m_syscall == QLatin1String("shmget")) {
0392         return convertShmFlags(a2);
0393     } else if (m_syscall == QLatin1String("mmap")) {
0394         return convertProt(a2, 1);
0395     } else if (m_syscall == QLatin1String("mprotect")) {
0396         return convertProt(a2, 0);
0397     } else if (m_syscall == QLatin1String("mq_open") && (m_a1 & O_CREAT)) {
0398         return convertModeShort(a2, 16);
0399     } else if ((m_syscall == QLatin1String("readlinkat")) || (m_syscall == QLatin1String("linkat"))) {
0400         return convertDirFd(a2);
0401     } else if (m_syscall == QLatin1String("lseek")) {
0402         return convertSeek(a2);
0403     } else if (m_syscall == QLatin1String("tgkill")) {
0404         return convertSignals(a2, 16);
0405     }
0406 
0407     return QStringLiteral("0x") + a2;
0408 }
0409 
0410 QString AuditConvertor::convertA3(const QString &a3)
0411 {
0412     if (m_syscall == QLatin1String("mmap")) {
0413         return convertMmap(a3);
0414     } else if (m_syscall == QLatin1String("mount")) {
0415         return convertMount(a3);
0416     } else if ((m_syscall == QLatin1String("recv")) || (m_syscall == QLatin1String("recvfrom")) || (m_syscall == QLatin1String("recvmmsg"))
0417                || (m_syscall == QLatin1String("send")) || (m_syscall == QLatin1String("sendto")) || (m_syscall == QLatin1String("sendmmsg"))) {
0418         return convertRecv(a3);
0419     }
0420 
0421     return QStringLiteral("0x") + a3;
0422 }
0423 
0424 QString AuditConvertor::convertSignals(const QString &sig, unsigned int base)
0425 {
0426     bool ok = false;
0427     ulong ival = sig.toULong(&ok, base);
0428     QString value;
0429 
0430     if (!ok) {
0431         return convertError(sig);
0432     } else if (signalMap.contains(ival)) {
0433         return signalMap.value(ival);
0434     } else {
0435         if (base == 16) {
0436             value = QLatin1String("0x");
0437         }
0438         value += sig;
0439         return QStringLiteral("unknown-signal(%1)").arg(value);
0440     }
0441 }
0442 
0443 QString AuditConvertor::convertDirFd(const QString &dirfd)
0444 {
0445     if (dirfd == QLatin1String("-100")) {
0446         return QStringLiteral("AT_FDCWD");
0447     } else {
0448         return QStringLiteral("0x") + dirfd;
0449     }
0450 }
0451 
0452 QString AuditConvertor::convertCloneFlags(const QString &cloneFlags)
0453 {
0454     ulong clone_sig;
0455     int cnt = 0;
0456     QString retValue;
0457 
0458     bool ok = false;
0459     ulong flags;
0460 
0461     flags = cloneFlags.toULong(&ok, 16);
0462 
0463     if (!ok) {
0464         return convertError(cloneFlags);
0465     }
0466 
0467     auto it = cloneFlagMap.constBegin();
0468     while (it != cloneFlagMap.constEnd()) {
0469         if (it.key() & flags) {
0470             if (cnt) {
0471                 retValue += QLatin1String("|");
0472             }
0473             retValue += it.value();
0474             cnt++;
0475         }
0476         ++it;
0477     }
0478 
0479     clone_sig = flags & 0xFF;
0480 
0481     if (signalMap.contains(clone_sig)) {
0482         if (cnt) {
0483             retValue += QLatin1String("|");
0484         }
0485         retValue += signalMap.value(clone_sig);
0486     }
0487 
0488     if (retValue.isEmpty()) {
0489         return QStringLiteral("0x%1").arg(cloneFlags);
0490     } else {
0491         return retValue;
0492     }
0493 }
0494 
0495 QString AuditConvertor::convertClockId(const QString &clockId)
0496 {
0497     bool ok = false;
0498     ulong ival = clockId.toULong(&ok, 16);
0499 
0500     if (!ok) {
0501         return convertError(clockId);
0502     } else {
0503         return clockMap.value(ival, QStringLiteral("unknown-clk_id(0x%1)").arg(clockId));
0504     }
0505 }
0506 
0507 QString AuditConvertor::convertPersonality(const QString &personality)
0508 {
0509     bool ok = false;
0510     ulong pers, pers2;
0511 
0512     pers = personality.toULong(&ok, 16);
0513 
0514     if (!ok) {
0515         return convertError(personality);
0516     }
0517 
0518     pers2 = pers & PER_MASK;
0519 
0520     if (personMap.contains(pers2)) {
0521         if (pers & ADDR_NO_RANDOMIZE) {
0522             return QStringLiteral("%1|~ADDR_NO_RANDOMIZE").arg(personMap.value(pers2));
0523         } else {
0524             return personMap.value(pers2);
0525         }
0526     } else {
0527         return QStringLiteral("unknown-personality(0x%1)").arg(personality);
0528     }
0529 }
0530 
0531 QString AuditConvertor::convertPtrace(const QString &ptrace)
0532 {
0533     bool ok = false;
0534     int trace = ptrace.toInt(&ok, 16);
0535 
0536     if (!ok) {
0537         return convertError(ptrace);
0538     } else {
0539         return ptraceMap.value(trace, QStringLiteral("unknown-ptrace(0x%1)").arg(ptrace));
0540     }
0541 }
0542 
0543 QString AuditConvertor::convertPrctlOpt(const QString &prctlOpt)
0544 {
0545     bool ok = false;
0546     int opt = prctlOpt.toUInt(&ok, 16);
0547 
0548     if (!ok) {
0549         return convertError(prctlOpt);
0550     } else {
0551         return prctloptMap.value(opt, QStringLiteral("unknown-prctl-option(0x%1)").arg(prctlOpt));
0552     }
0553 }
0554 
0555 QString AuditConvertor::convertRlimit(const QString &rlimit)
0556 {
0557     bool ok = false;
0558     ulong ival = rlimit.toULong(&ok, 16);
0559 
0560     if (!ok) {
0561         return convertError(rlimit);
0562     } else {
0563         return rlimitMap.value(ival, QStringLiteral("unknown-rlimit(0x%1)").arg(rlimit));
0564     }
0565 }
0566 
0567 QString AuditConvertor::convertSocketDomain(const QString &socketDomain)
0568 {
0569     bool ok = false;
0570     int ival = socketDomain.toULong(&ok, 16);
0571 
0572     if (!ok) {
0573         return convertError(socketDomain);
0574     } else {
0575         return famMap.value(ival, QStringLiteral("unknown-family(0x%1)").arg(socketDomain));
0576     }
0577 }
0578 
0579 QString AuditConvertor::convertSocketCall(const QString &socketCall, unsigned int base)
0580 {
0581     bool ok = false;
0582     int a0 = socketCall.toLong(&ok, base);
0583 
0584     if (!ok) {
0585         return convertError(socketCall);
0586     } else {
0587         return sockMap.value(a0, QStringLiteral("unknown-socketcall(%1)").arg(socketCall));
0588     }
0589 }
0590 
0591 QString AuditConvertor::convertIpcCall(const QString &ipcCall, unsigned int base)
0592 {
0593     bool ok = false;
0594     int a0 = ipcCall.toLong(&ok, base);
0595 
0596     if (!ok) {
0597         return convertError(ipcCall);
0598     } else {
0599         return ipcMap.value(a0, QStringLiteral("unknown-ipccall(%1)").arg(ipcCall));
0600     }
0601 }
0602 
0603 QString AuditConvertor::convertExitSysCall(const QString &exitSysCall)
0604 {
0605     if (exitSysCall == QLatin1String("0")) {
0606         return QStringLiteral("EXIT_SUCCESS");
0607     } else if (exitSysCall == QLatin1String("1")) {
0608         return QStringLiteral("EXIT_FAILURE");
0609     } else {
0610         return QStringLiteral("UNKNOWN");
0611     }
0612 }
0613 
0614 QString AuditConvertor::convertBpf(const QString &bpf)
0615 {
0616     bool ok = false;
0617     ulong cmd = bpf.toULong(&ok, 16);
0618 
0619     if (!ok) {
0620         return convertError(bpf);
0621     } else {
0622         return bpfMap.value(cmd, QStringLiteral("unknown-bpf-cmd(%1)").arg(bpf));
0623     }
0624 }
0625 
0626 QString AuditConvertor::convertModeShort(const QString &mode, int base)
0627 {
0628     bool ok = false;
0629     int val = mode.toULong(&ok, base);
0630 
0631     if (!ok) {
0632         return convertError(mode);
0633     } else {
0634         return convertModeShortInt(val);
0635     }
0636 }
0637 
0638 QString AuditConvertor::convertModeShortInt(int mode)
0639 {
0640     QString newMode;
0641 
0642     if (S_ISUID & mode) {
0643         newMode = QLatin1String("suid");
0644     }
0645 
0646     if (S_ISGID & mode) {
0647         if (!newMode.isEmpty()) {
0648             newMode += QLatin1String(",");
0649         }
0650         newMode += QLatin1String("sgid");
0651     }
0652     if (S_ISVTX & mode) {
0653         if (!newMode.isEmpty()) {
0654             newMode += QLatin1String(",");
0655         }
0656         newMode += QLatin1String("sticky");
0657     }
0658 
0659     if (!newMode.isEmpty()) {
0660         newMode += QStringLiteral(",");
0661     }
0662 
0663     return newMode += QStringLiteral("0%1").arg((S_IRWXU | S_IRWXG | S_IRWXO) & mode, 3, 8, QLatin1Char('0'));
0664 }
0665 
0666 QString AuditConvertor::convertFcntlCmd(const QString &cmd)
0667 {
0668     bool ok = false;
0669     int ival = cmd.toULong(&ok, 16);
0670 
0671     if (!ok) {
0672         return convertError(cmd);
0673     } else {
0674         return fcntlcmdMap.value(ival, QStringLiteral("unknown-fcntl-command(%1)").arg(ival));
0675     }
0676 }
0677 
0678 QString AuditConvertor::convertSockOptLevel(const QString &level)
0679 {
0680     bool ok = false;
0681     int ival = level.toULong(&ok, 16);
0682 
0683     if (!ok) {
0684         return convertError(level);
0685     } else if (ival == SOL_SOCKET) {
0686         return QStringLiteral("SOL_SOCKET");
0687     } else {
0688         protoent *p = getprotobynumber(ival);
0689         if (!p) {
0690             return socklevelMap.value(ival, QStringLiteral("unknown-sockopt-level(0x%1)").arg(level));
0691         } else {
0692             return QString::fromLatin1(p->p_name);
0693         }
0694     }
0695 }
0696 
0697 QString AuditConvertor::convertSocketType(const QString &type)
0698 {
0699     bool ok = false;
0700     ulong ival = type.toULong(&ok, 16);
0701 
0702     if (!ok) {
0703         return convertError(type);
0704     } else {
0705         return sockMap.value(ival, QStringLiteral("unknown-type(%1)").arg(type));
0706     }
0707 }
0708 
0709 QString AuditConvertor::convertSched(const QString &sched)
0710 {
0711     bool ok = false;
0712     ulong pol = sched.toULong(&ok, 16);
0713 
0714     if (!ok) {
0715         return convertError(sched);
0716     }
0717 
0718     QString retValue = schedMap.value(pol & 0x0F, QStringLiteral("unknown-scheduler-policy(0x%1)").arg(sched));
0719 
0720     if (schedMap.contains(pol & 0x0F) && (pol & 0x40000000)) {
0721         retValue += QLatin1String("|SCHED_RESET_ON_FORK");
0722     }
0723 
0724     return retValue;
0725 }
0726 
0727 QString AuditConvertor::convertOpenFlags(const QString &flags)
0728 {
0729     bool ok = false;
0730     ulong ival = flags.toULong(&ok, 16);
0731     int cnt = 0;
0732     QString retValue;
0733 
0734     if (!ok) {
0735         return convertError(flags);
0736     }
0737 
0738     if ((ival & O_ACCMODE) == 0) {
0739         retValue = QLatin1String("O_RDONLY");
0740         cnt++;
0741     }
0742 
0743     auto it = openflagMap.constBegin();
0744     while (it != openflagMap.constEnd()) {
0745         if (it.key() & ival) {
0746             if (cnt) {
0747                 retValue += QLatin1String("|");
0748             }
0749 
0750             retValue += it.value();
0751             cnt++;
0752         }
0753         ++it;
0754     }
0755 
0756     if (retValue.isEmpty()) {
0757         return QStringLiteral("0x%1").arg(flags);
0758     } else {
0759         return retValue;
0760     }
0761 }
0762 
0763 QString AuditConvertor::convertAccess(const QString &access)
0764 {
0765     bool ok = false;
0766     ulong mode = access.toULong(&ok, 16);
0767     QString retValue;
0768     unsigned int cnt = 0;
0769 
0770     if (!ok) {
0771         return convertError(access);
0772     }
0773 
0774     if ((mode & 0xF) == 0) {
0775         return QString::fromLatin1("F_OK");
0776     }
0777 
0778     auto it = accessMap.constBegin();
0779     while (it != accessMap.constEnd()) {
0780         if (it.key() & mode) {
0781             if (cnt) {
0782                 retValue += QLatin1String("|");
0783             }
0784             retValue += it.value();
0785             cnt++;
0786         }
0787         ++it;
0788     }
0789 
0790     if (retValue.isEmpty()) {
0791         return QStringLiteral("0x%1").arg(access);
0792     } else {
0793         return retValue;
0794     }
0795 }
0796 
0797 QString AuditConvertor::convertEpollCtl(const QString &ctl)
0798 {
0799     bool ok = false;
0800     ulong cmd = ctl.toULong(&ok, 16);
0801 
0802     if (!ok) {
0803         return convertError(ctl);
0804     } else {
0805         return epollctlMap.value(cmd, QStringLiteral("unknown-epoll_ctl-operation(%1)").arg(cmd));
0806     }
0807 }
0808 
0809 QString AuditConvertor::convertCapabilities(const QString &capabilities, int base)
0810 {
0811     bool ok = false;
0812     ulong cap = capabilities.toULong(&ok, base);
0813     QString value;
0814 
0815     if (!ok) {
0816         return convertError(capabilities);
0817     } else if (capMap.contains(cap)) {
0818         return capMap.value(cap);
0819     } else {
0820         if (base == 16) {
0821             value = QLatin1String("0x");
0822         }
0823         value += capabilities;
0824         return QStringLiteral("unknown-capability(%1)").arg(value);
0825     }
0826 }
0827 
0828 QString AuditConvertor::convertUmount(const QString &umount)
0829 {
0830     bool ok = false;
0831     ulong flags = umount.toULong(&ok, 16);
0832     int cnt = 0;
0833     QString retValue;
0834 
0835     if (!ok) {
0836         return convertError(umount);
0837     }
0838 
0839     auto it = umountMap.constBegin();
0840     while (it != umountMap.constEnd()) {
0841         if (it.key() & flags) {
0842             if (cnt) {
0843                 retValue += QLatin1String("|");
0844             }
0845 
0846             retValue += it.value();
0847             cnt++;
0848         }
0849         ++it;
0850     }
0851 
0852     if (retValue.isEmpty()) {
0853         return QStringLiteral("0x%1").arg(umount);
0854     } else {
0855         return retValue;
0856     }
0857 }
0858 
0859 QString AuditConvertor::convertIoctlReq(const QString &ioctlReq)
0860 {
0861     bool ok = false;
0862     ulong req = ioctlReq.toULong(&ok, 16);
0863 
0864     if (!ok) {
0865         return convertError(ioctlReq);
0866     } else {
0867         return ioctlreqMap.value(req, QStringLiteral("0x%1").arg(ioctlReq));
0868     }
0869 }
0870 
0871 QString AuditConvertor::convertFcntl(const QString &fcntl)
0872 {
0873     bool ok = false;
0874     int val = fcntl.toULong(&ok, 16);
0875 
0876     if (!ok) {
0877         return convertError(fcntl);
0878     }
0879 
0880     switch (m_a1) {
0881     case F_SETOWN:
0882         return convertUid(fcntl, 16);
0883     case F_SETFD:
0884         if (val == FD_CLOEXEC) {
0885             return QString::fromLatin1("FD_CLOEXEC");
0886         } else {
0887             return QString();
0888         }
0889     default:
0890         return fcntl;
0891     }
0892 }
0893 
0894 QString AuditConvertor::convertIpOptName(const QString &name)
0895 {
0896     bool ok = false;
0897     ulong opt = name.toULong(&ok, 16);
0898 
0899     if (!ok) {
0900         return convertError(name);
0901     } else {
0902         return ipoptnameMap.value(opt, QStringLiteral("unknown-ipopt-name(0x%1)").arg(name));
0903     }
0904 }
0905 
0906 QString AuditConvertor::convertSockOptName(const QString &name)
0907 {
0908     bool ok = false;
0909     ulong opt = name.toULong(&ok, 16);
0910 
0911     if (!ok) {
0912         return convertError(name);
0913     }
0914 
0915     int machine = audit_detect_machine();
0916 
0917     if ((machine == MACH_PPC64 || machine == MACH_PPC) && opt >= 16 && opt <= 21) {
0918         opt += 100;
0919     }
0920 
0921     return sockoptnameMap.value(opt, QStringLiteral("unknown-sockopt-name(0x%1)").arg(name));
0922 }
0923 
0924 QString AuditConvertor::convertTcpOptName(const QString &name)
0925 {
0926     bool ok = false;
0927     ulong opt = name.toULong(&ok, 16);
0928 
0929     if (!ok) {
0930         return convertError(name);
0931     } else {
0932         return tcpoptnameMap.value(opt, QStringLiteral("unknown-tcpopt-name(0x%1)").arg(name));
0933     }
0934 }
0935 
0936 QString AuditConvertor::convertUdpOptName(const QString &name)
0937 {
0938     bool ok = false;
0939     int opt = name.toULong(&ok, 16);
0940 
0941     if (!ok) {
0942         return convertError(name);
0943     }
0944 
0945     if (opt == 1) {
0946         return QStringLiteral("UDP_CORK");
0947     } else if (opt == 100) {
0948         return QStringLiteral("UDP_ENCAP");
0949     } else {
0950         return QStringLiteral("unknown-udpopt-name(0x%1)").arg(name);
0951     }
0952 }
0953 
0954 QString AuditConvertor::convertIp6OptName(const QString &name)
0955 {
0956     bool ok = false;
0957     ulong opt = name.toULong(&ok, 16);
0958 
0959     if (!ok) {
0960         return convertError(name);
0961     } else {
0962         return ip6optnameMap.value(opt, QStringLiteral("unknown-ip6opt-name(0x%1)").arg(name));
0963     }
0964 }
0965 
0966 QString AuditConvertor::convertPktOptName(const QString &name)
0967 {
0968     bool ok = false;
0969     ulong opt = name.toULong(&ok, 16);
0970 
0971     if (!ok) {
0972         return convertError(name);
0973     } else {
0974         return pktoptnameMap.value(opt, QStringLiteral("unknown-pktopt-name(0x%1)").arg(name));
0975     }
0976 }
0977 
0978 QString AuditConvertor::convertSocketProto(const QString &proto)
0979 {
0980     bool ok = false;
0981     unsigned int val = proto.toULong(&ok, 16);
0982 
0983     if (!ok) {
0984         return convertError(proto);
0985     }
0986 
0987     struct protoent *p = getprotobynumber(val);
0988 
0989     if (p) {
0990         return QString::fromLatin1(p->p_name);
0991     } else {
0992         return QStringLiteral("unknown-proto(%1)").arg(proto);
0993     }
0994 }
0995 
0996 QString AuditConvertor::convertRecv(const QString &recv)
0997 {
0998     bool ok = false;
0999     ulong rec = recv.toULong(&ok, 16);
1000     int cnt = 0;
1001     QString retValue;
1002 
1003     if (!ok) {
1004         return convertError(recv);
1005     }
1006 
1007     auto it = recvMap.constBegin();
1008     while (it != recvMap.constEnd()) {
1009         if (it.key() & rec) {
1010             if (cnt) {
1011                 retValue += QLatin1String("|");
1012             }
1013 
1014             retValue += it.value();
1015             cnt++;
1016         }
1017         ++it;
1018     }
1019 
1020     if (retValue.isEmpty()) {
1021         return QStringLiteral("0x%1").arg(recv);
1022     } else {
1023         return retValue;
1024     }
1025 }
1026 
1027 QString AuditConvertor::convertShmFlags(const QString &shmflags)
1028 {
1029     bool ok = false;
1030     ulong flags = shmflags.toULong(&ok, 16);
1031     ulong partial;
1032     int cnt = 0;
1033     QString retValue;
1034 
1035     if (!ok) {
1036         return convertError(shmflags);
1037     }
1038 
1039     partial = flags & 00003000;
1040 
1041     auto it = ipccmdMap.constBegin();
1042     while (it != ipccmdMap.constEnd()) {
1043         if (it.key() & partial) {
1044             if (cnt) {
1045                 retValue += QLatin1String("|");
1046             }
1047 
1048             retValue += it.value();
1049             cnt++;
1050         }
1051         ++it;
1052     }
1053 
1054     partial = flags & 00014000;
1055 
1056     auto it1 = shmmodeMap.constBegin();
1057     while (it1 != shmmodeMap.constEnd()) {
1058         if (it1.key() & partial) {
1059             if (cnt) {
1060                 retValue += QLatin1String("|");
1061             }
1062 
1063             retValue += it1.value();
1064             cnt++;
1065         }
1066         ++it1;
1067     }
1068 
1069     partial = flags & 000777;
1070 
1071     QString tmode = convertModeShortInt(partial);
1072 
1073     if (!tmode.isEmpty()) {
1074         if (!retValue.isEmpty()) {
1075             retValue += QLatin1String("|");
1076         }
1077         return retValue + tmode;
1078     } else {
1079         return QStringLiteral("0x") + shmflags;
1080     }
1081 }
1082 
1083 QString AuditConvertor::convertProt(const QString &proto, unsigned int is_mmap)
1084 {
1085     bool ok = false;
1086     ulong prot = proto.toULong(&ok, 16);
1087     int cnt = 0;
1088     QString retValue;
1089 
1090     if (!ok) {
1091         return convertError(proto);
1092     }
1093 
1094     if ((prot & 0x07) == 0) {
1095         return QStringLiteral("PROT_NONE");
1096     }
1097 
1098     auto it = protMap.constBegin();
1099     auto endIt = protMap.constEnd();
1100 
1101     if (!is_mmap) {
1102         endIt--;
1103     }
1104 
1105     while (it != endIt) {
1106         if (it.key() & prot) {
1107             if (cnt) {
1108                 retValue += QLatin1String("|");
1109             }
1110 
1111             retValue += it.value();
1112             cnt++;
1113         }
1114         ++it;
1115     }
1116 
1117     if (retValue.isEmpty()) {
1118         return QStringLiteral("0x%1").arg(proto);
1119     } else {
1120         return retValue;
1121     }
1122 }
1123 
1124 QString AuditConvertor::convertSeek(const QString &seek)
1125 {
1126     bool ok = false;
1127     unsigned int whence = 0xFF & seek.toULong(&ok, 16);
1128 
1129     if (!ok) {
1130         return convertError(seek);
1131     } else {
1132         return seekMap.value(whence, QStringLiteral("unknown-whence(%1)").arg(seek));
1133     }
1134 }
1135 
1136 QString AuditConvertor::convertMmap(const QString &mmap)
1137 {
1138     bool ok = false;
1139     ulong maps = mmap.toULong(&ok, 16);
1140     int cnt = 0;
1141     QString retValue;
1142 
1143     if (!ok) {
1144         return convertError(mmap);
1145     }
1146 
1147     if ((maps & 0x0F) == 0) {
1148         retValue = QLatin1String("MAP_FILE");
1149         cnt++;
1150     }
1151 
1152     auto it = mmapMap.constBegin();
1153     while (it != mmapMap.constEnd()) {
1154         if (it.key() & maps) {
1155             if (cnt) {
1156                 retValue += QLatin1String("|");
1157             }
1158 
1159             retValue += it.value();
1160             cnt++;
1161         }
1162         ++it;
1163     }
1164 
1165     if (retValue.isEmpty()) {
1166         return QStringLiteral("0x%1").arg(mmap);
1167     } else {
1168         return retValue;
1169     }
1170 }
1171 
1172 QString AuditConvertor::convertMount(const QString &mnt)
1173 {
1174     bool ok = false;
1175     ulong mounts = mnt.toULong(&ok, 16);
1176     int cnt = 0;
1177     QString retValue;
1178 
1179     if (!ok) {
1180         return convertError(mnt);
1181     }
1182 
1183     auto it = mmapMap.constBegin();
1184     while (it != mmapMap.constEnd()) {
1185         if (it.key() & mounts) {
1186             if (cnt) {
1187                 retValue += QLatin1String("|");
1188             }
1189 
1190             retValue += it.value();
1191             cnt++;
1192         }
1193         ++it;
1194     }
1195 
1196     if (retValue.isEmpty()) {
1197         return QStringLiteral("0x%1").arg(mnt);
1198     } else {
1199         return retValue;
1200     }
1201 }
1202 
1203 QString AuditConvertor::convertError(const QString &val)
1204 {
1205     return QStringLiteral("conversion error(%1)").arg(val);
1206 }