config.go 112 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934
  1. /*
  2. * Copyright (c) 2015, Psiphon Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. package psiphon
  20. import (
  21. "crypto/md5"
  22. "encoding/base64"
  23. "encoding/binary"
  24. "encoding/json"
  25. "fmt"
  26. "io/ioutil"
  27. "net/http"
  28. "os"
  29. "path/filepath"
  30. "reflect"
  31. "regexp"
  32. "strconv"
  33. "strings"
  34. "sync"
  35. "unicode"
  36. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
  37. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
  38. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/parameters"
  39. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/protocol"
  40. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/resolver"
  41. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/transforms"
  42. "golang.org/x/crypto/nacl/secretbox"
  43. )
  44. const (
  45. TUNNEL_POOL_SIZE = 1
  46. MAX_TUNNEL_POOL_SIZE = 32
  47. // Psiphon data directory name, relative to config.DataRootDirectory.
  48. // See config.GetPsiphonDataDirectory().
  49. PsiphonDataDirectoryName = "ca.psiphon.PsiphonTunnel.tunnel-core"
  50. // Filename constants, all relative to config.GetPsiphonDataDirectory().
  51. HomepageFilename = "homepage"
  52. NoticesFilename = "notices"
  53. OldNoticesFilename = "notices.1"
  54. UpgradeDownloadFilename = "upgrade"
  55. )
  56. // Config is the Psiphon configuration specified by the application. This
  57. // configuration controls the behavior of the core tunnel functionality.
  58. //
  59. // To distinguish omitted timeout params from explicit 0 value timeout params,
  60. // corresponding fields are int pointers. nil means no value was supplied and
  61. // to use the default; a non-nil pointer to 0 means no timeout.
  62. type Config struct {
  63. // DataRootDirectory is the directory in which to store persistent files,
  64. // which contain information such as server entries. By default, current
  65. // working directory.
  66. //
  67. // Psiphon will assume full control of files under this directory. They may
  68. // be deleted, moved or overwritten.
  69. DataRootDirectory string
  70. // UseNoticeFiles configures notice files for writing. If set, homepages
  71. // will be written to a file created at config.GetHomePageFilename()
  72. // and notices will be written to a file created at
  73. // config.GetNoticesFilename().
  74. //
  75. // The homepage file may be read after the Tunnels notice with count of 1.
  76. //
  77. // The value of UseNoticeFiles sets the size and frequency at which the
  78. // notices file, config.GetNoticesFilename(), will be rotated. See the
  79. // comment for UseNoticeFiles for more details. One rotated older file,
  80. // config.GetOldNoticesFilename(), is retained.
  81. //
  82. // The notice files may be may be read at any time; and should be opened
  83. // read-only for reading. Diagnostic notices are omitted from the notice
  84. // files.
  85. //
  86. // See comment for setNoticeFiles in notice.go for further details.
  87. UseNoticeFiles *UseNoticeFiles
  88. // PropagationChannelId is a string identifier which indicates how the
  89. // Psiphon client was distributed. This parameter is required. This value
  90. // is supplied by and depends on the Psiphon Network, and is typically
  91. // embedded in the client binary.
  92. PropagationChannelId string
  93. // SponsorId is a string identifier which indicates who is sponsoring this
  94. // Psiphon client. One purpose of this value is to determine the home
  95. // pages for display. This parameter is required. This value is supplied
  96. // by and depends on the Psiphon Network, and is typically embedded in the
  97. // client binary.
  98. SponsorId string
  99. // ClientVersion is the client version number that the client reports to
  100. // the server. The version number refers to the host client application,
  101. // not the core tunnel library. One purpose of this value is to enable
  102. // automatic updates. This value is supplied by and depends on the Psiphon
  103. // Network, and is typically embedded in the client binary.
  104. //
  105. // Note that sending a ClientPlatform string which includes "windows"
  106. // (case insensitive) and a ClientVersion of <= 44 will cause an error in
  107. // processing the response to DoConnectedRequest calls.
  108. ClientVersion string
  109. // ClientPlatform is the client platform ("Windows", "Android", etc.) that
  110. // the client reports to the server.
  111. ClientPlatform string
  112. // ClientFeatures is a list of feature names denoting enabled application
  113. // features. Clients report enabled features to the server for stats
  114. // purposes.
  115. ClientFeatures []string
  116. // EgressRegion is a ISO 3166-1 alpha-2 country code which indicates which
  117. // country to egress from. For the default, "", the best performing server
  118. // in any country is selected.
  119. EgressRegion string
  120. // SplitTunnelOwnRegion enables split tunnel mode for the client's own
  121. // country. When enabled, TCP port forward destinations that resolve to
  122. // the same GeoIP country as the client are connected to directly,
  123. // untunneled.
  124. SplitTunnelOwnRegion bool
  125. // SplitTunnelRegions enables selected split tunnel mode in which the
  126. // client specifies a list of ISO 3166-1 alpha-2 country codes for which
  127. // traffic should be untunneled. TCP port forwards destined to any
  128. // country specified in SplitTunnelRegions will be untunneled, regardless
  129. // of whether SplitTunnelOwnRegion is on or off.
  130. SplitTunnelRegions []string
  131. // ListenInterface specifies which interface to listen on. If no
  132. // interface is provided then listen on 127.0.0.1. If 'any' is provided
  133. // then use 0.0.0.0. If there are multiple IP addresses on an interface
  134. // use the first IPv4 address.
  135. ListenInterface string
  136. // DisableLocalSocksProxy disables running the local SOCKS proxy.
  137. DisableLocalSocksProxy bool
  138. // LocalSocksProxyPort specifies a port number for the local SOCKS proxy
  139. // running at 127.0.0.1. For the default value, 0, the system selects a
  140. // free port (a notice reporting the selected port is emitted).
  141. LocalSocksProxyPort int
  142. // LocalHttpProxyPort specifies a port number for the local HTTP proxy
  143. // running at 127.0.0.1. For the default value, 0, the system selects a
  144. // free port (a notice reporting the selected port is emitted).
  145. LocalHttpProxyPort int
  146. // DisableLocalHTTPProxy disables running the local HTTP proxy.
  147. DisableLocalHTTPProxy bool
  148. // NetworkLatencyMultiplier is a multiplier that is to be applied to
  149. // default network event timeouts. Set this to tune performance for
  150. // slow networks.
  151. // When set, must be >= 1.0.
  152. NetworkLatencyMultiplier float64
  153. // LimitTunnelProtocols indicates which protocols to use. Valid values
  154. // include: "SSH", "OSSH", "TLS-OSSH", "UNFRONTED-MEEK-OSSH",
  155. // "UNFRONTED-MEEK-HTTPS-OSSH", "UNFRONTED-MEEK-SESSION-TICKET-OSSH",
  156. // "FRONTED-MEEK-OSSH", "FRONTED-MEEK-HTTP-OSSH", "QUIC-OSSH",
  157. // "FRONTED-MEEK-QUIC-OSSH", "TAPDANCE-OSSH", and "CONJURE-OSSH".
  158. // For the default, an empty list, all protocols are used.
  159. LimitTunnelProtocols []string
  160. // InitialLimitTunnelProtocols is an optional initial phase of limited
  161. // protocols for the first InitialLimitTunnelProtocolsCandidateCount
  162. // candidates; after these candidates, LimitTunnelProtocols applies.
  163. //
  164. // For the default, an empty list, InitialLimitTunnelProtocols is off.
  165. InitialLimitTunnelProtocols []string
  166. // InitialLimitTunnelProtocolsCandidateCount is the number of candidates
  167. // to which InitialLimitTunnelProtocols is applied instead of
  168. // LimitTunnelProtocols.
  169. //
  170. // For the default, 0, InitialLimitTunnelProtocols is off.
  171. InitialLimitTunnelProtocolsCandidateCount int
  172. // LimitTLSProfiles indicates which TLS profiles to select from. Valid
  173. // values are listed in protocols.SupportedTLSProfiles.
  174. // For the default, an empty list, all profiles are candidates for
  175. // selection.
  176. LimitTLSProfiles []string
  177. // LimitQUICVersions indicates which QUIC versions to select from. Valid
  178. // values are listed in protocols.SupportedQUICVersions.
  179. // For the default, an empty list, all versions are candidates for
  180. // selection.
  181. LimitQUICVersions []string
  182. // EstablishTunnelTimeoutSeconds specifies a time limit after which to
  183. // halt the core tunnel controller if no tunnel has been established. The
  184. // default is parameters.EstablishTunnelTimeout.
  185. EstablishTunnelTimeoutSeconds *int
  186. // EstablishTunnelPausePeriodSeconds specifies the delay between attempts
  187. // to establish tunnels. Briefly pausing allows for network conditions to
  188. // improve and for asynchronous operations such as fetch remote server
  189. // list to complete. If omitted, a default value is used. This value is
  190. // typical overridden for testing.
  191. EstablishTunnelPausePeriodSeconds *int
  192. // EstablishTunnelPausePeriodSeconds specifies the grace period, or head
  193. // start, provided to the affinity server candidate when establishing. The
  194. // affinity server is the server used for the last established tunnel.
  195. EstablishTunnelServerAffinityGracePeriodMilliseconds *int
  196. // ConnectionWorkerPoolSize specifies how many connection attempts to
  197. // attempt in parallel. If omitted of when 0, a default is used; this is
  198. // recommended.
  199. ConnectionWorkerPoolSize int
  200. // TunnelPoolSize specifies how many tunnels to run in parallel. Port
  201. // forwards are multiplexed over multiple tunnels. If omitted or when 0,
  202. // the default is TUNNEL_POOL_SIZE, which is recommended. Any value over
  203. // MAX_TUNNEL_POOL_SIZE is treated as MAX_TUNNEL_POOL_SIZE.
  204. TunnelPoolSize int
  205. // StaggerConnectionWorkersMilliseconds adds a specified delay before
  206. // making each server candidate available to connection workers. This
  207. // option is enabled when StaggerConnectionWorkersMilliseconds > 0.
  208. StaggerConnectionWorkersMilliseconds int
  209. // LimitIntensiveConnectionWorkers limits the number of concurrent
  210. // connection workers attempting connections with resource intensive
  211. // protocols. This option is enabled when LimitIntensiveConnectionWorkers
  212. // > 0.
  213. LimitIntensiveConnectionWorkers int
  214. // LimitMeekBufferSizes selects smaller buffers for meek protocols.
  215. LimitMeekBufferSizes bool
  216. // LimitCPUThreads minimizes the number of CPU threads -- and associated
  217. // overhead -- the are used.
  218. LimitCPUThreads bool
  219. // LimitRelayBufferSizes selects smaller buffers for port forward relaying.
  220. LimitRelayBufferSizes bool
  221. // IgnoreHandshakeStatsRegexps skips compiling and using stats regexes.
  222. IgnoreHandshakeStatsRegexps bool
  223. // UpstreamProxyURL is a URL specifying an upstream proxy to use for all
  224. // outbound connections. The URL should include proxy type and
  225. // authentication information, as required. See example URLs here:
  226. // https://github.com/Psiphon-Labs/psiphon-tunnel-core/tree/master/psiphon/upstreamproxy
  227. UpstreamProxyURL string
  228. // CustomHeaders is a set of additional arbitrary HTTP headers that are
  229. // added to all plaintext HTTP requests and requests made through an HTTP
  230. // upstream proxy when specified by UpstreamProxyURL.
  231. CustomHeaders http.Header
  232. // NetworkConnectivityChecker is an interface that enables tunnel-core to
  233. // call into the host application to check for network connectivity. See:
  234. // NetworkConnectivityChecker doc.
  235. NetworkConnectivityChecker NetworkConnectivityChecker
  236. // DeviceBinder is an interface that enables tunnel-core to call into the
  237. // host application to bind sockets to specific devices. See: DeviceBinder
  238. // doc.
  239. //
  240. // When DeviceBinder is set, the "VPN" feature name is automatically added
  241. // when reporting ClientFeatures.
  242. DeviceBinder DeviceBinder
  243. // AllowDefaultDNSResolverWithBindToDevice indicates that it's safe to use
  244. // the default resolver when DeviceBinder is configured, as the host OS
  245. // will automatically exclude DNS requests from the VPN.
  246. AllowDefaultDNSResolverWithBindToDevice bool
  247. // IPv6Synthesizer is an interface that allows tunnel-core to call into
  248. // the host application to synthesize IPv6 addresses. See: IPv6Synthesizer
  249. // doc.
  250. IPv6Synthesizer IPv6Synthesizer
  251. // HasIPv6RouteGetter is an interface that allows tunnel-core to call into
  252. // the host application to determine if the host has an IPv6 route. See:
  253. // HasIPv6RouteGetter doc.
  254. HasIPv6RouteGetter HasIPv6RouteGetter
  255. // DNSServerGetter is an interface that enables tunnel-core to call into
  256. // the host application to discover the native network DNS server
  257. // settings. See: DNSServerGetter doc.
  258. DNSServerGetter DNSServerGetter
  259. // NetworkIDGetter in an interface that enables tunnel-core to call into
  260. // the host application to get an identifier for the host's current active
  261. // network. See: NetworkIDGetter doc.
  262. NetworkIDGetter NetworkIDGetter
  263. // NetworkID, when not blank, is used as the identifier for the host's
  264. // current active network.
  265. // NetworkID is ignored when NetworkIDGetter is set.
  266. NetworkID string
  267. // DisableTactics disables tactics operations including requests, payload
  268. // handling, and application of parameters.
  269. DisableTactics bool
  270. // DisableReplay causes any persisted dial parameters to be ignored when
  271. // they would otherwise be used for replay.
  272. DisableReplay bool
  273. // TargetServerEntry is an encoded server entry. When specified, this
  274. // server entry is used exclusively and all other known servers are
  275. // ignored; also, when set, ConnectionWorkerPoolSize is ignored and
  276. // the pool size is 1.
  277. TargetServerEntry string
  278. // DisableApi disables Psiphon server API calls including handshake,
  279. // connected, status, etc. This is used for special case temporary tunnels
  280. // (Windows VPN mode).
  281. DisableApi bool
  282. // TargetApiProtocol specifies whether to force use of "ssh" or "web" API
  283. // protocol. When blank, the default, the optimal API protocol is used.
  284. // Note that this capability check is not applied before the
  285. // "CandidateServers" count is emitted.
  286. //
  287. // This parameter is intended for testing and debugging only. Not all
  288. // parameters are supported in the legacy "web" API protocol, including
  289. // speed test samples.
  290. TargetApiProtocol string
  291. // RemoteServerListURLs is list of URLs which specify locations to fetch
  292. // out-of-band server entries. This facility is used when a tunnel cannot
  293. // be established to known servers. This value is supplied by and depends
  294. // on the Psiphon Network, and is typically embedded in the client binary.
  295. // All URLs must point to the same entity with the same ETag. At least one
  296. // TransferURL must have OnlyAfterAttempts = 0.
  297. RemoteServerListURLs parameters.TransferURLs
  298. // RemoteServerListSignaturePublicKey specifies a public key that's used
  299. // to authenticate the remote server list payload. This value is supplied
  300. // by and depends on the Psiphon Network, and is typically embedded in the
  301. // client binary.
  302. RemoteServerListSignaturePublicKey string
  303. // DisableRemoteServerListFetcher disables fetching remote server lists.
  304. // This is used for special case temporary tunnels.
  305. DisableRemoteServerListFetcher bool
  306. // FetchRemoteServerListRetryPeriodMilliseconds specifies the delay before
  307. // resuming a remote server list download after a failure. If omitted, a
  308. // default value is used. This value is typical overridden for testing.
  309. FetchRemoteServerListRetryPeriodMilliseconds *int
  310. // ObfuscatedServerListRootURLs is a list of URLs which specify root
  311. // locations from which to fetch obfuscated server list files. This value
  312. // is supplied by and depends on the Psiphon Network, and is typically
  313. // embedded in the client binary. All URLs must point to the same entity
  314. // with the same ETag. At least one DownloadURL must have
  315. // OnlyAfterAttempts = 0.
  316. ObfuscatedServerListRootURLs parameters.TransferURLs
  317. // EnableUpgradeDownload indicates whether to check for and download
  318. // upgrades. When set, UpgradeDownloadURLs and
  319. // UpgradeDownloadClientVersionHeader must also be set. ClientPlatform
  320. // and ClientVersion should also be set.
  321. EnableUpgradeDownload bool
  322. // UpgradeDownloadURLs is list of URLs which specify locations from which
  323. // to download a host client upgrade file, when one is available. The core
  324. // tunnel controller provides a resumable download facility which
  325. // downloads this resource and emits a notice when complete. This value is
  326. // supplied by and depends on the Psiphon Network, and is typically
  327. // embedded in the client binary. All URLs must point to the same entity
  328. // with the same ETag. At least one DownloadURL must have
  329. // OnlyAfterAttempts = 0.
  330. UpgradeDownloadURLs parameters.TransferURLs
  331. // UpgradeDownloadClientVersionHeader specifies the HTTP header name for
  332. // the entity at UpgradeDownloadURLs which specifies the client version
  333. // (an integer value). A HEAD request may be made to check the version
  334. // number available at UpgradeDownloadURLs.
  335. // UpgradeDownloadClientVersionHeader is required when UpgradeDownloadURLs
  336. // is specified.
  337. UpgradeDownloadClientVersionHeader string
  338. // FetchUpgradeRetryPeriodMilliseconds specifies the delay before resuming
  339. // a client upgrade download after a failure. If omitted, a default value
  340. // is used. This value is typical overridden for testing.
  341. FetchUpgradeRetryPeriodMilliseconds *int
  342. // EnableFeedbackUpload indicates whether to enable uploading feedback
  343. // data. When set, FeedbackUploadURLs and FeedbackEncryptionPublicKey
  344. // must also be set.
  345. EnableFeedbackUpload bool
  346. // FeedbackUploadURLs is a list of SecureTransferURLs which specify
  347. // locations where feedback data can be uploaded, pairing with each
  348. // location a public key with which to encrypt the feedback data. This
  349. // value is supplied by and depends on the Psiphon Network, and is
  350. // typically embedded in the client binary. At least one TransferURL must
  351. // have OnlyAfterAttempts = 0.
  352. FeedbackUploadURLs parameters.TransferURLs
  353. // FeedbackEncryptionPublicKey is a default base64-encoded, RSA public key
  354. // value used to encrypt feedback data. Used when uploading feedback with a
  355. // TransferURL which has no public key value configured, i.e.
  356. // B64EncodedPublicKey = "".
  357. FeedbackEncryptionPublicKey string
  358. // TrustedCACertificatesFilename specifies a file containing trusted CA
  359. // certs. When set, this toggles use of the trusted CA certs, specified in
  360. // TrustedCACertificatesFilename, for tunneled TLS connections that expect
  361. // server certificates signed with public certificate authorities
  362. // (currently, only upgrade downloads). This option is used with stock Go
  363. // TLS in cases where Go may fail to obtain a list of root CAs from the
  364. // operating system.
  365. TrustedCACertificatesFilename string
  366. // DisableSystemRootCAs, when true, disables loading system root CAs when
  367. // verifying TLS certificates for all remote server list downloads, upgrade
  368. // downloads, and feedback uploads. Each of these transfers has additional
  369. // security at the payload level. Verifying TLS certificates is preferred,
  370. // as an additional security and circumvention layer; set
  371. // DisableSystemRootCAs only in cases where system root CAs cannot be
  372. // loaded; for example, if unsupported (iOS < 12) or insufficient memory
  373. // (VPN extension on iOS < 15).
  374. DisableSystemRootCAs bool
  375. // DisablePeriodicSshKeepAlive indicates whether to send an SSH keepalive
  376. // every 1-2 minutes, when the tunnel is idle. If the SSH keepalive times
  377. // out, the tunnel is considered to have failed.
  378. DisablePeriodicSshKeepAlive bool
  379. // DeviceLocation is the optional, reported location the host device is
  380. // running in. This input value should be a string representing location
  381. // geohash. The device location is reported to the server in the connected
  382. // request and recorded for Psiphon stats.
  383. DeviceLocation string
  384. // DeviceRegion is the optional, reported region the host device is
  385. // running in. This input value should be a ISO 3166-1 alpha-2 country
  386. // code. The device region is reported to the server in the connected
  387. // request and recorded for Psiphon stats.
  388. //
  389. // When provided, this value may be used, pre-connection, to select
  390. // performance or circumvention optimization strategies for the given
  391. // region.
  392. DeviceRegion string
  393. // EmitDiagnosticNotices indicates whether to output notices containing
  394. // detailed information about the Psiphon session. As these notices may
  395. // contain sensitive information, they should not be insecurely distributed
  396. // or displayed to users. Default is off.
  397. EmitDiagnosticNotices bool
  398. // EmitDiagnosticNetworkParameters indicates whether to include network
  399. // parameters in diagnostic notices. As these parameters are sensitive
  400. // circumvention network information, they should not be insecurely
  401. // distributed or displayed to users. Default is off.
  402. EmitDiagnosticNetworkParameters bool
  403. // EmitBytesTransferred indicates whether to emit periodic notices showing
  404. // bytes sent and received.
  405. EmitBytesTransferred bool
  406. // EmitSLOKs indicates whether to emit notices for each seeded SLOK. As
  407. // this could reveal user browsing activity, it's intended for debugging
  408. // and testing only.
  409. EmitSLOKs bool
  410. // EmitRefractionNetworkingLogs indicates whether to emit gotapdance log
  411. // messages to stdout. Note that gotapdance log messages do not conform to
  412. // the Notice format standard. Default is off.
  413. EmitRefractionNetworkingLogs bool
  414. // EmitServerAlerts indicates whether to emit notices for server alerts.
  415. EmitServerAlerts bool
  416. // EmitClientAddress indicates whether to emit the client's public network
  417. // address, IP and port, as seen by the server.
  418. EmitClientAddress bool
  419. // RateLimits specify throttling configuration for the tunnel.
  420. RateLimits common.RateLimits
  421. // PacketTunnelTunDeviceFileDescriptor specifies a tun device file
  422. // descriptor to use for running a packet tunnel. When this value is > 0,
  423. // a packet tunnel is established through the server and packets are
  424. // relayed via the tun device file descriptor. The file descriptor is
  425. // duped in NewController. When PacketTunnelTunDeviceFileDescriptor is
  426. // set, TunnelPoolSize must be 1.
  427. PacketTunnelTunFileDescriptor int
  428. // PacketTunnelTransparentDNSIPv4Address is the IPv4 address of the DNS
  429. // server configured by a VPN using a packet tunnel. All DNS packets
  430. // destined to this DNS server are transparently redirected to the
  431. // Psiphon server DNS.
  432. PacketTunnelTransparentDNSIPv4Address string
  433. // PacketTunnelTransparentDNSIPv6Address is the IPv6 address of the DNS
  434. // server configured by a VPN using a packet tunnel. All DNS packets
  435. // destined to this DNS server are transparently redirected to the
  436. // Psiphon server DNS.
  437. PacketTunnelTransparentDNSIPv6Address string
  438. // SessionID specifies a client session ID to use in the Psiphon API. The
  439. // session ID should be a randomly generated value that is used only for a
  440. // single session, which is defined as the period between a user starting
  441. // a Psiphon client and stopping the client.
  442. //
  443. // A session ID must be 32 hex digits (lower case). When blank, a random
  444. // session ID is automatically generated. Supply a session ID when a
  445. // single client session will cross multiple Controller instances.
  446. SessionID string
  447. // Authorizations is a list of encoded, signed access control
  448. // authorizations that the client has obtained and will present to the
  449. // server.
  450. Authorizations []string
  451. // ServerEntrySignaturePublicKey is a base64-encoded, ed25519 public
  452. // key value used to verify individual server entry signatures. This value
  453. // is supplied by and depends on the Psiphon Network, and is typically
  454. // embedded in the client binary.
  455. ServerEntrySignaturePublicKey string
  456. // ExchangeObfuscationKey is a base64-encoded, NaCl secretbox key used to
  457. // obfuscate server info exchanges between clients.
  458. // Required for the exchange functionality.
  459. ExchangeObfuscationKey string
  460. // MigrateHomepageNoticesFilename migrates a homepage file from the path
  461. // previously configured with setNoticeFiles to the new path for homepage
  462. // files under the data root directory. The file specified by this config
  463. // value will be moved to config.GetHomePageFilename().
  464. //
  465. // Note: see comment for config.Commit() for a description of how file
  466. // migrations are performed.
  467. //
  468. // If not set, no migration operation will be performed.
  469. MigrateHomepageNoticesFilename string
  470. // MigrateRotatingNoticesFilename migrates notice files from the path
  471. // previously configured with setNoticeFiles to the new path for notice
  472. // files under the data root directory.
  473. //
  474. // MigrateRotatingNoticesFilename will be moved to
  475. // config.GetNoticesFilename().
  476. //
  477. // MigrateRotatingNoticesFilename.1 will be moved to
  478. // config.GetOldNoticesFilename().
  479. //
  480. // Note: see comment for config.Commit() for a description of how file
  481. // migrations are performed.
  482. //
  483. // If not set, no migration operation will be performed.
  484. MigrateRotatingNoticesFilename string
  485. // MigrateDataStoreDirectory indicates the location of the datastore
  486. // directory, as previously configured with the deprecated
  487. // DataStoreDirectory config field. Datastore files found in the specified
  488. // directory will be moved under the data root directory.
  489. //
  490. // Note: see comment for config.Commit() for a description of how file
  491. // migrations are performed.
  492. MigrateDataStoreDirectory string
  493. // MigrateRemoteServerListDownloadFilename indicates the location of
  494. // remote server list download files. The remote server list files found at
  495. // the specified path will be moved under the data root directory.
  496. //
  497. // Note: see comment for config.Commit() for a description of how file
  498. // migrations are performed.
  499. MigrateRemoteServerListDownloadFilename string
  500. // MigrateObfuscatedServerListDownloadDirectory indicates the location of
  501. // the obfuscated server list downloads directory, as previously configured
  502. // with ObfuscatedServerListDownloadDirectory. Obfuscated server list
  503. // download files found in the specified directory will be moved under the
  504. // data root directory.
  505. //
  506. // Warning: if the directory is empty after obfuscated server
  507. // list files are moved, then it will be deleted.
  508. //
  509. // Note: see comment for config.Commit() for a description of how file
  510. // migrations are performed.
  511. MigrateObfuscatedServerListDownloadDirectory string
  512. // MigrateUpgradeDownloadFilename indicates the location of downloaded
  513. // application upgrade files. Downloaded upgrade files found at the
  514. // specified path will be moved under the data root directory.
  515. //
  516. // Note: see comment for config.Commit() for a description of how file
  517. // migrations are performed.
  518. MigrateUpgradeDownloadFilename string
  519. //
  520. // The following parameters are deprecated.
  521. //
  522. // DataStoreDirectory is the directory in which to store the persistent
  523. // database, which contains information such as server entries. By
  524. // default, current working directory.
  525. //
  526. // Deprecated:
  527. // Use MigrateDataStoreDirectory. When MigrateDataStoreDirectory
  528. // is set, this parameter is ignored.
  529. //
  530. // DataStoreDirectory has been subsumed by the new data root directory,
  531. // which is configured with DataRootDirectory. If set, datastore files
  532. // found in the specified directory will be moved under the data root
  533. // directory.
  534. DataStoreDirectory string
  535. // RemoteServerListDownloadFilename specifies a target filename for
  536. // storing the remote server list download. Data is stored in co-located
  537. // files (RemoteServerListDownloadFilename.part*) to allow for resumable
  538. // downloading.
  539. //
  540. // Deprecated:
  541. // Use MigrateRemoteServerListDownloadFilename. When
  542. // MigrateRemoteServerListDownloadFilename is set, this parameter is
  543. // ignored.
  544. //
  545. // If set, remote server list download files found at the specified path
  546. // will be moved under the data root directory.
  547. RemoteServerListDownloadFilename string
  548. // ObfuscatedServerListDownloadDirectory specifies a target directory for
  549. // storing the obfuscated remote server list downloads. Data is stored in
  550. // co-located files (<OSL filename>.part*) to allow for resumable
  551. // downloading.
  552. //
  553. // Deprecated:
  554. // Use MigrateObfuscatedServerListDownloadDirectory. When
  555. // MigrateObfuscatedServerListDownloadDirectory is set, this parameter is
  556. // ignored.
  557. //
  558. // If set, obfuscated server list download files found at the specified path
  559. // will be moved under the data root directory.
  560. ObfuscatedServerListDownloadDirectory string
  561. // UpgradeDownloadFilename is the local target filename for an upgrade
  562. // download. This parameter is required when UpgradeDownloadURLs (or
  563. // UpgradeDownloadUrl) is specified. Data is stored in co-located files
  564. // (UpgradeDownloadFilename.part*) to allow for resumable downloading.
  565. //
  566. // Deprecated:
  567. // Use MigrateUpgradeDownloadFilename. When MigrateUpgradeDownloadFilename
  568. // is set, this parameter is ignored.
  569. //
  570. // If set, upgrade download files found at the specified path will be moved
  571. // under the data root directory.
  572. UpgradeDownloadFilename string
  573. // TunnelProtocol indicates which protocol to use. For the default, "",
  574. // all protocols are used.
  575. //
  576. // Deprecated: Use LimitTunnelProtocols. When LimitTunnelProtocols is not
  577. // nil, this parameter is ignored.
  578. TunnelProtocol string
  579. // Deprecated: Use CustomHeaders. When CustomHeaders is not nil, this
  580. // parameter is ignored.
  581. UpstreamProxyCustomHeaders http.Header
  582. // RemoteServerListUrl is a URL which specifies a location to fetch out-
  583. // of-band server entries. This facility is used when a tunnel cannot be
  584. // established to known servers. This value is supplied by and depends on
  585. // the Psiphon Network, and is typically embedded in the client binary.
  586. //
  587. // Deprecated: Use RemoteServerListURLs. When RemoteServerListURLs is not
  588. // nil, this parameter is ignored.
  589. RemoteServerListUrl string
  590. // ObfuscatedServerListRootURL is a URL which specifies the root location
  591. // from which to fetch obfuscated server list files. This value is
  592. // supplied by and depends on the Psiphon Network, and is typically
  593. // embedded in the client binary.
  594. //
  595. // Deprecated: Use ObfuscatedServerListRootURLs. When
  596. // ObfuscatedServerListRootURLs is not nil, this parameter is ignored.
  597. ObfuscatedServerListRootURL string
  598. // UpgradeDownloadUrl specifies a URL from which to download a host client
  599. // upgrade file, when one is available. The core tunnel controller
  600. // provides a resumable download facility which downloads this resource
  601. // and emits a notice when complete. This value is supplied by and depends
  602. // on the Psiphon Network, and is typically embedded in the client binary.
  603. //
  604. // Deprecated: Use UpgradeDownloadURLs. When UpgradeDownloadURLs is not
  605. // nil, this parameter is ignored.
  606. UpgradeDownloadUrl string
  607. //
  608. // The following parameters are for testing purposes.
  609. //
  610. // TransformHostNameProbability is for testing purposes.
  611. TransformHostNameProbability *float64
  612. // FragmentorProbability and associated Fragmentor fields are for testing
  613. // purposes.
  614. FragmentorProbability *float64
  615. FragmentorLimitProtocols []string
  616. FragmentorMinTotalBytes *int
  617. FragmentorMaxTotalBytes *int
  618. FragmentorMinWriteBytes *int
  619. FragmentorMaxWriteBytes *int
  620. FragmentorMinDelayMicroseconds *int
  621. FragmentorMaxDelayMicroseconds *int
  622. // MeekTrafficShapingProbability and associated fields are for testing
  623. // purposes.
  624. MeekTrafficShapingProbability *float64
  625. MeekTrafficShapingLimitProtocols []string
  626. MeekMinTLSPadding *int
  627. MeekMaxTLSPadding *int
  628. MeekMinLimitRequestPayloadLength *int
  629. MeekMaxLimitRequestPayloadLength *int
  630. MeekRedialTLSProbability *float64
  631. MeekAlternateCookieNameProbability *float64
  632. MeekAlternateContentTypeProbability *float64
  633. // ObfuscatedSSHAlgorithms and associated ObfuscatedSSH fields are for
  634. // testing purposes. If specified, ObfuscatedSSHAlgorithms must have 4 SSH
  635. // KEX elements in order: the kex algorithm, cipher, MAC, and server host
  636. // key algorithm.
  637. ObfuscatedSSHAlgorithms []string
  638. ObfuscatedSSHMinPadding *int
  639. ObfuscatedSSHMaxPadding *int
  640. // LivenessTestMinUpstreamBytes and other LivenessTest fields are for
  641. // testing purposes.
  642. LivenessTestMinUpstreamBytes *int
  643. LivenessTestMaxUpstreamBytes *int
  644. LivenessTestMinDownstreamBytes *int
  645. LivenessTestMaxDownstreamBytes *int
  646. // ReplayCandidateCount and other Replay fields are for testing purposes.
  647. ReplayCandidateCount *int
  648. ReplayDialParametersTTLSeconds *int
  649. ReplayTargetUpstreamBytes *int
  650. ReplayTargetDownstreamBytes *int
  651. ReplayTargetTunnelDurationSeconds *int
  652. ReplayLaterRoundMoveToFrontProbability *float64
  653. ReplayRetainFailedProbability *float64
  654. ReplayIgnoreChangedConfigState *bool
  655. // NetworkLatencyMultiplierMin and other NetworkLatencyMultiplier fields are
  656. // for testing purposes.
  657. NetworkLatencyMultiplierMin float64
  658. NetworkLatencyMultiplierMax float64
  659. NetworkLatencyMultiplierLambda float64
  660. // UseOnlyCustomTLSProfiles and other TLS configuration fields are for
  661. // testing purposes.
  662. UseOnlyCustomTLSProfiles *bool
  663. CustomTLSProfiles protocol.CustomTLSProfiles
  664. SelectRandomizedTLSProfileProbability *float64
  665. NoDefaultTLSSessionIDProbability *float64
  666. DisableFrontingProviderTLSProfiles protocol.LabeledTLSProfiles
  667. // ClientBurstUpstreamTargetBytes and other burst metric fields are for
  668. // testing purposes.
  669. ClientBurstUpstreamTargetBytes *int
  670. ClientBurstUpstreamDeadlineMilliseconds *int
  671. ClientBurstDownstreamTargetBytes *int
  672. ClientBurstDownstreamDeadlineMilliseconds *int
  673. // ApplicationParameters is for testing purposes.
  674. ApplicationParameters parameters.KeyValues
  675. // CustomHostNameRegexes and other custom host name fields are for testing
  676. // purposes.
  677. CustomHostNameRegexes []string
  678. CustomHostNameProbability *float64
  679. CustomHostNameLimitProtocols []string
  680. // ConjureCachedRegistrationTTLSeconds and other Conjure fields are for
  681. // testing purposes.
  682. ConjureCachedRegistrationTTLSeconds *int
  683. ConjureAPIRegistrarBidirectionalURL string
  684. ConjureAPIRegistrarFrontingSpecs parameters.FrontingSpecs
  685. ConjureAPIRegistrarMinDelayMilliseconds *int
  686. ConjureAPIRegistrarMaxDelayMilliseconds *int
  687. ConjureDecoyRegistrarProbability *float64
  688. ConjureDecoyRegistrarWidth *int
  689. ConjureDecoyRegistrarMinDelayMilliseconds *int
  690. ConjureDecoyRegistrarMaxDelayMilliseconds *int
  691. ConjureEnableIPv6Dials *bool
  692. ConjureEnablePortRandomization *bool
  693. ConjureEnableRegistrationOverrides *bool
  694. ConjureLimitTransports protocol.ConjureTransports
  695. ConjureSTUNServerAddresses []string
  696. ConjureDTLSEmptyInitialPacketProbability *float64
  697. // HoldOffTunnelMinDurationMilliseconds and other HoldOffTunnel fields are
  698. // for testing purposes.
  699. HoldOffTunnelMinDurationMilliseconds *int
  700. HoldOffTunnelMaxDurationMilliseconds *int
  701. HoldOffTunnelProtocols []string
  702. HoldOffTunnelFrontingProviderIDs []string
  703. HoldOffTunnelProbability *float64
  704. // RestrictFrontingProviderIDs and other RestrictFrontingProviderIDs fields
  705. // are for testing purposes.
  706. RestrictFrontingProviderIDs []string
  707. RestrictFrontingProviderIDsClientProbability *float64
  708. // UpstreamProxyAllowAllServerEntrySources is for testing purposes.
  709. UpstreamProxyAllowAllServerEntrySources *bool
  710. // LimitTunnelDialPortNumbers is for testing purposes.
  711. LimitTunnelDialPortNumbers parameters.TunnelProtocolPortLists
  712. // QUICDisablePathMTUDiscoveryProbability is for testing purposes.
  713. QUICDisablePathMTUDiscoveryProbability *float64
  714. // DNSResolverAttemptsPerServer and other DNSResolver fields are for
  715. // testing purposes.
  716. DNSResolverAttemptsPerServer *int
  717. DNSResolverAttemptsPerPreferredServer *int
  718. DNSResolverRequestTimeoutMilliseconds *int
  719. DNSResolverAwaitTimeoutMilliseconds *int
  720. DNSResolverPreresolvedIPAddressCIDRs parameters.LabeledCIDRs
  721. DNSResolverPreresolvedIPAddressProbability *float64
  722. DNSResolverAlternateServers []string
  723. DNSResolverPreferredAlternateServers []string
  724. DNSResolverPreferAlternateServerProbability *float64
  725. DNSResolverProtocolTransformSpecs transforms.Specs
  726. DNSResolverProtocolTransformScopedSpecNames transforms.ScopedSpecNames
  727. DNSResolverProtocolTransformProbability *float64
  728. DNSResolverIncludeEDNS0Probability *float64
  729. DNSResolverCacheExtensionInitialTTLMilliseconds *int
  730. DNSResolverCacheExtensionVerifiedTTLMilliseconds *int
  731. DirectHTTPProtocolTransformSpecs transforms.Specs
  732. DirectHTTPProtocolTransformScopedSpecNames transforms.ScopedSpecNames
  733. DirectHTTPProtocolTransformProbability *float64
  734. FrontedHTTPProtocolTransformSpecs transforms.Specs
  735. FrontedHTTPProtocolTransformScopedSpecNames transforms.ScopedSpecNames
  736. FrontedHTTPProtocolTransformProbability *float64
  737. OSSHObfuscatorSeedTransformSpecs transforms.Specs
  738. OSSHObfuscatorSeedTransformScopedSpecNames transforms.ScopedSpecNames
  739. OSSHObfuscatorSeedTransformProbability *float64
  740. ObfuscatedQUICNonceTransformSpecs transforms.Specs
  741. ObfuscatedQUICNonceTransformScopedSpecNames transforms.ScopedSpecNames
  742. ObfuscatedQUICNonceTransformProbability *float64
  743. // OSSHPrefix parameters are for testing purposes only.
  744. OSSHPrefixSpecs transforms.Specs
  745. OSSHPrefixScopedSpecNames transforms.ScopedSpecNames
  746. OSSHPrefixProbability *float64
  747. OSSHPrefixSplitMinDelayMilliseconds *int
  748. OSSHPrefixSplitMaxDelayMilliseconds *int
  749. OSSHPrefixEnableFragmentor *bool
  750. // TLSTunnelTrafficShapingProbability and associated fields are for testing.
  751. TLSTunnelTrafficShapingProbability *float64
  752. TLSTunnelMinTLSPadding *int
  753. TLSTunnelMaxTLSPadding *int
  754. // TLSFragmentClientHello fields are for testing purposes only.
  755. TLSFragmentClientHelloProbability *float64
  756. TLSFragmentClientHelloLimitProtocols []string
  757. // AdditionalParameters is used for testing.
  758. AdditionalParameters string
  759. // params is the active parameters.Parameters with defaults, config values,
  760. // and, optionally, tactics applied.
  761. //
  762. // New tactics must be applied by calling Config.SetParameters; calling
  763. // params.Set directly will fail to add config values.
  764. params *parameters.Parameters
  765. dialParametersHash []byte
  766. dynamicConfigMutex sync.Mutex
  767. sponsorID string
  768. authorizations []string
  769. deviceBinder DeviceBinder
  770. networkIDGetter NetworkIDGetter
  771. clientFeatures []string
  772. resolverMutex sync.Mutex
  773. resolver *resolver.Resolver
  774. committed bool
  775. loadTimestamp string
  776. }
  777. // Config field which specifies if notice files should be used and at which
  778. // frequency and size they should be rotated.
  779. //
  780. // If either RotatingFileSize or RotatingSyncFrequency are <= 0, default values
  781. // are used.
  782. //
  783. // See comment for setNoticeFiles in notice.go for further details.
  784. type UseNoticeFiles struct {
  785. RotatingFileSize int
  786. RotatingSyncFrequency int
  787. }
  788. // LoadConfig parses a JSON format Psiphon config JSON string and returns a
  789. // Config struct populated with config values.
  790. //
  791. // The Config struct may then be programmatically populated with additional
  792. // values, including callbacks such as DeviceBinder.
  793. //
  794. // Before using the Config, Commit must be called, which will perform further
  795. // validation and initialize internal data structures.
  796. func LoadConfig(configJson []byte) (*Config, error) {
  797. var config Config
  798. err := json.Unmarshal(configJson, &config)
  799. if err != nil {
  800. return nil, errors.Trace(err)
  801. }
  802. config.loadTimestamp = common.TruncateTimestampToHour(
  803. common.GetCurrentTimestamp())
  804. return &config, nil
  805. }
  806. // IsCommitted checks if Commit was called.
  807. func (config *Config) IsCommitted() bool {
  808. return config.committed
  809. }
  810. // Commit validates Config fields finalizes initialization.
  811. //
  812. // Config fields should not be set after calling Config, as any changes may
  813. // not be reflected in internal data structures.
  814. //
  815. // If migrateFromLegacyFields is set to true, then an attempt to migrate from
  816. // legacy fields is made.
  817. //
  818. // Migration from legacy fields:
  819. // Config fields of the naming Migrate* (e.g. MigrateDataStoreDirectory) specify
  820. // a file migration operation which should be performed. These fields correspond
  821. // to deprecated fields, which previously could be used to specify where Psiphon
  822. // stored different sets of persistent files (e.g. MigrateDataStoreDirectory
  823. // corresponds to the deprecated field DataStoreDirectory).
  824. //
  825. // Psiphon now stores all persistent data under the configurable
  826. // DataRootDirectory (see Config.DataRootDirectory). The deprecated fields, and
  827. // corresponding Migrate* fields, are now used to specify the file or directory
  828. // path where, or under which, persistent files and directories created by
  829. // previous versions of Psiphon exist, so they can be moved under the
  830. // DataRootDirectory.
  831. //
  832. // For each migration operation:
  833. // - In the case of directories that could have defaulted to the current working
  834. // directory, persistent files and directories created by Psiphon are
  835. // precisely targeted to avoid moving files which were not created by Psiphon.
  836. // - If no file is found at the specified path, or an error is encountered while
  837. // migrating the file, then an error is logged and execution continues
  838. // normally.
  839. //
  840. // A sentinel file which signals that file migration has been completed, and
  841. // should not be attempted again, is created under DataRootDirectory after one
  842. // full pass through Commit(), regardless of whether file migration succeeds or
  843. // fails. It is better to not endlessly retry file migrations on each Commit()
  844. // because file system errors are expected to be rare and persistent files will
  845. // be re-populated over time.
  846. func (config *Config) Commit(migrateFromLegacyFields bool) error {
  847. // Apply any additional parameters first
  848. additionalParametersInfoMsgs, err := config.applyAdditionalParameters()
  849. if err != nil {
  850. return errors.TraceMsg(err, "failed to apply additional parameters")
  851. }
  852. // Do SetEmitDiagnosticNotices first, to ensure config file errors are
  853. // emitted.
  854. if config.EmitDiagnosticNotices {
  855. SetEmitDiagnosticNotices(
  856. true, config.EmitDiagnosticNetworkParameters)
  857. }
  858. // Migrate and set notice files before any operations that may emit an
  859. // error. This is to ensure config file errors are written to file when
  860. // notice files are configured with config.UseNoticeFiles.
  861. //
  862. // Note:
  863. // Errors encountered while configuring the data directory cannot be written
  864. // to notice files. This is because notices files are created within the
  865. // data directory.
  866. if config.DataRootDirectory == "" {
  867. wd, err := os.Getwd()
  868. if err != nil {
  869. return errors.Trace(common.RedactFilePathsError(err))
  870. }
  871. config.DataRootDirectory = wd
  872. }
  873. // Create root directory
  874. dataDirectoryPath := config.GetPsiphonDataDirectory()
  875. if !common.FileExists(dataDirectoryPath) {
  876. err := os.Mkdir(dataDirectoryPath, os.ModePerm)
  877. if err != nil {
  878. return errors.Tracef(
  879. "failed to create datastore directory with error: %s",
  880. common.RedactFilePathsError(err, dataDirectoryPath))
  881. }
  882. }
  883. // Check if the migration from legacy config fields has already been
  884. // completed. See the Migrate* config fields for more details.
  885. migrationCompleteFilePath := filepath.Join(config.GetPsiphonDataDirectory(), "migration_complete")
  886. needMigration := !common.FileExists(migrationCompleteFilePath)
  887. // Collect notices to emit them after notice files are set
  888. var noticeMigrationAlertMsgs []string
  889. var noticeMigrationInfoMsgs []string
  890. // Migrate notices first to ensure notice files are used for notices if
  891. // UseNoticeFiles is set.
  892. homepageFilePath := config.GetHomePageFilename()
  893. noticesFilePath := config.GetNoticesFilename()
  894. if migrateFromLegacyFields {
  895. if needMigration {
  896. // Move notice files that exist at legacy file paths under the data root
  897. // directory.
  898. noticeMigrationInfoMsgs = append(noticeMigrationInfoMsgs, "Config migration: need migration")
  899. noticeMigrations := migrationsFromLegacyNoticeFilePaths(config)
  900. successfulMigrations := 0
  901. for _, migration := range noticeMigrations {
  902. err := DoFileMigration(migration)
  903. if err != nil {
  904. alertMsg := fmt.Sprintf("Config migration: %s", errors.Trace(err))
  905. noticeMigrationAlertMsgs = append(noticeMigrationAlertMsgs, alertMsg)
  906. } else {
  907. successfulMigrations += 1
  908. }
  909. }
  910. infoMsg := fmt.Sprintf("Config migration: %d/%d notice files successfully migrated", successfulMigrations, len(noticeMigrations))
  911. noticeMigrationInfoMsgs = append(noticeMigrationInfoMsgs, infoMsg)
  912. } else {
  913. noticeMigrationInfoMsgs = append(noticeMigrationInfoMsgs, "Config migration: migration already completed")
  914. }
  915. }
  916. if config.UseNoticeFiles != nil {
  917. setNoticeFiles(
  918. homepageFilePath,
  919. noticesFilePath,
  920. config.UseNoticeFiles.RotatingFileSize,
  921. config.UseNoticeFiles.RotatingSyncFrequency)
  922. }
  923. // Emit notices now that notice files are set if configured
  924. for _, msg := range additionalParametersInfoMsgs {
  925. NoticeInfo(msg)
  926. }
  927. for _, msg := range noticeMigrationAlertMsgs {
  928. NoticeWarning(msg)
  929. }
  930. for _, msg := range noticeMigrationInfoMsgs {
  931. NoticeInfo(msg)
  932. }
  933. // Promote legacy fields.
  934. if config.CustomHeaders == nil {
  935. config.CustomHeaders = config.UpstreamProxyCustomHeaders
  936. config.UpstreamProxyCustomHeaders = nil
  937. }
  938. if config.RemoteServerListUrl != "" && config.RemoteServerListURLs == nil {
  939. config.RemoteServerListURLs = promoteLegacyTransferURL(config.RemoteServerListUrl)
  940. }
  941. if config.ObfuscatedServerListRootURL != "" && config.ObfuscatedServerListRootURLs == nil {
  942. config.ObfuscatedServerListRootURLs = promoteLegacyTransferURL(config.ObfuscatedServerListRootURL)
  943. }
  944. if config.UpgradeDownloadUrl != "" && config.UpgradeDownloadURLs == nil {
  945. config.UpgradeDownloadURLs = promoteLegacyTransferURL(config.UpgradeDownloadUrl)
  946. }
  947. if config.TunnelProtocol != "" && len(config.LimitTunnelProtocols) == 0 {
  948. config.LimitTunnelProtocols = []string{config.TunnelProtocol}
  949. }
  950. if config.DataStoreDirectory != "" && config.MigrateDataStoreDirectory == "" {
  951. config.MigrateDataStoreDirectory = config.DataStoreDirectory
  952. }
  953. if config.RemoteServerListDownloadFilename != "" && config.MigrateRemoteServerListDownloadFilename == "" {
  954. config.MigrateRemoteServerListDownloadFilename = config.RemoteServerListDownloadFilename
  955. }
  956. if config.ObfuscatedServerListDownloadDirectory != "" && config.MigrateObfuscatedServerListDownloadDirectory == "" {
  957. config.MigrateObfuscatedServerListDownloadDirectory = config.ObfuscatedServerListDownloadDirectory
  958. }
  959. if config.UpgradeDownloadFilename != "" && config.MigrateUpgradeDownloadFilename == "" {
  960. config.MigrateUpgradeDownloadFilename = config.UpgradeDownloadFilename
  961. }
  962. // Supply default values.
  963. // Create datastore directory.
  964. dataStoreDirectoryPath := config.GetDataStoreDirectory()
  965. if !common.FileExists(dataStoreDirectoryPath) {
  966. err := os.Mkdir(dataStoreDirectoryPath, os.ModePerm)
  967. if err != nil {
  968. return errors.Tracef(
  969. "failed to create datastore directory with error: %s",
  970. common.RedactFilePathsError(err, dataStoreDirectoryPath))
  971. }
  972. }
  973. // Create OSL directory.
  974. oslDirectoryPath := config.GetObfuscatedServerListDownloadDirectory()
  975. if !common.FileExists(oslDirectoryPath) {
  976. err := os.Mkdir(oslDirectoryPath, os.ModePerm)
  977. if err != nil {
  978. return errors.Tracef(
  979. "failed to create osl directory with error: %s",
  980. common.RedactFilePathsError(err, oslDirectoryPath))
  981. }
  982. }
  983. if config.ClientVersion == "" {
  984. config.ClientVersion = "0"
  985. }
  986. if config.TunnelPoolSize == 0 {
  987. config.TunnelPoolSize = TUNNEL_POOL_SIZE
  988. }
  989. // Validate config fields.
  990. if !common.FileExists(config.DataRootDirectory) {
  991. return errors.TraceNew("DataRootDirectory does not exist")
  992. }
  993. if config.PropagationChannelId == "" {
  994. return errors.TraceNew("propagation channel ID is missing from the configuration file")
  995. }
  996. if config.SponsorId == "" {
  997. return errors.TraceNew("sponsor ID is missing from the configuration file")
  998. }
  999. _, err = strconv.Atoi(config.ClientVersion)
  1000. if err != nil {
  1001. return errors.Tracef("invalid client version: %s", err)
  1002. }
  1003. if !common.Contains(
  1004. []string{"", protocol.PSIPHON_SSH_API_PROTOCOL, protocol.PSIPHON_WEB_API_PROTOCOL},
  1005. config.TargetApiProtocol) {
  1006. return errors.TraceNew("invalid TargetApiProtocol")
  1007. }
  1008. if !config.DisableRemoteServerListFetcher {
  1009. if config.RemoteServerListURLs != nil {
  1010. if config.RemoteServerListSignaturePublicKey == "" {
  1011. return errors.TraceNew("missing RemoteServerListSignaturePublicKey")
  1012. }
  1013. }
  1014. if config.ObfuscatedServerListRootURLs != nil {
  1015. if config.RemoteServerListSignaturePublicKey == "" {
  1016. return errors.TraceNew("missing RemoteServerListSignaturePublicKey")
  1017. }
  1018. }
  1019. }
  1020. if config.EnableUpgradeDownload {
  1021. if len(config.UpgradeDownloadURLs) == 0 {
  1022. return errors.TraceNew("missing UpgradeDownloadURLs")
  1023. }
  1024. if config.UpgradeDownloadClientVersionHeader == "" {
  1025. return errors.TraceNew("missing UpgradeDownloadClientVersionHeader")
  1026. }
  1027. }
  1028. if config.EnableFeedbackUpload {
  1029. if len(config.FeedbackUploadURLs) == 0 {
  1030. return errors.TraceNew("missing FeedbackUploadURLs")
  1031. }
  1032. if config.FeedbackEncryptionPublicKey == "" {
  1033. return errors.TraceNew("missing FeedbackEncryptionPublicKey")
  1034. }
  1035. }
  1036. // This constraint is expected by logic in Controller.runTunnels().
  1037. if config.PacketTunnelTunFileDescriptor > 0 && config.TunnelPoolSize != 1 {
  1038. return errors.TraceNew("packet tunnel mode requires TunnelPoolSize to be 1")
  1039. }
  1040. // SessionID must be PSIPHON_API_CLIENT_SESSION_ID_LENGTH lowercase hex-encoded bytes.
  1041. if config.SessionID == "" {
  1042. sessionID, err := MakeSessionId()
  1043. if err != nil {
  1044. return errors.Trace(err)
  1045. }
  1046. config.SessionID = sessionID
  1047. }
  1048. if len(config.SessionID) != 2*protocol.PSIPHON_API_CLIENT_SESSION_ID_LENGTH ||
  1049. -1 != strings.IndexFunc(config.SessionID, func(c rune) bool {
  1050. return !unicode.Is(unicode.ASCII_Hex_Digit, c) || unicode.IsUpper(c)
  1051. }) {
  1052. return errors.TraceNew("invalid SessionID")
  1053. }
  1054. config.params, err = parameters.NewParameters(
  1055. func(err error) {
  1056. NoticeWarning("Parameters getValue failed: %s", err)
  1057. })
  1058. if err != nil {
  1059. return errors.Trace(err)
  1060. }
  1061. if config.ObfuscatedSSHAlgorithms != nil &&
  1062. len(config.ObfuscatedSSHAlgorithms) != 4 {
  1063. // TODO: validate each algorithm?
  1064. return errors.TraceNew("invalid ObfuscatedSSHAlgorithms")
  1065. }
  1066. // parametersParameters.Set will validate the config fields applied to
  1067. // parametersParameters.
  1068. err = config.SetParameters("", false, nil)
  1069. if err != nil {
  1070. return errors.Trace(err)
  1071. }
  1072. // Calculate and set the dial parameters hash. After this point, related
  1073. // config fields must not change.
  1074. config.setDialParametersHash()
  1075. // Set defaults for dynamic config fields.
  1076. config.SetDynamicConfig(config.SponsorId, config.Authorizations)
  1077. // Initialize config.deviceBinder and config.config.networkIDGetter. These
  1078. // wrap config.DeviceBinder and config.NetworkIDGetter/NetworkID with
  1079. // loggers.
  1080. //
  1081. // New variables are set to avoid mutating input config fields.
  1082. // Internally, code must use config.deviceBinder and
  1083. // config.networkIDGetter and not the input/exported fields.
  1084. if config.DeviceBinder != nil {
  1085. config.deviceBinder = newLoggingDeviceBinder(config.DeviceBinder)
  1086. }
  1087. networkIDGetter := config.NetworkIDGetter
  1088. if networkIDGetter == nil {
  1089. // Limitation: unlike NetworkIDGetter, which calls back to platform APIs
  1090. // this method of network identification is not dynamic and will not reflect
  1091. // network changes that occur while running.
  1092. if config.NetworkID != "" {
  1093. networkIDGetter = newStaticNetworkGetter(config.NetworkID)
  1094. } else {
  1095. networkIDGetter = newStaticNetworkGetter("UNKNOWN")
  1096. }
  1097. }
  1098. config.networkIDGetter = newLoggingNetworkIDGetter(networkIDGetter)
  1099. // Initialize config.clientFeatures, which adds feature names on top of
  1100. // those specified by the host application in config.ClientFeatures.
  1101. config.clientFeatures = config.ClientFeatures
  1102. feature := "VPN"
  1103. if config.DeviceBinder != nil && !common.Contains(config.clientFeatures, feature) {
  1104. config.clientFeatures = append(config.clientFeatures, feature)
  1105. }
  1106. // Migrate from old config fields. This results in files being moved under
  1107. // a config specified data root directory.
  1108. if migrateFromLegacyFields && needMigration {
  1109. // If unset, set MigrateDataStoreDirectory to the previous default value for
  1110. // DataStoreDirectory to ensure that datastore files are migrated.
  1111. if config.MigrateDataStoreDirectory == "" {
  1112. wd, err := os.Getwd()
  1113. if err != nil {
  1114. return errors.Trace(err)
  1115. }
  1116. NoticeInfo("MigrateDataStoreDirectory unset, using working directory")
  1117. config.MigrateDataStoreDirectory = wd
  1118. }
  1119. // Move files that exist at legacy file paths under the data root
  1120. // directory.
  1121. migrations, err := migrationsFromLegacyFilePaths(config)
  1122. if err != nil {
  1123. return errors.Trace(err)
  1124. }
  1125. // Do migrations
  1126. successfulMigrations := 0
  1127. for _, migration := range migrations {
  1128. err := DoFileMigration(migration)
  1129. if err != nil {
  1130. NoticeWarning("Config migration: %s", errors.Trace(err))
  1131. } else {
  1132. successfulMigrations += 1
  1133. }
  1134. }
  1135. NoticeInfo(fmt.Sprintf(
  1136. "Config migration: %d/%d legacy files successfully migrated",
  1137. successfulMigrations, len(migrations)))
  1138. // Remove OSL directory if empty
  1139. if config.MigrateObfuscatedServerListDownloadDirectory != "" {
  1140. files, err := ioutil.ReadDir(config.MigrateObfuscatedServerListDownloadDirectory)
  1141. if err != nil {
  1142. NoticeWarning(
  1143. "Error reading OSL directory: %s",
  1144. errors.Trace(common.RedactFilePathsError(err, config.MigrateObfuscatedServerListDownloadDirectory)))
  1145. } else if len(files) == 0 {
  1146. err := os.Remove(config.MigrateObfuscatedServerListDownloadDirectory)
  1147. if err != nil {
  1148. NoticeWarning(
  1149. "Error deleting empty OSL directory: %s",
  1150. errors.Trace(common.RedactFilePathsError(err, config.MigrateObfuscatedServerListDownloadDirectory)))
  1151. }
  1152. }
  1153. }
  1154. f, err := os.Create(migrationCompleteFilePath)
  1155. if err != nil {
  1156. NoticeWarning(
  1157. "Config migration: failed to create migration completed file with error %s",
  1158. errors.Trace(common.RedactFilePathsError(err, migrationCompleteFilePath)))
  1159. } else {
  1160. NoticeInfo("Config migration: completed")
  1161. f.Close()
  1162. }
  1163. }
  1164. config.committed = true
  1165. return nil
  1166. }
  1167. // GetParameters returns the current parameters.Parameters.
  1168. func (config *Config) GetParameters() *parameters.Parameters {
  1169. return config.params
  1170. }
  1171. // SetParameters resets the parameters.Parameters to the default values,
  1172. // applies any config file values, and then applies the input parameters (from
  1173. // tactics, etc.)
  1174. //
  1175. // Set skipOnError to false when initially applying only config values, as
  1176. // this will validate the values and should fail. Set skipOnError to true when
  1177. // applying tactics to ignore invalid or unknown parameter values from tactics.
  1178. //
  1179. // In the case of applying tactics, do not call Config.parameters.Set
  1180. // directly as this will not first apply config values.
  1181. //
  1182. // If there is an error, the existing Config.parameters are left
  1183. // entirely unmodified.
  1184. func (config *Config) SetParameters(tag string, skipOnError bool, applyParameters map[string]interface{}) error {
  1185. setParameters := []map[string]interface{}{config.makeConfigParameters()}
  1186. if applyParameters != nil {
  1187. setParameters = append(setParameters, applyParameters)
  1188. }
  1189. counts, err := config.params.Set(tag, skipOnError, setParameters...)
  1190. if err != nil {
  1191. return errors.Trace(err)
  1192. }
  1193. NoticeInfo("applied %v parameters with tag '%s'", counts, tag)
  1194. // Emit certain individual parameter values for quick reference in diagnostics.
  1195. p := config.params.Get()
  1196. NoticeInfo(
  1197. "NetworkLatencyMultiplier Min/Max/Lambda: %f/%f/%f",
  1198. p.Float(parameters.NetworkLatencyMultiplierMin),
  1199. p.Float(parameters.NetworkLatencyMultiplierMax),
  1200. p.Float(parameters.NetworkLatencyMultiplierLambda))
  1201. // Application Parameters are feature flags/config info, delivered as Client
  1202. // Parameters via tactics/etc., to be communicated to the outer application.
  1203. // Emit these now, as notices.
  1204. if p.WeightedCoinFlip(parameters.ApplicationParametersProbability) {
  1205. NoticeApplicationParameters(p.KeyValues(parameters.ApplicationParameters))
  1206. }
  1207. return nil
  1208. }
  1209. // SetResolver sets the current resolver.
  1210. func (config *Config) SetResolver(resolver *resolver.Resolver) {
  1211. config.resolverMutex.Lock()
  1212. defer config.resolverMutex.Unlock()
  1213. config.resolver = resolver
  1214. }
  1215. // GetResolver returns the current resolver. May return nil.
  1216. func (config *Config) GetResolver() *resolver.Resolver {
  1217. config.resolverMutex.Lock()
  1218. defer config.resolverMutex.Unlock()
  1219. return config.resolver
  1220. }
  1221. // SetDynamicConfig sets the current client sponsor ID and authorizations.
  1222. // Invalid values for sponsor ID are ignored. The caller must not modify the
  1223. // input authorizations slice.
  1224. func (config *Config) SetDynamicConfig(sponsorID string, authorizations []string) {
  1225. config.dynamicConfigMutex.Lock()
  1226. defer config.dynamicConfigMutex.Unlock()
  1227. if sponsorID != "" {
  1228. config.sponsorID = sponsorID
  1229. }
  1230. config.authorizations = authorizations
  1231. }
  1232. // GetSponsorID returns the current client sponsor ID.
  1233. func (config *Config) GetSponsorID() string {
  1234. config.dynamicConfigMutex.Lock()
  1235. defer config.dynamicConfigMutex.Unlock()
  1236. return config.sponsorID
  1237. }
  1238. // IsSplitTunnelEnabled indicates if split tunnel mode is enabled, either for
  1239. // the client's own country, a specified list of countries, or both.
  1240. func (config *Config) IsSplitTunnelEnabled() bool {
  1241. return config.SplitTunnelOwnRegion || len(config.SplitTunnelRegions) > 0
  1242. }
  1243. // GetAuthorizations returns the current client authorizations.
  1244. // The caller must not modify the returned slice.
  1245. func (config *Config) GetAuthorizations() []string {
  1246. config.dynamicConfigMutex.Lock()
  1247. defer config.dynamicConfigMutex.Unlock()
  1248. return config.authorizations
  1249. }
  1250. // GetPsiphonDataDirectory returns the directory under which all persistent
  1251. // files should be stored. This directory is created under
  1252. // config.DataRootDirectory. The motivation for an additional directory is that
  1253. // config.DataRootDirectory defaults to the current working directory, which may
  1254. // include non-tunnel-core files that should be excluded from directory-spanning
  1255. // operations (e.g. excluding all tunnel-core files from backup).
  1256. func (config *Config) GetPsiphonDataDirectory() string {
  1257. return filepath.Join(config.DataRootDirectory, PsiphonDataDirectoryName)
  1258. }
  1259. // GetHomePageFilename the path where the homepage notices file will be created.
  1260. func (config *Config) GetHomePageFilename() string {
  1261. return filepath.Join(config.GetPsiphonDataDirectory(), HomepageFilename)
  1262. }
  1263. // GetNoticesFilename returns the path where the notices file will be created.
  1264. // When the file is rotated it will be moved to config.GetOldNoticesFilename().
  1265. func (config *Config) GetNoticesFilename() string {
  1266. return filepath.Join(config.GetPsiphonDataDirectory(), NoticesFilename)
  1267. }
  1268. // GetOldNoticeFilename returns the path where the rotated notices file will be
  1269. // created.
  1270. func (config *Config) GetOldNoticesFilename() string {
  1271. return filepath.Join(config.GetPsiphonDataDirectory(), OldNoticesFilename)
  1272. }
  1273. // GetDataStoreDirectory returns the directory in which the persistent database
  1274. // will be stored. Created in Config.Commit(). The persistent database contains
  1275. // information such as server entries.
  1276. func (config *Config) GetDataStoreDirectory() string {
  1277. return filepath.Join(config.GetPsiphonDataDirectory(), "datastore")
  1278. }
  1279. // GetObfuscatedServerListDownloadDirectory returns the directory in which
  1280. // obfuscated remote server list downloads will be stored. Created in
  1281. // Config.Commit().
  1282. func (config *Config) GetObfuscatedServerListDownloadDirectory() string {
  1283. return filepath.Join(config.GetPsiphonDataDirectory(), "osl")
  1284. }
  1285. // GetRemoteServerListDownloadFilename returns the filename where the remote
  1286. // server list download will be stored. Data is stored in co-located files
  1287. // (RemoteServerListDownloadFilename.part*) to allow for resumable downloading.
  1288. func (config *Config) GetRemoteServerListDownloadFilename() string {
  1289. return filepath.Join(config.GetPsiphonDataDirectory(), "remote_server_list")
  1290. }
  1291. // GetUpgradeDownloadFilename specifies the filename where upgrade downloads
  1292. // will be stored. This filename is valid when UpgradeDownloadURLs
  1293. // (or UpgradeDownloadUrl) is specified. Data is stored in co-located files
  1294. // (UpgradeDownloadFilename.part*) to allow for resumable downloading.
  1295. func (config *Config) GetUpgradeDownloadFilename() string {
  1296. return filepath.Join(config.GetPsiphonDataDirectory(), UpgradeDownloadFilename)
  1297. }
  1298. // UseUpstreamProxy indicates if an upstream proxy has been
  1299. // configured.
  1300. func (config *Config) UseUpstreamProxy() bool {
  1301. return config.UpstreamProxyURL != ""
  1302. }
  1303. // GetNetworkID returns the current network ID. When NetworkIDGetter
  1304. // is set, this calls into the host application; otherwise, a default
  1305. // value is returned.
  1306. func (config *Config) GetNetworkID() string {
  1307. return config.networkIDGetter.GetNetworkID()
  1308. }
  1309. func (config *Config) makeConfigParameters() map[string]interface{} {
  1310. // Build set of config values to apply to parameters.
  1311. //
  1312. // Note: names of some config fields such as
  1313. // StaggerConnectionWorkersMilliseconds and LimitMeekBufferSizes have
  1314. // changed in the parameters. The existing config fields are retained for
  1315. // backwards compatibility.
  1316. applyParameters := make(map[string]interface{})
  1317. // To support platform clients that configure NetworkLatencyMultiplier, set
  1318. // the NetworkLatencyMultiplierMin/NetworkLatencyMultiplierMax range to the
  1319. // specified value. Also set the older NetworkLatencyMultiplier tactic, since
  1320. // that will be used in the case of replaying with dial parameters persisted
  1321. // by an older client version.
  1322. if config.NetworkLatencyMultiplier > 0.0 {
  1323. applyParameters[parameters.NetworkLatencyMultiplier] = config.NetworkLatencyMultiplier
  1324. applyParameters[parameters.NetworkLatencyMultiplierMin] = config.NetworkLatencyMultiplier
  1325. applyParameters[parameters.NetworkLatencyMultiplierMax] = config.NetworkLatencyMultiplier
  1326. }
  1327. if config.NetworkLatencyMultiplierMin > 0.0 {
  1328. applyParameters[parameters.NetworkLatencyMultiplierMin] = config.NetworkLatencyMultiplierMin
  1329. }
  1330. if config.NetworkLatencyMultiplierMax > 0.0 {
  1331. applyParameters[parameters.NetworkLatencyMultiplierMax] = config.NetworkLatencyMultiplierMax
  1332. }
  1333. if config.NetworkLatencyMultiplierLambda > 0.0 {
  1334. applyParameters[parameters.NetworkLatencyMultiplierLambda] = config.NetworkLatencyMultiplierLambda
  1335. }
  1336. if len(config.LimitTunnelProtocols) > 0 {
  1337. applyParameters[parameters.LimitTunnelProtocols] = protocol.TunnelProtocols(config.LimitTunnelProtocols)
  1338. }
  1339. if len(config.InitialLimitTunnelProtocols) > 0 && config.InitialLimitTunnelProtocolsCandidateCount > 0 {
  1340. applyParameters[parameters.InitialLimitTunnelProtocols] = protocol.TunnelProtocols(config.InitialLimitTunnelProtocols)
  1341. applyParameters[parameters.InitialLimitTunnelProtocolsCandidateCount] = config.InitialLimitTunnelProtocolsCandidateCount
  1342. }
  1343. if len(config.LimitTLSProfiles) > 0 {
  1344. applyParameters[parameters.LimitTLSProfiles] = protocol.TunnelProtocols(config.LimitTLSProfiles)
  1345. }
  1346. if len(config.LimitQUICVersions) > 0 {
  1347. applyParameters[parameters.LimitQUICVersions] = protocol.QUICVersions(config.LimitQUICVersions)
  1348. }
  1349. if config.EstablishTunnelTimeoutSeconds != nil {
  1350. applyParameters[parameters.EstablishTunnelTimeout] = fmt.Sprintf("%ds", *config.EstablishTunnelTimeoutSeconds)
  1351. }
  1352. if config.EstablishTunnelServerAffinityGracePeriodMilliseconds != nil {
  1353. applyParameters[parameters.EstablishTunnelServerAffinityGracePeriod] = fmt.Sprintf("%dms", *config.EstablishTunnelServerAffinityGracePeriodMilliseconds)
  1354. }
  1355. if config.EstablishTunnelPausePeriodSeconds != nil {
  1356. applyParameters[parameters.EstablishTunnelPausePeriod] = fmt.Sprintf("%ds", *config.EstablishTunnelPausePeriodSeconds)
  1357. }
  1358. if config.ConnectionWorkerPoolSize != 0 {
  1359. applyParameters[parameters.ConnectionWorkerPoolSize] = config.ConnectionWorkerPoolSize
  1360. }
  1361. if config.TunnelPoolSize != 0 {
  1362. applyParameters[parameters.TunnelPoolSize] = config.TunnelPoolSize
  1363. }
  1364. if config.StaggerConnectionWorkersMilliseconds > 0 {
  1365. applyParameters[parameters.StaggerConnectionWorkersPeriod] = fmt.Sprintf("%dms", config.StaggerConnectionWorkersMilliseconds)
  1366. }
  1367. if config.LimitIntensiveConnectionWorkers > 0 {
  1368. applyParameters[parameters.LimitIntensiveConnectionWorkers] = config.LimitIntensiveConnectionWorkers
  1369. }
  1370. applyParameters[parameters.MeekLimitBufferSizes] = config.LimitMeekBufferSizes
  1371. applyParameters[parameters.IgnoreHandshakeStatsRegexps] = config.IgnoreHandshakeStatsRegexps
  1372. if config.EstablishTunnelTimeoutSeconds != nil {
  1373. applyParameters[parameters.EstablishTunnelTimeout] = fmt.Sprintf("%ds", *config.EstablishTunnelTimeoutSeconds)
  1374. }
  1375. if config.FetchRemoteServerListRetryPeriodMilliseconds != nil {
  1376. applyParameters[parameters.FetchRemoteServerListRetryPeriod] = fmt.Sprintf("%dms", *config.FetchRemoteServerListRetryPeriodMilliseconds)
  1377. }
  1378. if config.FetchUpgradeRetryPeriodMilliseconds != nil {
  1379. applyParameters[parameters.FetchUpgradeRetryPeriod] = fmt.Sprintf("%dms", *config.FetchUpgradeRetryPeriodMilliseconds)
  1380. }
  1381. if !config.DisableRemoteServerListFetcher {
  1382. if config.RemoteServerListURLs != nil {
  1383. applyParameters[parameters.RemoteServerListSignaturePublicKey] = config.RemoteServerListSignaturePublicKey
  1384. applyParameters[parameters.RemoteServerListURLs] = config.RemoteServerListURLs
  1385. }
  1386. if config.ObfuscatedServerListRootURLs != nil {
  1387. applyParameters[parameters.RemoteServerListSignaturePublicKey] = config.RemoteServerListSignaturePublicKey
  1388. applyParameters[parameters.ObfuscatedServerListRootURLs] = config.ObfuscatedServerListRootURLs
  1389. }
  1390. }
  1391. if config.EnableUpgradeDownload {
  1392. applyParameters[parameters.UpgradeDownloadURLs] = config.UpgradeDownloadURLs
  1393. applyParameters[parameters.UpgradeDownloadClientVersionHeader] = config.UpgradeDownloadClientVersionHeader
  1394. }
  1395. if config.EnableFeedbackUpload {
  1396. applyParameters[parameters.FeedbackUploadURLs] = config.FeedbackUploadURLs
  1397. applyParameters[parameters.FeedbackEncryptionPublicKey] = config.FeedbackEncryptionPublicKey
  1398. }
  1399. applyParameters[parameters.TunnelRateLimits] = config.RateLimits
  1400. if config.TransformHostNameProbability != nil {
  1401. applyParameters[parameters.TransformHostNameProbability] = *config.TransformHostNameProbability
  1402. }
  1403. if config.FragmentorProbability != nil {
  1404. applyParameters[parameters.FragmentorProbability] = *config.FragmentorProbability
  1405. }
  1406. if len(config.FragmentorLimitProtocols) > 0 {
  1407. applyParameters[parameters.FragmentorLimitProtocols] = protocol.TunnelProtocols(config.FragmentorLimitProtocols)
  1408. }
  1409. if config.FragmentorMinTotalBytes != nil {
  1410. applyParameters[parameters.FragmentorMinTotalBytes] = *config.FragmentorMinTotalBytes
  1411. }
  1412. if config.FragmentorMaxTotalBytes != nil {
  1413. applyParameters[parameters.FragmentorMaxTotalBytes] = *config.FragmentorMaxTotalBytes
  1414. }
  1415. if config.FragmentorMinWriteBytes != nil {
  1416. applyParameters[parameters.FragmentorMinWriteBytes] = *config.FragmentorMinWriteBytes
  1417. }
  1418. if config.FragmentorMaxWriteBytes != nil {
  1419. applyParameters[parameters.FragmentorMaxWriteBytes] = *config.FragmentorMaxWriteBytes
  1420. }
  1421. if config.FragmentorMinDelayMicroseconds != nil {
  1422. applyParameters[parameters.FragmentorMinDelay] = fmt.Sprintf("%dus", *config.FragmentorMinDelayMicroseconds)
  1423. }
  1424. if config.FragmentorMaxDelayMicroseconds != nil {
  1425. applyParameters[parameters.FragmentorMaxDelay] = fmt.Sprintf("%dus", *config.FragmentorMaxDelayMicroseconds)
  1426. }
  1427. if config.MeekTrafficShapingProbability != nil {
  1428. applyParameters[parameters.MeekTrafficShapingProbability] = *config.MeekTrafficShapingProbability
  1429. }
  1430. if len(config.MeekTrafficShapingLimitProtocols) > 0 {
  1431. applyParameters[parameters.MeekTrafficShapingLimitProtocols] = protocol.TunnelProtocols(config.MeekTrafficShapingLimitProtocols)
  1432. }
  1433. if config.MeekMinTLSPadding != nil {
  1434. applyParameters[parameters.MeekMinTLSPadding] = *config.MeekMinTLSPadding
  1435. }
  1436. if config.MeekMaxTLSPadding != nil {
  1437. applyParameters[parameters.MeekMaxTLSPadding] = *config.MeekMaxTLSPadding
  1438. }
  1439. if config.MeekMinLimitRequestPayloadLength != nil {
  1440. applyParameters[parameters.MeekMinLimitRequestPayloadLength] = *config.MeekMinLimitRequestPayloadLength
  1441. }
  1442. if config.MeekMaxLimitRequestPayloadLength != nil {
  1443. applyParameters[parameters.MeekMaxLimitRequestPayloadLength] = *config.MeekMaxLimitRequestPayloadLength
  1444. }
  1445. if config.MeekRedialTLSProbability != nil {
  1446. applyParameters[parameters.MeekRedialTLSProbability] = *config.MeekRedialTLSProbability
  1447. }
  1448. if config.MeekAlternateCookieNameProbability != nil {
  1449. applyParameters[parameters.MeekAlternateCookieNameProbability] = *config.MeekAlternateCookieNameProbability
  1450. }
  1451. if config.MeekAlternateContentTypeProbability != nil {
  1452. applyParameters[parameters.MeekAlternateContentTypeProbability] = *config.MeekAlternateContentTypeProbability
  1453. }
  1454. if config.ObfuscatedSSHMinPadding != nil {
  1455. applyParameters[parameters.ObfuscatedSSHMinPadding] = *config.ObfuscatedSSHMinPadding
  1456. }
  1457. if config.ObfuscatedSSHMaxPadding != nil {
  1458. applyParameters[parameters.ObfuscatedSSHMaxPadding] = *config.ObfuscatedSSHMaxPadding
  1459. }
  1460. if config.LivenessTestMinUpstreamBytes != nil {
  1461. applyParameters[parameters.LivenessTestMinUpstreamBytes] = *config.LivenessTestMinUpstreamBytes
  1462. }
  1463. if config.LivenessTestMaxUpstreamBytes != nil {
  1464. applyParameters[parameters.LivenessTestMaxUpstreamBytes] = *config.LivenessTestMaxUpstreamBytes
  1465. }
  1466. if config.LivenessTestMinDownstreamBytes != nil {
  1467. applyParameters[parameters.LivenessTestMinDownstreamBytes] = *config.LivenessTestMinDownstreamBytes
  1468. }
  1469. if config.LivenessTestMaxDownstreamBytes != nil {
  1470. applyParameters[parameters.LivenessTestMaxDownstreamBytes] = *config.LivenessTestMaxDownstreamBytes
  1471. }
  1472. if config.ReplayCandidateCount != nil {
  1473. applyParameters[parameters.ReplayCandidateCount] = *config.ReplayCandidateCount
  1474. }
  1475. if config.ReplayDialParametersTTLSeconds != nil {
  1476. applyParameters[parameters.ReplayDialParametersTTL] = fmt.Sprintf("%ds", *config.ReplayDialParametersTTLSeconds)
  1477. }
  1478. if config.ReplayTargetUpstreamBytes != nil {
  1479. applyParameters[parameters.ReplayTargetUpstreamBytes] = *config.ReplayTargetUpstreamBytes
  1480. }
  1481. if config.ReplayTargetDownstreamBytes != nil {
  1482. applyParameters[parameters.ReplayTargetDownstreamBytes] = *config.ReplayTargetDownstreamBytes
  1483. }
  1484. if config.ReplayTargetTunnelDurationSeconds != nil {
  1485. applyParameters[parameters.ReplayTargetTunnelDuration] = fmt.Sprintf("%ds", *config.ReplayTargetTunnelDurationSeconds)
  1486. }
  1487. if config.ReplayLaterRoundMoveToFrontProbability != nil {
  1488. applyParameters[parameters.ReplayLaterRoundMoveToFrontProbability] = *config.ReplayLaterRoundMoveToFrontProbability
  1489. }
  1490. if config.ReplayRetainFailedProbability != nil {
  1491. applyParameters[parameters.ReplayRetainFailedProbability] = *config.ReplayRetainFailedProbability
  1492. }
  1493. if config.ReplayIgnoreChangedConfigState != nil {
  1494. applyParameters[parameters.ReplayIgnoreChangedConfigState] = *config.ReplayIgnoreChangedConfigState
  1495. }
  1496. if config.UseOnlyCustomTLSProfiles != nil {
  1497. applyParameters[parameters.UseOnlyCustomTLSProfiles] = *config.UseOnlyCustomTLSProfiles
  1498. }
  1499. if len(config.CustomTLSProfiles) > 0 {
  1500. applyParameters[parameters.CustomTLSProfiles] = config.CustomTLSProfiles
  1501. }
  1502. if config.SelectRandomizedTLSProfileProbability != nil {
  1503. applyParameters[parameters.SelectRandomizedTLSProfileProbability] = *config.SelectRandomizedTLSProfileProbability
  1504. }
  1505. if config.NoDefaultTLSSessionIDProbability != nil {
  1506. applyParameters[parameters.NoDefaultTLSSessionIDProbability] = *config.NoDefaultTLSSessionIDProbability
  1507. }
  1508. if len(config.DisableFrontingProviderTLSProfiles) > 0 {
  1509. applyParameters[parameters.DisableFrontingProviderTLSProfiles] = config.DisableFrontingProviderTLSProfiles
  1510. }
  1511. if config.ClientBurstUpstreamTargetBytes != nil {
  1512. applyParameters[parameters.ClientBurstUpstreamTargetBytes] = *config.ClientBurstUpstreamTargetBytes
  1513. }
  1514. if config.ClientBurstUpstreamDeadlineMilliseconds != nil {
  1515. applyParameters[parameters.ClientBurstUpstreamDeadline] = fmt.Sprintf("%dms", *config.ClientBurstUpstreamDeadlineMilliseconds)
  1516. }
  1517. if config.ClientBurstDownstreamTargetBytes != nil {
  1518. applyParameters[parameters.ClientBurstDownstreamTargetBytes] = *config.ClientBurstDownstreamTargetBytes
  1519. }
  1520. if config.ClientBurstDownstreamDeadlineMilliseconds != nil {
  1521. applyParameters[parameters.ClientBurstDownstreamDeadline] = fmt.Sprintf("%dms", *config.ClientBurstDownstreamDeadlineMilliseconds)
  1522. }
  1523. if config.ApplicationParameters != nil {
  1524. applyParameters[parameters.ApplicationParameters] = config.ApplicationParameters
  1525. }
  1526. if config.CustomHostNameRegexes != nil {
  1527. applyParameters[parameters.CustomHostNameRegexes] = parameters.RegexStrings(config.CustomHostNameRegexes)
  1528. }
  1529. if config.CustomHostNameProbability != nil {
  1530. applyParameters[parameters.CustomHostNameProbability] = *config.CustomHostNameProbability
  1531. }
  1532. if config.CustomHostNameLimitProtocols != nil {
  1533. applyParameters[parameters.CustomHostNameLimitProtocols] = protocol.TunnelProtocols(config.CustomHostNameLimitProtocols)
  1534. }
  1535. if config.ConjureCachedRegistrationTTLSeconds != nil {
  1536. applyParameters[parameters.ConjureCachedRegistrationTTL] = fmt.Sprintf("%ds", *config.ConjureCachedRegistrationTTLSeconds)
  1537. }
  1538. if config.ConjureAPIRegistrarBidirectionalURL != "" {
  1539. applyParameters[parameters.ConjureAPIRegistrarBidirectionalURL] = config.ConjureAPIRegistrarBidirectionalURL
  1540. }
  1541. if len(config.ConjureAPIRegistrarFrontingSpecs) > 0 {
  1542. applyParameters[parameters.ConjureAPIRegistrarFrontingSpecs] = config.ConjureAPIRegistrarFrontingSpecs
  1543. }
  1544. if config.ConjureAPIRegistrarMinDelayMilliseconds != nil {
  1545. applyParameters[parameters.ConjureAPIRegistrarMinDelay] = fmt.Sprintf("%dms", *config.ConjureAPIRegistrarMinDelayMilliseconds)
  1546. }
  1547. if config.ConjureAPIRegistrarMaxDelayMilliseconds != nil {
  1548. applyParameters[parameters.ConjureAPIRegistrarMaxDelay] = fmt.Sprintf("%dms", *config.ConjureAPIRegistrarMaxDelayMilliseconds)
  1549. }
  1550. if config.ConjureDecoyRegistrarProbability != nil {
  1551. applyParameters[parameters.ConjureDecoyRegistrarProbability] = *config.ConjureDecoyRegistrarProbability
  1552. }
  1553. if config.ConjureDecoyRegistrarWidth != nil {
  1554. applyParameters[parameters.ConjureDecoyRegistrarWidth] = *config.ConjureDecoyRegistrarWidth
  1555. }
  1556. if config.ConjureDecoyRegistrarMinDelayMilliseconds != nil {
  1557. applyParameters[parameters.ConjureDecoyRegistrarMinDelay] = fmt.Sprintf("%dms", *config.ConjureDecoyRegistrarMinDelayMilliseconds)
  1558. }
  1559. if config.ConjureDecoyRegistrarMaxDelayMilliseconds != nil {
  1560. applyParameters[parameters.ConjureDecoyRegistrarMaxDelay] = fmt.Sprintf("%dms", *config.ConjureDecoyRegistrarMaxDelayMilliseconds)
  1561. }
  1562. if config.ConjureEnableIPv6Dials != nil {
  1563. applyParameters[parameters.ConjureEnableIPv6Dials] = *config.ConjureEnableIPv6Dials
  1564. }
  1565. if config.ConjureEnablePortRandomization != nil {
  1566. applyParameters[parameters.ConjureEnablePortRandomization] = *config.ConjureEnablePortRandomization
  1567. }
  1568. if config.ConjureEnableRegistrationOverrides != nil {
  1569. applyParameters[parameters.ConjureEnableRegistrationOverrides] = *config.ConjureEnableRegistrationOverrides
  1570. }
  1571. if config.ConjureLimitTransports != nil {
  1572. applyParameters[parameters.ConjureLimitTransports] = config.ConjureLimitTransports
  1573. }
  1574. if config.ConjureSTUNServerAddresses != nil {
  1575. applyParameters[parameters.ConjureSTUNServerAddresses] = config.ConjureSTUNServerAddresses
  1576. }
  1577. if config.ConjureDTLSEmptyInitialPacketProbability != nil {
  1578. applyParameters[parameters.ConjureDTLSEmptyInitialPacketProbability] = *config.ConjureDTLSEmptyInitialPacketProbability
  1579. }
  1580. if config.HoldOffTunnelMinDurationMilliseconds != nil {
  1581. applyParameters[parameters.HoldOffTunnelMinDuration] = fmt.Sprintf("%dms", *config.HoldOffTunnelMinDurationMilliseconds)
  1582. }
  1583. if config.HoldOffTunnelMaxDurationMilliseconds != nil {
  1584. applyParameters[parameters.HoldOffTunnelMaxDuration] = fmt.Sprintf("%dms", *config.HoldOffTunnelMaxDurationMilliseconds)
  1585. }
  1586. if len(config.HoldOffTunnelProtocols) > 0 {
  1587. applyParameters[parameters.HoldOffTunnelProtocols] = protocol.TunnelProtocols(config.HoldOffTunnelProtocols)
  1588. }
  1589. if len(config.HoldOffTunnelFrontingProviderIDs) > 0 {
  1590. applyParameters[parameters.HoldOffTunnelFrontingProviderIDs] = config.HoldOffTunnelFrontingProviderIDs
  1591. }
  1592. if config.HoldOffTunnelProbability != nil {
  1593. applyParameters[parameters.HoldOffTunnelProbability] = *config.HoldOffTunnelProbability
  1594. }
  1595. if len(config.RestrictFrontingProviderIDs) > 0 {
  1596. applyParameters[parameters.RestrictFrontingProviderIDs] = config.RestrictFrontingProviderIDs
  1597. }
  1598. if config.RestrictFrontingProviderIDsClientProbability != nil {
  1599. applyParameters[parameters.RestrictFrontingProviderIDsClientProbability] = *config.RestrictFrontingProviderIDsClientProbability
  1600. }
  1601. if config.UpstreamProxyAllowAllServerEntrySources != nil {
  1602. applyParameters[parameters.UpstreamProxyAllowAllServerEntrySources] = *config.UpstreamProxyAllowAllServerEntrySources
  1603. }
  1604. if len(config.LimitTunnelDialPortNumbers) > 0 {
  1605. applyParameters[parameters.LimitTunnelDialPortNumbers] = config.LimitTunnelDialPortNumbers
  1606. }
  1607. if config.QUICDisablePathMTUDiscoveryProbability != nil {
  1608. applyParameters[parameters.QUICDisableClientPathMTUDiscoveryProbability] = *config.QUICDisablePathMTUDiscoveryProbability
  1609. }
  1610. if config.DNSResolverAttemptsPerServer != nil {
  1611. applyParameters[parameters.DNSResolverAttemptsPerServer] = *config.DNSResolverAttemptsPerServer
  1612. }
  1613. if config.DNSResolverAttemptsPerPreferredServer != nil {
  1614. applyParameters[parameters.DNSResolverAttemptsPerPreferredServer] = *config.DNSResolverAttemptsPerPreferredServer
  1615. }
  1616. if config.DNSResolverRequestTimeoutMilliseconds != nil {
  1617. applyParameters[parameters.DNSResolverRequestTimeout] = fmt.Sprintf("%dms", *config.DNSResolverRequestTimeoutMilliseconds)
  1618. }
  1619. if config.DNSResolverAwaitTimeoutMilliseconds != nil {
  1620. applyParameters[parameters.DNSResolverAwaitTimeout] = fmt.Sprintf("%dms", *config.DNSResolverAwaitTimeoutMilliseconds)
  1621. }
  1622. if config.DNSResolverPreresolvedIPAddressProbability != nil {
  1623. applyParameters[parameters.DNSResolverPreresolvedIPAddressProbability] = *config.DNSResolverPreresolvedIPAddressProbability
  1624. }
  1625. if config.DNSResolverPreresolvedIPAddressCIDRs != nil {
  1626. applyParameters[parameters.DNSResolverPreresolvedIPAddressCIDRs] = config.DNSResolverPreresolvedIPAddressCIDRs
  1627. }
  1628. if config.DNSResolverAlternateServers != nil {
  1629. applyParameters[parameters.DNSResolverAlternateServers] = config.DNSResolverAlternateServers
  1630. }
  1631. if config.DNSResolverPreferredAlternateServers != nil {
  1632. applyParameters[parameters.DNSResolverPreferredAlternateServers] = config.DNSResolverPreferredAlternateServers
  1633. }
  1634. if config.DNSResolverPreferAlternateServerProbability != nil {
  1635. applyParameters[parameters.DNSResolverPreferAlternateServerProbability] = *config.DNSResolverPreferAlternateServerProbability
  1636. }
  1637. if config.DNSResolverProtocolTransformSpecs != nil {
  1638. applyParameters[parameters.DNSResolverProtocolTransformSpecs] = config.DNSResolverProtocolTransformSpecs
  1639. }
  1640. if config.DNSResolverProtocolTransformScopedSpecNames != nil {
  1641. applyParameters[parameters.DNSResolverProtocolTransformScopedSpecNames] = config.DNSResolverProtocolTransformScopedSpecNames
  1642. }
  1643. if config.DNSResolverProtocolTransformProbability != nil {
  1644. applyParameters[parameters.DNSResolverProtocolTransformProbability] = *config.DNSResolverProtocolTransformProbability
  1645. }
  1646. if config.DNSResolverIncludeEDNS0Probability != nil {
  1647. applyParameters[parameters.DNSResolverIncludeEDNS0Probability] = *config.DNSResolverIncludeEDNS0Probability
  1648. }
  1649. if config.DNSResolverCacheExtensionInitialTTLMilliseconds != nil {
  1650. applyParameters[parameters.DNSResolverCacheExtensionInitialTTL] = fmt.Sprintf("%dms", *config.DNSResolverCacheExtensionInitialTTLMilliseconds)
  1651. }
  1652. if config.DNSResolverCacheExtensionVerifiedTTLMilliseconds != nil {
  1653. applyParameters[parameters.DNSResolverCacheExtensionVerifiedTTL] = fmt.Sprintf("%dms", *config.DNSResolverCacheExtensionVerifiedTTLMilliseconds)
  1654. }
  1655. if config.DirectHTTPProtocolTransformSpecs != nil {
  1656. applyParameters[parameters.DirectHTTPProtocolTransformSpecs] = config.DirectHTTPProtocolTransformSpecs
  1657. }
  1658. if config.DirectHTTPProtocolTransformScopedSpecNames != nil {
  1659. applyParameters[parameters.DirectHTTPProtocolTransformScopedSpecNames] = config.DirectHTTPProtocolTransformScopedSpecNames
  1660. }
  1661. if config.DirectHTTPProtocolTransformProbability != nil {
  1662. applyParameters[parameters.DirectHTTPProtocolTransformProbability] = *config.DirectHTTPProtocolTransformProbability
  1663. }
  1664. if config.FrontedHTTPProtocolTransformSpecs != nil {
  1665. applyParameters[parameters.FrontedHTTPProtocolTransformSpecs] = config.FrontedHTTPProtocolTransformSpecs
  1666. }
  1667. if config.FrontedHTTPProtocolTransformScopedSpecNames != nil {
  1668. applyParameters[parameters.FrontedHTTPProtocolTransformScopedSpecNames] = config.FrontedHTTPProtocolTransformScopedSpecNames
  1669. }
  1670. if config.FrontedHTTPProtocolTransformProbability != nil {
  1671. applyParameters[parameters.FrontedHTTPProtocolTransformProbability] = *config.FrontedHTTPProtocolTransformProbability
  1672. }
  1673. if config.OSSHObfuscatorSeedTransformSpecs != nil {
  1674. applyParameters[parameters.OSSHObfuscatorSeedTransformSpecs] = config.OSSHObfuscatorSeedTransformSpecs
  1675. }
  1676. if config.OSSHObfuscatorSeedTransformScopedSpecNames != nil {
  1677. applyParameters[parameters.OSSHObfuscatorSeedTransformScopedSpecNames] = config.OSSHObfuscatorSeedTransformScopedSpecNames
  1678. }
  1679. if config.OSSHObfuscatorSeedTransformProbability != nil {
  1680. applyParameters[parameters.OSSHObfuscatorSeedTransformProbability] = *config.OSSHObfuscatorSeedTransformProbability
  1681. }
  1682. if config.ObfuscatedQUICNonceTransformSpecs != nil {
  1683. applyParameters[parameters.ObfuscatedQUICNonceTransformSpecs] = config.ObfuscatedQUICNonceTransformSpecs
  1684. }
  1685. if config.ObfuscatedQUICNonceTransformScopedSpecNames != nil {
  1686. applyParameters[parameters.ObfuscatedQUICNonceTransformScopedSpecNames] = config.ObfuscatedQUICNonceTransformScopedSpecNames
  1687. }
  1688. if config.ObfuscatedQUICNonceTransformProbability != nil {
  1689. applyParameters[parameters.ObfuscatedQUICNonceTransformProbability] = *config.ObfuscatedQUICNonceTransformProbability
  1690. }
  1691. if config.OSSHPrefixSpecs != nil {
  1692. applyParameters[parameters.OSSHPrefixSpecs] = config.OSSHPrefixSpecs
  1693. }
  1694. if config.OSSHPrefixScopedSpecNames != nil {
  1695. applyParameters[parameters.OSSHPrefixScopedSpecNames] = config.OSSHPrefixScopedSpecNames
  1696. }
  1697. if config.OSSHPrefixProbability != nil {
  1698. applyParameters[parameters.OSSHPrefixProbability] = *config.OSSHPrefixProbability
  1699. }
  1700. if config.OSSHPrefixSplitMinDelayMilliseconds != nil {
  1701. applyParameters[parameters.OSSHPrefixSplitMinDelay] = fmt.Sprintf("%dms", *config.OSSHPrefixSplitMinDelayMilliseconds)
  1702. }
  1703. if config.OSSHPrefixSplitMaxDelayMilliseconds != nil {
  1704. applyParameters[parameters.OSSHPrefixSplitMaxDelay] = fmt.Sprintf("%dms", *config.OSSHPrefixSplitMaxDelayMilliseconds)
  1705. }
  1706. if config.OSSHPrefixEnableFragmentor != nil {
  1707. applyParameters[parameters.OSSHPrefixEnableFragmentor] = *config.OSSHPrefixEnableFragmentor
  1708. }
  1709. if config.TLSTunnelTrafficShapingProbability != nil {
  1710. applyParameters[parameters.TLSTunnelTrafficShapingProbability] = *config.TLSTunnelTrafficShapingProbability
  1711. }
  1712. if config.TLSTunnelMinTLSPadding != nil {
  1713. applyParameters[parameters.TLSTunnelMinTLSPadding] = *config.TLSTunnelMinTLSPadding
  1714. }
  1715. if config.TLSTunnelMaxTLSPadding != nil {
  1716. applyParameters[parameters.TLSTunnelMaxTLSPadding] = *config.TLSTunnelMaxTLSPadding
  1717. }
  1718. if config.TLSFragmentClientHelloProbability != nil {
  1719. applyParameters[parameters.TLSFragmentClientHelloProbability] = *config.TLSFragmentClientHelloProbability
  1720. }
  1721. if len(config.TLSFragmentClientHelloLimitProtocols) > 0 {
  1722. applyParameters[parameters.TLSFragmentClientHelloLimitProtocols] = protocol.TunnelProtocols(config.TLSFragmentClientHelloLimitProtocols)
  1723. }
  1724. // When adding new config dial parameters that may override tactics, also
  1725. // update setDialParametersHash.
  1726. return applyParameters
  1727. }
  1728. func (config *Config) setDialParametersHash() {
  1729. // Calculate and store a hash of the config values that may impact
  1730. // dial parameters. This hash is used as part of the dial parameters
  1731. // replay mechanism to detect when persisted dial parameters should
  1732. // be discarded due to conflicting config changes.
  1733. //
  1734. // With a couple of minor exceptions, configuring dial parameters via the
  1735. // config is intended for testing only, and so these parameters are expected
  1736. // to be present in test runs only. It remains an important case to discard
  1737. // replay dial parameters when test config parameters are varied.
  1738. //
  1739. // Hashing the parameter names detects some ambiguous hash cases, such as two
  1740. // consecutive int64 parameters, one omitted and one not, that are flipped.
  1741. // The serialization is not completely unambiguous, and the format is
  1742. // currently limited by legacy cases (not invalidating replay dial parameters
  1743. // for production clients is more important than invalidating for test runs).
  1744. // We cannot hash the entire config JSON as it contains non-dial parameter
  1745. // fields which may frequently change across runs.
  1746. //
  1747. // MD5 hash is used solely as a data checksum and not for any security
  1748. // purpose.
  1749. hash := md5.New()
  1750. if len(config.LimitTunnelProtocols) > 0 {
  1751. hash.Write([]byte("LimitTunnelProtocols"))
  1752. for _, protocol := range config.LimitTunnelProtocols {
  1753. hash.Write([]byte(protocol))
  1754. }
  1755. }
  1756. if len(config.InitialLimitTunnelProtocols) > 0 && config.InitialLimitTunnelProtocolsCandidateCount > 0 {
  1757. hash.Write([]byte("InitialLimitTunnelProtocols"))
  1758. for _, protocol := range config.InitialLimitTunnelProtocols {
  1759. hash.Write([]byte(protocol))
  1760. }
  1761. binary.Write(hash, binary.LittleEndian, int64(config.InitialLimitTunnelProtocolsCandidateCount))
  1762. }
  1763. if len(config.LimitTLSProfiles) > 0 {
  1764. hash.Write([]byte("LimitTLSProfiles"))
  1765. for _, profile := range config.LimitTLSProfiles {
  1766. hash.Write([]byte(profile))
  1767. }
  1768. }
  1769. if len(config.LimitQUICVersions) > 0 {
  1770. hash.Write([]byte("LimitQUICVersions"))
  1771. for _, version := range config.LimitQUICVersions {
  1772. hash.Write([]byte(version))
  1773. }
  1774. }
  1775. // Whether a custom User-Agent is specified is a binary flag: when not set,
  1776. // the replay dial parameters value applies. When set, external
  1777. // considerations apply.
  1778. if _, ok := config.CustomHeaders["User-Agent"]; ok {
  1779. hash.Write([]byte("CustomHeaders User-Agent"))
  1780. hash.Write([]byte{1})
  1781. }
  1782. if config.UpstreamProxyURL != "" {
  1783. hash.Write([]byte("UpstreamProxyURL"))
  1784. hash.Write([]byte(config.UpstreamProxyURL))
  1785. }
  1786. if config.TransformHostNameProbability != nil {
  1787. hash.Write([]byte("TransformHostNameProbability"))
  1788. binary.Write(hash, binary.LittleEndian, *config.TransformHostNameProbability)
  1789. }
  1790. if config.FragmentorProbability != nil {
  1791. hash.Write([]byte("FragmentorProbability"))
  1792. binary.Write(hash, binary.LittleEndian, *config.FragmentorProbability)
  1793. }
  1794. if len(config.FragmentorLimitProtocols) > 0 {
  1795. hash.Write([]byte("FragmentorLimitProtocols"))
  1796. for _, protocol := range config.FragmentorLimitProtocols {
  1797. hash.Write([]byte(protocol))
  1798. }
  1799. }
  1800. if config.FragmentorMinTotalBytes != nil {
  1801. hash.Write([]byte("FragmentorMinTotalBytes"))
  1802. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMinTotalBytes))
  1803. }
  1804. if config.FragmentorMaxTotalBytes != nil {
  1805. hash.Write([]byte("FragmentorMaxTotalBytes"))
  1806. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMaxTotalBytes))
  1807. }
  1808. if config.FragmentorMinWriteBytes != nil {
  1809. hash.Write([]byte("FragmentorMinWriteBytes"))
  1810. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMinWriteBytes))
  1811. }
  1812. if config.FragmentorMaxWriteBytes != nil {
  1813. hash.Write([]byte("FragmentorMaxWriteBytes"))
  1814. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMaxWriteBytes))
  1815. }
  1816. if config.FragmentorMinDelayMicroseconds != nil {
  1817. hash.Write([]byte("FragmentorMinDelayMicroseconds"))
  1818. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMinDelayMicroseconds))
  1819. }
  1820. if config.FragmentorMaxDelayMicroseconds != nil {
  1821. hash.Write([]byte("FragmentorMaxDelayMicroseconds"))
  1822. binary.Write(hash, binary.LittleEndian, int64(*config.FragmentorMaxDelayMicroseconds))
  1823. }
  1824. if config.MeekTrafficShapingProbability != nil {
  1825. hash.Write([]byte("MeekTrafficShapingProbability"))
  1826. binary.Write(hash, binary.LittleEndian, *config.MeekTrafficShapingProbability)
  1827. }
  1828. if len(config.MeekTrafficShapingLimitProtocols) > 0 {
  1829. hash.Write([]byte("MeekTrafficShapingLimitProtocols"))
  1830. for _, protocol := range config.MeekTrafficShapingLimitProtocols {
  1831. hash.Write([]byte(protocol))
  1832. }
  1833. }
  1834. if config.MeekMinLimitRequestPayloadLength != nil {
  1835. hash.Write([]byte("MeekMinLimitRequestPayloadLength"))
  1836. binary.Write(hash, binary.LittleEndian, int64(*config.MeekMinLimitRequestPayloadLength))
  1837. }
  1838. if config.MeekMaxLimitRequestPayloadLength != nil {
  1839. hash.Write([]byte("MeekMaxLimitRequestPayloadLength"))
  1840. binary.Write(hash, binary.LittleEndian, int64(*config.MeekMaxLimitRequestPayloadLength))
  1841. }
  1842. if config.MeekRedialTLSProbability != nil {
  1843. hash.Write([]byte("MeekRedialTLSProbability"))
  1844. binary.Write(hash, binary.LittleEndian, *config.MeekRedialTLSProbability)
  1845. }
  1846. if config.ObfuscatedSSHMinPadding != nil {
  1847. hash.Write([]byte("ObfuscatedSSHMinPadding"))
  1848. binary.Write(hash, binary.LittleEndian, int64(*config.ObfuscatedSSHMinPadding))
  1849. }
  1850. if config.ObfuscatedSSHMaxPadding != nil {
  1851. hash.Write([]byte("ObfuscatedSSHMaxPadding"))
  1852. binary.Write(hash, binary.LittleEndian, int64(*config.ObfuscatedSSHMaxPadding))
  1853. }
  1854. if config.LivenessTestMinUpstreamBytes != nil {
  1855. hash.Write([]byte("LivenessTestMinUpstreamBytes"))
  1856. binary.Write(hash, binary.LittleEndian, int64(*config.LivenessTestMinUpstreamBytes))
  1857. }
  1858. if config.LivenessTestMaxUpstreamBytes != nil {
  1859. hash.Write([]byte("LivenessTestMaxUpstreamBytes"))
  1860. binary.Write(hash, binary.LittleEndian, int64(*config.LivenessTestMaxUpstreamBytes))
  1861. }
  1862. if config.LivenessTestMinDownstreamBytes != nil {
  1863. hash.Write([]byte("LivenessTestMinDownstreamBytes"))
  1864. binary.Write(hash, binary.LittleEndian, int64(*config.LivenessTestMinDownstreamBytes))
  1865. }
  1866. if config.LivenessTestMaxDownstreamBytes != nil {
  1867. hash.Write([]byte("LivenessTestMaxDownstreamBytes"))
  1868. binary.Write(hash, binary.LittleEndian, int64(*config.LivenessTestMaxDownstreamBytes))
  1869. }
  1870. // Legacy case: these parameters are included in the hash unconditionally,
  1871. // and so will impact almost all production clients. These parameter names
  1872. // are not hashed since that would invalidate all replay dial parameters for
  1873. // existing clients whose hashes predate the inclusion of parameter names.
  1874. binary.Write(hash, binary.LittleEndian, config.NetworkLatencyMultiplierMin)
  1875. binary.Write(hash, binary.LittleEndian, config.NetworkLatencyMultiplierMax)
  1876. binary.Write(hash, binary.LittleEndian, config.NetworkLatencyMultiplierLambda)
  1877. if config.UseOnlyCustomTLSProfiles != nil {
  1878. hash.Write([]byte("UseOnlyCustomTLSProfiles"))
  1879. binary.Write(hash, binary.LittleEndian, *config.UseOnlyCustomTLSProfiles)
  1880. }
  1881. if len(config.CustomTLSProfiles) > 0 {
  1882. hash.Write([]byte("CustomTLSProfiles"))
  1883. for _, customTLSProfile := range config.CustomTLSProfiles {
  1884. encodedCustomTLSProofile, _ := json.Marshal(customTLSProfile)
  1885. hash.Write(encodedCustomTLSProofile)
  1886. }
  1887. }
  1888. if config.SelectRandomizedTLSProfileProbability != nil {
  1889. hash.Write([]byte("SelectRandomizedTLSProfileProbability"))
  1890. binary.Write(hash, binary.LittleEndian, *config.SelectRandomizedTLSProfileProbability)
  1891. }
  1892. if config.NoDefaultTLSSessionIDProbability != nil {
  1893. hash.Write([]byte("NoDefaultTLSSessionIDProbability"))
  1894. binary.Write(hash, binary.LittleEndian, *config.NoDefaultTLSSessionIDProbability)
  1895. }
  1896. if len(config.DisableFrontingProviderTLSProfiles) > 0 {
  1897. hash.Write([]byte("DisableFrontingProviderTLSProfiles"))
  1898. encodedDisableFrontingProviderTLSProfiles, _ :=
  1899. json.Marshal(config.DisableFrontingProviderTLSProfiles)
  1900. hash.Write(encodedDisableFrontingProviderTLSProfiles)
  1901. }
  1902. if len(config.CustomHostNameRegexes) > 0 {
  1903. hash.Write([]byte("CustomHostNameRegexes"))
  1904. for _, customHostNameRegex := range config.CustomHostNameRegexes {
  1905. hash.Write([]byte(customHostNameRegex))
  1906. }
  1907. }
  1908. if config.CustomHostNameProbability != nil {
  1909. hash.Write([]byte("CustomHostNameProbability"))
  1910. binary.Write(hash, binary.LittleEndian, *config.CustomHostNameProbability)
  1911. }
  1912. if len(config.CustomHostNameLimitProtocols) > 0 {
  1913. hash.Write([]byte("CustomHostNameLimitProtocols"))
  1914. for _, protocol := range config.CustomHostNameLimitProtocols {
  1915. hash.Write([]byte(protocol))
  1916. }
  1917. }
  1918. if config.ConjureCachedRegistrationTTLSeconds != nil {
  1919. hash.Write([]byte("ConjureCachedRegistrationTTLSeconds"))
  1920. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureCachedRegistrationTTLSeconds))
  1921. }
  1922. if config.ConjureAPIRegistrarBidirectionalURL != "" {
  1923. hash.Write([]byte("ConjureAPIRegistrarBidirectionalURL"))
  1924. hash.Write([]byte(config.ConjureAPIRegistrarBidirectionalURL))
  1925. }
  1926. if len(config.ConjureAPIRegistrarFrontingSpecs) > 0 {
  1927. hash.Write([]byte("ConjureAPIRegistrarFrontingSpecs"))
  1928. for _, frontingSpec := range config.ConjureAPIRegistrarFrontingSpecs {
  1929. encodedFrontSpec, _ := json.Marshal(frontingSpec)
  1930. hash.Write(encodedFrontSpec)
  1931. }
  1932. }
  1933. if config.ConjureAPIRegistrarMinDelayMilliseconds != nil {
  1934. hash.Write([]byte("ConjureAPIRegistrarMinDelayMilliseconds"))
  1935. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureAPIRegistrarMinDelayMilliseconds))
  1936. }
  1937. if config.ConjureAPIRegistrarMaxDelayMilliseconds != nil {
  1938. hash.Write([]byte("ConjureAPIRegistrarMaxDelayMilliseconds"))
  1939. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureAPIRegistrarMaxDelayMilliseconds))
  1940. }
  1941. if config.ConjureDecoyRegistrarWidth != nil {
  1942. hash.Write([]byte("ConjureDecoyRegistrarWidth"))
  1943. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureDecoyRegistrarWidth))
  1944. }
  1945. if config.ConjureDecoyRegistrarMinDelayMilliseconds != nil {
  1946. hash.Write([]byte("ConjureDecoyRegistrarMinDelayMilliseconds"))
  1947. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureDecoyRegistrarMinDelayMilliseconds))
  1948. }
  1949. if config.ConjureDecoyRegistrarMaxDelayMilliseconds != nil {
  1950. hash.Write([]byte("ConjureDecoyRegistrarMaxDelayMilliseconds"))
  1951. binary.Write(hash, binary.LittleEndian, int64(*config.ConjureDecoyRegistrarMaxDelayMilliseconds))
  1952. }
  1953. if config.ConjureLimitTransports != nil {
  1954. hash.Write([]byte("ConjureLimitTransports"))
  1955. for _, transport := range config.ConjureLimitTransports {
  1956. hash.Write([]byte(transport))
  1957. }
  1958. }
  1959. if config.ConjureSTUNServerAddresses != nil {
  1960. hash.Write([]byte("ConjureSTUNServerAddresses"))
  1961. for _, address := range config.ConjureSTUNServerAddresses {
  1962. hash.Write([]byte(address))
  1963. }
  1964. }
  1965. if config.HoldOffTunnelMinDurationMilliseconds != nil {
  1966. hash.Write([]byte("HoldOffTunnelMinDurationMilliseconds"))
  1967. binary.Write(hash, binary.LittleEndian, int64(*config.HoldOffTunnelMinDurationMilliseconds))
  1968. }
  1969. if config.HoldOffTunnelMaxDurationMilliseconds != nil {
  1970. hash.Write([]byte("HoldOffTunnelMaxDurationMilliseconds"))
  1971. binary.Write(hash, binary.LittleEndian, int64(*config.HoldOffTunnelMaxDurationMilliseconds))
  1972. }
  1973. if len(config.HoldOffTunnelProtocols) > 0 {
  1974. hash.Write([]byte("HoldOffTunnelProtocols"))
  1975. for _, protocol := range config.HoldOffTunnelProtocols {
  1976. hash.Write([]byte(protocol))
  1977. }
  1978. }
  1979. if len(config.HoldOffTunnelFrontingProviderIDs) > 0 {
  1980. hash.Write([]byte("HoldOffTunnelFrontingProviderIDs"))
  1981. for _, providerID := range config.HoldOffTunnelFrontingProviderIDs {
  1982. hash.Write([]byte(providerID))
  1983. }
  1984. }
  1985. if config.HoldOffTunnelProbability != nil {
  1986. hash.Write([]byte("HoldOffTunnelProbability"))
  1987. binary.Write(hash, binary.LittleEndian, *config.HoldOffTunnelProbability)
  1988. }
  1989. if len(config.RestrictFrontingProviderIDs) > 0 {
  1990. hash.Write([]byte("RestrictFrontingProviderIDs"))
  1991. for _, providerID := range config.RestrictFrontingProviderIDs {
  1992. hash.Write([]byte(providerID))
  1993. }
  1994. }
  1995. if config.RestrictFrontingProviderIDsClientProbability != nil {
  1996. hash.Write([]byte("RestrictFrontingProviderIDsClientProbability"))
  1997. binary.Write(hash, binary.LittleEndian, *config.RestrictFrontingProviderIDsClientProbability)
  1998. }
  1999. if config.UpstreamProxyAllowAllServerEntrySources != nil {
  2000. hash.Write([]byte("UpstreamProxyAllowAllServerEntrySources"))
  2001. binary.Write(hash, binary.LittleEndian, *config.UpstreamProxyAllowAllServerEntrySources)
  2002. }
  2003. if len(config.LimitTunnelDialPortNumbers) > 0 {
  2004. hash.Write([]byte("LimitTunnelDialPortNumbers"))
  2005. encodedLimitTunnelDialPortNumbers, _ :=
  2006. json.Marshal(config.LimitTunnelDialPortNumbers)
  2007. hash.Write(encodedLimitTunnelDialPortNumbers)
  2008. }
  2009. if config.QUICDisablePathMTUDiscoveryProbability != nil {
  2010. hash.Write([]byte("QUICDisablePathMTUDiscoveryProbability"))
  2011. binary.Write(hash, binary.LittleEndian, *config.QUICDisablePathMTUDiscoveryProbability)
  2012. }
  2013. if config.DNSResolverAttemptsPerServer != nil {
  2014. hash.Write([]byte("DNSResolverAttemptsPerServer"))
  2015. binary.Write(hash, binary.LittleEndian, int64(*config.DNSResolverAttemptsPerServer))
  2016. }
  2017. if config.DNSResolverRequestTimeoutMilliseconds != nil {
  2018. hash.Write([]byte("DNSResolverRequestTimeoutMilliseconds"))
  2019. binary.Write(hash, binary.LittleEndian, int64(*config.DNSResolverRequestTimeoutMilliseconds))
  2020. }
  2021. if config.DNSResolverAwaitTimeoutMilliseconds != nil {
  2022. hash.Write([]byte("DNSResolverAwaitTimeoutMilliseconds"))
  2023. binary.Write(hash, binary.LittleEndian, int64(*config.DNSResolverAwaitTimeoutMilliseconds))
  2024. }
  2025. if config.DNSResolverPreresolvedIPAddressCIDRs != nil {
  2026. hash.Write([]byte("DNSResolverPreresolvedIPAddressCIDRs"))
  2027. encodedDNSResolverPreresolvedIPAddressCIDRs, _ :=
  2028. json.Marshal(config.DNSResolverPreresolvedIPAddressCIDRs)
  2029. hash.Write(encodedDNSResolverPreresolvedIPAddressCIDRs)
  2030. }
  2031. if config.DNSResolverPreresolvedIPAddressProbability != nil {
  2032. hash.Write([]byte("DNSResolverPreresolvedIPAddressProbability"))
  2033. binary.Write(hash, binary.LittleEndian, *config.DNSResolverPreresolvedIPAddressProbability)
  2034. }
  2035. if config.DNSResolverAlternateServers != nil {
  2036. hash.Write([]byte("DNSResolverAlternateServers"))
  2037. for _, server := range config.DNSResolverAlternateServers {
  2038. hash.Write([]byte(server))
  2039. }
  2040. }
  2041. if config.DNSResolverPreferAlternateServerProbability != nil {
  2042. hash.Write([]byte("DNSResolverPreferAlternateServerProbability"))
  2043. binary.Write(hash, binary.LittleEndian, *config.DNSResolverPreferAlternateServerProbability)
  2044. }
  2045. if config.DNSResolverProtocolTransformSpecs != nil {
  2046. hash.Write([]byte("DNSResolverProtocolTransformSpecs"))
  2047. encodedDNSResolverProtocolTransformSpecs, _ :=
  2048. json.Marshal(config.DNSResolverProtocolTransformSpecs)
  2049. hash.Write(encodedDNSResolverProtocolTransformSpecs)
  2050. }
  2051. if config.DNSResolverProtocolTransformScopedSpecNames != nil {
  2052. hash.Write([]byte("DNSResolverProtocolTransformScopedSpecNames"))
  2053. encodedDNSResolverProtocolTransformScopedSpecNames, _ :=
  2054. json.Marshal(config.DNSResolverProtocolTransformScopedSpecNames)
  2055. hash.Write(encodedDNSResolverProtocolTransformScopedSpecNames)
  2056. }
  2057. if config.DNSResolverProtocolTransformProbability != nil {
  2058. hash.Write([]byte("DNSResolverProtocolTransformProbability"))
  2059. binary.Write(hash, binary.LittleEndian, *config.DNSResolverProtocolTransformProbability)
  2060. }
  2061. if config.DNSResolverIncludeEDNS0Probability != nil {
  2062. hash.Write([]byte("DNSResolverIncludeEDNS0Probability"))
  2063. binary.Write(hash, binary.LittleEndian, *config.DNSResolverIncludeEDNS0Probability)
  2064. }
  2065. if config.DNSResolverCacheExtensionInitialTTLMilliseconds != nil {
  2066. hash.Write([]byte("DNSResolverCacheExtensionInitialTTLMilliseconds"))
  2067. binary.Write(hash, binary.LittleEndian, int64(*config.DNSResolverCacheExtensionInitialTTLMilliseconds))
  2068. }
  2069. if config.DNSResolverCacheExtensionVerifiedTTLMilliseconds != nil {
  2070. hash.Write([]byte("DNSResolverCacheExtensionVerifiedTTLMilliseconds"))
  2071. binary.Write(hash, binary.LittleEndian, int64(*config.DNSResolverCacheExtensionVerifiedTTLMilliseconds))
  2072. }
  2073. if config.DirectHTTPProtocolTransformSpecs != nil {
  2074. hash.Write([]byte("DirectHTTPProtocolTransformSpecs"))
  2075. encodedDirectHTTPProtocolTransformSpecs, _ :=
  2076. json.Marshal(config.DirectHTTPProtocolTransformSpecs)
  2077. hash.Write(encodedDirectHTTPProtocolTransformSpecs)
  2078. }
  2079. if config.DirectHTTPProtocolTransformScopedSpecNames != nil {
  2080. hash.Write([]byte("DirectHTTPProtocolTransformScopedSpecNames"))
  2081. encodedDirectHTTPProtocolTransformScopedSpecNames, _ :=
  2082. json.Marshal(config.DirectHTTPProtocolTransformScopedSpecNames)
  2083. hash.Write(encodedDirectHTTPProtocolTransformScopedSpecNames)
  2084. }
  2085. if config.DirectHTTPProtocolTransformProbability != nil {
  2086. hash.Write([]byte("DirectHTTPProtocolTransformProbability"))
  2087. binary.Write(hash, binary.LittleEndian, *config.DirectHTTPProtocolTransformProbability)
  2088. }
  2089. if config.FrontedHTTPProtocolTransformSpecs != nil {
  2090. hash.Write([]byte("FrontedHTTPProtocolTransformSpecs"))
  2091. encodedFrontedHTTPProtocolTransformSpecs, _ :=
  2092. json.Marshal(config.FrontedHTTPProtocolTransformSpecs)
  2093. hash.Write(encodedFrontedHTTPProtocolTransformSpecs)
  2094. }
  2095. if config.FrontedHTTPProtocolTransformScopedSpecNames != nil {
  2096. hash.Write([]byte("FrontedHTTPProtocolTransformScopedSpecNames"))
  2097. encodedFrontedHTTPProtocolTransformScopedSpecNames, _ :=
  2098. json.Marshal(config.FrontedHTTPProtocolTransformScopedSpecNames)
  2099. hash.Write(encodedFrontedHTTPProtocolTransformScopedSpecNames)
  2100. }
  2101. if config.FrontedHTTPProtocolTransformProbability != nil {
  2102. hash.Write([]byte("FrontedHTTPProtocolTransformProbability"))
  2103. binary.Write(hash, binary.LittleEndian, *config.FrontedHTTPProtocolTransformProbability)
  2104. }
  2105. if config.OSSHObfuscatorSeedTransformSpecs != nil {
  2106. hash.Write([]byte("OSSHObfuscatorSeedTransformSpecs"))
  2107. encodedOSSHObfuscatorSeedTransformSpecs, _ :=
  2108. json.Marshal(config.OSSHObfuscatorSeedTransformSpecs)
  2109. hash.Write(encodedOSSHObfuscatorSeedTransformSpecs)
  2110. }
  2111. if config.OSSHObfuscatorSeedTransformScopedSpecNames != nil {
  2112. hash.Write([]byte("OSSHObfuscatorSeedTransformScopedSpecNames"))
  2113. encodedOSSHObfuscatorSeedTransformScopedSpecNames, _ :=
  2114. json.Marshal(config.OSSHObfuscatorSeedTransformScopedSpecNames)
  2115. hash.Write(encodedOSSHObfuscatorSeedTransformScopedSpecNames)
  2116. }
  2117. if config.OSSHObfuscatorSeedTransformProbability != nil {
  2118. hash.Write([]byte("OSSHObfuscatorSeedTransformProbability"))
  2119. binary.Write(hash, binary.LittleEndian, *config.OSSHObfuscatorSeedTransformProbability)
  2120. }
  2121. if config.ObfuscatedQUICNonceTransformSpecs != nil {
  2122. hash.Write([]byte("ObfuscatedQUICNonceTransformSpecs"))
  2123. encodedObfuscatedQUICNonceTransformSpecs, _ :=
  2124. json.Marshal(config.ObfuscatedQUICNonceTransformSpecs)
  2125. hash.Write(encodedObfuscatedQUICNonceTransformSpecs)
  2126. }
  2127. if config.ObfuscatedQUICNonceTransformScopedSpecNames != nil {
  2128. hash.Write([]byte("ObfuscatedQUICNonceTransformScopedSpecNames"))
  2129. encodedObfuscatedQUICNonceTransformScopedSpecNames, _ :=
  2130. json.Marshal(config.ObfuscatedQUICNonceTransformScopedSpecNames)
  2131. hash.Write(encodedObfuscatedQUICNonceTransformScopedSpecNames)
  2132. }
  2133. if config.ObfuscatedQUICNonceTransformProbability != nil {
  2134. hash.Write([]byte("ObfuscatedQUICNonceTransformProbability"))
  2135. binary.Write(hash, binary.LittleEndian, *config.ObfuscatedQUICNonceTransformProbability)
  2136. }
  2137. if config.OSSHPrefixSpecs != nil {
  2138. hash.Write([]byte("OSSHPrefixSpecs"))
  2139. encodedOSSHPrefixSpecs, _ := json.Marshal(config.OSSHPrefixSpecs)
  2140. hash.Write(encodedOSSHPrefixSpecs)
  2141. }
  2142. if config.OSSHPrefixScopedSpecNames != nil {
  2143. hash.Write([]byte("OSSHPrefixScopedSpecNames"))
  2144. encodedOSSHPrefixScopedSpecNames, _ := json.Marshal(config.OSSHPrefixScopedSpecNames)
  2145. hash.Write(encodedOSSHPrefixScopedSpecNames)
  2146. }
  2147. if config.OSSHPrefixProbability != nil {
  2148. hash.Write([]byte("OSSHPrefixProbability"))
  2149. binary.Write(hash, binary.LittleEndian, *config.OSSHPrefixProbability)
  2150. }
  2151. if config.OSSHPrefixSplitMinDelayMilliseconds != nil {
  2152. hash.Write([]byte("OSSHPrefixSplitMinDelayMilliseconds"))
  2153. binary.Write(hash, binary.LittleEndian, int64(*config.OSSHPrefixSplitMinDelayMilliseconds))
  2154. }
  2155. if config.OSSHPrefixSplitMaxDelayMilliseconds != nil {
  2156. hash.Write([]byte("OSSHPrefixSplitMaxDelayMilliseconds"))
  2157. binary.Write(hash, binary.LittleEndian, int64(*config.OSSHPrefixSplitMaxDelayMilliseconds))
  2158. }
  2159. if config.OSSHPrefixEnableFragmentor != nil {
  2160. hash.Write([]byte("OSSHPrefixEnableFragmentor"))
  2161. binary.Write(hash, binary.LittleEndian, *config.OSSHPrefixEnableFragmentor)
  2162. }
  2163. if config.TLSTunnelTrafficShapingProbability != nil {
  2164. hash.Write([]byte("TLSTunnelTrafficShapingProbability"))
  2165. binary.Write(hash, binary.LittleEndian, *config.TLSTunnelTrafficShapingProbability)
  2166. }
  2167. if config.TLSTunnelMinTLSPadding != nil {
  2168. hash.Write([]byte("TLSTunnelMinTLSPadding"))
  2169. binary.Write(hash, binary.LittleEndian, int64(*config.TLSTunnelMinTLSPadding))
  2170. }
  2171. if config.TLSTunnelMaxTLSPadding != nil {
  2172. hash.Write([]byte("TLSTunnelMaxTLSPadding"))
  2173. binary.Write(hash, binary.LittleEndian, int64(*config.TLSTunnelMaxTLSPadding))
  2174. }
  2175. if config.TLSFragmentClientHelloProbability != nil {
  2176. hash.Write([]byte("TLSFragmentClientHelloProbability"))
  2177. binary.Write(hash, binary.LittleEndian, *config.TLSFragmentClientHelloProbability)
  2178. }
  2179. if len(config.TLSFragmentClientHelloLimitProtocols) > 0 {
  2180. hash.Write([]byte("TLSFragmentClientHelloLimitProtocols"))
  2181. for _, protocol := range config.TLSFragmentClientHelloLimitProtocols {
  2182. hash.Write([]byte(protocol))
  2183. }
  2184. }
  2185. config.dialParametersHash = hash.Sum(nil)
  2186. }
  2187. // applyAdditionalParameters decodes and applies any additional parameters
  2188. // stored in config.AdditionalParameter to the Config and returns an array
  2189. // of notices which should be logged at the info level. If there is no error,
  2190. // then config.AdditionalParameter is set to "" to conserve memory and further
  2191. // calls will do nothing. This function should only be called once.
  2192. //
  2193. // If there is an error, the existing Config is left entirely unmodified.
  2194. func (config *Config) applyAdditionalParameters() ([]string, error) {
  2195. if config.AdditionalParameters == "" {
  2196. return nil, nil
  2197. }
  2198. b, err := base64.StdEncoding.DecodeString(config.AdditionalParameters)
  2199. if err != nil {
  2200. return nil, errors.Trace(err)
  2201. }
  2202. if len(b) < 32 {
  2203. return nil, errors.Tracef("invalid length, len(b) == %d", len(b))
  2204. }
  2205. var key [32]byte
  2206. copy(key[:], b[:32])
  2207. decrypted, ok := secretbox.Open(nil, b[32:], &[24]byte{}, &key)
  2208. if !ok {
  2209. return nil, errors.TraceNew("secretbox.Open failed")
  2210. }
  2211. var additionalParameters Config
  2212. err = json.Unmarshal(decrypted, &additionalParameters)
  2213. if err != nil {
  2214. return nil, errors.Trace(err)
  2215. }
  2216. src := reflect.ValueOf(&additionalParameters).Elem()
  2217. dest := reflect.ValueOf(config).Elem()
  2218. var infoNotices []string
  2219. for i := 0; i < src.NumField(); i++ {
  2220. if !src.Field(i).IsZero() {
  2221. dest.Field(i).Set(src.Field(i))
  2222. infoNotice := fmt.Sprintf("%s overridden by AdditionalParameters", dest.Type().Field(i).Name)
  2223. infoNotices = append(infoNotices, infoNotice)
  2224. }
  2225. }
  2226. // Reset field to conserve memory since this is a one-time operation.
  2227. config.AdditionalParameters = ""
  2228. return infoNotices, nil
  2229. }
  2230. func promoteLegacyTransferURL(URL string) parameters.TransferURLs {
  2231. transferURLs := make(parameters.TransferURLs, 1)
  2232. transferURLs[0] = &parameters.TransferURL{
  2233. URL: base64.StdEncoding.EncodeToString([]byte(URL)),
  2234. SkipVerify: false,
  2235. OnlyAfterAttempts: 0,
  2236. }
  2237. return transferURLs
  2238. }
  2239. type loggingDeviceBinder struct {
  2240. d DeviceBinder
  2241. }
  2242. func newLoggingDeviceBinder(d DeviceBinder) *loggingDeviceBinder {
  2243. return &loggingDeviceBinder{d: d}
  2244. }
  2245. func (d *loggingDeviceBinder) BindToDevice(fileDescriptor int) (string, error) {
  2246. deviceInfo, err := d.d.BindToDevice(fileDescriptor)
  2247. if err == nil && deviceInfo != "" {
  2248. NoticeBindToDevice(deviceInfo)
  2249. }
  2250. return deviceInfo, err
  2251. }
  2252. type staticNetworkGetter struct {
  2253. networkID string
  2254. }
  2255. func newStaticNetworkGetter(networkID string) *staticNetworkGetter {
  2256. return &staticNetworkGetter{networkID: networkID}
  2257. }
  2258. func (n *staticNetworkGetter) GetNetworkID() string {
  2259. return n.networkID
  2260. }
  2261. type loggingNetworkIDGetter struct {
  2262. n NetworkIDGetter
  2263. }
  2264. func newLoggingNetworkIDGetter(n NetworkIDGetter) *loggingNetworkIDGetter {
  2265. return &loggingNetworkIDGetter{n: n}
  2266. }
  2267. func (n *loggingNetworkIDGetter) GetNetworkID() string {
  2268. networkID := n.n.GetNetworkID()
  2269. // All PII must appear after the initial "-"
  2270. // See: https://godoc.org/github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon#NetworkIDGetter
  2271. logNetworkID := networkID
  2272. index := strings.Index(logNetworkID, "-")
  2273. if index != -1 {
  2274. logNetworkID = logNetworkID[:index]
  2275. }
  2276. if len(logNetworkID)+1 < len(networkID) {
  2277. // Indicate when additional network info was present after the first "-".
  2278. logNetworkID += "+[redacted]"
  2279. }
  2280. NoticeNetworkID(logNetworkID)
  2281. return networkID
  2282. }
  2283. // migrationsFromLegacyNoticeFilePaths returns the file migrations which must be
  2284. // performed to move notice files from legacy file paths, which were configured
  2285. // with the legacy config fields HomepageNoticesFilename and
  2286. // RotatingNoticesFilename, to the new file paths used by Psiphon which exist
  2287. // under the data root directory.
  2288. func migrationsFromLegacyNoticeFilePaths(config *Config) []FileMigration {
  2289. var noticeMigrations []FileMigration
  2290. if config.MigrateHomepageNoticesFilename != "" {
  2291. noticeMigrations = append(noticeMigrations, FileMigration{
  2292. Name: "hompage",
  2293. OldPath: config.MigrateHomepageNoticesFilename,
  2294. NewPath: config.GetHomePageFilename(),
  2295. })
  2296. }
  2297. if config.MigrateRotatingNoticesFilename != "" {
  2298. migrations := []FileMigration{
  2299. {
  2300. Name: "notices",
  2301. OldPath: config.MigrateRotatingNoticesFilename,
  2302. NewPath: config.GetNoticesFilename(),
  2303. IsDir: false,
  2304. },
  2305. {
  2306. Name: "notices.1",
  2307. OldPath: config.MigrateRotatingNoticesFilename + ".1",
  2308. NewPath: config.GetNoticesFilename() + ".1",
  2309. },
  2310. }
  2311. noticeMigrations = append(noticeMigrations, migrations...)
  2312. }
  2313. return noticeMigrations
  2314. }
  2315. // migrationsFromLegacyFilePaths returns the file migrations which must be
  2316. // performed to move files from legacy file paths, which were configured with
  2317. // legacy config fields, to the new file paths used by Psiphon which exist
  2318. // under the data root directory.
  2319. // Note: an attempt is made to redact any file paths from the returned error.
  2320. func migrationsFromLegacyFilePaths(config *Config) ([]FileMigration, error) {
  2321. migrations := []FileMigration{
  2322. {
  2323. Name: "psiphon.boltdb",
  2324. OldPath: filepath.Join(config.MigrateDataStoreDirectory, "psiphon.boltdb"),
  2325. NewPath: filepath.Join(config.GetDataStoreDirectory(), "psiphon.boltdb"),
  2326. },
  2327. {
  2328. Name: "psiphon.boltdb.lock",
  2329. OldPath: filepath.Join(config.MigrateDataStoreDirectory, "psiphon.boltdb.lock"),
  2330. NewPath: filepath.Join(config.GetDataStoreDirectory(), "psiphon.boltdb.lock"),
  2331. },
  2332. }
  2333. if config.MigrateRemoteServerListDownloadFilename != "" {
  2334. // Migrate remote server list files
  2335. rslMigrations := []FileMigration{
  2336. {
  2337. Name: "remote_server_list",
  2338. OldPath: config.MigrateRemoteServerListDownloadFilename,
  2339. NewPath: config.GetRemoteServerListDownloadFilename(),
  2340. },
  2341. {
  2342. Name: "remote_server_list.part",
  2343. OldPath: config.MigrateRemoteServerListDownloadFilename + ".part",
  2344. NewPath: config.GetRemoteServerListDownloadFilename() + ".part",
  2345. },
  2346. {
  2347. Name: "remote_server_list.part.etag",
  2348. OldPath: config.MigrateRemoteServerListDownloadFilename + ".part.etag",
  2349. NewPath: config.GetRemoteServerListDownloadFilename() + ".part.etag",
  2350. },
  2351. }
  2352. migrations = append(migrations, rslMigrations...)
  2353. }
  2354. if config.MigrateObfuscatedServerListDownloadDirectory != "" {
  2355. // Migrate OSL registry file and downloads
  2356. oslFileRegex, err := regexp.Compile(`^osl-.+$`)
  2357. if err != nil {
  2358. return nil, errors.TraceMsg(err, "failed to compile regex for osl files")
  2359. }
  2360. files, err := ioutil.ReadDir(config.MigrateObfuscatedServerListDownloadDirectory)
  2361. if err != nil {
  2362. NoticeWarning(
  2363. "Migration: failed to read OSL download directory with error %s",
  2364. common.RedactFilePathsError(err, config.MigrateObfuscatedServerListDownloadDirectory))
  2365. } else {
  2366. for _, file := range files {
  2367. if oslFileRegex.MatchString(file.Name()) {
  2368. fileMigration := FileMigration{
  2369. Name: "osl",
  2370. OldPath: filepath.Join(config.MigrateObfuscatedServerListDownloadDirectory, file.Name()),
  2371. NewPath: filepath.Join(config.GetObfuscatedServerListDownloadDirectory(), file.Name()),
  2372. }
  2373. migrations = append(migrations, fileMigration)
  2374. }
  2375. }
  2376. }
  2377. }
  2378. if config.MigrateUpgradeDownloadFilename != "" {
  2379. // Migrate downloaded upgrade files
  2380. oldUpgradeDownloadFilename := filepath.Base(config.MigrateUpgradeDownloadFilename)
  2381. // Create regex for:
  2382. // <old_upgrade_download_filename>
  2383. // <old_upgrade_download_filename>.<client_version_number>
  2384. // <old_upgrade_download_filename>.<client_version_number>.part
  2385. // <old_upgrade_download_filename>.<client_version_number>.part.etag
  2386. upgradeDownloadFileRegex, err := regexp.Compile(`^` + oldUpgradeDownloadFilename + `(\.\d+(\.part(\.etag)?)?)?$`)
  2387. if err != nil {
  2388. return nil, errors.TraceMsg(err, "failed to compile regex for upgrade files")
  2389. }
  2390. upgradeDownloadDir := filepath.Dir(config.MigrateUpgradeDownloadFilename)
  2391. files, err := ioutil.ReadDir(upgradeDownloadDir)
  2392. if err != nil {
  2393. NoticeWarning(
  2394. "Migration: failed to read upgrade download directory with error %s",
  2395. common.RedactFilePathsError(err, upgradeDownloadDir))
  2396. } else {
  2397. for _, file := range files {
  2398. if upgradeDownloadFileRegex.MatchString(file.Name()) {
  2399. oldFileSuffix := strings.TrimPrefix(file.Name(), oldUpgradeDownloadFilename)
  2400. fileMigration := FileMigration{
  2401. Name: "upgrade",
  2402. OldPath: filepath.Join(upgradeDownloadDir, file.Name()),
  2403. NewPath: config.GetUpgradeDownloadFilename() + oldFileSuffix,
  2404. }
  2405. migrations = append(migrations, fileMigration)
  2406. }
  2407. }
  2408. }
  2409. }
  2410. return migrations, nil
  2411. }