protocol

package
v2.0.10+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2020 License: GPL-3.0 Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TUNNEL_PROTOCOL_SSH                              = "SSH"
	TUNNEL_PROTOCOL_OBFUSCATED_SSH                   = "OSSH"
	TUNNEL_PROTOCOL_UNFRONTED_MEEK                   = "UNFRONTED-MEEK-OSSH"
	TUNNEL_PROTOCOL_UNFRONTED_MEEK_HTTPS             = "UNFRONTED-MEEK-HTTPS-OSSH"
	TUNNEL_PROTOCOL_UNFRONTED_MEEK_SESSION_TICKET    = "UNFRONTED-MEEK-SESSION-TICKET-OSSH"
	TUNNEL_PROTOCOL_FRONTED_MEEK                     = "FRONTED-MEEK-OSSH"
	TUNNEL_PROTOCOL_FRONTED_MEEK_HTTP                = "FRONTED-MEEK-HTTP-OSSH"
	TUNNEL_PROTOCOL_QUIC_OBFUSCATED_SSH              = "QUIC-OSSH"
	TUNNEL_PROTOCOL_FRONTED_MEEK_QUIC_OBFUSCATED_SSH = "FRONTED-MEEK-QUIC-OSSH"
	TUNNEL_PROTOCOL_MARIONETTE_OBFUSCATED_SSH        = "MARIONETTE-OSSH"
	TUNNEL_PROTOCOL_TAPDANCE_OBFUSCATED_SSH          = "TAPDANCE-OSSH"
	TUNNEL_PROTOCOL_CONJOUR_OBFUSCATED_SSH           = "CONJOUR-OSSH"

	SERVER_ENTRY_SOURCE_EMBEDDED   = "EMBEDDED"
	SERVER_ENTRY_SOURCE_REMOTE     = "REMOTE"
	SERVER_ENTRY_SOURCE_DISCOVERY  = "DISCOVERY"
	SERVER_ENTRY_SOURCE_TARGET     = "TARGET"
	SERVER_ENTRY_SOURCE_OBFUSCATED = "OBFUSCATED"
	SERVER_ENTRY_SOURCE_EXCHANGED  = "EXCHANGED"

	CAPABILITY_SSH_API_REQUESTS            = "ssh-api-requests"
	CAPABILITY_UNTUNNELED_WEB_API_REQUESTS = "handshake"

	CLIENT_CAPABILITY_SERVER_REQUESTS = "server-requests"

	PSIPHON_API_HANDSHAKE_REQUEST_NAME = "psiphon-handshake"
	PSIPHON_API_CONNECTED_REQUEST_NAME = "psiphon-connected"
	PSIPHON_API_STATUS_REQUEST_NAME    = "psiphon-status"
	PSIPHON_API_OSL_REQUEST_NAME       = "psiphon-osl"

	// PSIPHON_API_CLIENT_VERIFICATION_REQUEST_NAME may still be used by older Android clients
	PSIPHON_API_CLIENT_VERIFICATION_REQUEST_NAME = "psiphon-client-verification"

	PSIPHON_API_CLIENT_SESSION_ID_LENGTH = 16

	PSIPHON_SSH_API_PROTOCOL = "ssh"
	PSIPHON_WEB_API_PROTOCOL = "web"

	PACKET_TUNNEL_CHANNEL_TYPE = "tun@psiphon.ca"
	RANDOM_STREAM_CHANNEL_TYPE = "random@psiphon.ca"

	PSIPHON_API_HANDSHAKE_AUTHORIZATIONS = "authorizations"
)
View Source
const (
	TLS_VERSION_12 = "TLSv1.2"
	TLS_VERSION_13 = "TLSv1.3"

	TLS_PROFILE_IOS_111    = "iOS-11.1"
	TLS_PROFILE_IOS_121    = "iOS-12.1"
	TLS_PROFILE_CHROME_58  = "Chrome-58"
	TLS_PROFILE_CHROME_62  = "Chrome-62"
	TLS_PROFILE_CHROME_70  = "Chrome-70"
	TLS_PROFILE_CHROME_72  = "Chrome-72"
	TLS_PROFILE_FIREFOX_55 = "Firefox-55"
	TLS_PROFILE_FIREFOX_56 = "Firefox-56"
	TLS_PROFILE_FIREFOX_65 = "Firefox-65"
	TLS_PROFILE_RANDOMIZED = "Randomized-v2"
)
View Source
const (
	QUIC_VERSION_GQUIC39      = "gQUICv39"
	QUIC_VERSION_GQUIC43      = "gQUICv43"
	QUIC_VERSION_GQUIC44      = "gQUICv44"
	QUIC_VERSION_OBFUSCATED   = "OBFUSCATED"
	QUIC_VERSION_IETF_DRAFT24 = "IETF-draft-24"
)

