Diese Website existiert nur weil wir Werbung mit AdSense ausliefern.
Bitte den AdBlocker daher auf dieser Website ausschalten! Danke.

Text aus Email-Datei extrahieren via command-line

Alles rund um das Internet, Internet-Anwendungen (E-Mail, Surfen, Cloud usw.) und das Einrichten von Netzwerken einschl. VPN unter Linux

Moderator: Moderatoren

abgdf
Guru
Guru
Beiträge: 3141
Registriert: 13. Apr 2004, 21:15

Re: Text aus Email-Datei extrahieren via command-line

Beitrag von abgdf » 7. Mär 2019, 16:31

OsunSeyi hat geschrieben:
7. Mär 2019, 00:58
Ich denke an `cat message | mail2text > message.txt`.

Code: Alles auswählen

Content-Type: text/plain;
 charset=utf-8
Content-Transfer-Encoding: base64

U2VociBnZWVocnRlciBIZXJyIEJyw7Z0amUsDQoNCnZpZWxlbiBEYW5rIGbDvHIgSWhyZSBOYWNo
cmljaHQuIERlciBWb3JnYW5nIGlzdCBmw7xyIGRhcyBHZW5lcmFsa29uc3VsYXQgYWJnZXNjaGxv
c3Nlbi4gRGllIGVudHNjaGVpZHVuZ3NyZWxldmFudGVuI
Da bin ich mit meinem Latein am Ende![/code]
Ich aber (noch) nicht. ;) Probier' mal dieses als "mail2text.py" und also "cat message | mail2text.py":

Code: Alles auswählen

#!/usr/bin/python
# coding: utf-8

# mail2text.py

import email
import email.utils
import base64
import sys

lines = sys.stdin.readlines()
l = []
for i in lines:
    l.append(i.rstrip("\n"))
lines = l

messages = []
mail = email.message_from_string("\n".join(lines))
for part in mail.walk():
    if part.get_content_type() == 'text/plain':
        payload = part.get_payload()
        enc = part['Content-Transfer-Encoding']
        if enc == 'base64':
            payload += "+++"
            payload = base64.b64decode(payload)
            messages.append(payload)
        else:
            messages.append(payload)

for i in messages:
    print i
Schöne Grüße an Herrn Br.... . ;)

Werbung:
josef-wien
Ultimate Guru
Ultimate Guru
Beiträge: 5182
Registriert: 23. Sep 2008, 17:09

Re: Text aus Email-Datei extrahieren via command-line

Beitrag von josef-wien » 7. Mär 2019, 18:28

OsunSeyi hat geschrieben:
7. Mär 2019, 00:58

Code: Alles auswählen

cat message | mail2text > message.txt
Oh Du armes, mißbrauchtes cat.

Code: Alles auswählen

<message mail2text >message.txt

Code: Alles auswählen

mail2text <message >message.txt

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 358
Registriert: 27. Mai 2006, 01:28

Re: Text aus Email-Datei extrahieren via command-line

Beitrag von OsunSeyi » 7. Mär 2019, 22:50

@ josef-wien

Danke, ich werd's mir zu Herzen nehmen und mehr über die Bash lernen. Allerdings ist möglicherweise Hopfen und Malz verloren, denn meine Scripte werden immer "hausbackener" je länger das geht. :ops:

https://www.jan-trippler.de/de/script_tipps/tuning.html

@ abgdf:

Vielen Dank, arbeitet soweit bestens!
Unglaublich, wie schön kurz so etwas sein kann...

Auf jeden Fall sind die Anhänge raus und den Rest kann ich selber in ein brauchbares Ergebnis überführen. Was allerdings nicht klappt, ist die Konvertierung von base64:

Code: Alles auswählen

Traceback (most recent call last):
  File "/home/tom/BIN/TextTools/mail2text", line 25, in <module>
    payload = base64.b64decode(payload)
  File "/usr/lib/python2.7/base64.py", line 78, in b64decode
    raise TypeError(msg)
TypeError: Incorrect padding
Wenn ich den Code in eine extra Datei kopiere, klappt das Konverieren mit
"openssl enc -d -base64 -in file" aber durchaus!

Es wäre natürlich viel einfacher, wenn's direkt ginge.

Ps: es gibt dazu aber etwas im Netz:
https://frageit.de/questions/41538884/p ... en-strings
Grauenhafte Übersetzung :fies:

Ich habe in gandenloser Unwissenheit und Einfalt einfach mal ein und auch mehrere " =" hinzugefügt, was allerdings nichts am Ergebnis geändert hat...

Pps:
https://www.python-forum.de/viewtopic.php?t=23650
https://im-coder.com/wie-dekodiert-man- ... ython.html (letzter Beitrag)
Kann man nicht zur Not auch externe Programme mit Python aufrufen und 'openssl' die Konvertierung vornehmen lassen?

abgdf
Guru
Guru
Beiträge: 3141
Registriert: 13. Apr 2004, 21:15

Re: Text aus Email-Datei extrahieren via command-line

Beitrag von abgdf » 9. Mär 2019, 11:16

OsunSeyi hat geschrieben:
7. Mär 2019, 22:50
Was allerdings nicht klappt, ist die Konvertierung von base64

Code: Alles auswählen

TypeError: Incorrect padding
Wenn ich den Code in eine extra Datei kopiere, klappt das Konverieren mit
"openssl enc -d -base64 -in file" aber durchaus!

Es wäre natürlich viel einfacher, wenn's direkt ginge.
Laut diesem:
https://gist.github.com/perrygeo/ee7c65bb1541ff6ac770

liegt "Incorrect Padding" daran, daß base64 eine bestimmte Anzahl von Zeichen voraussetzt (ein Vielfaches von 4 oder so), die der String so nicht hat. Einfache Lösung: Ein paar geeignete Zeichen anfügen. In dem Dokument ist es "=". Das ging bei mir nicht. Mit "+" ging es. Deshalb hatte ich in meinem Skript die Zeile:

Code: Alles auswählen

payload += "+++"
Die fügt drei Pluszeichen an. Kann sein, daß es bei Dir mit "=" geht, dann wäre es stattdessen:

Code: Alles auswählen

payload += "==="
OsunSeyi hat geschrieben:Kann man nicht zur Not auch externe Programme mit Python aufrufen und 'openssl' die Konvertierung vornehmen lassen?
Sicherlich. Ein system-Call ginge so:

Code: Alles auswählen

import os
os.system("your_program")

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 358
Registriert: 27. Mai 2006, 01:28

Re: Text aus Email-Datei extrahieren via command-line

Beitrag von OsunSeyi » 13. Mär 2019, 06:42

Leider kann das Phyton-Script auch nicht reinen Html-Mails umgehen..
Da liegt der Hase also wieder im Pfeffer...

Code: Alles auswählen

Return-Path: <anbieter-xc1p3f839jxmh@mail.ebay-kleinanzeigen.de>
Received:
Received:
Received:
DKIM-Signature:
Received:
Received:
Subject:
Content-Type: text/html;charset=UTF-8
Date: Mon, 11 Mar 2019 12:27:10 +0100 (CET)
Content-Transfer-Encoding: 7bit
X-Comaas-Tenant:
Message-ID:
To:
X-TOI-SPAM:
X-TOI-VIRUSSCAN:
X-TOI-MSGID:
X-ENVELOPE-TO:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1">
</head>
<body vlink="#001e9b" alink="#001e9b" link="#001e9b" bgcolor="#ffffff">
        ---TEXT---
</body>
</html>

abgdf
Guru
Guru
Beiträge: 3141
Registriert: 13. Apr 2004, 21:15

Re: Text aus Email-Datei extrahieren via command-line

Beitrag von abgdf » 13. Mär 2019, 11:14

Locker bleiben:

Code: Alles auswählen

#!/usr/bin/python
# coding: utf-8

# mail2text.py

import email
import email.utils
import base64
import sys
from bs4 import BeautifulSoup


lines = sys.stdin.readlines()
l = []
for i in lines:
    l.append(i.rstrip("\n"))
lines = l

