示例#1
0
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))
}
示例#2
0
// 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
}
示例#3
0
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:", password)

		} else {
			fmt.Println(err)
		}

	} else if operation(op) == operationDecrypt {
		var err error
		if password, err = secret.Decrypt(password); err == nil {
			fmt.Println("Decrypted password:", password)

		} else {
			fmt.Println(err)
		}

	} else {
		fmt.Println("Invalid operation")
		flag.PrintDefaults()
	}
}
示例#4
0
// 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
}
示例#5
0
// 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)
		}
	}
}