hysteria/app/auth/external.go
2022-11-24 00:22:44 -08:00

97 lines
2.2 KiB
Go

package auth
import (
"bytes"
"encoding/json"
"io/ioutil"
"net"
"net/http"
"os/exec"
"strconv"
"strings"
"github.com/sirupsen/logrus"
)
type CmdAuthProvider struct {
Cmd string
}
func (p *CmdAuthProvider) Auth(addr net.Addr, auth []byte, sSend uint64, sRecv uint64) (bool, string) {
cmd := exec.Command(p.Cmd, addr.String(), string(auth), strconv.Itoa(int(sSend)), strconv.Itoa(int(sRecv)))
out, err := cmd.Output()
if err != nil {
if _, ok := err.(*exec.ExitError); ok {
return false, strings.TrimSpace(string(out))
} else {
logrus.WithFields(logrus.Fields{
"error": err,
}).Error("Failed to execute auth command")
return false, "internal error"
}
} else {
return true, strings.TrimSpace(string(out))
}
}
type HTTPAuthProvider struct {
Client *http.Client
URL string
}
type authReq struct {
Addr string `json:"addr"`
Payload []byte `json:"payload"`
Send uint64 `json:"send"`
Recv uint64 `json:"recv"`
}
type authResp struct {
OK bool `json:"ok"`
Msg string `json:"msg"`
}
func (p *HTTPAuthProvider) Auth(addr net.Addr, auth []byte, sSend uint64, sRecv uint64) (bool, string) {
jbs, err := json.Marshal(&authReq{
Addr: addr.String(),
Payload: auth,
Send: sSend,
Recv: sRecv,
})
if err != nil {
logrus.WithFields(logrus.Fields{
"error": err,
}).Error("Failed to marshal auth request")
return false, "internal error"
}
resp, err := p.Client.Post(p.URL, "application/json", bytes.NewBuffer(jbs))
if err != nil {
logrus.WithFields(logrus.Fields{
"error": err,
}).Error("Failed to send auth request")
return false, "internal error"
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
logrus.WithFields(logrus.Fields{
"code": resp.StatusCode,
}).Error("Invalid status code from auth server")
return false, "internal error"
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
logrus.WithFields(logrus.Fields{
"error": err,
}).Error("Failed to read auth response")
return false, "internal error"
}
var ar authResp
err = json.Unmarshal(data, &ar)
if err != nil {
logrus.WithFields(logrus.Fields{
"error": err,
}).Error("Failed to unmarshal auth response")
return false, "internal error"
}
return ar.OK, ar.Msg
}