mirror of
https://git.sr.ht/~adnano/go-gemini
synced 2024-11-10 00:32:11 +01:00
Reject invalid status codes
This commit is contained in:
parent
cafc19aed7
commit
c548e8baa8
25
client.go
25
client.go
@ -15,11 +15,11 @@ import (
|
||||
|
||||
// Client errors.
|
||||
var (
|
||||
ErrProtocol = errors.New("gemini: protocol error")
|
||||
ErrInvalidURL = errors.New("gemini: requested URL is invalid")
|
||||
ErrCertificateNotValid = errors.New("gemini: certificate is invalid")
|
||||
ErrInvalidURL = errors.New("gemini: invalid URL")
|
||||
ErrInvalidResponse = errors.New("gemini: invalid response")
|
||||
ErrInvalidCertificate = errors.New("gemini: invalid certificate")
|
||||
ErrUnknownCertificate = errors.New("gemini: unknown certificate")
|
||||
ErrCertificateNotTrusted = errors.New("gemini: certificate is not trusted")
|
||||
ErrCertificateUnknown = errors.New("gemini: certificate is unknown")
|
||||
)
|
||||
|
||||
// Request represents a Gemini request.
|
||||
@ -133,11 +133,18 @@ func (resp *Response) read(r *bufio.Reader) error {
|
||||
}
|
||||
resp.Status = status
|
||||
|
||||
// Disregard invalid status codes
|
||||
const minStatus, maxStatus = 1, 6
|
||||
statusClass := status / 10
|
||||
if statusClass < minStatus || statusClass > maxStatus {
|
||||
return ErrInvalidResponse
|
||||
}
|
||||
|
||||
// Read one space
|
||||
if b, err := r.ReadByte(); err != nil {
|
||||
return err
|
||||
} else if b != ' ' {
|
||||
return ErrProtocol
|
||||
return ErrInvalidResponse
|
||||
}
|
||||
|
||||
// Read the meta
|
||||
@ -149,7 +156,7 @@ func (resp *Response) read(r *bufio.Reader) error {
|
||||
meta = meta[:len(meta)-1]
|
||||
// Ensure meta is less than or equal to 1024 bytes
|
||||
if len(meta) > 1024 {
|
||||
return ErrProtocol
|
||||
return ErrInvalidResponse
|
||||
}
|
||||
resp.Meta = meta
|
||||
|
||||
@ -157,7 +164,7 @@ func (resp *Response) read(r *bufio.Reader) error {
|
||||
if b, err := r.ReadByte(); err != nil {
|
||||
return err
|
||||
} else if b != '\n' {
|
||||
return ErrProtocol
|
||||
return ErrInvalidResponse
|
||||
}
|
||||
|
||||
// Read response body
|
||||
@ -244,11 +251,11 @@ func (c *Client) Send(req *Request) (*Response, error) {
|
||||
// Read the response
|
||||
resp := &Response{}
|
||||
r := bufio.NewReader(conn)
|
||||
// Store connection information
|
||||
resp.TLS = conn.ConnectionState()
|
||||
if err := resp.read(r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Store connection information
|
||||
resp.TLS = conn.ConnectionState()
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ func main() {
|
||||
// To generate a TLS key pair, run:
|
||||
//
|
||||
// go run -tags=example ../cert
|
||||
//
|
||||
cert, err := tls.LoadX509KeyPair("examples/client/localhost.crt", "examples/client/localhost.key")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -28,7 +28,7 @@ func init() {
|
||||
// Alert the user that the certificate is not trusted
|
||||
fmt.Printf("Warning: Certificate for %s is not trusted!\n", hostname)
|
||||
fmt.Println("This could indicate a Man-in-the-Middle attack.")
|
||||
case gemini.ErrCertificateUnknown:
|
||||
case gemini.ErrUnknownCertificate:
|
||||
// Prompt the user to trust the certificate
|
||||
trust := trustCertificate(cert)
|
||||
switch trust {
|
||||
|
@ -14,6 +14,7 @@ func main() {
|
||||
// To generate a TLS key pair, run:
|
||||
//
|
||||
// go run -tags=example ../cert
|
||||
//
|
||||
cert, err := tls.LoadX509KeyPair("examples/server/localhost.crt", "examples/server/localhost.key")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
4
tofu.go
4
tofu.go
@ -79,7 +79,7 @@ func (k *KnownHosts) AddTemporary(hostname string, cert *x509.Certificate) {
|
||||
// Lookup looks for the provided certificate in the list of known hosts.
|
||||
// If the hostname is in the list, but the fingerprint differs,
|
||||
// Lookup returns ErrCertificateNotTrusted.
|
||||
// If the hostname is not in the list, Lookup returns ErrCertificateUnknown.
|
||||
// If the hostname is not in the list, Lookup returns ErrUnknownCertificate.
|
||||
// If the certificate is found and the fingerprint matches, error will be nil.
|
||||
func (k *KnownHosts) Lookup(hostname string, cert *x509.Certificate) error {
|
||||
now := time.Now().Unix()
|
||||
@ -99,7 +99,7 @@ func (k *KnownHosts) Lookup(hostname string, cert *x509.Certificate) error {
|
||||
// Fingerprint does not match
|
||||
return ErrCertificateNotTrusted
|
||||
}
|
||||
return ErrCertificateUnknown
|
||||
return ErrUnknownCertificate
|
||||
}
|
||||
|
||||
// Parse parses the provided reader and adds the parsed known hosts to the list.
|
||||
|
Loading…
Reference in New Issue
Block a user