diff --git a/build-static-bundle.sh b/build-static-bundle.sh index 596aa7901201be621cf8b6d99dce7346f014f67e..e8d09941ae158c9566c7b11421dd35a1864eee60 100755 --- a/build-static-bundle.sh +++ b/build-static-bundle.sh @@ -20,7 +20,7 @@ gpg --homedir $tmpdir --list-options show-only-fpr-mbox -k '*' \ hash=$(echo $mbox | /usr/lib/gnupg/gpg-wks-client --print-wkd-hash | awk '{print $1}') domain=${mbox##*@} key=$(base64 -w0 < ${tmpdir}/openpgpkeys/${domain}/hu/${hash}) - echo "${comma} \"${hash}\": {\"Addr\": \"${mbox}\", \"Data\": \"${key}\"}" + echo "${comma} \"${hash}@${domain}\": {\"Addr\": \"${mbox}\", \"Data\": \"${key}\"}" comma=, done) echo '}' diff --git a/ldap.go b/ldap.go index 897d5109af9129e528c70b695c7e6f0d9ab1109c..62adf6ce3ea5d4624b3d8ec4bb12093650eb96c6 100644 --- a/ldap.go +++ b/ldap.go @@ -37,10 +37,10 @@ func NewLDAPStorage(uri, bindDN, bindPw, baseDN, filter string) (Storage, error) } if filter == "" { - filter = fmt.Sprintf("(%s=%%s)", hashLDAPAttr) + filter = fmt.Sprintf("(%s=%%h@%%d)", hashLDAPAttr) } - if !strings.Contains(filter, "%s") { - return nil, errors.New("filter expression does not contain literal '%s' token") + if !strings.Contains(filter, "%h") { + return nil, errors.New("filter expression does not contain literal '%h' token") } return &ldapStorage{ @@ -50,8 +50,15 @@ func NewLDAPStorage(uri, bindDN, bindPw, baseDN, filter string) (Storage, error) }, nil } -func (s *ldapStorage) Lookup(ctx context.Context, hash string) (*Key, error) { - filter := fmt.Sprintf(s.filter, ldap.EscapeFilter(hash)) +// Replace '%h' (for hash) and '%d' (for domain) tokens in the +// configured LDAP filter string, and return the result. +func (s *ldapStorage) filterExpr(hash, domain string) string { + // This is only safe because domain can't contain %h. + f := strings.Replace(s.filter, "%d", ldap.EscapeFilter(domain), -1) + return strings.Replace(f, "%h", ldap.EscapeFilter(hash), -1) +} + +func (s *ldapStorage) Lookup(ctx context.Context, hash, domain string) (*Key, error) { req := ldap.NewSearchRequest( s.baseDN, ldap.ScopeWholeSubtree, @@ -59,7 +66,7 @@ func (s *ldapStorage) Lookup(ctx context.Context, hash string) (*Key, error) { 0, 0, false, - filter, + s.filterExpr(hash, domain), []string{mailLDAPAttr, keyLDAPAttr}, nil, ) diff --git a/server.go b/server.go index 137372a6ea68c42779269b1bbca13059e6375b44..a64b2595d077ea8f9cc6de71d136564fb3bf4390 100644 --- a/server.go +++ b/server.go @@ -84,7 +84,7 @@ type Storage interface { // information. The special ErrNotFound error can be used to // indicate that no key was found, as opposed to a generic // backend error. - Lookup(context.Context, string) (*Key, error) + Lookup(context.Context, string, string) (*Key, error) } // Server for the WKD protocol. @@ -138,7 +138,7 @@ func (s *Server) serveDiscovery(w http.ResponseWriter, r *http.Request, request // Go through available storages until one returns a valid key. for _, storage := range s.storages { - key, err = storage.Lookup(r.Context(), request.Hash) + key, err = storage.Lookup(r.Context(), request.Hash, request.Domain) if err == nil { break } diff --git a/static.go b/static.go index c3f0f2dc444860bb2905aa327d0c5173d4325374..f6fbd2e042b01066cc7e49e7e3513174acf3dfe1 100644 --- a/static.go +++ b/static.go @@ -3,6 +3,7 @@ package wkd import ( "context" "encoding/json" + "fmt" "os" ) @@ -30,8 +31,9 @@ func NewStaticStorage(path string) (Storage, error) { return &staticStorage{keys: keys}, nil } -func (s *staticStorage) Lookup(ctx context.Context, hash string) (*Key, error) { - if key, ok := s.keys[hash]; ok { +func (s *staticStorage) Lookup(ctx context.Context, hash, domain string) (*Key, error) { + hashAddr := fmt.Sprintf("%s@%s", hash, domain) + if key, ok := s.keys[hashAddr]; ok { return key, nil } return nil, ErrNotFound