bool AuditRule::Parse()

in AuditRules.cpp [140:292]


bool AuditRule::Parse(const std::string& text, std::string& error) {
    error.clear();
    auto clean_text = trim_whitespace(text);
    if (clean_text.empty() || clean_text[0] == '#') {
        return false;
    }
    auto args = split(text, ' ');
    if (args.empty()) {
        return false;
    }

    if (args[0].size() < 2 || args[0][0] != '-') {
        error.append("Invalid option '");
        error.append(args[0]);
        error.append("'");
        return false;
    }

    bool watch = false;

    char rule_opt = args[0][1];
    if (rule_opt == 'w' || rule_opt == 'W') {
        watch = true;
        SetSyscallAll();
        if (rule_opt == 'W') {
            is_delete_rule = true;
        }
        if (!parse_add_w_arg(args[1], error)) {
            return false;
        }
    } else if (rule_opt != 'a' && rule_opt != 'A' && rule_opt != 'd') {
        return false;
    } else {
        if (rule_opt == 'A') {
            ruleptr()->flags |= AUDIT_FILTER_PREPEND;
        } else if (rule_opt == 'd') {
            is_delete_rule = true;
        }
        if (!parse_add_a_arg(args[1], error)) {
            return false;
        }
    }

    size_t idx = 2;
    while(idx < args.size()) {
        if (args[idx].size() < 2 || args[idx][0] != '-') {
            error.append("Invalid option '");
            error.append(args[idx]);
            error.append("'");
            return false;
        }
        if (idx+1 >= args.size()) {
            error.append("Missing value for option '");
            error.append(args[idx]);
            error.append("'");
            return false;
        }
        switch (args[idx][1]) {
            case 'A':
                /* fallthrough */
            case 'd':
                /* fallthrough */
            case 'a':
                error.append("The '-");
                error.push_back(args[idx][1]);
                error.append("' option is not allowed with the '-");
                error.push_back(rule_opt);
                error.append("' option");
                return false;
            case 'W':
                /* fallthrough */
            case 'w':
                error.append("The '-");
                error.push_back(args[idx][1]);
                error.append("' option is not allowed with the '-");
                error.push_back(rule_opt);
                error.append("' option");
                return false;
            case 'p':
                if (!watch) {
                    error.append("The '-p' option is not allowed with the '-");
                    error.push_back(rule_opt);
                    error.append("' option");
                    return false;
                }
                if (!parse_add_p_arg(args[idx+1], error)) {
                    return false;
                }
                idx += 2;
                break;
            case 'k':
                if (!parse_add_k_arg(args[idx+1], error)) {
                    return false;
                }
                idx += 2;
                break;
            case 'S':
                if (watch) {
                    error.append("The '-S' option is not allowed with the '-");
                    error.push_back(rule_opt);
                    error.append("' option");
                    return false;
                }
                if ((ruleptr()->flags & FILTER_MASK) == AUDIT_FILTER_TASK) {
                    error.append("The '-S' option is not allowed with the task rules");
                    return false;
                }
                if (!parse_add_S_arg(args[idx+1], error)) {
                    return false;
                }
                idx += 2;
                break;
            case 'F':
                if (watch) {
                    error.append("The '-F' option is not allowed with the '-");
                    error.push_back(rule_opt);
                    error.append("' option");
                    return false;
                }
                if (args[idx].size() > 2) {
                    if (!parse_add_F_arg(args[idx].substr(2), error)) {
                        return false;
                    }
                    idx += 1;
                } else {
                    if (!parse_add_F_arg(args[idx+1], error)) {
                        return false;
                    }
                    idx += 2;
                }
                break;
            case 'C':
                if (watch) {
                    error.append("The '-C' option is not allowed with the '-");
                    error.push_back(rule_opt);
                    error.append("' option");
                    return false;
                }
                if (!parse_add_C_arg(args[idx+1], error)) {
                    return false;
                }
                idx += 2;
                break;
            default:
                error.append("Unsupported option '");
                error.append(args[idx]);
                error.append("'");
                return false;
        }
    }

    return true;
}