55 lines
1.3 KiB
Go
55 lines
1.3 KiB
Go
package rep
|
|
|
|
import (
|
|
"crypto/subtle"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.crumpington.com/public/jldb/lib/httpconn"
|
|
)
|
|
|
|
func (rep *Replicator) handlerLogf(pattern string, args ...any) {
|
|
log.Printf("[HTTP-HANDLER] "+pattern, args...)
|
|
}
|
|
|
|
// checkBasicAuth tests whether the caller has provided the appropriate basic auth
|
|
// header. The caller should provide the PSK as the basic-auth password.
|
|
func (rep *Replicator) checkBasicAuth(w http.ResponseWriter, r *http.Request) bool {
|
|
_, pwd, _ := r.BasicAuth()
|
|
if subtle.ConstantTimeCompare([]byte(pwd), rep.pskBytes[:]) != 1 {
|
|
rep.handlerLogf("PSK mismatch.")
|
|
http.Error(w, "not authorized", http.StatusUnauthorized)
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// acceptConnect accepts a CONNECT request and checks the PSK.
|
|
func (rep *Replicator) acceptConnect(w http.ResponseWriter, r *http.Request) net.Conn {
|
|
conn, err := httpconn.Accept(w, r)
|
|
if err != nil {
|
|
rep.handlerLogf("Failed to accept connection: %s", err)
|
|
return nil
|
|
}
|
|
|
|
psk := [64]byte{}
|
|
|
|
conn.SetReadDeadline(time.Now().Add(rep.conf.NetTimeout))
|
|
if _, err := io.ReadFull(conn, psk[:]); err != nil {
|
|
conn.Close()
|
|
rep.handlerLogf("Failed to read PSK: %v", err)
|
|
return nil
|
|
}
|
|
|
|
if subtle.ConstantTimeCompare(psk[:], rep.pskBytes[:]) != 1 {
|
|
conn.Close()
|
|
rep.handlerLogf("PSK mismatch.")
|
|
return nil
|
|
}
|
|
|
|
return conn
|
|
}
|