config.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package config
  2. import (
  3. "strings"
  4. "github.com/drakkan/sftpgo/ldapauthserver/logger"
  5. "github.com/spf13/viper"
  6. )
  7. const (
  8. logSender = "config"
  9. // DefaultConfigName defines the name for the default config file.
  10. // This is the file name without extension, we use viper and so we
  11. // support all the config files format supported by viper
  12. DefaultConfigName = "ldapauth"
  13. // ConfigEnvPrefix defines a prefix that ENVIRONMENT variables will use
  14. configEnvPrefix = "ldapauth"
  15. )
  16. // HTTPDConfig defines configuration for the HTTPD server
  17. type HTTPDConfig struct {
  18. BindAddress string `mapstructure:"bind_address"`
  19. BindPort int `mapstructure:"bind_port"`
  20. AuthUserFile string `mapstructure:"auth_user_file"`
  21. CertificateFile string `mapstructure:"certificate_file"`
  22. CertificateKeyFile string `mapstructure:"certificate_key_file"`
  23. }
  24. // LDAPConfig defines the configuration parameters for LDAP connections and searches
  25. type LDAPConfig struct {
  26. BaseDN string `mapstructure:"basedn"`
  27. BindURL string `mapstructure:"bind_url"`
  28. BindUsername string `mapstructure:"bind_username"`
  29. BindPassword string `mapstructure:"bind_password"`
  30. SearchFilter string `mapstructure:"search_filter"`
  31. SearchBaseAttrs []string `mapstructure:"search_base_attrs"`
  32. DefaultUID int `mapstructure:"default_uid"`
  33. DefaultGID int `mapstructure:"default_gid"`
  34. ForceDefaultUID bool `mapstructure:"force_default_uid"`
  35. ForceDefaultGID bool `mapstructure:"force_default_gid"`
  36. InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
  37. CACertificates []string `mapstructure:"ca_certificates"`
  38. }
  39. type appConfig struct {
  40. HTTPD HTTPDConfig `mapstructure:"httpd"`
  41. LDAP LDAPConfig `mapstructure:"ldap"`
  42. }
  43. var conf appConfig
  44. func init() {
  45. conf = appConfig{
  46. HTTPD: HTTPDConfig{
  47. BindAddress: "",
  48. BindPort: 9000,
  49. AuthUserFile: "",
  50. CertificateFile: "",
  51. CertificateKeyFile: "",
  52. },
  53. LDAP: LDAPConfig{
  54. BaseDN: "dc=example,dc=com",
  55. BindURL: "ldap://192.168.1.103:389",
  56. BindUsername: "cn=Directory Manager",
  57. BindPassword: "YOUR_ADMIN_PASSWORD_HERE",
  58. SearchFilter: "(&(objectClass=nsPerson)(uid=%s))",
  59. SearchBaseAttrs: []string{
  60. "dn",
  61. "homeDirectory",
  62. "uidNumber",
  63. "gidNumber",
  64. "nsSshPublicKey",
  65. },
  66. DefaultUID: 0,
  67. DefaultGID: 0,
  68. ForceDefaultUID: true,
  69. ForceDefaultGID: true,
  70. InsecureSkipVerify: false,
  71. CACertificates: nil,
  72. },
  73. }
  74. viper.SetEnvPrefix(configEnvPrefix)
  75. replacer := strings.NewReplacer(".", "__")
  76. viper.SetEnvKeyReplacer(replacer)
  77. viper.SetConfigName(DefaultConfigName)
  78. viper.AutomaticEnv()
  79. viper.AllowEmptyEnv(true)
  80. }
  81. // GetHomeDirectory returns the configured name for the LDAP field to use as home directory
  82. func (l *LDAPConfig) GetHomeDirectory() string {
  83. if len(l.SearchBaseAttrs) > 1 {
  84. return l.SearchBaseAttrs[1]
  85. }
  86. return "homeDirectory"
  87. }
  88. // GetUIDNumber returns the configured name for the LDAP field to use as UID
  89. func (l *LDAPConfig) GetUIDNumber() string {
  90. if len(l.SearchBaseAttrs) > 2 {
  91. return l.SearchBaseAttrs[2]
  92. }
  93. return "uidNumber"
  94. }
  95. // GetGIDNumber returns the configured name for the LDAP field to use as GID
  96. func (l *LDAPConfig) GetGIDNumber() string {
  97. if len(l.SearchBaseAttrs) > 3 {
  98. return l.SearchBaseAttrs[3]
  99. }
  100. return "gidNumber"
  101. }
  102. // GetPublicKey returns the configured name for the LDAP field to use as public keys
  103. func (l *LDAPConfig) GetPublicKey() string {
  104. if len(l.SearchBaseAttrs) > 4 {
  105. return l.SearchBaseAttrs[4]
  106. }
  107. return "nsSshPublicKey"
  108. }
  109. // GetHTTPDConfig returns the configuration for the HTTP server
  110. func GetHTTPDConfig() HTTPDConfig {
  111. return conf.HTTPD
  112. }
  113. // GetLDAPConfig returns LDAP related settings
  114. func GetLDAPConfig() LDAPConfig {
  115. return conf.LDAP
  116. }
  117. func getRedactedConf() appConfig {
  118. c := conf
  119. return c
  120. }
  121. // LoadConfig loads the configuration
  122. func LoadConfig(configDir, configName string) error {
  123. var err error
  124. viper.AddConfigPath(configDir)
  125. viper.AddConfigPath(".")
  126. viper.SetConfigName(configName)
  127. if err = viper.ReadInConfig(); err != nil {
  128. logger.Warn(logSender, "", "error loading configuration file: %v. Default configuration will be used: %+v",
  129. err, getRedactedConf())
  130. logger.WarnToConsole("error loading configuration file: %v. Default configuration will be used.", err)
  131. return err
  132. }
  133. err = viper.Unmarshal(&conf)
  134. if err != nil {
  135. logger.Warn(logSender, "", "error parsing configuration file: %v. Default configuration will be used: %+v",
  136. err, getRedactedConf())
  137. logger.WarnToConsole("error parsing configuration file: %v. Default configuration will be used.", err)
  138. return err
  139. }
  140. logger.Debug(logSender, "", "config file used: '%#v', config loaded: %+v", viper.ConfigFileUsed(), getRedactedConf())
  141. return err
  142. }