Variables

Functions

func DeriveSSHServerKEXPRNGSeed

func DeriveSSHServerKEXPRNGSeed(obfuscatedKey string) (*prng.Seed, error)

func DeriveSSHServerVersionPRNGSeed

func DeriveSSHServerVersionPRNGSeed(obfuscatedKey string) (*prng.Seed, error)

func EncodeServerEntry

func EncodeServerEntry(serverEntry *ServerEntry) (string, error)

EncodeServerEntry returns a string containing the encoding of a ServerEntry following Psiphon conventions.

func EncodeServerEntryFields

func EncodeServerEntryFields(serverEntryFields ServerEntryFields) (string, error)

EncodeServerEntryFields returns a string containing the encoding of ServerEntryFields following Psiphon conventions.

func GenerateServerEntryTag

func GenerateServerEntryTag(ipAddress, webServerSecret string) string

GenerateServerEntryTag creates a server entry tag value that is cryptographically derived from the IP address and web server secret in a way that is difficult to reverse the IP address value from the tag or compute the tag without having the web server secret, a 256-bit random value which is unique per server, in addition to the IP address. A database consisting only of server entry tags should be resistent to an attack that attempts to reverse all the server IPs, even given a small IP space (IPv4), or some subset of the web server secrets.

func GetCapability

func GetCapability(protocol string) string

GetCapability returns the server capability corresponding to the tunnel protocol.

func GetTacticsCapability added in v1.0.5

func GetTacticsCapability(protocol string) string

GetTacticsCapability returns the server tactics capability corresponding to the tunnel protocol.

func NewServerEntrySignatureKeyPair

func NewServerEntrySignatureKeyPair() (string, string, error)

NewServerEntrySignatureKeyPair creates an ed25519 key pair for use in server entry signing and verification.

func QUICVersionIsObfuscated added in v1.0.10

func QUICVersionIsObfuscated(version string) bool

func TLSProfileIsRandomized added in v1.0.10

func TLSProfileIsRandomized(tlsProfile string) bool

func TagToDiagnosticID

func TagToDiagnosticID(tag string) string

TagToDiagnosticID returns a prefix of the server entry tag that should be sufficient to uniquely identify servers in diagnostics, while also being more human readable than emitting the full tag. The tag is used as the base of the diagnostic ID as it doesn't leak the server IP address in diagnostic output.

func TunnelProtocolIsCompatibleWithFragmentor

func TunnelProtocolIsCompatibleWithFragmentor(protocol string) bool

func TunnelProtocolIsResourceIntensive added in v1.0.7

func TunnelProtocolIsResourceIntensive(protocol string) bool

func TunnelProtocolUsesDarkDecoys

func TunnelProtocolUsesDarkDecoys(protocol string) bool

func TunnelProtocolUsesFrontedMeek added in v1.0.10

func TunnelProtocolUsesFrontedMeek(protocol string) bool

func TunnelProtocolUsesFrontedMeekQUIC

func TunnelProtocolUsesFrontedMeekQUIC(protocol string) bool

func TunnelProtocolUsesMarionette added in v1.0.9

func TunnelProtocolUsesMarionette(protocol string) bool

func TunnelProtocolUsesMeek added in v1.0.5

func TunnelProtocolUsesMeek(protocol string) bool

func TunnelProtocolUsesMeekHTTP

func TunnelProtocolUsesMeekHTTP(protocol string) bool

func TunnelProtocolUsesMeekHTTPS

func TunnelProtocolUsesMeekHTTPS(protocol string) bool

