2022-08-24 12:33:10 +00:00
|
|
|
package supervisor
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"crypto/tls"
|
|
|
|
"encoding/json"
|
2023-08-25 13:39:25 +00:00
|
|
|
"fmt"
|
2022-08-24 12:33:10 +00:00
|
|
|
"net/http"
|
|
|
|
"sync"
|
2023-08-25 13:39:25 +00:00
|
|
|
|
|
|
|
"github.com/cloudflare/cloudflared/features"
|
2022-08-24 12:33:10 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// When experimental post-quantum tunnels are enabled, and we're hitting an
|
|
|
|
// issue creating the tunnel, we'll report the first error
|
|
|
|
// to https://pqtunnels.cloudflareresearch.com.
|
|
|
|
|
2023-08-22 14:47:33 +00:00
|
|
|
const (
|
|
|
|
PQKex = tls.CurveID(0xfe31) // X25519Kyber768Draft00
|
|
|
|
PQKexName = "X25519Kyber768Draft00"
|
|
|
|
)
|
2022-08-24 12:33:10 +00:00
|
|
|
|
2023-08-22 14:47:33 +00:00
|
|
|
var (
|
2022-08-24 12:33:10 +00:00
|
|
|
pqtMux sync.Mutex // protects pqtSubmitted and pqtWaitForMessage
|
|
|
|
pqtSubmitted bool // whether an error has already been submitted
|
|
|
|
|
|
|
|
// Number of errors to ignore before printing elaborate instructions.
|
|
|
|
pqtWaitForMessage int
|
|
|
|
)
|
|
|
|
|
|
|
|
func handlePQTunnelError(rep error, config *TunnelConfig) {
|
|
|
|
needToMessage := false
|
|
|
|
|
|
|
|
pqtMux.Lock()
|
|
|
|
needToSubmit := !pqtSubmitted
|
|
|
|
if needToSubmit {
|
|
|
|
pqtSubmitted = true
|
|
|
|
}
|
|
|
|
pqtWaitForMessage--
|
|
|
|
if pqtWaitForMessage < 0 {
|
|
|
|
pqtWaitForMessage = 5
|
|
|
|
needToMessage = true
|
|
|
|
}
|
|
|
|
pqtMux.Unlock()
|
|
|
|
|
|
|
|
if needToMessage {
|
|
|
|
config.Log.Info().Msgf(
|
|
|
|
"\n\n" +
|
|
|
|
"===================================================================================\n" +
|
|
|
|
"You are hitting an error while using the experimental post-quantum tunnels feature.\n" +
|
|
|
|
"\n" +
|
|
|
|
"Please check:\n" +
|
|
|
|
"\n" +
|
|
|
|
" https://pqtunnels.cloudflareresearch.com\n" +
|
|
|
|
"\n" +
|
|
|
|
"for known problems.\n" +
|
|
|
|
"===================================================================================\n\n",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if needToSubmit {
|
|
|
|
go submitPQTunnelError(rep, config)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func submitPQTunnelError(rep error, config *TunnelConfig) {
|
|
|
|
body, err := json.Marshal(struct {
|
|
|
|
Group int `json:"g"`
|
|
|
|
Message string `json:"m"`
|
|
|
|
Version string `json:"v"`
|
|
|
|
}{
|
2023-08-22 14:47:33 +00:00
|
|
|
Group: int(PQKex),
|
2022-08-24 12:33:10 +00:00
|
|
|
Message: rep.Error(),
|
|
|
|
Version: config.ReportedVersion,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
config.Log.Err(err).Msg("Failed to create error report")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := http.Post(
|
|
|
|
"https://pqtunnels.cloudflareresearch.com",
|
|
|
|
"application/json",
|
|
|
|
bytes.NewBuffer(body),
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
config.Log.Err(err).Msg(
|
|
|
|
"Failed to submit post-quantum tunnel error report",
|
|
|
|
)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if resp.StatusCode != 200 {
|
|
|
|
config.Log.Error().Msgf(
|
|
|
|
"Failed to submit post-quantum tunnel error report: status %d",
|
|
|
|
resp.StatusCode,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
resp.Body.Close()
|
|
|
|
}
|
2023-08-25 13:39:25 +00:00
|
|
|
|
|
|
|
func curvePreference(pqMode features.PostQuantumMode, currentCurve []tls.CurveID) ([]tls.CurveID, error) {
|
|
|
|
switch pqMode {
|
|
|
|
case features.PostQuantumStrict:
|
|
|
|
// If the user passes the -post-quantum flag, we override
|
|
|
|
// CurvePreferences to only support hybrid post-quantum key agreements.
|
|
|
|
return []tls.CurveID{PQKex}, nil
|
|
|
|
case features.PostQuantumPrefer:
|
|
|
|
if len(currentCurve) == 0 {
|
|
|
|
return []tls.CurveID{PQKex}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if currentCurve[0] != PQKex {
|
|
|
|
return append([]tls.CurveID{PQKex}, currentCurve...), nil
|
|
|
|
}
|
|
|
|
return currentCurve, nil
|
|
|
|
case features.PostQuantumDisabled:
|
|
|
|
curvePref := currentCurve
|
|
|
|
// Remove PQ from curve preference
|
|
|
|
for i, curve := range currentCurve {
|
|
|
|
if curve == PQKex {
|
|
|
|
curvePref = append(curvePref[:i], curvePref[i+1:]...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return curvePref, nil
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("Unexpected post quantum mode")
|
|
|
|
}
|
|
|
|
}
|