#!/usr/bin/awk -f # # Remove the digital signature from an e-mail message # # BUG: This assumes there are no repeated headers (such as "Received") # in the first part of the multipart/signed message. (Usually, it just # contains Content-Type and Content-Transfer-Encoding, but it may # contain more.) # # Author: Bert Bos # Created: 12 March 2015 # # Copyright © 2015 World Wide Web Consortium # See http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 BEGIN {IGNORECASE = 1; RS = "\r\n|\n|\r"; ORS = "\r\n"; state = "head"} # Simply copy every line of an unsigned message. state == "copy" {print} # Copy message body until the second boundary. state == "part-body" && $0 ~ boundary {state = "skip-rest"} state == "part-body" {print} # After the first boundary are the headers of the main message. state == "part-head" && /^$/ { for (i in head) printf "%s", head[i] print "" state = "part-body" } state == "part-head" && /^[^ \t]/ { key = tolower(gensub(/:.*/, "", 1)) delete head[key]} state == "part-head" {head[key] = head[key] $0 ORS} # Skip text in the preamble until the first boundary. state == "preamble" && $0 ~ boundary {state = "part-head"} # Collect top-level mail headers, which end at the first empty line. state == "head" && /^$/ { if (head["content-type"] ~ /^Content-Type: *multipart\/signed/) { state = "preamble" boundary ="--" gensub(/.*boundary="([^"]*)".*/,"\\1",1,head["content-type"]) } else { # Not a signed message, so output the headers we collected and # simply copy the rest of the message from now on. for (i in head) printf "%s", head[i] print state = "copy" } } state == "head" && /^[^ \t]/ {key = tolower(gensub(/:.*/, "", 1))} state == "head" {head[key] = head[key] $0 ORS} # No rule for "skip-rest": All remaining lines are ignored.