func TunnelProtocolUsesObfuscatedSSH

func TunnelProtocolUsesObfuscatedSSH(protocol string) bool

func TunnelProtocolUsesObfuscatedSessionTickets

func TunnelProtocolUsesObfuscatedSessionTickets(protocol string) bool

func TunnelProtocolUsesQUIC added in v1.0.7

func TunnelProtocolUsesQUIC(protocol string) bool

func TunnelProtocolUsesSSH

func TunnelProtocolUsesSSH(protocol string) bool

func TunnelProtocolUsesTapdance added in v1.0.9

func TunnelProtocolUsesTapdance(protocol string) bool

func UseClientTunnelProtocol

func UseClientTunnelProtocol(
	clientProtocol string,
	serverProtocols TunnelProtocols) bool

func ValidateServerEntryFields added in v1.0.7

func ValidateServerEntryFields(serverEntryFields ServerEntryFields) error

ValidateServerEntryFields checks for malformed server entries.

Types

type ConditionallyEnabledComponents

type ConditionallyEnabledComponents interface {
	QUICEnabled() bool
	MarionetteEnabled() bool
	TapdanceEnabled() bool
}

ConditionallyEnabledComponents defines an interface which can be queried to determine which conditionally compiled protocol components are present.

type ConnectedResponse

type ConnectedResponse struct {
	ConnectedTimestamp string `json:"connected_timestamp"`
	Padding            string `json:"padding"`
}

type CustomTLSProfile

type CustomTLSProfile struct {
	Name     string
	UTLSSpec *UTLSSpec
}

CustomTLSProfile specifies custom TLS profile. This is used to deploy custom ClientHellos as tactics data.

func (*CustomTLSProfile) GetClientHelloSpec

func (profile *CustomTLSProfile) GetClientHelloSpec() (*utls.ClientHelloSpec, error)

GetClientHelloSpec creates a new utls.ClientHelloSpec from the ClientHello definition in UTLSpec.

A new utls.ClientHelloSpec, with no shared data, is created for each call, as per: https://github.com/refraction-networking/utls/blob/4da67951864128358459681399dd208c49d5d001/u_parrots.go#L483

type CustomTLSProfiles

type CustomTLSProfiles []*CustomTLSProfile

func (CustomTLSProfiles) Validate

func (profiles CustomTLSProfiles) Validate() error

Validate checks that the profiles in CustomTLSProfiles are initialized and have no name conflicts.

type HandshakeResponse

type HandshakeResponse struct {
	SSHSessionID           string              `json:"ssh_session_id"`
	Homepages              []string            `json:"homepages"`
	UpgradeClientVersion   string              `json:"upgrade_client_version"`
	PageViewRegexes        []map[string]string `json:"page_view_regexes"`
	HttpsRequestRegexes    []map[string]string `json:"https_request_regexes"`
	EncodedServerList      []string            `json:"encoded_server_list"`
	ClientRegion           string              `json:"client_region"`
	ServerTimestamp        string              `json:"server_timestamp"`
	ActiveAuthorizationIDs []string            `json:"active_authorization_ids"`
	TacticsPayload         json.RawMessage     `json:"tactics_payload"`
	Padding                string              `json:"padding"`
}

type MeekCookieData

type MeekCookieData struct {
	MeekProtocolVersion  int    `json:"v"`
	ClientTunnelProtocol string `json:"t"`
	EndPoint             string `json:"e"`
}

type OSLRequest

type OSLRequest struct {
	ClearLocalSLOKs bool             `json:"clear_local_sloks"`
	SeedPayload     *osl.SeedPayload `json:"seed_payload"`
}

type QUICVersions added in v1.0.9

type QUICVersions []string

func (QUICVersions) PruneInvalid added in v1.0.9

func (versions QUICVersions) PruneInvalid() QUICVersions

func (QUICVersions) Validate added in v1.0.9

func (versions QUICVersions) Validate() error

type RandomStreamRequest added in v1.0.9

type RandomStreamRequest struct {
	UpstreamBytes   int `json:"u"`
	DownstreamBytes int `json:"d"`
}

type SSHPasswordPayload

