init repo
This commit is contained in:
commit
d06d136601
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.idea/
|
||||
config.ini
|
11
config.sample.ini
Normal file
11
config.sample.ini
Normal file
@ -0,0 +1,11 @@
|
||||
version = 0.1
|
||||
service_name = netire-cryptall
|
||||
|
||||
[ldap]
|
||||
host = ldap.exmaple.com
|
||||
port = 636
|
||||
bind_dn =
|
||||
bind_pw =
|
||||
search_base = ou=people,dc=user,dc=mc8051,dc=de
|
||||
query_filter = (&(mail=%s)(pgpEnabled=True)(objectClass=person))
|
||||
key_attribute = pgpKey
|
167
gpgit.go
Normal file
167
gpgit.go
Normal file
@ -0,0 +1,167 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/emersion/go-message"
|
||||
"github.com/emersion/go-pgpmime"
|
||||
"gopkg.in/ini.v1"
|
||||
"gopkg.in/ldap.v3"
|
||||
)
|
||||
|
||||
var config *ini.File
|
||||
|
||||
func getArmoredKeyRing(recipient *string) (string, error) {
|
||||
tlsConfig := &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
l, err := ldap.DialTLS(
|
||||
"tcp",
|
||||
fmt.Sprintf("%s:%s", config.Section("ldap").Key("host").String(), config.Section("ldap").Key("port").String()),
|
||||
tlsConfig)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
keyAttribute := config.Section("ldap").Key("key_attribute").String()
|
||||
searchRequest := ldap.NewSearchRequest(
|
||||
config.Section("ldap").Key("search_base").String(),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
fmt.Sprintf(config.Section("ldap").Key("query_filter").String(), *recipient),
|
||||
[]string{"dn", "uid", keyAttribute}, // A list attributes to retrieve
|
||||
nil,
|
||||
)
|
||||
|
||||
sr, err := l.Search(searchRequest)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if len(sr.Entries) > 1 || len(sr.Entries) == 0 {
|
||||
return "", fmt.Errorf("to many or none entries %d", len(sr.Entries))
|
||||
}
|
||||
|
||||
entry := sr.Entries[0]
|
||||
return entry.GetAttributeValue(keyAttribute), nil
|
||||
}
|
||||
|
||||
func isPGPMessage(msg string) (bool, error) {
|
||||
matched, err := regexp.MatchString(`-----BEGIN PGP MESSAGE-----[\s\S]+?-----END PGP MESSAGE-----`, msg)
|
||||
return matched, err
|
||||
}
|
||||
|
||||
func isEncrypted(mail *message.Entity) (bool) {
|
||||
t, _, _ := mail.Header.ContentType()
|
||||
if strings.ToLower(t) == "multipart/encrypted" {
|
||||
return true
|
||||
}
|
||||
|
||||
if mail.MultipartReader() == nil {
|
||||
if b, err := ioutil.ReadAll(mail.Body); err == nil {
|
||||
enc, _ := isPGPMessage(string(b))
|
||||
if enc {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func encryptEML(eml string, armoredKeyRing *string) {
|
||||
var b bytes.Buffer
|
||||
var r, r2 io.Reader
|
||||
|
||||
r = strings.NewReader(eml)
|
||||
|
||||
m, err := message.Read(r)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if isEncrypted(m) {
|
||||
log.Print(eml)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
r2 = strings.NewReader(*armoredKeyRing)
|
||||
entityList, err := openpgp.ReadArmoredKeyRing(r2)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Create a new PGP/MIME writer
|
||||
var ciphertext struct{ *message.Writer }
|
||||
cleartext := pgpmime.Encrypt(&ciphertext, nil, entityList, nil, nil)
|
||||
|
||||
// Add the PGP/MIME Content-Type header field to the mail header
|
||||
m.Header.Set("Content-Type", cleartext.ContentType())
|
||||
m.Header.Set(
|
||||
"X-Encrypted-By",
|
||||
fmt.Sprintf("%s-v%s", config.Section("").Key("service_name").String(), config.Section("").Key("version").String()))
|
||||
|
||||
// Create a new mail writer with our mail header
|
||||
mw, err := message.CreateWriter(&b, m.Header)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// Set the PGP/MIME writer output to the mail body
|
||||
ciphertext.Writer = mw
|
||||
|
||||
// Close all writers
|
||||
if err := cleartext.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := mw.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println(b.String())
|
||||
}
|
||||
|
||||
func main() {
|
||||
cfg, err := ini.Load("config.ini")
|
||||
if err != nil {
|
||||
fmt.Printf("Fail to read file: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
config = cfg
|
||||
|
||||
argsWithoutProg := os.Args[1:]
|
||||
|
||||
if len(argsWithoutProg) != 1 {
|
||||
log.Fatal("No recipient as argument")
|
||||
}
|
||||
recipient := argsWithoutProg[0]
|
||||
|
||||
fi, err := os.Stdin.Stat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if fi.Size() == 0 {
|
||||
log.Fatal("stdin is empty")
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(os.Stdin)
|
||||
rawEml := string(data)
|
||||
|
||||
armoredKeyRing, err := getArmoredKeyRing(&recipient)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
encryptEML(rawEml, &armoredKeyRing)
|
||||
os.Exit(0)
|
||||
}
|
40
ldap.schema
Normal file
40
ldap.schema
Normal file
@ -0,0 +1,40 @@
|
||||
attributeType ( 1.3.6.1.4.1.3401.8.2.11 NAME 'pgpKey'
|
||||
DESC 'pgpKey attribute for PGP'
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
|
||||
SINGLE-VALUE
|
||||
X-ORIGIN 'Pretty Good Privacy (PGP)' )
|
||||
attributeType ( 1.3.6.1.4.1.3401.8.2.13 NAME 'pgpEnabled'
|
||||
DESC 'pgpDisabled attribute for PGP'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||
SINGLE-VALUE
|
||||
X-ORIGIN 'Pretty Good Privacy (PGP)' )
|
||||
attributeType ( 1.3.6.1.4.1.3401.8.2.14 NAME 'pgpKeyID'
|
||||
DESC 'pgpKeyID attribute for PGP'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||
SINGLE-VALUE
|
||||
X-ORIGIN 'Pretty Good Privacy (PGP)' )
|
||||
attributeType ( 1.3.6.1.4.1.3401.8.2.15 NAME 'pgpKeyType'
|
||||
DESC 'pgpKeyType attribute for PGP'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||
SINGLE-VALUE
|
||||
X-ORIGIN 'Pretty Good Privacy (PGP)' )
|
||||
attributeType ( 1.3.6.1.4.1.3401.8.2.17 NAME 'pgpKeyCreateTime'
|
||||
DESC 'pgpKeyCreateTime attribute for PGP'
|
||||
EQUALITY caseIgnoreMatch
|
||||
ORDERING caseIgnoreOrderingMatch
|
||||
SUBSTR caseIgnoreSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||
SINGLE-VALUE
|
||||
X-ORIGIN 'Pretty Good Privacy (PGP)' )
|
||||
|
||||
objectClass ( 1.3.6.1.4.1.3401.8.2.24 NAME 'pgpKeyInfo'
|
||||
DESC 'PGP defined objectclass to maintain information about a PGP key'
|
||||
SUP top AUXILIARY
|
||||
MUST ( pgpKey )
|
||||
MAY ( pgpEnabled $ pgpKeyID $ pgpKeyType $ pgpKeyCreateTime )
|
||||
X-ORIGIN 'Pretty Good Privacy (PGP)' )
|
82
sample.mail
Normal file
82
sample.mail
Normal file
@ -0,0 +1,82 @@
|
||||
Return-Path: <niklas@example.org>
|
||||
Delivered-To: nico@example.com
|
||||
X-Spam-Flag: NO
|
||||
X-Spam-Score: -2.899
|
||||
X-Spam-Level:
|
||||
MIME-Version: 1.0
|
||||
Date: Sun, 03 Nov 2019 20:34:55 +0000
|
||||
Content-Type: multipart/alternative;
|
||||
boundary="--=_RainLoop_447_783840555.1572813295"
|
||||
From: "=?utf-8?B?U2Now7x0cnVtcGYsIE5pa2xhcw==?=" <niklas@example.org>
|
||||
Message-ID: <7ba96fec1371da1611054b67982dec34@example.org>
|
||||
Subject: Lorem Ipsum
|
||||
To: nico@example.com
|
||||
|
||||
|
||||
----=_RainLoop_447_783840555.1572813295
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy =
|
||||
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam =
|
||||
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet c=
|
||||
lita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit am=
|
||||
et. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam non=
|
||||
umy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed d=
|
||||
iam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. St=
|
||||
et clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor si=
|
||||
t amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam=
|
||||
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, s=
|
||||
ed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum=
|
||||
. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolo=
|
||||
r sit amet. =0A=0ADuis autem vel eum iriure dolor in hendrerit in vulputa=
|
||||
te velit esse molestie consequat, vel illum dolore eu feugiat nulla facil=
|
||||
isis at vero eros et accumsan et iusto odio dignissim qui blandit praesen=
|
||||
t luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lor=
|
||||
em ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy n=
|
||||
ibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. =0A=
|
||||
=0AUt wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper s=
|
||||
uscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel =
|
||||
eum iriure dolor in hendrerit in vulputate velit esse molestie consequat,=
|
||||
vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et =
|
||||
iusto odio dignissim qui blandit praesent luptatum zzril delenit augue du=
|
||||
is dolore te feugait nulla facilisi. =0A * Lorem =0A * Ipsum =0A * dolor
|
||||
|
||||
----=_RainLoop_447_783840555.1572813295
|
||||
Content-Type: text/html; charset="utf-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
<!DOCTYPE html><html><head><meta http-equiv=3D"Content-Type" content=3D"t=
|
||||
ext/html; charset=3Dutf-8" /></head><body><div data-html-editor-font-wrap=
|
||||
per=3D"true" style=3D"font-family: arial, sans-serif; font-size: 13px;"> =
|
||||
<br>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam non=
|
||||
umy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed d=
|
||||
iam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. St=
|
||||
et clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor si=
|
||||
t amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam=
|
||||
nonumy eirmod tempor <em>invidunt ut labore et dolore magna aliquyam era=
|
||||
t, sed diam</em> voluptua. At vero eos et accusam et justo duo dolores et=
|
||||
ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem i=
|
||||
psum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing el=
|
||||
itr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna ali=
|
||||
quyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolore=
|
||||
s et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lor=
|
||||
em ipsum dolor sit amet. <br><br>Duis autem vel eum iriure dolor in hendr=
|
||||
erit in vulputate velit esse molestie consequat, vel illum dolore eu feug=
|
||||
iat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui =
|
||||
blandit praesent luptatum <strong>zzril </strong>delenit <u><em><strong>a=
|
||||
ugue duis dolore te feugait</strong></em></u> nulla facilisi. Lorem ipsum=
|
||||
dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euis=
|
||||
mod tincidunt ut laoreet dolore magna aliquam erat volutpat. <br><br><spa=
|
||||
n style=3D"background-color:#999999;">Ut wisi enim ad minim veniam, quis =
|
||||
nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea=
|
||||
commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulpu=
|
||||
tate velit esse molestie consequat, vel illum dolore eu feugiat nulla fac=
|
||||
ilisis at vero eros et accumsan et iusto odio dignissim qui blandit praes=
|
||||
ent luptatum zzril </span><span style=3D"color:#c0392b;"><strong><span st=
|
||||
yle=3D"background-color:#999999;">delenit augue duis dolore te feugait nu=
|
||||
lla facilisi</span></strong></span><span style=3D"background-color:#99999=
|
||||
9;">. </span><br> <ol> <li>Lorem</li> <li>Ipsum</li> <li>dolor</li> </ol>=
|
||||
<signature></signature> </div></body></html>
|
||||
|
||||
----=_RainLoop_447_783840555.1572813295--
|
41
sample_encrypted.mail
Normal file
41
sample_encrypted.mail
Normal file
@ -0,0 +1,41 @@
|
||||
Return-Path: <niklas@example.org>
|
||||
Delivered-To: nico@example.com
|
||||
X-Spam-Flag: NO
|
||||
X-Spam-Score: -2.899
|
||||
X-Spam-Level:
|
||||
MIME-Version: 1.0
|
||||
Date: Sun, 03 Nov 2019 20:57:20 +0000
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
From: "=?utf-8?B?U2Now7x0cnVtcGYsIE5pa2xhcw==?=" <niklas@example.org>
|
||||
Message-ID: <1c3ebfd9ea9ac4c83c9420823d0f1c71@example.org>
|
||||
Subject: Lorem Ipsum Encrypted
|
||||
To: nico@example.com
|
||||
X-Spamd-Bar: /
|
||||
|
||||
-----BEGIN PGP MESSAGE-----=0AVersion: OpenPGP.js v2.6.2=0AComment: https=
|
||||
://openpgpjs.org=0A=0AwcFMA6Ac9Cn7YTymARAAgCXEZ0JUljhiFQPtIAoNIqDR638zhaT=
|
||||
eDvIF4oMM=0AXJp8to55bx5RcKWPjbxKjKj5fVw7dd/02pjUgP/podp/JIpaOcnDjswj01uZ=
|
||||
=0AQ+oKZbNZ7A2PEldu5uZSgBS964YW/01W4Of0XX/9j4gc9j80D18GSuD5APpn=0AOB/PDlr=
|
||||
hQ2ndCZSH0PoZj6dpT/jZn03QYqmQEkrcSO3y9gCY68p9Sefc+2f8=0AcQF3NTPjyuDrJRa2k=
|
||||
5G4Yk34wb24wBmYCZkUIB6bOB4eya/ivmJFGbhDTDlk=0Aozczf6Rw01am0/DLpY96LGtB483=
|
||||
sPie+wdYjFLOeD4CX9kUX9pEUBqwV4sIV=0A/+Xq1cv4CApvfigvP+G7SW1K7UCZv0E4Mxysm=
|
||||
s8D7ZR9iYrMtogQOf8OeloV=0AN2Ut4HZLVJjnpNBBDdKfwFopoNXXl7zlLG4R9CYVli3xUK2=
|
||||
0JRV9CbENvv1V=0Ab7KnxY1rhQ+a50tosgZzK61sFtRwHsyW/JagzdWL46gylhnQLh71+VNdI=
|
||||
aSK=0AvwmtwnKlNc7c7zE6zFWTnZOogzHv4vKKI4h0OTuUXb4hEMS9u9xFkrhVF+LV=0AatG+=
|
||||
3ShvfPtymGysPWvpQb9uXDZdj+9L0rRFR05DvwrhbZWcSqFQligo882Y=0AhLxlh6P9kKr5kt=
|
||||
BninOWHazG2IIHjw54JvDpXBddcp7SwfcByU7wUYJg8yYU=0A650GZWxb6RGhMkLow4dBGIGi=
|
||||
QdOsm4GsXvbyVgxZ9tiWFsFaTVDAsl5Oe3Tn=0A39Js8GTs96VAEx0wNVHr2fSIrpu/Optit+=
|
||||
ZfjkdudaaEXRKGp4QfU47PsHeA=0APnziq6cLxTJcLSGat+HwUeYklWrrKOp1gFC507Wp4C52=
|
||||
SRxg8TGWhLVlOaeB=0A7yRIBhVC9JLWS+gl5wD6YPTg/Ft0vZPQjz7pWS34icSrYYVuFT11zV=
|
||||
CD2W6V=0AqeE9+WLrJkBgqSssx3lNepKsoP938HXhDZh6r608vyllyn6QYxaI/03J21B5=0Ai=
|
||||
0hWs1bXESHKy753EaE/KeKeJ8VMGtoFgScKk5XNNUOlg37s5BrqBt0Dll+/=0AG0oVbroet+I=
|
||||
HMrnuUt7Yc8if2c/4+mY1kBfWPvTgEFmQRVDVDNrywFJPbwVn=0ApaQceuqbh19B9uH1hGVoX=
|
||||
brgCNbNjuwkRAmb8gw9FnT3oWKUZyTctxR9dakk=0AjNuaDZrQE9U63J79LKTXVdYCuaxAdny=
|
||||
aTy3RTcfdAYGYU+8FPhITSn4nMMqz=0Ai3QrJIo2jSrH1FAelKXwyaG57FRX+oWIb3xvJWdSt=
|
||||
WUf41M+jBxXYodTlozz=0AzVuFOtROEts+t7UfkZGixbBVjpL3OeLmMIYvOC4CKGR0egCNAqi=
|
||||
yqRWsrk/K=0A+bCCZQXjY4uKeSjDhorlZ2T/PNQTOkeqwNzRyOjafW+1nBf4pgZSpCaxdXf6=
|
||||
=0A/PfVHWD2vt5Ung1MgnXZoyqvbVcWjtg0+3SBLtrZI+kuB31Yf8zHRhrPlHW+=0Auxz/fiF=
|
||||
iCnY9YoFUHys23A/p08SsRf7iuBVPHquQEIdilWhN0xzPV/sPRLFF=0AdZCY65djjw4iSgwpY=
|
||||
SSaFXDHObCjPq/7F/M+tL/Lga7FsXdM+q9LR8RfAgti=0AZ104/rujVGuTmQ=3D=3D=0A=3D6=
|
||||
Y+a=0A-----END PGP MESSAGE-----
|
Loading…
Reference in New Issue
Block a user