1package gosec 2 3import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "io/ioutil" 9) 10 11const ( 12 // Globals are applicable to all rules and used for general 13 // configuration settings for gosec. 14 Globals = "global" 15) 16 17// GlobalOption defines the name of the global options 18type GlobalOption string 19 20const ( 21 // Nosec global option for #nosec directive 22 Nosec GlobalOption = "nosec" 23 // Audit global option which indicates that gosec runs in audit mode 24 Audit GlobalOption = "audit" 25 // NoSecAlternative global option alternative for #nosec directive 26 NoSecAlternative GlobalOption = "#nosec" 27) 28 29// Config is used to provide configuration and customization to each of the rules. 30type Config map[string]interface{} 31 32// NewConfig initializes a new configuration instance. The configuration data then 33// needs to be loaded via c.ReadFrom(strings.NewReader("config data")) 34// or from a *os.File. 35func NewConfig() Config { 36 cfg := make(Config) 37 cfg[Globals] = make(map[GlobalOption]string) 38 return cfg 39} 40 41func (c Config) keyToGlobalOptions(key string) GlobalOption { 42 return GlobalOption(key) 43} 44 45func (c Config) convertGlobals() { 46 if globals, ok := c[Globals]; ok { 47 if settings, ok := globals.(map[string]interface{}); ok { 48 validGlobals := map[GlobalOption]string{} 49 for k, v := range settings { 50 validGlobals[c.keyToGlobalOptions(k)] = fmt.Sprintf("%v", v) 51 } 52 c[Globals] = validGlobals 53 } 54 } 55} 56 57// ReadFrom implements the io.ReaderFrom interface. This 58// should be used with io.Reader to load configuration from 59//file or from string etc. 60func (c Config) ReadFrom(r io.Reader) (int64, error) { 61 data, err := ioutil.ReadAll(r) 62 if err != nil { 63 return int64(len(data)), err 64 } 65 if err = json.Unmarshal(data, &c); err != nil { 66 return int64(len(data)), err 67 } 68 c.convertGlobals() 69 return int64(len(data)), nil 70} 71 72// WriteTo implements the io.WriteTo interface. This should 73// be used to save or print out the configuration information. 74func (c Config) WriteTo(w io.Writer) (int64, error) { 75 data, err := json.Marshal(c) 76 if err != nil { 77 return int64(len(data)), err 78 } 79 return io.Copy(w, bytes.NewReader(data)) 80} 81 82// Get returns the configuration section for the supplied key 83func (c Config) Get(section string) (interface{}, error) { 84 settings, found := c[section] 85 if !found { 86 return nil, fmt.Errorf("Section %s not in configuration", section) 87 } 88 return settings, nil 89} 90 91// Set section in the configuration to specified value 92func (c Config) Set(section string, value interface{}) { 93 c[section] = value 94} 95 96// GetGlobal returns value associated with global configuration option 97func (c Config) GetGlobal(option GlobalOption) (string, error) { 98 if globals, ok := c[Globals]; ok { 99 if settings, ok := globals.(map[GlobalOption]string); ok { 100 if value, ok := settings[option]; ok { 101 return value, nil 102 } 103 return "", fmt.Errorf("global setting for %s not found", option) 104 } 105 } 106 return "", fmt.Errorf("no global config options found") 107} 108 109// SetGlobal associates a value with a global configuration option 110func (c Config) SetGlobal(option GlobalOption, value string) { 111 if globals, ok := c[Globals]; ok { 112 if settings, ok := globals.(map[GlobalOption]string); ok { 113 settings[option] = value 114 } 115 } 116} 117 118// IsGlobalEnabled checks if a global option is enabled 119func (c Config) IsGlobalEnabled(option GlobalOption) (bool, error) { 120 value, err := c.GetGlobal(option) 121 if err != nil { 122 return false, err 123 } 124 return (value == "true" || value == "enabled"), nil 125} 126