From a48d74a651b180c82e226d62b6e1e5af0657d007 Mon Sep 17 00:00:00 2001 From: Gurkengewuerz Date: Thu, 28 Nov 2019 17:08:19 +0100 Subject: [PATCH] added mysql backend --- config.sample.ini | 13 +++++++++- gpgit.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/config.sample.ini b/config.sample.ini index 68aa520..a488e36 100644 --- a/config.sample.ini +++ b/config.sample.ini @@ -1,5 +1,7 @@ version = 0.1 service_name = netire-cryptall +# available backends: ldap, mysql +backend = mysql [ldap] host = ldap.exmaple.com @@ -8,4 +10,13 @@ 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 \ No newline at end of file +key_attribute = pgpKey + +[mysql] +host = sql.exmaple.com +port = 3306 +username = +password = +database = vmail +# use %u as a placeholder for the username and %d as the domain (username@domain.com) +query = SELECT pgp_key FROM pgp LEFT JOIN account USING(account_id) LEFT JOIN domain ON account.domain_id = domain.domain_id WHERE username = '%u' AND domain = '%d' and enabled = true diff --git a/gpgit.go b/gpgit.go index 3e449d3..21a7854 100644 --- a/gpgit.go +++ b/gpgit.go @@ -3,6 +3,7 @@ package main import ( "bytes" "crypto/tls" + "database/sql" "fmt" "golang.org/x/crypto/openpgp" "io" @@ -15,13 +16,14 @@ import ( "git.gurkengewuerz.de/Gurkengewuerz/go-gpgmime" "github.com/emersion/go-message" + _ "github.com/go-sql-driver/mysql" "gopkg.in/ini.v1" "gopkg.in/ldap.v3" ) var config *ini.File -func getArmoredKeyRing(recipient *string) (string, error) { +func getArmoredKeyRing_ldap(recipient *string) (string, error) { tlsConfig := &tls.Config{ InsecureSkipVerify: true, } @@ -58,6 +60,63 @@ func getArmoredKeyRing(recipient *string) (string, error) { return entry.GetAttributeValue(keyAttribute), nil } +type pgpSQL struct { + pgpKey string +} + +func getArmoredKeyRing_mysql(recipient *string) (string, error) { + db, err := sql.Open( + "mysql", + fmt.Sprintf( + "%s:%s@tcp(%s:%s)/%s", + config.Section("mysql").Key("username").String(), + config.Section("mysql").Key("password").String(), + config.Section("mysql").Key("host").String(), + config.Section("mysql").Key("port").String(), + config.Section("mysql").Key("database").String())) + + if err != nil { + log.Fatal(err) + } + + components := strings.Split(*recipient, "@") + username, domain := components[0], components[1] + + query := config.Section("mysql").Key("query").String() + query = strings.Replace(query, "%u", username, 1) + query = strings.Replace(query, "%d", domain, 1) + + row := db.QueryRow(query) + + var key pgpSQL + err = row.Scan(&key.pgpKey) + + if err == sql.ErrNoRows { + return "", fmt.Errorf("no entries for user %s at domain %s", username, domain) + } + + if err != nil { + log.Fatal(err) + } + + err = db.Close() + if err != nil { + log.Fatal(err) + } + + return key.pgpKey, nil +} + +func getArmoredKeyRing(recipient *string) (string, error) { + backend := strings.ToLower(config.Section("").Key("backend").String()) + if backend == "ldap" { + return getArmoredKeyRing_ldap(recipient) + } else if backend == "mysql" { + return getArmoredKeyRing_mysql(recipient) + } + return "", fmt.Errorf("unknown backend option %s", backend) +} + func isPGPMessage(msg string) (bool, error) { matched, err := regexp.MatchString(`-----BEGIN PGP MESSAGE-----[\s\S]+?-----END PGP MESSAGE-----`, msg) return matched, err