Пример #1
0
// ChangePasswd is used to change user password
func (u *User) ChangePasswd(passwd string) error {
	if len(passwd) < 6 {
		return errors.New("password must be at least 6 chars length")
	}
	hashed, err := bcrypt.GenerateFromPassword([]byte(passwd), 10)
	if err != nil {
		return err
	}
	u.Passwd = string(hashed)
	if u.HaveMailbox {
		salt, err := NewUUID()
		if err != nil {
			return err
		}
		salt = "$6$" + salt[:16]
		c := sha512_crypt.New()
		if u.DovePasswd, err = c.Generate([]byte(passwd), []byte(salt)); err != nil {
			return err
		}
	}
	return DB.Save(u).Error
}
Пример #2
0
// UserAdd add an user
func UserAdd(login, passwd, mbQuota string, haveMailbox, authRelay, isCatchall bool) error {
	login = strings.ToLower(login)
	// login must be < 257 char
	l := len(login)
	if l > 256 {
		return errors.New("login must have less than 256 chars")
	}
	if l < 4 {
		return errors.New("login must be at least 4 char")
	}

	// passwd > 6 char
	if len(passwd) < 6 {
		return errors.New("password must be at least 6 chars length")
	}

	// no catchall without mailbox
	if isCatchall && !haveMailbox {
		return errors.New("only users with mailbox can be defined as catchall")
	}

	//OK
	user := &User{
		Login:       login,
		AuthRelay:   authRelay,
		HaveMailbox: haveMailbox,
	}

	// if we have to create mailbox, login must be a valid email address
	if haveMailbox {
		// check if dovecot is available
		if !Cfg.GetDovecotSupportEnabled() {
			return errors.New("you must enable (and install) Dovecot support")
		}

		if _, err := mail.ParseAddress(login); err != nil {
			return errors.New("'login' must be a valid email address")
		}

		t := strings.Split(login, "@")
		if len(t) != 2 {
			return errors.New("'login' must be a valid email address")
		}

		// Quota
		if mbQuota == "" {
			// get default
			mbQuota = Cfg.GetUserMailboxDefaultQuota()
		}
		user.MailboxQuota = mbQuota

		// rcpthost must be in rcpthost && must be local && not an alias
		rcpthost, err := RcpthostGet(t[1])
		if err != nil && err != gorm.ErrRecordNotFound {
			return err
		}
		exists := err == nil
		if !exists {
			err = DB.Save(&RcptHost{
				Hostname: t[1],
				IsLocal:  true,
			}).Error
			if err != nil {
				return err
			}
		} else if !rcpthost.IsLocal {
			return errors.New("rcpthost " + t[1] + " is already handled by tmail but declared as remote destination")
		} else if rcpthost.IsAlias {
			return errors.New("rcpthost " + t[1] + " is an domain alias. You can't add user for this kind of domain")
		}
		// home = base/d/domain/u/user
		user.Home = Cfg.GetUsersHomeBase() + "/" + string(t[1][0]) + "/" + t[1] + "/" + string(t[0][0]) + "/" + t[0]

		// catchall
		if isCatchall {
			// is there another catchall for this domain
			u, err := UserGetCatchallForDomain(t[1])
			if err != nil {
				return errors.New("unable to check catchall existense for domain " + t[1])
			}
			if u != nil {
				return errors.New("domain " + t[1] + "already have a catchall: " + u.Login)
			}
		}
	}

	// hash passwd
	hashed, err := bcrypt.GenerateFromPassword([]byte(passwd), 10)
	if err != nil {
		return err
	}
	user.Passwd = string(hashed)

	// sha512 for dovecot compatibility
	// {SHA512-CRYPT}$6$iW6KmxlZL56A1raN$4DjgXTUzFZlGQgq61YnBMF2AYWKdY5ZanOUWTDBhuvBYVzkdNjqrmpYnLlQ3M0kU1joUH0Bb2aJcPhUF0xlSq/
	salt, err := NewUUID()
	if err != nil {
		return err
	}
	salt = "$6$" + salt[:16]
	c := sha512_crypt.New()
	user.DovePasswd, err = c.Generate([]byte(passwd), []byte(salt))
	if err != nil {
		return err
	}
	return DB.Save(user).Error
}
Пример #3
-1
func crypt_sha512(pass string) (string, error) {
	c := sha512_crypt.New()
	sha, err := c.Generate([]byte(pass), []byte("$6$"+random(16)))
	if err != nil {
		return "", fmt.Errorf("Error generating crypt for password: %s\n", err)
	}
	return sha, err
}