mirror of
https://code.rocketnine.space/tslocum/gmitohtml.git
synced 2024-11-27 17:38:14 +01:00
Allow specifying client certificate
This commit is contained in:
parent
fb5e7f4ea4
commit
26115183a9
1 changed files with 34 additions and 2 deletions
|
@ -3,6 +3,7 @@ package gmitohtml
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
@ -14,8 +15,13 @@ import (
|
||||||
|
|
||||||
var lastRequestTime = time.Now().Unix()
|
var lastRequestTime = time.Now().Unix()
|
||||||
|
|
||||||
|
var clientCerts = make(map[string]tls.Certificate)
|
||||||
|
|
||||||
|
// ErrInvalidCertificate is the error returned when an invalid certificate is provided.
|
||||||
|
var ErrInvalidCertificate = errors.New("invalid certificate")
|
||||||
|
|
||||||
// Fetch downloads and converts a Gemini page.
|
// Fetch downloads and converts a Gemini page.
|
||||||
func fetch(u string, clientCertFile string, clientCertKey string) ([]byte, []byte, error) {
|
func fetch(u string) ([]byte, []byte, error) {
|
||||||
if u == "" {
|
if u == "" {
|
||||||
return nil, nil, ErrInvalidURL
|
return nil, nil, ErrInvalidURL
|
||||||
}
|
}
|
||||||
|
@ -39,6 +45,16 @@ func fetch(u string, clientCertFile string, clientCertKey string) ([]byte, []byt
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
certHost := requestURL.Hostname()
|
||||||
|
if strings.HasPrefix(certHost, "www.") {
|
||||||
|
certHost = certHost[4:]
|
||||||
|
}
|
||||||
|
|
||||||
|
clientCert, certAvailable := clientCerts[certHost]
|
||||||
|
if certAvailable {
|
||||||
|
tlsConfig.Certificates = []tls.Certificate{clientCert}
|
||||||
|
}
|
||||||
|
|
||||||
conn, err := tls.Dial("tcp", host, tlsConfig)
|
conn, err := tls.Dial("tcp", host, tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -153,7 +169,7 @@ func handleRequest(writer http.ResponseWriter, request *http.Request) {
|
||||||
u.RawQuery = request.URL.RawQuery
|
u.RawQuery = request.URL.RawQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
header, data, err := fetch(u.String(), "", "")
|
header, data, err := fetch(u.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(writer, "Error: failed to fetch %s: %s", u, err)
|
fmt.Fprintf(writer, "Error: failed to fetch %s: %s", u, err)
|
||||||
return
|
return
|
||||||
|
@ -205,3 +221,19 @@ func StartDaemon(address string) error {
|
||||||
func LastRequestTime() int64 {
|
func LastRequestTime() int64 {
|
||||||
return lastRequestTime
|
return lastRequestTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetClientCertificate sets the client certificate to use for a domain.
|
||||||
|
func SetClientCertificate(domain string, certificate string, privateKey string) error {
|
||||||
|
if len(certificate) == 0 || len(privateKey) == 0 {
|
||||||
|
delete(clientCerts, domain)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
clientCert, err := tls.LoadX509KeyPair(certificate, privateKey)
|
||||||
|
if err != nil {
|
||||||
|
return ErrInvalidCertificate
|
||||||
|
}
|
||||||
|
|
||||||
|
clientCerts[domain] = clientCert
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue