Skip to content
Snippets Groups Projects
Select Git revision
1 result Searching

tls.go

Blame
  • tls.go 4.32 KiB
    package serverutil
    
    import (
    	"crypto/tls"
    	"errors"
    	"fmt"
    	"log"
    	"net/http"
    	"regexp"
    	"strings"
    
    	common "git.autistici.org/ai3/go-common"
    )
    
    // TLSAuthACL describes a single access control entry. Path and
    // CommonName are anchored regular expressions (they must match the
    // entire string). The first path to match in a list of ACLs will
    // identify the ACL to be applied.
    type TLSAuthACL struct {
    	Path       string `yaml:"path"`
    	CommonName string `yaml:"cn"`
    
    	pathRx, cnRx *regexp.Regexp
    }
    
    func (p *TLSAuthACL) compile() error {
    	var err error
    	p.pathRx, err = regexp.Compile("^" + p.Path + "$")
    	if err != nil {
    		return err
    	}
    	p.cnRx, err = regexp.Compile("^" + p.CommonName + "$")
    	return err
    }
    
    func (p *TLSAuthACL) matchPath(req *http.Request) bool {
    	return p.pathRx.MatchString(req.URL.Path)
    }
    
    func (p *TLSAuthACL) matchCN(req *http.Request) bool {
    	for _, cert := range req.TLS.PeerCertificates {
    		if p.cnRx.MatchString(cert.Subject.CommonName) {
    			return true
    		}
    	}
    	return false
    }
    
    // TLSAuthACLListFlag is a convenience type that allows callers to use
    // the 'flag' package to specify a list of TLSAuthACL objects. It
    // implements the flag.Value interface.
    type TLSAuthACLListFlag []*TLSAuthACL
    
    func (l TLSAuthACLListFlag) String() string {
    	var out []string
    	for _, acl := range l {
    		out = append(out, fmt.Sprintf("%s:%s", acl.Path, acl.CommonName))
    	}
    	return strings.Join(out, ",")
    }
    
    func (l *TLSAuthACLListFlag) Set(value string) error {
    	parts := strings.SplitN(value, ":", 2)
    	if len(parts) != 2 {
    		return errors.New("bad acl format")
    	}
    	*l = append(*l, &TLSAuthACL{
    		Path:       parts[0],
    		CommonName: parts[1],
    	})