messages = []
mail = email.message_from_string("\n".join(lines))
for part in mail.walk():
    if part.get_content_type() == 'text/plain':
        payload = part.get_payload()
        enc = part['Content-Transfer-Encoding']
        if enc == 'base64':
            payload += "+++"
            payload = base64.b64decode(payload)
            messages.append(payload)
        else:
            messages.append(payload)
    if part.get_content_type() == 'text/html':
        payload = part.get_payload()
        messages.append(payload)
        soup = BeautifulSoup("\n".join(messages), 'html.parser')
        text = soup.get_text()
        messages = text.split("\n")

for i in messages:
    print i
Modul "BeautifulSoup"/bs4 wird benötigt. Bei mir (OpenSuSE 13.1) gibt es Pakete in der Distribution (python-beautifulsoup...rpm, python-beautifulsoup4...rpm). Bei Dir bestimmt auch.

Benutzeravatar
OsunSeyi
Hacker
Hacker
Beiträge: 358
Registriert: 27. Mai 2006, 01:28

Re: Text aus Email-Datei extrahieren via command-line

Beitrag von OsunSeyi » 13. Mär 2019, 11:38

:thumbs:

Das war's...
Jetzt bleibt noch die Frage nach den Base64 codierten Mails.
Wenn ich also nicht die Zeichen zählen will (aber ich kann kein Phyton), bliebe als Möglichkeit:

Code: Alles auswählen

import os
os.system(/usr/bin/openssl)
Aber dann geht's ja weiter, nämlich wie die Optionen an openssl übergeben...

Code: Alles auswählen

openssl enc -d -base64 -in file
Im Script finde ich:

Code: Alles auswählen

        if enc == 'base64':
            payload += "+++"
            payload = base64.b64decode(payload)
            messages.append(payload)
:???: :mute:
In besagtem Link https://im-coder.com/wie-dekodiert-man- ... ython.html (letzter Beitrag) heißt es so schön:

Überraschend, aber die derzeit akzeptierte Antwort ist nicht ganz richtig.
Wie einigen anderen Antworten gesagt, es ist etwas genannt base64url Codierung, und es ist ein Teil der RFC7515.

Im Grunde, die Sie ersetzt haben '+' und '/' chars durch '-' und '_' sind; und zusätzlich entfernt alle nachgestellten '=' Zeichen, da kann man immer sagen, wie viele chars du bist fehlt, nur durch die Betrachtung der kodierten string der Länge.

Hier ein illustratives Beispiel aus RFC7515 in C#:
...


Also, angesichts der grottigen Übersetzung rate ich mal, daß Base64 mit nicht stimmiger Anzahl Zeichen (falschem Bounding) trotzdem korrekter Bestandteil von RFC7515 sein kann? Es kommt einem ja auch krude vor, immer erst die Anzahl Zeichen vom Base64-Teil zählen zu müssen, um dann ggF noch Zeichen hinzuzufügen...

abgdf
Guru
Guru
Beiträge: 3141
Registriert: 13. Apr 2004, 21:15

Re: Text aus Email-Datei extrahieren via command-line

Beitrag von abgdf » 13. Mär 2019, 12:56

OsunSeyi hat geschrieben:
13. Mär 2019, 11:38
Also, angesichts der grottigen Übersetzung rate ich mal, daß Base64 mit nicht stimmiger Anzahl Zeichen (falschem Bounding) trotzdem korrekter Bestandteil von RFC7515 sein kann? Es kommt einem ja auch krude vor, immer erst die Anzahl Zeichen vom Base64-Teil zählen zu müssen, um dann ggF noch Zeichen hinzuzufügen...
In dem anderen Link hieß es, man bräuchte immer was, das durch 4 teilbar sei. Wenn man 3 Zeichen hinzufüge, sei man auf der sicheren Seite. Sollten es zu viele Zeichen sein, würden sie abgeschnitten.
Fragt sich nur, welche Zeichen. "=" wurde vorgeschlagen, aber bei mir ging nur "+". "+" ging bei Dir nicht. Wie gesagt, ich würde mal "=" versuchen. Es ist immer schwer, was zu einem Fehler zu sagen, der bei einem selbst nicht auftritt (bei mir ging "+" ja).

Antworten