type SSHPasswordPayload struct {
	SessionId          string   `json:"SessionId"`
	SshPassword        string   `json:"SshPassword"`
	ClientCapabilities []string `json:"ClientCapabilities"`
}

type ServerEntry

type ServerEntry struct {
	Tag                           string   `json:"tag"`
	IpAddress                     string   `json:"ipAddress"`
	WebServerPort                 string   `json:"webServerPort"` // not an int
	WebServerSecret               string   `json:"webServerSecret"`
	WebServerCertificate          string   `json:"webServerCertificate"`
	SshPort                       int      `json:"sshPort"`
	SshUsername                   string   `json:"sshUsername"`
	SshPassword                   string   `json:"sshPassword"`
	SshHostKey                    string   `json:"sshHostKey"`
	SshObfuscatedPort             int      `json:"sshObfuscatedPort"`
	SshObfuscatedQUICPort         int      `json:"sshObfuscatedQUICPort"`
	SshObfuscatedTapdancePort     int      `json:"sshObfuscatedTapdancePort"`
	SshObfuscatedKey              string   `json:"sshObfuscatedKey"`
	Capabilities                  []string `json:"capabilities"`
	Region                        string   `json:"region"`
	MeekServerPort                int      `json:"meekServerPort"`
	MeekCookieEncryptionPublicKey string   `json:"meekCookieEncryptionPublicKey"`
	MeekObfuscatedKey             string   `json:"meekObfuscatedKey"`
	MeekFrontingHost              string   `json:"meekFrontingHost"`
	MeekFrontingHosts             []string `json:"meekFrontingHosts"`
	MeekFrontingDomain            string   `json:"meekFrontingDomain"`
	MeekFrontingAddresses         []string `json:"meekFrontingAddresses"`
	MeekFrontingAddressesRegex    string   `json:"meekFrontingAddressesRegex"`
	MeekFrontingDisableSNI        bool     `json:"meekFrontingDisableSNI"`
	TacticsRequestPublicKey       string   `json:"tacticsRequestPublicKey"`
	TacticsRequestObfuscatedKey   string   `json:"tacticsRequestObfuscatedKey"`
	MarionetteFormat              string   `json:"marionetteFormat"`
	ConfigurationVersion          int      `json:"configurationVersion"`
	Signature                     string   `json:"signature"`

	// These local fields are not expected to be present in downloaded server
	// entries. They are added by the client to record and report stats about
	// how and when server entries are obtained.
	// All local fields should be included the list of fields in RemoveUnsignedFields.
	LocalSource       string `json:"localSource,omitempty"`
	LocalTimestamp    string `json:"localTimestamp,omitempty"`
	IsLocalDerivedTag bool   `json:"isLocalDerivedTag,omitempty"`
}

ServerEntry represents a Psiphon server. It contains information about how to establish a tunnel connection to the server through several protocols. Server entries are JSON records downloaded from various sources.

func DecodeServerEntry

func DecodeServerEntry(
	encodedServerEntry, timestamp, serverEntrySource string) (*ServerEntry, error)

DecodeServerEntry extracts a server entry from the encoding used by remote server lists and Psiphon server handshake requests.

The resulting ServerEntry.LocalSource is populated with serverEntrySource, which should be one of SERVER_ENTRY_SOURCE_EMBEDDED, SERVER_ENTRY_SOURCE_REMOTE, SERVER_ENTRY_SOURCE_DISCOVERY, SERVER_ENTRY_SOURCE_TARGET, SERVER_ENTRY_SOURCE_OBFUSCATED. ServerEntry.LocalTimestamp is populated with the provided timestamp, which should be a RFC 3339 formatted string. These local fields are stored with the server entry and reported to the server as stats (a coarse granularity timestamp is reported).

func (*ServerEntry) GetDiagnosticID

func (serverEntry *ServerEntry) GetDiagnosticID() string

func (*ServerEntry) GetSupportedProtocols

func (serverEntry *ServerEntry) GetSupportedProtocols(
	conditionallyEnabled ConditionallyEnabledComponents,
	useUpstreamProxy bool,
	limitTunnelProtocols []string,
	excludeIntensive bool) []string

