func BuildHTTPHeader(r *http.Request, content []byte) { if r.ContentLength > 0 { r.Header.Set("Content-Type", check.SupportedContentType) hash := md5.New() hash.Write(content) hashBytes := hash.Sum(nil) hashBase64 := base64.StdEncoding.EncodeToString(hashBytes) r.Header.Set("Content-MD5", hashBase64) } r.Header.Set("Date", time.Now().Format(time.RFC1123)) stringToSign, err := check.BuildStringToSign(r, "1") if err != nil { Fatalln("Error creating authorization", err) } s := config.ShelterConfig.RESTServer.Secrets["1"] s, err = secret.Decrypt(s) if err != nil { Fatalln("Error retrieving secret", err) } signature := check.GenerateSignature(stringToSign, s) r.Header.Set("Authorization", fmt.Sprintf("%s %d:%s", check.SupportedNamespace, 1, signature)) }
// initializeSession verify if the session was already created, if not creates it // otherwise use the already created session. We are reusing the session because Gustavo // Niemeyer said that this should be the correct behaviour of the system func initializeSession( uris []string, databaseName string, auth bool, username, password string, ) error { sessionLock.Lock() defer sessionLock.Unlock() if session != nil { return nil } var dialInfo mgo.DialInfo var err error if auth { password, err = secret.Decrypt(password) if err != nil { return err } dialInfo = mgo.DialInfo{ Addrs: uris, Timeout: Timeout, Database: databaseName, Username: username, Password: password, } } else { dialInfo = mgo.DialInfo{ Addrs: uris, Timeout: Timeout, Database: databaseName, } } // Connect to the database session, err = mgo.DialWithInfo(&dialInfo) return err }
func main() { flag.Parse() if len(op) == 0 { fmt.Println("Operation not informed") flag.PrintDefaults() return } op = strings.ToLower(op) if len(password) == 0 { fmt.Println("Password not informed") flag.PrintDefaults() return } if operation(op) == operationEncrypt { var err error if password, err = secret.Encrypt(password); err == nil { fmt.Println("Encrypted password:"******"Decrypted password:"******"Invalid operation") flag.PrintDefaults() } }
// Function used to notify a single domain. It can return error if there's a problem while // filling the template or sending the e-mail func notifyDomain(domain *model.Domain) error { from := config.ShelterConfig.Notification.From emailsPerLanguage := make(map[string][]string) for _, owner := range domain.Owners { emailsPerLanguage[owner.Language] = append(emailsPerLanguage[owner.Language], owner.Email.Address) } if len(emailsPerLanguage) == 0 { log.Infof("There's no owner to notify domain %s", domain.FQDN) } server := fmt.Sprintf("%s:%d", config.ShelterConfig.Notification.SMTPServer.Server, config.ShelterConfig.Notification.SMTPServer.Port, ) password := config.ShelterConfig.Notification.SMTPServer.Auth.Password if len(password) > 0 { var err error password, err = secret.Decrypt(password) if err != nil { return err } } for language, emails := range emailsPerLanguage { t := getTemplate(language) if t == nil { return ErrTemplateNotFound } domainMail := protocol.Domain{ Domain: *domain, From: config.ShelterConfig.Notification.From, To: strings.Join(emails, ","), } var msg bytes.Buffer if err := t.ExecuteTemplate(&msg, "notification", domainMail); err != nil { return err } // Remove extra new lines that can appear because of the template execution. Special // lines used for controlling the templates are removed but the new lines are left // behind msgBytes := bytes.TrimSpace(msg.Bytes()) msgBytes = extraSpaces.ReplaceAll(msgBytes, []byte("\n\n")) switch config.ShelterConfig.Notification.SMTPServer.Auth.Type { case config.AuthenticationTypePlain: log.Debugf("Sending notification for domain %s to %v via server %s with plain authentication", domain.FQDN, emails, server) auth := smtp.PlainAuth("", config.ShelterConfig.Notification.SMTPServer.Auth.Username, password, config.ShelterConfig.Notification.SMTPServer.Server, ) if err := smtp.SendMail(server, auth, from, emails, msgBytes); err != nil { return err } case config.AuthenticationTypeCRAMMD5Auth: log.Debugf("Sending notification for domain %s to %v via server %s with CRAM MD5 authentication", domain.FQDN, emails, server) auth := smtp.CRAMMD5Auth( config.ShelterConfig.Notification.SMTPServer.Auth.Username, password, ) if err := smtp.SendMail(server, auth, from, emails, msgBytes); err != nil { return err } default: log.Debugf("Sending notification for domain %s to %v via server %s without authentication", domain.FQDN, emails, server) if err := smtp.SendMail(server, nil, from, emails, msgBytes); err != nil { return err } } } return nil }
// Verify HTTP headers and fill context with user preferences func (i *Validator) Before(w http.ResponseWriter, r *http.Request) { // We first check the language header, because if it's acceptable the next messages are // going to be returned in the language choosen by the user language, ok := check.HTTPAcceptLanguage(r) if ok { i.validatorHandler.SetLanguage(language) } else { if err := i.validatorHandler.MessageResponse("accept-language-error", r.RequestURI); err == nil { w.WriteHeader(http.StatusNotAcceptable) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } if !check.HTTPAccept(r) { if err := i.validatorHandler.MessageResponse("accept-error", r.RequestURI); err == nil { w.WriteHeader(http.StatusNotAcceptable) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } if !check.HTTPAcceptCharset(r) { if err := i.validatorHandler.MessageResponse("accept-charset-error", r.RequestURI); err == nil { w.WriteHeader(http.StatusNotAcceptable) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } if !check.HTTPContentType(r) { if err := i.validatorHandler.MessageResponse("invalid-content-type", r.RequestURI); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } if r.Body != nil { body, err := ioutil.ReadAll(r.Body) if err != nil { log.Println("Error reading the request. Details:", err) w.WriteHeader(http.StatusInternalServerError) return } defer func() { r.Body = ioutil.NopCloser(bytes.NewBuffer(body)) }() if !check.HTTPContentMD5(r, body) { if err := i.validatorHandler.MessageResponse("invalid-content-md5", r.RequestURI); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } } timeFrameOK, err := check.HTTPDate(r) if err != nil { if err := i.validatorHandler.MessageResponse("invalid-header-date", r.RequestURI); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } else if !timeFrameOK { if err := i.validatorHandler.MessageResponse("invalid-date-time-frame", r.RequestURI); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } authorized, err := check.HTTPAuthorization(r, func(secretId string) (string, error) { s, ok := config.ShelterConfig.RESTServer.Secrets[secretId] if !ok { return "", ErrSecretNotFound } s, err = secret.Decrypt(s) if err != nil { return "", err } return s, nil }) if err == nil && !authorized { w.WriteHeader(http.StatusUnauthorized) return } else if authorized { return } messageId := "" switch err { case check.ErrHTTPContentTypeNotFound: messageId = "content-type-missing" case check.ErrHTTPContentMD5NotFound: messageId = "content-md5-missing" case check.ErrHTTPDateNotFound: messageId = "date-missing" case check.ErrHTTPAuthorizationNotFound: messageId = "authorization-missing" case check.ErrInvalidHTTPAuthorization: messageId = "invalid-authorization" case ErrSecretNotFound: messageId = "secret-not-found" } if len(messageId) == 0 { log.Println("Error checking authorization. Details:", err) w.WriteHeader(http.StatusInternalServerError) } else { if err := i.validatorHandler.MessageResponse(messageId, r.RequestURI); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } } }