Ist es möglich, diese Procmail-Filterung ein wenig zu bereinigen?

Ist es möglich, diese Procmail-Filterung ein wenig zu bereinigen?

Ich habe diesen Procmail-Filter, der zu funktionieren scheint, auf den ich aber nicht wirklich stolz bin. Ich bin überzeugt, dass wir mit verschachtelten Abschnitten viel mehr Optimierung und Übersichtlichkeit erreichen können, aber ich erziele keine funktionalen Ergebnisse.

:0
* !^X-ClamAV
VIRUS=|/usr/bin/clamdscan --no-summary --stdout -

:0fw
* !^X-ClamAV
* VIRUS ?? .*: \/.* FOUND
| formail -a "X-ClamAV: Yes, $MATCH"
:0Efw
* !^X-ClamAV
| formail -a "X-ClamAV: Virus Free"

:0
* ^X-ClamAV: Yes
$MAILDIR/.virus/

Sie haben es vielleicht verstanden, ich versuche, die E-Mail-Header mit X-ClamAV: Yes, $MATCHoder X-ClamAV: Virus Freeabhängig vom Clamdscan-Ergebnis zu markieren und sie bei positivem Ergebnis in $MAILDIR /.virus/ zu platzieren. Das ist alles.

BEARBEITEN:

Vielleicht ist das besser:

:0
* !^X-Virus-Status
VIRUS=|/usr/bin/clamdscan --no-summary --stdout -

:0
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
{
        :0fhw
        | formail -a "X-Virus-Status: Infected, $MATCH"
}
:0Efw
| formail -a "X-Virus-Status: Virus Free"

:0
* ^X-Virus-Status: Infected
$MAILDIR/.virus/

(Ich habe das Tag geändert, um mit AddHeader vom Clamav-Filter filtern zu können)

EDIT2:

Aber ich habe den Fehler gemacht, nicht gut oder überhaupt nicht zu erklären, dass die E-Mail tatsächlich vor procmail (clamav-milter) markiert werden kann und daher bereits enthält X-Virus-Status: Infected. In diesem Fall macht es keinen Sinn, den Scan zu wiederholen, aber Sie müssen die E-Mail in platzieren .virus. Aus diesem Grund muss ich Folgendes einfügen:

:0
* ^X-Virus-Status: Infected
$MAILDIR/.virus/

aus der Zahnspange

Aber meine Lösung scheint nicht gut zu sein ( procmail: Skipped "--no-summary --stdout -"):

:0
* !^X-Virus-Status
{
        VIRUS=|/usr/bin/clamdscan --no-summary --stdout -

        :0
        * VIRUS ?? .*: \/.* FOUND
        {
                VIRUSNAME=`echo "$MATCH" | sed 's/ FOUND$//'`
                :0fhw
                | formail -a "X-Virus-Status: Infected ($VIRUSNAME)"
        }
        :0Efw
        | formail -a "X-Virus-Status: Virus Free"
}

:0
* ^X-Virus-Status: Infected
$MAILDIR/.virus/

Ich möchte das nicht überschreiben X-Virus-Status.

  • Wenn nicht markiert -> scannen -> markieren (infiziert oder nicht) -> einfügen, .viruswenn infiziert
  • Wenn bereits markiert -> einfügen, .viruswenn infiziert

Mit anderen Worten (vielleicht klarer):

1) tagged X-Virus-Status?
    yes:    go 2)
    no: scan -> infected?
                yes: tag infected
                no: tag non infected
2) tagged X-Virus-Status: Infected?
    yes: put in .virus
    no: go 3)
3) continue procmail filters

EDIT3:

Die Lösung, die ich in EDIT2 ausprobiert habe, dieselbe wie die von @tripleee vorgeschlagene, war gut. Das Problem betraf den Filter, dessen Argumente nicht gelesen wurden.

ich ersetzte

VIRUS=|/usr/bin/clamdscan --no-summary --stdout -

von