GetSupportedProtocols returns a list of tunnel protocols supported by the ServerEntry's capabilities.

func (*ServerEntry) GetSupportedTacticsProtocols added in v1.0.5

func (serverEntry *ServerEntry) GetSupportedTacticsProtocols() []string

GetSupportedTacticsProtocols returns a list of tunnel protocols, supported by the ServerEntry's capabilities, that may be used for tactics requests.

func (*ServerEntry) GetUntunneledWebRequestPorts

func (serverEntry *ServerEntry) GetUntunneledWebRequestPorts() []string

func (*ServerEntry) HasSignature

func (serverEntry *ServerEntry) HasSignature() bool

func (*ServerEntry) SupportsProtocol

func (serverEntry *ServerEntry) SupportsProtocol(protocol string) bool

SupportsProtocol returns true if and only if the ServerEntry has the necessary capability to support the specified tunnel protocol.

func (*ServerEntry) SupportsSSHAPIRequests

func (serverEntry *ServerEntry) SupportsSSHAPIRequests() bool

SupportsSSHAPIRequests returns true when the server supports SSH API requests.

type ServerEntryFields added in v1.0.7

type ServerEntryFields map[string]interface{}

ServerEntryFields is an alternate representation of ServerEntry which enables future compatibility when unmarshaling and persisting new server entries which may contain new, unrecognized fields not in the ServerEntry type for a particular client version.

When new JSON server entries with new fields are unmarshaled to ServerEntry types, unrecognized fields are discarded. When unmarshaled to ServerEntryFields, unrecognized fields are retained and may be persisted and available when the client is upgraded and unmarshals to an updated ServerEntry type.

func DecodeServerEntryFields added in v1.0.7

func DecodeServerEntryFields(
	encodedServerEntry, timestamp, serverEntrySource string) (ServerEntryFields, error)

DecodeServerEntryFields extracts an encoded server entry into a ServerEntryFields type, much like DecodeServerEntry. Unrecognized fields not in ServerEntry are retained in the ServerEntryFields.

LocalSource/LocalTimestamp map entries are set only when the corresponding inputs are non-blank.

func DecodeServerEntryList added in v1.0.5

func DecodeServerEntryList(
	encodedServerEntryList, timestamp,
	serverEntrySource string) ([]ServerEntryFields, error)

DecodeServerEntryList extracts server entries from the list encoding used by remote server lists and Psiphon server handshake requests. Each server entry is validated and invalid entries are skipped. See DecodeServerEntry for note on serverEntrySource/timestamp.

func (ServerEntryFields) AddSignature

func (fields ServerEntryFields) AddSignature(publicKey, privateKey string) error

AddSignature signs a server entry and attaches a new field containing the signature. Any existing "signature" field will be replaced.

The signature incudes a public key ID that is derived from a digest of the public key value. This ID is intended for future use when multiple signing keys may be deployed.

func (ServerEntryFields) GetConfigurationVersion added in v1.0.7

func (fields ServerEntryFields) GetConfigurationVersion() int

func (ServerEntryFields) GetDiagnosticID

func (fields ServerEntryFields) GetDiagnosticID() string

func (ServerEntryFields) GetIPAddress added in v1.0.7

func (fields ServerEntryFields) GetIPAddress() string

func (ServerEntryFields) GetLocalSource

func (fields ServerEntryFields) GetLocalSource() string

func (ServerEntryFields) GetLocalTimestamp

func (fields ServerEntryFields) GetLocalTimestamp() string

func (ServerEntryFields) GetServerEntry

func (fields ServerEntryFields) GetServerEntry() (*ServerEntry, error)

GetServerEntry converts a ServerEntryFields into a ServerEntry.

func (ServerEntryFields) GetTag

func (fields ServerEntryFields) GetTag() string

func (ServerEntryFields) GetWebServerCertificate

func (fields ServerEntryFields) GetWebServerCertificate() string

func (ServerEntryFields) GetWebServerPort

func (fields ServerEntryFields) GetWebServerPort() string

func (ServerEntryFields) GetWebServerSecret

func (fields ServerEntryFields) GetWebServerSecret() string

