diff --git a/cmd/csaf_provider/actions.go b/cmd/csaf_provider/actions.go index ccb85d8..60f117c 100644 --- a/cmd/csaf_provider/actions.go +++ b/cmd/csaf_provider/actions.go @@ -29,6 +29,8 @@ import ( const dateFormat = time.RFC3339 +// cleanFileName removes the "/" "\" charachters and replace the two or more +// occurences of "." with only one from the passed string. func cleanFileName(s string) string { s = strings.ReplaceAll(s, `/`, ``) s = strings.ReplaceAll(s, `\`, ``) @@ -37,6 +39,10 @@ func cleanFileName(s string) string { return s } +// loadCSAF loads the csaf file from the request, calls the "UploadLimter" function to +// set the upload limit size of the file and the "cleanFileName" to refine +// the filename. It returns the filename, file content in a buffer of bytes +// and an error. func (c *controller) loadCSAF(r *http.Request) (string, []byte, error) { file, handler, err := r.FormFile("csaf") if err != nil { diff --git a/cmd/csaf_provider/config.go b/cmd/csaf_provider/config.go index 65e1dce..920d5d6 100644 --- a/cmd/csaf_provider/config.go +++ b/cmd/csaf_provider/config.go @@ -21,14 +21,16 @@ import ( ) const ( + // The environment name, that contains the path to the config file. configEnv = "CSAF_CONFIG" - defaultConfigPath = "/usr/lib/casf/config.toml" - defaultFolder = "/var/www/" - defaultWeb = "/var/www/html" - defaultOpenPGPURL = "https://openpgp.circl.lu/pks/lookup?op=get&search=${FINGERPRINT}" - defaultUploadLimit = 50 * 1024 * 1024 + defaultConfigPath = "/usr/lib/casf/config.toml" // Default path to the config file. + defaultFolder = "/var/www/" // Default folder path. + defaultWeb = "/var/www/html" // Default web path. + defaultOpenPGPURL = "https://openpgp.circl.lu/pks/lookup?op=get&search=${FINGERPRINT}" // Default OpenPGP URL. + defaultUploadLimit = 50 * 1024 * 1024 // Default limit size of the uploaded file. ) +// configs contains the config values for the provider. type config struct { Password *string `toml:"password"` Key string `toml:"key"` @@ -56,6 +58,7 @@ const ( tlpRed tlp = "red" ) +// valid returns true if the checked tlp matches one of the defined tlps. func (t tlp) valid() bool { switch t { case tlpCSAF, tlpWhite, tlpGreen, tlpAmber, tlpRed: @@ -73,6 +76,8 @@ func (t *tlp) UnmarshalText(text []byte) error { return fmt.Errorf("invalid config TLP value: %v", string(text)) } +// uploadLimiter returns a reader that reads from a given r reader but stops +// with EOF after the defined bytes in the "UploadLimit" config option. func (cfg *config) uploadLimiter(r io.Reader) io.Reader { // Zero or less means no upload limit. if cfg.UploadLimit == nil || *cfg.UploadLimit < 1 { @@ -100,6 +105,8 @@ func (cfg *config) modelTLPs() []csaf.TLPLabel { return tlps } +// loadCryptoKey loads the armored data into the key stored in the file specified by the +// "key" config value and return it with nil, otherwise an error. func (cfg *config) loadCryptoKey() (*crypto.Key, error) { f, err := os.Open(cfg.Key) if err != nil { @@ -109,11 +116,18 @@ func (cfg *config) loadCryptoKey() (*crypto.Key, error) { return crypto.NewKeyFromArmoredReader(f) } +// checkPassword compares the given hashed password with the plaintext in the "password" config value. +// It returns true if these matches or if the "password" config value is not set, otherwise false. func (cfg *config) checkPassword(hash string) bool { return cfg.Password == nil || bcrypt.CompareHashAndPassword([]byte(hash), []byte(*cfg.Password)) == nil } +// loadConfig extracts the config values from the config file. The path to the +// file is taken either from environment variable "CSAF_CONFIG" or from the +// defined default path in "defaultConfigPath". +// Default values are set in case some are missing in the file. +// It returns these values in a struct and nil if there is no error. func loadConfig() (*config, error) { path := os.Getenv(configEnv) if path == "" { diff --git a/cmd/csaf_provider/create.go b/cmd/csaf_provider/create.go index 7507dfd..b4bf281 100644 --- a/cmd/csaf_provider/create.go +++ b/cmd/csaf_provider/create.go @@ -18,6 +18,8 @@ import ( "github.com/csaf-poc/csaf_distribution/util" ) +// ensureFolders initializes the paths and call functions to create +// the directories and files. func ensureFolders(c *config) error { wellknown := filepath.Join(c.Web, ".well-known") @@ -38,6 +40,8 @@ func ensureFolders(c *config) error { return createSecurity(c, wellknown) } +// createWellknown creates ".well-known" directory if not exist and returns nil. +// An error is returned if the it is not a directory. func createWellknown(wellknown string) error { st, err := os.Stat(wellknown) if err != nil { @@ -52,6 +56,10 @@ func createWellknown(wellknown string) error { return nil } +// createFeedFolders creates the feed folders according to the tlp values +// in the "tlps" config option if they do not already exist. +// No creation for the "csaf" option will be done. +// It creates also symbolic links to feed folders. func createFeedFolders(c *config, wellknown string) error { for _, t := range c.TLPs { if t == tlpCSAF { @@ -75,6 +83,8 @@ func createFeedFolders(c *config, wellknown string) error { return nil } +// createSecurity creats the "security.txt" file if does not exist +// and writes the CSAF field inside the file. func createSecurity(c *config, wellknown string) error { security := filepath.Join(wellknown, "security.txt") if _, err := os.Stat(security); err != nil { @@ -93,6 +103,7 @@ func createSecurity(c *config, wellknown string) error { return nil } +// createProviderMetadata creates the provider-metadata.json file if does not exist. func createProviderMetadata(c *config, wellknownCSAF string) error { path := filepath.Join(wellknownCSAF, "provider-metadata.json") _, err := os.Stat(path)