2022-07-07 14:03:57 +00:00
|
|
|
from imaplib import IMAP4_SSL, IMAP4
|
2022-07-05 09:44:22 +00:00
|
|
|
from os import listdir
|
|
|
|
from os.path import isfile, join
|
|
|
|
import sys
|
|
|
|
|
2022-07-07 14:03:57 +00:00
|
|
|
# COMMAND USAGE
|
|
|
|
#
|
|
|
|
# start a test IMAP server locally (see comment below)
|
|
|
|
# then call this script. eg:
|
|
|
|
# ./send-to-imap.py dovecot ./emails/dxflrs/
|
|
|
|
|
|
|
|
# DOCKER CONTAINERS TO QUICKLY SPAWN A REFERENCE SERVER
|
|
|
|
#
|
|
|
|
# -- Dovecot --
|
|
|
|
# cmd: docker run --rm -it -p 993:993 -p 143:143 dovecot/dovecot
|
|
|
|
# user: test (any)
|
|
|
|
# pw: pass
|
|
|
|
#
|
|
|
|
# -- Maddy --
|
|
|
|
# cmds:
|
|
|
|
# docker volume create maddydata
|
|
|
|
# openssl req -nodes -new -x509 -keyout privkey.pem -out fullchain.pem
|
|
|
|
# docker run --rm -it --name maddy -e MADDY_DOMAIN=example.com -e MADDY_HOSTNAME=mx.example.com -v maddydata:/data -p 143:143 -p 993:993 --entrypoint /bin/sh foxcpp/maddy
|
|
|
|
# mkdir /data/tls
|
|
|
|
# docker cp ./fullchain.pem maddy:/data/tls/
|
|
|
|
# docker cp ./privkey.pem maddy:/data/tls/
|
|
|
|
# maddyctl creds create test@example.com
|
|
|
|
# maddyctl imap-acct create test@example.com
|
|
|
|
# maddy -config /data/maddy.conf run --debug
|
|
|
|
#
|
|
|
|
# docker run --rm -it -v maddydata:/data-p 143:143 -p 993:993 foxcpp/maddy
|
2022-07-07 16:19:37 +00:00
|
|
|
#
|
|
|
|
# -- Cyrus --
|
|
|
|
# docker run --rm -it --name cyrus -v /dev/log:/dev/log -p 143:143 -p 993:993 debian:buster
|
|
|
|
# apt update; apt install -y cyrus-imapd cyrus-pop3d cyrus-nntpd cyrus-caldav cyrus-admin sasl2-bin vim
|
|
|
|
# # ( 1. No Configuration / 8. Europe / 37. Paris / yes)
|
|
|
|
# vim /etc/imapd.conf
|
|
|
|
# # (uncomment 'admins: cyrus')
|
|
|
|
# touch /var/lib/cyrus/tls_sessions.db
|
|
|
|
# chown cyrus:mail /var/lib/cyrus/tls_sessions.db
|
|
|
|
# mkdir /run/cyrus
|
|
|
|
# chown -R cyrus:mail /run/cyrus
|
|
|
|
# cyrmaster -D -l 32 -C /etc/imapd.conf -M /etc/cyrus.conf
|
|
|
|
# docker exec -ti --name cyrus /bin/bash
|
|
|
|
# saslpasswd2 cyrus
|
|
|
|
# # (put "cyrus" as password)
|
|
|
|
# saslpasswd2 test
|
|
|
|
# # (put "pass" as password)
|
|
|
|
# cyradm -u cyrus localhost
|
|
|
|
# cm kzUXL7HyS5OjLcU8
|
|
|
|
# setaclmailbox kzUXL7HyS5OjLcU8 test ktelrswip
|
|
|
|
#
|
|
|
|
# -> note, must be run between 2 send-imap commands in cyradm
|
|
|
|
# localhost> setaclmailbox kzUXL7HyS5OjLcU8 cyrus x
|
|
|
|
# localhost> dm kzUXL7HyS5OjLcU8
|
|
|
|
# localhost> cm kzUXL7HyS5OjLcU8
|
|
|
|
# localhost> setaclmailbox kzUXL7HyS5OjLcU8 test ktelrswip
|
2022-07-07 14:03:57 +00:00
|
|
|
|
2022-07-05 10:04:04 +00:00
|
|
|
def rebuild_body_res(b):
|
|
|
|
bb = b''
|
|
|
|
for e in b:
|
|
|
|
if type(e) is tuple:
|
|
|
|
bb += b'\r\n'.join([p for p in e])
|
|
|
|
else:
|
|
|
|
bb += e
|
|
|
|
|
|
|
|
f = bb[bb.find(b'('):]
|
|
|
|
return f
|
|
|
|
|
2022-07-07 14:03:57 +00:00
|
|
|
target = sys.argv[1]
|
|
|
|
path = sys.argv[2]
|
|
|
|
|
|
|
|
parameters = {
|
|
|
|
"dovecot": {
|
|
|
|
"con": IMAP4_SSL,
|
|
|
|
"user": "test",
|
|
|
|
"pw": "pass",
|
2022-07-07 16:19:37 +00:00
|
|
|
"ext": ".dovecot",
|
2022-07-07 14:03:57 +00:00
|
|
|
},
|
|
|
|
"maddy": {
|
|
|
|
"con": IMAP4_SSL,
|
|
|
|
"user": "test@example.com",
|
|
|
|
"pw": "pass",
|
|
|
|
"ext": ".maddy",
|
|
|
|
},
|
2022-07-07 16:19:37 +00:00
|
|
|
"cyrus": {
|
|
|
|
"con": IMAP4,
|
|
|
|
"user": "test",
|
|
|
|
"pw": "pass",
|
|
|
|
"ext": ".cyrus",
|
|
|
|
}
|
2022-07-07 14:03:57 +00:00
|
|
|
}
|
|
|
|
conf = parameters[target]
|
|
|
|
|
2022-07-05 09:44:22 +00:00
|
|
|
onlyfiles = [join(path, f) for f in listdir(path) if isfile(join(path, f)) and len(f) > 4 and f[-4:] == ".eml"]
|
|
|
|
|
|
|
|
test_mb = "kzUXL7HyS5OjLcU8"
|
2022-07-07 14:03:57 +00:00
|
|
|
with conf['con'](host="localhost") as M:
|
|
|
|
print(M.login(conf['user'], conf['pw']))
|
|
|
|
print(M.delete(test_mb))
|
|
|
|
print(M.create(test_mb))
|
|
|
|
|
|
|
|
|
|
|
|
print(M.list())
|
|
|
|
print(M.select(test_mb))
|
|
|
|
failed = 0
|
2022-07-05 09:44:22 +00:00
|
|
|
for (idx, f) in enumerate(onlyfiles):
|
|
|
|
f_noext = f[:-4]
|
2022-07-07 14:03:57 +00:00
|
|
|
try:
|
|
|
|
with open(f, 'r+b') as mail:
|
|
|
|
print(M.append(test_mb, [], None, mail.read()))
|
|
|
|
seq = (f"{idx+1-failed}:{idx+1-failed}").encode()
|
|
|
|
(r, b) = M.fetch(seq, "(BODY)")
|
|
|
|
print((r, b))
|
|
|
|
assert r == 'OK'
|
2022-07-05 10:04:04 +00:00
|
|
|
|
|
|
|
|
2022-07-07 14:03:57 +00:00
|
|
|
with open(f_noext + conf['ext'] + ".body", 'w+b') as w:
|
|
|
|
w.write(rebuild_body_res(b))
|
2022-07-05 09:44:22 +00:00
|
|
|
|
2022-07-07 14:03:57 +00:00
|
|
|
(r, b) = M.fetch(seq, "(BODYSTRUCTURE)")
|
|
|
|
print((r, b))
|
|
|
|
assert r == 'OK'
|
|
|
|
with open(f_noext + conf['ext'] + ".bodystructure", 'w+b') as w:
|
|
|
|
w.write(rebuild_body_res(b))
|
|
|
|
except:
|
|
|
|
failed += 1
|
|
|
|
print(f"failed {f}")
|
2022-07-05 09:44:22 +00:00
|
|
|
|
|
|
|
M.close()
|
|
|
|
M.logout()
|