func (ServerEntryFields) HasSignature

func (fields ServerEntryFields) HasSignature() bool

func (ServerEntryFields) RemoveUnsignedFields

func (fields ServerEntryFields) RemoveUnsignedFields()

RemoveUnsignedFields prepares a server entry for signing or signature verification by removing unsigned fields. The JSON marshalling of the remaining fields is the data that is signed.

func (ServerEntryFields) SetLocalSource added in v1.0.7

func (fields ServerEntryFields) SetLocalSource(source string)

func (ServerEntryFields) SetLocalTimestamp added in v1.0.7

func (fields ServerEntryFields) SetLocalTimestamp(timestamp string)

func (ServerEntryFields) SetTag

func (fields ServerEntryFields) SetTag(tag string)

SetTag sets a local, derived server entry tag. A tag is an identifier used in server entry pruning and potentially other use cases. An explict tag, set by the Psiphon Network, may be present in a server entry that is imported; otherwise, the client will set a derived tag. The tag should be generated using GenerateServerEntryTag. When SetTag finds a explicit tag, the new, derived tag is ignored. The isLocalTag local field is set to distinguish explict and derived tags and is used in signature verification to determine if the tag field is part of the signature.

func (ServerEntryFields) VerifySignature

func (fields ServerEntryFields) VerifySignature(publicKey string) error

VerifySignature verifies the signature set by AddSignature.

VerifySignature must be called before using any server entry that is imported from an untrusted source, such as client-to-client exchange.

type StatusResponse

type StatusResponse struct {
	InvalidServerEntryTags []string `json:"invalid_server_entry_tags"`
	Padding                string   `json:"padding"`
}

type StreamingServerEntryDecoder added in v1.0.5

type StreamingServerEntryDecoder struct {
	// contains filtered or unexported fields
}

StreamingServerEntryDecoder performs the DecodeServerEntryList operation, loading only one server entry into memory at a time.

func NewStreamingServerEntryDecoder added in v1.0.5

func NewStreamingServerEntryDecoder(
	encodedServerEntryListReader io.Reader,
	timestamp, serverEntrySource string) *StreamingServerEntryDecoder

NewStreamingServerEntryDecoder creates a new StreamingServerEntryDecoder.

func (*StreamingServerEntryDecoder) Next added in v1.0.5

Next reads and decodes, and validates the next server entry from the input stream, returning a nil server entry when the stream is complete.

Limitations:

  • Each encoded server entry line cannot exceed bufio.MaxScanTokenSize, the default buffer size which this decoder uses. This is 64K.
  • DecodeServerEntry is called on each encoded server entry line, which will allocate memory to hex decode and JSON deserialze the server entry. As this is not presently reusing a fixed buffer, each call will allocate additional memory; garbage collection is necessary to reclaim that memory for reuse for the next server entry.

type TLSProfiles added in v1.0.5

type TLSProfiles []string

func (TLSProfiles) PruneInvalid added in v1.0.7

func (profiles TLSProfiles) PruneInvalid() TLSProfiles

func (TLSProfiles) Validate added in v1.0.5

func (profiles TLSProfiles) Validate() error

type TunnelProtocols added in v1.0.5

type TunnelProtocols []string

func (TunnelProtocols) PruneInvalid added in v1.0.7

func (t TunnelProtocols) PruneInvalid() TunnelProtocols

func (TunnelProtocols) Validate added in v1.0.5

func (t TunnelProtocols) Validate() error

type UTLSExtension

type UTLSExtension struct {
	Name string
	Data json.RawMessage
}

UTLSExtension specifies one of the several utls.TLSExtension concrete implementations.

func (*UTLSExtension) GetUTLSExtension

func (e *UTLSExtension) GetUTLSExtension() (utls.TLSExtension, error)

GetUTLSExtension instantiates the specified utls.TLSExtension concrete implementation.

type UTLSSpec

type UTLSSpec struct {
	TLSVersMin         uint16
	TLSVersMax         uint16
	CipherSuites       []uint16
	CompressionMethods []uint8
	Extensions         []*UTLSExtension
	GetSessionID       string
}

UTLSSpec specifies a utls.ClientHelloSpec.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL