201 lines
4.6 KiB
Go
Raw Normal View History

2020-11-09 11:06:02 +01:00
package server
import (
"crypto/md5"
"errors"
"fmt"
2020-11-09 23:43:57 +01:00
"io/ioutil"
"syscall"
2020-11-09 11:06:02 +01:00
"time"
"github.com/h44z/wg-portal/internal/common"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
2021-02-21 23:23:58 +01:00
func (s *Server) PrepareNewUser() (Peer, error) {
2020-11-09 11:06:02 +01:00
device := s.users.GetDevice()
2021-02-21 23:23:58 +01:00
peer := Peer{}
peer.IsNew = true
peer.AllowedIPsStr = device.AllowedIPsStr
peer.IPs = make([]string, len(device.IPs))
2020-11-09 11:06:02 +01:00
for i := range device.IPs {
freeIP, err := s.users.GetAvailableIp(device.IPs[i])
if err != nil {
2021-02-21 23:23:58 +01:00
return Peer{}, err
2020-11-09 11:06:02 +01:00
}
2021-02-21 23:23:58 +01:00
peer.IPs[i] = freeIP
2020-11-09 11:06:02 +01:00
}
2021-02-21 23:23:58 +01:00
peer.IPsStr = common.ListToString(peer.IPs)
2020-11-09 11:06:02 +01:00
psk, err := wgtypes.GenerateKey()
if err != nil {
2021-02-21 23:23:58 +01:00
return Peer{}, err
2020-11-09 11:06:02 +01:00
}
key, err := wgtypes.GeneratePrivateKey()
if err != nil {
2021-02-21 23:23:58 +01:00
return Peer{}, err
2020-11-09 11:06:02 +01:00
}
2021-02-21 23:23:58 +01:00
peer.PresharedKey = psk.String()
peer.PrivateKey = key.String()
peer.PublicKey = key.PublicKey().String()
peer.UID = fmt.Sprintf("u%x", md5.Sum([]byte(peer.PublicKey)))
2020-11-09 11:06:02 +01:00
2021-02-21 23:23:58 +01:00
return peer, nil
2020-11-09 11:06:02 +01:00
}
func (s *Server) CreateUserByEmail(email, identifierSuffix string, disabled bool) error {
ldapUser := s.ldapUsers.GetUserData(s.ldapUsers.GetUserDNByMail(email))
if ldapUser.DN == "" {
2021-02-21 23:23:58 +01:00
return errors.New("no peer with email " + email + " found")
2020-11-09 11:06:02 +01:00
}
device := s.users.GetDevice()
2021-02-21 23:23:58 +01:00
peer := Peer{}
peer.AllowedIPsStr = device.AllowedIPsStr
peer.IPs = make([]string, len(device.IPs))
for i := range device.IPs {
freeIP, err := s.users.GetAvailableIp(device.IPs[i])
if err != nil {
return err
}
2021-02-21 23:23:58 +01:00
peer.IPs[i] = freeIP
}
2021-02-21 23:23:58 +01:00
peer.IPsStr = common.ListToString(peer.IPs)
2020-11-09 11:06:02 +01:00
psk, err := wgtypes.GenerateKey()
if err != nil {
return err
}
key, err := wgtypes.GeneratePrivateKey()
if err != nil {
return err
}
2021-02-21 23:23:58 +01:00
peer.PresharedKey = psk.String()
peer.PrivateKey = key.String()
peer.PublicKey = key.PublicKey().String()
peer.UID = fmt.Sprintf("u%x", md5.Sum([]byte(peer.PublicKey)))
peer.Email = email
peer.Identifier = fmt.Sprintf("%s %s (%s)", ldapUser.Firstname, ldapUser.Lastname, identifierSuffix)
2020-11-09 11:06:02 +01:00
now := time.Now()
if disabled {
2021-02-21 23:23:58 +01:00
peer.DeactivatedAt = &now
2020-11-09 11:06:02 +01:00
}
2021-02-21 23:23:58 +01:00
return s.CreateUser(peer)
2020-11-09 11:06:02 +01:00
}
2021-02-21 23:23:58 +01:00
func (s *Server) CreateUser(user Peer) error {
2020-11-09 11:06:02 +01:00
device := s.users.GetDevice()
user.AllowedIPsStr = device.AllowedIPsStr
if len(user.IPs) == 0 {
for i := range device.IPs {
freeIP, err := s.users.GetAvailableIp(device.IPs[i])
if err != nil {
return err
}
user.IPs[i] = freeIP
}
user.IPsStr = common.ListToString(user.IPs)
}
2020-11-09 11:06:02 +01:00
if user.PrivateKey == "" { // if private key is empty create a new one
psk, err := wgtypes.GenerateKey()
if err != nil {
return err
}
key, err := wgtypes.GeneratePrivateKey()
if err != nil {
return err
}
user.PresharedKey = psk.String()
user.PrivateKey = key.String()
user.PublicKey = key.PublicKey().String()
}
user.UID = fmt.Sprintf("u%x", md5.Sum([]byte(user.PublicKey)))
// Create WireGuard interface
2020-11-09 11:06:02 +01:00
if user.DeactivatedAt == nil {
2021-02-21 23:23:58 +01:00
if err := s.wg.AddPeer(user.GetConfig()); err != nil {
2020-11-09 11:06:02 +01:00
return err
}
}
// Create in database
if err := s.users.CreateUser(user); err != nil {
return err
}
2020-11-09 23:43:57 +01:00
return s.WriteWireGuardConfigFile()
2020-11-09 11:06:02 +01:00
}
2021-02-21 23:23:58 +01:00
func (s *Server) UpdateUser(user Peer, updateTime time.Time) error {
2020-11-09 11:06:02 +01:00
currentUser := s.users.GetUserByKey(user.PublicKey)
// Update WireGuard device
var err error
switch {
case user.DeactivatedAt == &updateTime:
err = s.wg.RemovePeer(user.PublicKey)
case user.DeactivatedAt == nil && currentUser.Peer != nil:
2021-02-21 23:23:58 +01:00
err = s.wg.UpdatePeer(user.GetConfig())
2020-11-09 11:06:02 +01:00
case user.DeactivatedAt == nil && currentUser.Peer == nil:
2021-02-21 23:23:58 +01:00
err = s.wg.AddPeer(user.GetConfig())
2020-11-09 11:06:02 +01:00
}
if err != nil {
return err
}
// Update in database
if err := s.users.UpdateUser(user); err != nil {
return err
}
2020-11-09 23:43:57 +01:00
return s.WriteWireGuardConfigFile()
2020-11-09 11:06:02 +01:00
}
2021-02-21 23:23:58 +01:00
func (s *Server) DeleteUser(user Peer) error {
2020-11-09 11:06:02 +01:00
// Delete WireGuard peer
if err := s.wg.RemovePeer(user.PublicKey); err != nil {
return err
}
// Delete in database
if err := s.users.DeleteUser(user); err != nil {
return err
}
2020-11-09 23:43:57 +01:00
return s.WriteWireGuardConfigFile()
2020-11-09 11:06:02 +01:00
}
func (s *Server) RestoreWireGuardInterface() error {
activeUsers := s.users.GetActiveUsers()
for i := range activeUsers {
if activeUsers[i].Peer == nil {
2021-02-21 23:23:58 +01:00
if err := s.wg.AddPeer(activeUsers[i].GetConfig()); err != nil {
return err
}
}
}
return nil
}
2020-11-09 23:43:57 +01:00
func (s *Server) WriteWireGuardConfigFile() error {
if s.config.WG.WireGuardConfig == "" {
return nil // writing disabled
}
if err := syscall.Access(s.config.WG.WireGuardConfig, syscall.O_RDWR); err != nil {
return err
}
device := s.users.GetDevice()
2021-02-21 23:23:58 +01:00
cfg, err := device.GetConfigFile(s.users.GetActiveUsers())
2020-11-09 23:43:57 +01:00
if err != nil {
return err
}
if err := ioutil.WriteFile(s.config.WG.WireGuardConfig, cfg, 0644); err != nil {
return err
}
return nil
}