config_test.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. package config_test
  2. import (
  3. "encoding/json"
  4. "os"
  5. "path/filepath"
  6. "strings"
  7. "testing"
  8. "github.com/spf13/viper"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. "github.com/drakkan/sftpgo/common"
  12. "github.com/drakkan/sftpgo/config"
  13. "github.com/drakkan/sftpgo/dataprovider"
  14. "github.com/drakkan/sftpgo/ftpd"
  15. "github.com/drakkan/sftpgo/httpclient"
  16. "github.com/drakkan/sftpgo/httpd"
  17. "github.com/drakkan/sftpgo/sftpd"
  18. "github.com/drakkan/sftpgo/webdavd"
  19. )
  20. const (
  21. tempConfigName = "temp"
  22. )
  23. func reset() {
  24. viper.Reset()
  25. config.Init()
  26. }
  27. func TestLoadConfigTest(t *testing.T) {
  28. reset()
  29. configDir := ".."
  30. err := config.LoadConfig(configDir, "")
  31. assert.NoError(t, err)
  32. assert.NotEqual(t, httpd.Conf{}, config.GetHTTPConfig())
  33. assert.NotEqual(t, dataprovider.Config{}, config.GetProviderConf())
  34. assert.NotEqual(t, sftpd.Configuration{}, config.GetSFTPDConfig())
  35. assert.NotEqual(t, httpclient.Config{}, config.GetHTTPConfig())
  36. confName := tempConfigName + ".json"
  37. configFilePath := filepath.Join(configDir, confName)
  38. err = config.LoadConfig(configDir, confName)
  39. assert.NoError(t, err)
  40. err = os.WriteFile(configFilePath, []byte("{invalid json}"), os.ModePerm)
  41. assert.NoError(t, err)
  42. err = config.LoadConfig(configDir, confName)
  43. assert.NoError(t, err)
  44. err = os.WriteFile(configFilePath, []byte("{\"sftpd\": {\"bind_port\": \"a\"}}"), os.ModePerm)
  45. assert.NoError(t, err)
  46. err = config.LoadConfig(configDir, confName)
  47. assert.Error(t, err)
  48. err = os.Remove(configFilePath)
  49. assert.NoError(t, err)
  50. }
  51. func TestLoadConfigFileNotFound(t *testing.T) {
  52. reset()
  53. viper.SetConfigName("configfile")
  54. err := config.LoadConfig(os.TempDir(), "")
  55. assert.NoError(t, err)
  56. }
  57. func TestEmptyBanner(t *testing.T) {
  58. reset()
  59. configDir := ".."
  60. confName := tempConfigName + ".json"
  61. configFilePath := filepath.Join(configDir, confName)
  62. err := config.LoadConfig(configDir, "")
  63. assert.NoError(t, err)
  64. sftpdConf := config.GetSFTPDConfig()
  65. sftpdConf.Banner = " "
  66. c := make(map[string]sftpd.Configuration)
  67. c["sftpd"] = sftpdConf
  68. jsonConf, _ := json.Marshal(c)
  69. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  70. assert.NoError(t, err)
  71. err = config.LoadConfig(configDir, confName)
  72. assert.NoError(t, err)
  73. sftpdConf = config.GetSFTPDConfig()
  74. assert.NotEmpty(t, strings.TrimSpace(sftpdConf.Banner))
  75. err = os.Remove(configFilePath)
  76. assert.NoError(t, err)
  77. ftpdConf := config.GetFTPDConfig()
  78. ftpdConf.Banner = " "
  79. c1 := make(map[string]ftpd.Configuration)
  80. c1["ftpd"] = ftpdConf
  81. jsonConf, _ = json.Marshal(c1)
  82. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  83. assert.NoError(t, err)
  84. err = config.LoadConfig(configDir, confName)
  85. assert.NoError(t, err)
  86. ftpdConf = config.GetFTPDConfig()
  87. assert.NotEmpty(t, strings.TrimSpace(ftpdConf.Banner))
  88. err = os.Remove(configFilePath)
  89. assert.NoError(t, err)
  90. }
  91. func TestInvalidUploadMode(t *testing.T) {
  92. reset()
  93. configDir := ".."
  94. confName := tempConfigName + ".json"
  95. configFilePath := filepath.Join(configDir, confName)
  96. err := config.LoadConfig(configDir, "")
  97. assert.NoError(t, err)
  98. commonConf := config.GetCommonConfig()
  99. commonConf.UploadMode = 10
  100. c := make(map[string]common.Configuration)
  101. c["common"] = commonConf
  102. jsonConf, err := json.Marshal(c)
  103. assert.NoError(t, err)
  104. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  105. assert.NoError(t, err)
  106. err = config.LoadConfig(configDir, confName)
  107. assert.NoError(t, err)
  108. assert.Equal(t, 0, config.GetCommonConfig().UploadMode)
  109. err = os.Remove(configFilePath)
  110. assert.NoError(t, err)
  111. }
  112. func TestInvalidExternalAuthScope(t *testing.T) {
  113. reset()
  114. configDir := ".."
  115. confName := tempConfigName + ".json"
  116. configFilePath := filepath.Join(configDir, confName)
  117. err := config.LoadConfig(configDir, "")
  118. assert.NoError(t, err)
  119. providerConf := config.GetProviderConf()
  120. providerConf.ExternalAuthScope = 100
  121. c := make(map[string]dataprovider.Config)
  122. c["data_provider"] = providerConf
  123. jsonConf, err := json.Marshal(c)
  124. assert.NoError(t, err)
  125. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  126. assert.NoError(t, err)
  127. err = config.LoadConfig(configDir, confName)
  128. assert.NoError(t, err)
  129. assert.Equal(t, 0, config.GetProviderConf().ExternalAuthScope)
  130. err = os.Remove(configFilePath)
  131. assert.NoError(t, err)
  132. }
  133. func TestInvalidCredentialsPath(t *testing.T) {
  134. reset()
  135. configDir := ".."
  136. confName := tempConfigName + ".json"
  137. configFilePath := filepath.Join(configDir, confName)
  138. err := config.LoadConfig(configDir, "")
  139. assert.NoError(t, err)
  140. providerConf := config.GetProviderConf()
  141. providerConf.CredentialsPath = ""
  142. c := make(map[string]dataprovider.Config)
  143. c["data_provider"] = providerConf
  144. jsonConf, err := json.Marshal(c)
  145. assert.NoError(t, err)
  146. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  147. assert.NoError(t, err)
  148. err = config.LoadConfig(configDir, confName)
  149. assert.NoError(t, err)
  150. assert.Equal(t, "credentials", config.GetProviderConf().CredentialsPath)
  151. err = os.Remove(configFilePath)
  152. assert.NoError(t, err)
  153. }
  154. func TestInvalidProxyProtocol(t *testing.T) {
  155. reset()
  156. configDir := ".."
  157. confName := tempConfigName + ".json"
  158. configFilePath := filepath.Join(configDir, confName)
  159. err := config.LoadConfig(configDir, "")
  160. assert.NoError(t, err)
  161. commonConf := config.GetCommonConfig()
  162. commonConf.ProxyProtocol = 10
  163. c := make(map[string]common.Configuration)
  164. c["common"] = commonConf
  165. jsonConf, err := json.Marshal(c)
  166. assert.NoError(t, err)
  167. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  168. assert.NoError(t, err)
  169. err = config.LoadConfig(configDir, confName)
  170. assert.NoError(t, err)
  171. assert.Equal(t, 0, config.GetCommonConfig().ProxyProtocol)
  172. err = os.Remove(configFilePath)
  173. assert.NoError(t, err)
  174. }
  175. func TestInvalidUsersBaseDir(t *testing.T) {
  176. reset()
  177. configDir := ".."
  178. confName := tempConfigName + ".json"
  179. configFilePath := filepath.Join(configDir, confName)
  180. err := config.LoadConfig(configDir, "")
  181. assert.NoError(t, err)
  182. providerConf := config.GetProviderConf()
  183. providerConf.UsersBaseDir = "."
  184. c := make(map[string]dataprovider.Config)
  185. c["data_provider"] = providerConf
  186. jsonConf, err := json.Marshal(c)
  187. assert.NoError(t, err)
  188. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  189. assert.NoError(t, err)
  190. err = config.LoadConfig(configDir, confName)
  191. assert.NoError(t, err)
  192. assert.Empty(t, config.GetProviderConf().UsersBaseDir)
  193. err = os.Remove(configFilePath)
  194. assert.NoError(t, err)
  195. }
  196. func TestSetGetConfig(t *testing.T) {
  197. reset()
  198. sftpdConf := config.GetSFTPDConfig()
  199. sftpdConf.MaxAuthTries = 10
  200. config.SetSFTPDConfig(sftpdConf)
  201. assert.Equal(t, sftpdConf.MaxAuthTries, config.GetSFTPDConfig().MaxAuthTries)
  202. dataProviderConf := config.GetProviderConf()
  203. dataProviderConf.Host = "test host"
  204. config.SetProviderConf(dataProviderConf)
  205. assert.Equal(t, dataProviderConf.Host, config.GetProviderConf().Host)
  206. httpdConf := config.GetHTTPDConfig()
  207. httpdConf.Bindings = append(httpdConf.Bindings, httpd.Binding{Address: "0.0.0.0"})
  208. config.SetHTTPDConfig(httpdConf)
  209. assert.Equal(t, httpdConf.Bindings[0].Address, config.GetHTTPDConfig().Bindings[0].Address)
  210. commonConf := config.GetCommonConfig()
  211. commonConf.IdleTimeout = 10
  212. config.SetCommonConfig(commonConf)
  213. assert.Equal(t, commonConf.IdleTimeout, config.GetCommonConfig().IdleTimeout)
  214. ftpdConf := config.GetFTPDConfig()
  215. ftpdConf.CertificateFile = "cert"
  216. ftpdConf.CertificateKeyFile = "key"
  217. config.SetFTPDConfig(ftpdConf)
  218. assert.Equal(t, ftpdConf.CertificateFile, config.GetFTPDConfig().CertificateFile)
  219. assert.Equal(t, ftpdConf.CertificateKeyFile, config.GetFTPDConfig().CertificateKeyFile)
  220. webDavConf := config.GetWebDAVDConfig()
  221. webDavConf.CertificateFile = "dav_cert"
  222. webDavConf.CertificateKeyFile = "dav_key"
  223. config.SetWebDAVDConfig(webDavConf)
  224. assert.Equal(t, webDavConf.CertificateFile, config.GetWebDAVDConfig().CertificateFile)
  225. assert.Equal(t, webDavConf.CertificateKeyFile, config.GetWebDAVDConfig().CertificateKeyFile)
  226. kmsConf := config.GetKMSConfig()
  227. kmsConf.Secrets.MasterKeyPath = "apath"
  228. kmsConf.Secrets.URL = "aurl"
  229. config.SetKMSConfig(kmsConf)
  230. assert.Equal(t, kmsConf.Secrets.MasterKeyPath, config.GetKMSConfig().Secrets.MasterKeyPath)
  231. assert.Equal(t, kmsConf.Secrets.URL, config.GetKMSConfig().Secrets.URL)
  232. telemetryConf := config.GetTelemetryConfig()
  233. telemetryConf.BindPort = 10001
  234. telemetryConf.BindAddress = "0.0.0.0"
  235. config.SetTelemetryConfig(telemetryConf)
  236. assert.Equal(t, telemetryConf.BindPort, config.GetTelemetryConfig().BindPort)
  237. assert.Equal(t, telemetryConf.BindAddress, config.GetTelemetryConfig().BindAddress)
  238. }
  239. func TestServiceToStart(t *testing.T) {
  240. reset()
  241. configDir := ".."
  242. err := config.LoadConfig(configDir, "")
  243. assert.NoError(t, err)
  244. assert.True(t, config.HasServicesToStart())
  245. sftpdConf := config.GetSFTPDConfig()
  246. sftpdConf.Bindings[0].Port = 0
  247. config.SetSFTPDConfig(sftpdConf)
  248. assert.False(t, config.HasServicesToStart())
  249. ftpdConf := config.GetFTPDConfig()
  250. ftpdConf.Bindings[0].Port = 2121
  251. config.SetFTPDConfig(ftpdConf)
  252. assert.True(t, config.HasServicesToStart())
  253. ftpdConf.Bindings[0].Port = 0
  254. config.SetFTPDConfig(ftpdConf)
  255. webdavdConf := config.GetWebDAVDConfig()
  256. webdavdConf.Bindings[0].Port = 9000
  257. config.SetWebDAVDConfig(webdavdConf)
  258. assert.True(t, config.HasServicesToStart())
  259. webdavdConf.Bindings[0].Port = 0
  260. config.SetWebDAVDConfig(webdavdConf)
  261. assert.False(t, config.HasServicesToStart())
  262. sftpdConf.Bindings[0].Port = 2022
  263. config.SetSFTPDConfig(sftpdConf)
  264. assert.True(t, config.HasServicesToStart())
  265. }
  266. func TestSFTPDBindingsCompatibility(t *testing.T) {
  267. reset()
  268. configDir := ".."
  269. confName := tempConfigName + ".json"
  270. configFilePath := filepath.Join(configDir, confName)
  271. err := config.LoadConfig(configDir, "")
  272. assert.NoError(t, err)
  273. sftpdConf := config.GetSFTPDConfig()
  274. require.Len(t, sftpdConf.Bindings, 1)
  275. sftpdConf.Bindings = nil
  276. sftpdConf.BindPort = 9022 //nolint:staticcheck
  277. sftpdConf.BindAddress = "127.0.0.1" //nolint:staticcheck
  278. c := make(map[string]sftpd.Configuration)
  279. c["sftpd"] = sftpdConf
  280. jsonConf, err := json.Marshal(c)
  281. assert.NoError(t, err)
  282. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  283. assert.NoError(t, err)
  284. err = config.LoadConfig(configDir, confName)
  285. assert.NoError(t, err)
  286. sftpdConf = config.GetSFTPDConfig()
  287. // the default binding should be replaced with the deprecated configuration
  288. require.Len(t, sftpdConf.Bindings, 1)
  289. require.Equal(t, 9022, sftpdConf.Bindings[0].Port)
  290. require.Equal(t, "127.0.0.1", sftpdConf.Bindings[0].Address)
  291. require.True(t, sftpdConf.Bindings[0].ApplyProxyConfig)
  292. err = config.LoadConfig(configDir, confName)
  293. assert.NoError(t, err)
  294. sftpdConf = config.GetSFTPDConfig()
  295. require.Len(t, sftpdConf.Bindings, 1)
  296. require.Equal(t, 9022, sftpdConf.Bindings[0].Port)
  297. require.Equal(t, "127.0.0.1", sftpdConf.Bindings[0].Address)
  298. require.True(t, sftpdConf.Bindings[0].ApplyProxyConfig)
  299. err = os.Remove(configFilePath)
  300. assert.NoError(t, err)
  301. }
  302. func TestFTPDBindingsCompatibility(t *testing.T) {
  303. reset()
  304. configDir := ".."
  305. confName := tempConfigName + ".json"
  306. configFilePath := filepath.Join(configDir, confName)
  307. err := config.LoadConfig(configDir, "")
  308. assert.NoError(t, err)
  309. ftpdConf := config.GetFTPDConfig()
  310. require.Len(t, ftpdConf.Bindings, 1)
  311. ftpdConf.Bindings = nil
  312. ftpdConf.BindPort = 9022 //nolint:staticcheck
  313. ftpdConf.BindAddress = "127.1.0.1" //nolint:staticcheck
  314. ftpdConf.ForcePassiveIP = "127.1.1.1" //nolint:staticcheck
  315. ftpdConf.TLSMode = 2 //nolint:staticcheck
  316. c := make(map[string]ftpd.Configuration)
  317. c["ftpd"] = ftpdConf
  318. jsonConf, err := json.Marshal(c)
  319. assert.NoError(t, err)
  320. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  321. assert.NoError(t, err)
  322. err = config.LoadConfig(configDir, confName)
  323. assert.NoError(t, err)
  324. ftpdConf = config.GetFTPDConfig()
  325. // the default binding should be replaced with the deprecated configuration
  326. require.Len(t, ftpdConf.Bindings, 1)
  327. require.Equal(t, 9022, ftpdConf.Bindings[0].Port)
  328. require.Equal(t, "127.1.0.1", ftpdConf.Bindings[0].Address)
  329. require.True(t, ftpdConf.Bindings[0].ApplyProxyConfig)
  330. require.Equal(t, 2, ftpdConf.Bindings[0].TLSMode)
  331. require.Equal(t, "127.1.1.1", ftpdConf.Bindings[0].ForcePassiveIP)
  332. err = os.Remove(configFilePath)
  333. assert.NoError(t, err)
  334. }
  335. func TestWebDAVDBindingsCompatibility(t *testing.T) {
  336. reset()
  337. configDir := ".."
  338. confName := tempConfigName + ".json"
  339. configFilePath := filepath.Join(configDir, confName)
  340. err := config.LoadConfig(configDir, "")
  341. assert.NoError(t, err)
  342. webdavConf := config.GetWebDAVDConfig()
  343. require.Len(t, webdavConf.Bindings, 1)
  344. webdavConf.Bindings = nil
  345. webdavConf.BindPort = 9080 //nolint:staticcheck
  346. webdavConf.BindAddress = "127.0.0.1" //nolint:staticcheck
  347. c := make(map[string]webdavd.Configuration)
  348. c["webdavd"] = webdavConf
  349. jsonConf, err := json.Marshal(c)
  350. assert.NoError(t, err)
  351. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  352. assert.NoError(t, err)
  353. err = config.LoadConfig(configDir, confName)
  354. assert.NoError(t, err)
  355. webdavConf = config.GetWebDAVDConfig()
  356. // the default binding should be replaced with the deprecated configuration
  357. require.Len(t, webdavConf.Bindings, 1)
  358. require.Equal(t, 9080, webdavConf.Bindings[0].Port)
  359. require.Equal(t, "127.0.0.1", webdavConf.Bindings[0].Address)
  360. require.False(t, webdavConf.Bindings[0].EnableHTTPS)
  361. err = os.Remove(configFilePath)
  362. assert.NoError(t, err)
  363. }
  364. func TestHTTPDBindingsCompatibility(t *testing.T) {
  365. reset()
  366. configDir := ".."
  367. confName := tempConfigName + ".json"
  368. configFilePath := filepath.Join(configDir, confName)
  369. err := config.LoadConfig(configDir, "")
  370. assert.NoError(t, err)
  371. httpdConf := config.GetHTTPDConfig()
  372. require.Len(t, httpdConf.Bindings, 1)
  373. httpdConf.Bindings = nil
  374. httpdConf.BindPort = 9080 //nolint:staticcheck
  375. httpdConf.BindAddress = "127.1.1.1" //nolint:staticcheck
  376. c := make(map[string]httpd.Conf)
  377. c["httpd"] = httpdConf
  378. jsonConf, err := json.Marshal(c)
  379. assert.NoError(t, err)
  380. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  381. assert.NoError(t, err)
  382. err = config.LoadConfig(configDir, confName)
  383. assert.NoError(t, err)
  384. httpdConf = config.GetHTTPDConfig()
  385. // the default binding should be replaced with the deprecated configuration
  386. require.Len(t, httpdConf.Bindings, 1)
  387. require.Equal(t, 9080, httpdConf.Bindings[0].Port)
  388. require.Equal(t, "127.1.1.1", httpdConf.Bindings[0].Address)
  389. require.False(t, httpdConf.Bindings[0].EnableHTTPS)
  390. require.True(t, httpdConf.Bindings[0].EnableWebAdmin)
  391. err = os.Remove(configFilePath)
  392. assert.NoError(t, err)
  393. }
  394. func TestSFTPDBindingsFromEnv(t *testing.T) {
  395. reset()
  396. os.Setenv("SFTPGO_SFTPD__BINDINGS__0__ADDRESS", "127.0.0.1")
  397. os.Setenv("SFTPGO_SFTPD__BINDINGS__0__PORT", "2200")
  398. os.Setenv("SFTPGO_SFTPD__BINDINGS__0__APPLY_PROXY_CONFIG", "false")
  399. os.Setenv("SFTPGO_SFTPD__BINDINGS__3__ADDRESS", "127.0.1.1")
  400. os.Setenv("SFTPGO_SFTPD__BINDINGS__3__PORT", "2203")
  401. os.Setenv("SFTPGO_SFTPD__BINDINGS__3__APPLY_PROXY_CONFIG", "1")
  402. t.Cleanup(func() {
  403. os.Unsetenv("SFTPGO_SFTPD__BINDINGS__0__ADDRESS")
  404. os.Unsetenv("SFTPGO_SFTPD__BINDINGS__0__PORT")
  405. os.Unsetenv("SFTPGO_SFTPD__BINDINGS__0__APPLY_PROXY_CONFIG")
  406. os.Unsetenv("SFTPGO_SFTPD__BINDINGS__3__ADDRESS")
  407. os.Unsetenv("SFTPGO_SFTPD__BINDINGS__3__PORT")
  408. os.Unsetenv("SFTPGO_SFTPD__BINDINGS__3__APPLY_PROXY_CONFIG")
  409. })
  410. configDir := ".."
  411. err := config.LoadConfig(configDir, "")
  412. assert.NoError(t, err)
  413. bindings := config.GetSFTPDConfig().Bindings
  414. require.Len(t, bindings, 2)
  415. require.Equal(t, 2200, bindings[0].Port)
  416. require.Equal(t, "127.0.0.1", bindings[0].Address)
  417. require.False(t, bindings[0].ApplyProxyConfig)
  418. require.Equal(t, 2203, bindings[1].Port)
  419. require.Equal(t, "127.0.1.1", bindings[1].Address)
  420. require.True(t, bindings[1].ApplyProxyConfig)
  421. }
  422. func TestFTPDBindingsFromEnv(t *testing.T) {
  423. reset()
  424. os.Setenv("SFTPGO_FTPD__BINDINGS__0__ADDRESS", "127.0.0.1")
  425. os.Setenv("SFTPGO_FTPD__BINDINGS__0__PORT", "2200")
  426. os.Setenv("SFTPGO_FTPD__BINDINGS__0__APPLY_PROXY_CONFIG", "f")
  427. os.Setenv("SFTPGO_FTPD__BINDINGS__0__TLS_MODE", "2")
  428. os.Setenv("SFTPGO_FTPD__BINDINGS__0__FORCE_PASSIVE_IP", "127.0.1.2")
  429. os.Setenv("SFTPGO_FTPD__BINDINGS__0__TLS_CIPHER_SUITES", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
  430. os.Setenv("SFTPGO_FTPD__BINDINGS__9__ADDRESS", "127.0.1.1")
  431. os.Setenv("SFTPGO_FTPD__BINDINGS__9__PORT", "2203")
  432. os.Setenv("SFTPGO_FTPD__BINDINGS__9__APPLY_PROXY_CONFIG", "t")
  433. os.Setenv("SFTPGO_FTPD__BINDINGS__9__TLS_MODE", "1")
  434. os.Setenv("SFTPGO_FTPD__BINDINGS__9__FORCE_PASSIVE_IP", "127.0.1.1")
  435. os.Setenv("SFTPGO_FTPD__BINDINGS__9__CLIENT_AUTH_TYPE", "2")
  436. t.Cleanup(func() {
  437. os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__ADDRESS")
  438. os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__PORT")
  439. os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__APPLY_PROXY_CONFIG")
  440. os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__TLS_MODE")
  441. os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__FORCE_PASSIVE_IP")
  442. os.Unsetenv("SFTPGO_FTPD__BINDINGS__0__TLS_CIPHER_SUITES")
  443. os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__ADDRESS")
  444. os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__PORT")
  445. os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__APPLY_PROXY_CONFIG")
  446. os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__TLS_MODE")
  447. os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__FORCE_PASSIVE_IP")
  448. os.Unsetenv("SFTPGO_FTPD__BINDINGS__9__CLIENT_AUTH_TYPE")
  449. })
  450. configDir := ".."
  451. err := config.LoadConfig(configDir, "")
  452. assert.NoError(t, err)
  453. bindings := config.GetFTPDConfig().Bindings
  454. require.Len(t, bindings, 2)
  455. require.Equal(t, 2200, bindings[0].Port)
  456. require.Equal(t, "127.0.0.1", bindings[0].Address)
  457. require.False(t, bindings[0].ApplyProxyConfig)
  458. require.Equal(t, 2, bindings[0].TLSMode)
  459. require.Equal(t, "127.0.1.2", bindings[0].ForcePassiveIP)
  460. require.Equal(t, 0, bindings[0].ClientAuthType)
  461. require.Len(t, bindings[0].TLSCipherSuites, 2)
  462. require.Equal(t, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", bindings[0].TLSCipherSuites[0])
  463. require.Equal(t, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", bindings[0].TLSCipherSuites[1])
  464. require.Equal(t, 2203, bindings[1].Port)
  465. require.Equal(t, "127.0.1.1", bindings[1].Address)
  466. require.True(t, bindings[1].ApplyProxyConfig)
  467. require.Equal(t, 1, bindings[1].TLSMode)
  468. require.Equal(t, "127.0.1.1", bindings[1].ForcePassiveIP)
  469. require.Equal(t, 2, bindings[1].ClientAuthType)
  470. require.Nil(t, bindings[1].TLSCipherSuites)
  471. }
  472. func TestWebDAVBindingsFromEnv(t *testing.T) {
  473. reset()
  474. os.Setenv("SFTPGO_WEBDAVD__BINDINGS__1__ADDRESS", "127.0.0.1")
  475. os.Setenv("SFTPGO_WEBDAVD__BINDINGS__1__PORT", "8000")
  476. os.Setenv("SFTPGO_WEBDAVD__BINDINGS__1__ENABLE_HTTPS", "0")
  477. os.Setenv("SFTPGO_WEBDAVD__BINDINGS__1__TLS_CIPHER_SUITES", "TLS_RSA_WITH_AES_128_CBC_SHA ")
  478. os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__ADDRESS", "127.0.1.1")
  479. os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__PORT", "9000")
  480. os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__ENABLE_HTTPS", "1")
  481. os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__CLIENT_AUTH_TYPE", "1")
  482. os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__PREFIX", "/dav2")
  483. t.Cleanup(func() {
  484. os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__1__ADDRESS")
  485. os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__1__PORT")
  486. os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__1__ENABLE_HTTPS")
  487. os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__1__TLS_CIPHER_SUITES")
  488. os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__ADDRESS")
  489. os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__PORT")
  490. os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__ENABLE_HTTPS")
  491. os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__CLIENT_AUTH_TYPE")
  492. os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__PREFIX")
  493. })
  494. configDir := ".."
  495. err := config.LoadConfig(configDir, "")
  496. assert.NoError(t, err)
  497. bindings := config.GetWebDAVDConfig().Bindings
  498. require.Len(t, bindings, 3)
  499. require.Equal(t, 0, bindings[0].Port)
  500. require.Empty(t, bindings[0].Address)
  501. require.False(t, bindings[0].EnableHTTPS)
  502. require.Len(t, bindings[0].TLSCipherSuites, 0)
  503. require.Empty(t, bindings[0].Prefix)
  504. require.Equal(t, 8000, bindings[1].Port)
  505. require.Equal(t, "127.0.0.1", bindings[1].Address)
  506. require.False(t, bindings[1].EnableHTTPS)
  507. require.Equal(t, 0, bindings[1].ClientAuthType)
  508. require.Len(t, bindings[1].TLSCipherSuites, 1)
  509. require.Equal(t, "TLS_RSA_WITH_AES_128_CBC_SHA", bindings[1].TLSCipherSuites[0])
  510. require.Empty(t, bindings[1].Prefix)
  511. require.Equal(t, 9000, bindings[2].Port)
  512. require.Equal(t, "127.0.1.1", bindings[2].Address)
  513. require.True(t, bindings[2].EnableHTTPS)
  514. require.Equal(t, 1, bindings[2].ClientAuthType)
  515. require.Nil(t, bindings[2].TLSCipherSuites)
  516. require.Equal(t, "/dav2", bindings[2].Prefix)
  517. }
  518. func TestHTTPDBindingsFromEnv(t *testing.T) {
  519. reset()
  520. sockPath := filepath.Clean(os.TempDir())
  521. os.Setenv("SFTPGO_HTTPD__BINDINGS__0__ADDRESS", sockPath)
  522. os.Setenv("SFTPGO_HTTPD__BINDINGS__0__PORT", "0")
  523. os.Setenv("SFTPGO_HTTPD__BINDINGS__0__TLS_CIPHER_SUITES", " TLS_AES_128_GCM_SHA256")
  524. os.Setenv("SFTPGO_HTTPD__BINDINGS__1__ADDRESS", "127.0.0.1")
  525. os.Setenv("SFTPGO_HTTPD__BINDINGS__1__PORT", "8000")
  526. os.Setenv("SFTPGO_HTTPD__BINDINGS__1__ENABLE_HTTPS", "0")
  527. os.Setenv("SFTPGO_HTTPD__BINDINGS__1__ENABLE_WEB_ADMIN", "1")
  528. os.Setenv("SFTPGO_HTTPD__BINDINGS__2__ADDRESS", "127.0.1.1")
  529. os.Setenv("SFTPGO_HTTPD__BINDINGS__2__PORT", "9000")
  530. os.Setenv("SFTPGO_HTTPD__BINDINGS__2__ENABLE_WEB_ADMIN", "0")
  531. os.Setenv("SFTPGO_HTTPD__BINDINGS__2__ENABLE_HTTPS", "1")
  532. os.Setenv("SFTPGO_HTTPD__BINDINGS__2__CLIENT_AUTH_TYPE", "1")
  533. os.Setenv("SFTPGO_HTTPD__BINDINGS__2__TLS_CIPHER_SUITES", " TLS_AES_256_GCM_SHA384 , TLS_CHACHA20_POLY1305_SHA256")
  534. t.Cleanup(func() {
  535. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__ADDRESS")
  536. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__PORT")
  537. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__TLS_CIPHER_SUITES")
  538. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__1__ADDRESS")
  539. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__1__PORT")
  540. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__1__ENABLE_HTTPS")
  541. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__1__ENABLE_WEB_ADMIN")
  542. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__ADDRESS")
  543. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__PORT")
  544. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__ENABLE_HTTPS")
  545. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__ENABLE_WEB_ADMIN")
  546. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__CLIENT_AUTH_TYPE")
  547. os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__TLS_CIPHER_SUITES")
  548. })
  549. configDir := ".."
  550. err := config.LoadConfig(configDir, "")
  551. assert.NoError(t, err)
  552. bindings := config.GetHTTPDConfig().Bindings
  553. require.Len(t, bindings, 3)
  554. require.Equal(t, 0, bindings[0].Port)
  555. require.Equal(t, sockPath, bindings[0].Address)
  556. require.False(t, bindings[0].EnableHTTPS)
  557. require.True(t, bindings[0].EnableWebAdmin)
  558. require.Len(t, bindings[0].TLSCipherSuites, 1)
  559. require.Equal(t, "TLS_AES_128_GCM_SHA256", bindings[0].TLSCipherSuites[0])
  560. require.Equal(t, 8000, bindings[1].Port)
  561. require.Equal(t, "127.0.0.1", bindings[1].Address)
  562. require.False(t, bindings[1].EnableHTTPS)
  563. require.True(t, bindings[1].EnableWebAdmin)
  564. require.Nil(t, bindings[1].TLSCipherSuites)
  565. require.Equal(t, 9000, bindings[2].Port)
  566. require.Equal(t, "127.0.1.1", bindings[2].Address)
  567. require.True(t, bindings[2].EnableHTTPS)
  568. require.False(t, bindings[2].EnableWebAdmin)
  569. require.Equal(t, 1, bindings[2].ClientAuthType)
  570. require.Len(t, bindings[2].TLSCipherSuites, 2)
  571. require.Equal(t, "TLS_AES_256_GCM_SHA384", bindings[2].TLSCipherSuites[0])
  572. require.Equal(t, "TLS_CHACHA20_POLY1305_SHA256", bindings[2].TLSCipherSuites[1])
  573. }
  574. func TestHTTPClientCertificatesFromEnv(t *testing.T) {
  575. reset()
  576. configDir := ".."
  577. confName := tempConfigName + ".json"
  578. configFilePath := filepath.Join(configDir, confName)
  579. err := config.LoadConfig(configDir, "")
  580. assert.NoError(t, err)
  581. httpConf := config.GetHTTPConfig()
  582. httpConf.Certificates = append(httpConf.Certificates, httpclient.TLSKeyPair{
  583. Cert: "cert",
  584. Key: "key",
  585. })
  586. c := make(map[string]httpclient.Config)
  587. c["http"] = httpConf
  588. jsonConf, err := json.Marshal(c)
  589. require.NoError(t, err)
  590. err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
  591. require.NoError(t, err)
  592. err = config.LoadConfig(configDir, confName)
  593. require.NoError(t, err)
  594. require.Len(t, config.GetHTTPConfig().Certificates, 1)
  595. require.Equal(t, "cert", config.GetHTTPConfig().Certificates[0].Cert)
  596. require.Equal(t, "key", config.GetHTTPConfig().Certificates[0].Key)
  597. os.Setenv("SFTPGO_HTTP__CERTIFICATES__0__CERT", "cert0")
  598. os.Setenv("SFTPGO_HTTP__CERTIFICATES__0__KEY", "key0")
  599. os.Setenv("SFTPGO_HTTP__CERTIFICATES__8__CERT", "cert8")
  600. os.Setenv("SFTPGO_HTTP__CERTIFICATES__9__CERT", "cert9")
  601. os.Setenv("SFTPGO_HTTP__CERTIFICATES__9__KEY", "key9")
  602. t.Cleanup(func() {
  603. os.Unsetenv("SFTPGO_HTTP__CERTIFICATES__0__CERT")
  604. os.Unsetenv("SFTPGO_HTTP__CERTIFICATES__0__KEY")
  605. os.Unsetenv("SFTPGO_HTTP__CERTIFICATES__8__CERT")
  606. os.Unsetenv("SFTPGO_HTTP__CERTIFICATES__9__CERT")
  607. os.Unsetenv("SFTPGO_HTTP__CERTIFICATES__9__KEY")
  608. })
  609. err = config.LoadConfig(configDir, confName)
  610. require.NoError(t, err)
  611. require.Len(t, config.GetHTTPConfig().Certificates, 2)
  612. require.Equal(t, "cert0", config.GetHTTPConfig().Certificates[0].Cert)
  613. require.Equal(t, "key0", config.GetHTTPConfig().Certificates[0].Key)
  614. require.Equal(t, "cert9", config.GetHTTPConfig().Certificates[1].Cert)
  615. require.Equal(t, "key9", config.GetHTTPConfig().Certificates[1].Key)
  616. err = os.Remove(configFilePath)
  617. assert.NoError(t, err)
  618. config.Init()
  619. err = config.LoadConfig(configDir, "")
  620. require.NoError(t, err)
  621. require.Len(t, config.GetHTTPConfig().Certificates, 2)
  622. require.Equal(t, "cert0", config.GetHTTPConfig().Certificates[0].Cert)
  623. require.Equal(t, "key0", config.GetHTTPConfig().Certificates[0].Key)
  624. require.Equal(t, "cert9", config.GetHTTPConfig().Certificates[1].Cert)
  625. require.Equal(t, "key9", config.GetHTTPConfig().Certificates[1].Key)
  626. }
  627. func TestConfigFromEnv(t *testing.T) {
  628. reset()
  629. os.Setenv("SFTPGO_SFTPD__BINDINGS__0__ADDRESS", "127.0.0.1")
  630. os.Setenv("SFTPGO_WEBDAVD__BINDINGS__0__PORT", "12000")
  631. os.Setenv("SFTPGO_DATA_PROVIDER__PASSWORD_HASHING__ARGON2_OPTIONS__ITERATIONS", "41")
  632. os.Setenv("SFTPGO_DATA_PROVIDER__POOL_SIZE", "10")
  633. os.Setenv("SFTPGO_DATA_PROVIDER__ACTIONS__EXECUTE_ON", "add")
  634. os.Setenv("SFTPGO_KMS__SECRETS__URL", "local")
  635. os.Setenv("SFTPGO_KMS__SECRETS__MASTER_KEY_PATH", "path")
  636. os.Setenv("SFTPGO_TELEMETRY__TLS_CIPHER_SUITES", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA")
  637. t.Cleanup(func() {
  638. os.Unsetenv("SFTPGO_SFTPD__BINDINGS__0__ADDRESS")
  639. os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__0__PORT")
  640. os.Unsetenv("SFTPGO_DATA_PROVIDER__PASSWORD_HASHING__ARGON2_OPTIONS__ITERATIONS")
  641. os.Unsetenv("SFTPGO_DATA_PROVIDER__POOL_SIZE")
  642. os.Unsetenv("SFTPGO_DATA_PROVIDER__ACTIONS__EXECUTE_ON")
  643. os.Unsetenv("SFTPGO_KMS__SECRETS__URL")
  644. os.Unsetenv("SFTPGO_KMS__SECRETS__MASTER_KEY_PATH")
  645. os.Unsetenv("SFTPGO_TELEMETRY__TLS_CIPHER_SUITES")
  646. })
  647. err := config.LoadConfig(".", "invalid config")
  648. assert.NoError(t, err)
  649. sftpdConfig := config.GetSFTPDConfig()
  650. assert.Equal(t, "127.0.0.1", sftpdConfig.Bindings[0].Address)
  651. assert.Equal(t, 12000, config.GetWebDAVDConfig().Bindings[0].Port)
  652. dataProviderConf := config.GetProviderConf()
  653. assert.Equal(t, uint32(41), dataProviderConf.PasswordHashing.Argon2Options.Iterations)
  654. assert.Equal(t, 10, dataProviderConf.PoolSize)
  655. assert.Len(t, dataProviderConf.Actions.ExecuteOn, 1)
  656. assert.Contains(t, dataProviderConf.Actions.ExecuteOn, "add")
  657. kmsConfig := config.GetKMSConfig()
  658. assert.Equal(t, "local", kmsConfig.Secrets.URL)
  659. assert.Equal(t, "path", kmsConfig.Secrets.MasterKeyPath)
  660. telemetryConfig := config.GetTelemetryConfig()
  661. assert.Len(t, telemetryConfig.TLSCipherSuites, 2)
  662. assert.Equal(t, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", telemetryConfig.TLSCipherSuites[0])
  663. assert.Equal(t, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", telemetryConfig.TLSCipherSuites[1])
  664. }