config.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright (c) 2014, 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. "encoding/json"
  22. "errors"
  23. "os"
  24. )
  25. type Config struct {
  26. LogFilename string
  27. DataStoreDirectory string
  28. DataStoreTempDirectory string
  29. PropagationChannelId string
  30. SponsorId string
  31. RemoteServerListUrl string
  32. RemoteServerListSignaturePublicKey string
  33. ClientVersion int
  34. ClientPlatform string
  35. TunnelWholeDevice int
  36. EgressRegion string
  37. TunnelProtocol string
  38. LocalSocksProxyPort int
  39. LocalHttpProxyPort int
  40. ConnectionWorkerPoolSize int
  41. TunnelPoolSize int
  42. PortForwardFailureThreshold int
  43. UpstreamHttpProxyAddress string
  44. BindToDeviceProvider DeviceBinder
  45. BindToDeviceDnsServer string
  46. }
  47. // LoadConfig parses and validates a JSON format Psiphon config JSON
  48. // string and returns a Config struct populated with config values.
  49. func LoadConfig(configJson []byte) (*Config, error) {
  50. var config Config
  51. err := json.Unmarshal(configJson, &config)
  52. if err != nil {
  53. return nil, ContextError(err)
  54. }
  55. // These fields are required; the rest are optional
  56. if config.PropagationChannelId == "" {
  57. return nil, ContextError(
  58. errors.New("propagation channel ID is missing from the configuration file"))
  59. }
  60. if config.SponsorId == "" {
  61. return nil, ContextError(
  62. errors.New("sponsor ID is missing from the configuration file"))
  63. }
  64. if config.RemoteServerListUrl == "" {
  65. return nil, ContextError(
  66. errors.New("remote server list URL is missing from the configuration file"))
  67. }
  68. if config.RemoteServerListSignaturePublicKey == "" {
  69. return nil, ContextError(
  70. errors.New("remote server list signature public key is missing from the configuration file"))
  71. }
  72. if config.DataStoreDirectory == "" {
  73. config.DataStoreDirectory, err = os.Getwd()
  74. if err != nil {
  75. return nil, ContextError(err)
  76. }
  77. }
  78. if config.TunnelProtocol != "" {
  79. if !Contains(SupportedTunnelProtocols, config.TunnelProtocol) {
  80. return nil, ContextError(
  81. errors.New("invalid tunnel protocol"))
  82. }
  83. }
  84. if config.ConnectionWorkerPoolSize == 0 {
  85. config.ConnectionWorkerPoolSize = CONNECTION_WORKER_POOL_SIZE
  86. }
  87. if config.TunnelPoolSize == 0 {
  88. config.TunnelPoolSize = TUNNEL_POOL_SIZE
  89. }
  90. if config.PortForwardFailureThreshold == 0 {
  91. config.PortForwardFailureThreshold = PORT_FORWARD_FAILURE_THRESHOLD
  92. }
  93. if config.BindToDeviceProvider != nil {
  94. return nil, ContextError(errors.New("interface must be set at runtime"))
  95. }
  96. return &config, nil
  97. }