VIRUS=`/usr/bin/clamdscan --no-summary --stdout -`

und jetzt scheint es in Ordnung zu sein.

Antwort1

Eine kurze stilistische Anmerkung: Die Klammern sind hier nicht erforderlich.

:0fhw
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
| formail -a "X-Virus-Status: Infected, $MATCH"

Die fhwFlags beziehen sich auf die Aktion und werden nur ausgeführt, wenn die Bedingungen erfüllt sind.

Andererseits würde ich wahrscheinlich alle Aktionen, die Sie ausführen möchten, wenn diese Bedingungen erfüllt sind, in Klammern setzen.

Als Alternative zur Behebung der Syntaxfehler können Sie Backticks um die VIRUS-Zuweisung herum verwenden. Sie können auch die Zuweisungssyntax verwenden =|, aber wenn die erste bei Ihnen nicht funktioniert, versuchen Sie die andere. Bei mir funktioniert es hier einwandfrei.

:0
* !^X-Virus-Status
{ VIRUS=`clamdscan --no-summary --stdout -` }

:0
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
{
    :0fhw
    | formail -a "X-Virus-Status: Infected, $MATCH"

    :0
    $MAILDIR/.virus/
}
:0Efw
| formail -a "X-Virus-Status: Virus Free"

Vielleicht wäre es auch sinnvoll, das letzte „FOUND“-Token zu löschen, MATCHbevor es in den Header geschrieben wird.

:0
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
{
    VIRUSNAME=`echo "$MATCH" | sed 's/ FOUND$//'`
    :0fhw
    | formail -a "X-Virus-Status: Infected, $VIRUSNAME"

(Ich hatte Mühe, eine Lösung zu finden, die keinen externen Prozess zum Abschneiden des Saitenendes erfordert. Vielleicht könnte man so etwas durch geschicktes Einritzen erreichen, aber für dieses einfache Rezept wäre das wahrscheinlich übertrieben.)

Schließlich bin ich mir nicht sicher, ob Sie das überschreiben möchten, X-Virus-Statusauch wenn es bereits vorhanden war. Ihr :0Ewird passieren, wenn eine oder beide Bedingungen falsch sind. Vielleicht meinten Sie stattdessen dies;

:0
* !^X-Virus-Status
{
    VIRUS=`clamdscan --no-summary --stdout -`
    
    :0
    * VIRUS ?? .*: \/.* FOUND
    {
        VIRUSNAME=`echo "$MATCH" | sed 's/ FOUND$//'`
        :0fhw
        | formail -a "X-Virus-Status: Infected, $VIRUSNAME"

        :0
        $MAILDIR/.virus/
    }
    :0Efw
    | formail -a "X-Virus-Status: Virus Free"
}

Mit anderen Worten: Führen Sie diese Aktionen hier nur aus, wenn X-Virus-Status:sie nicht bereits in den Headern vorhanden waren; wenn das Ergebnis von Clamscan anzeigt, dass kein Virus vorhanden war, fügen Sie den Header „Virusfrei“ hinzu.

Ich habe das entfernt /usr/bin; es ist wahrscheinlich besser, sicherzustellen, dass Ihr PATHvernünftig ist, als alle Pfade fest zu codieren, aber das liegt natürlich letztendlich bei Ihnen.

Mit Ihrer aktualisierten Frage vermute ich, dass die Logik, die Sie wollen, ist

:0
* !^X-Virus-Status
{
    VIRUS=`clamdscan --no-summary --stdout -`
    
    :0
    * VIRUS ?? .*: \/.* FOUND
    {
        VIRUSNAME=`echo "$MATCH" | sed 's/ FOUND$//'`
        :0fhw
        | formail -a "X-Virus-Status: Infected, $VIRUSNAME"
    }
    :0Efw
    | formail -a "X-Virus-Status: Virus Free"
}

:0
* ^X-Virus-Status: Infected
$MAILDIR/.virus/

verwandte Informationen