Validate the client IP allocation
This commit is contained in:
		
							parent
							
								
									15703b9185
								
							
						
					
					
						commit
						e52ffaf686
					
				|  | @ -89,11 +89,25 @@ func NewClient() echo.HandlerFunc { | ||||||
| 		client := new(model.Client) | 		client := new(model.Client) | ||||||
| 		c.Bind(client) | 		c.Bind(client) | ||||||
| 
 | 
 | ||||||
|  | 		// initialize db
 | ||||||
|  | 		dir := "./db" | ||||||
|  | 		db, err := scribble.New(dir, nil) | ||||||
|  | 		if err != nil { | ||||||
|  | 			log.Error("Cannot initialize the database: ", err) | ||||||
|  | 			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot access database"}) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// read server information
 | ||||||
|  | 		serverInterface := model.ServerInterface{} | ||||||
|  | 		if err := db.Read("server", "interfaces", &serverInterface); err != nil { | ||||||
|  | 			log.Error("Cannot fetch server interface config from database: ", err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		// validate the input Allocation IPs
 | 		// validate the input Allocation IPs
 | ||||||
| 		// TODO: validate if they are really available
 | 		allocatedIPs, err := util.GetAllocatedIPs() | ||||||
| 		if util.ValidateCIDRList(client.AllocatedIPs) == false { | 		check, err := util.ValidateIPAllocation(serverInterface.Addresses, allocatedIPs, client.AllocatedIPs) | ||||||
| 			log.Warnf("Invalid allocation ip input from user: %v", client.AllocatedIPs) | 		if !check { | ||||||
| 			return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "IP allocation is not valid"}) | 			return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, fmt.Sprintf("%s", err)}) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// validate the input AllowedIPs
 | 		// validate the input AllowedIPs
 | ||||||
|  | @ -118,12 +132,6 @@ func NewClient() echo.HandlerFunc { | ||||||
| 		client.UpdatedAt = client.CreatedAt | 		client.UpdatedAt = client.CreatedAt | ||||||
| 
 | 
 | ||||||
| 		// write client to the database
 | 		// write client to the database
 | ||||||
| 		dir := "./db" |  | ||||||
| 		db, err := scribble.New(dir, nil) |  | ||||||
| 		if err != nil { |  | ||||||
| 			log.Error("Cannot initialize the database: ", err) |  | ||||||
| 			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot access database"}) |  | ||||||
| 		} |  | ||||||
| 		db.Write("clients", client.ID, client) | 		db.Write("clients", client.ID, client) | ||||||
| 		log.Infof("Created wireguard client: %v", client) | 		log.Infof("Created wireguard client: %v", client) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										40
									
								
								util/util.go
								
								
								
								
							
							
						
						
									
										40
									
								
								util/util.go
								
								
								
								
							|  | @ -268,3 +268,43 @@ func GetAvailableIP(cidr string, allocatedList []string) (string, error) { | ||||||
| 
 | 
 | ||||||
| 	return "", errors.New("No more available ip address") | 	return "", errors.New("No more available ip address") | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // ValidateIPAllocation to validate the list of client's ip allocation
 | ||||||
|  | // They must have a correct format and available in serverAddresses space
 | ||||||
|  | func ValidateIPAllocation(serverAddresses []string, ipAllocatedList []string, ipAllocationList []string) (bool, error) { | ||||||
|  | 	for _, clientCIDR := range ipAllocationList { | ||||||
|  | 		ip, _, _ := net.ParseCIDR(clientCIDR) | ||||||
|  | 
 | ||||||
|  | 		// clientCIDR must be in CIDR format
 | ||||||
|  | 		if ip == nil { | ||||||
|  | 			return false, fmt.Errorf("Invalid ip allocation input %s. Must be in CIDR format", clientCIDR) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// return false immediately if the ip is already in use (in ipAllocatedList)
 | ||||||
|  | 		for _, item := range ipAllocatedList { | ||||||
|  | 			if item == ip.String() { | ||||||
|  | 				return false, fmt.Errorf("IP %s already allocated", ip) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// even if it is not in use, we still need to check if it
 | ||||||
|  | 		// belongs to a network of the server.
 | ||||||
|  | 		var isValid bool = false | ||||||
|  | 		for _, serverCIDR := range serverAddresses { | ||||||
|  | 			_, serverNet, _ := net.ParseCIDR(serverCIDR) | ||||||
|  | 			if serverNet.Contains(ip) { | ||||||
|  | 				isValid = true | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// current ip allocation is valid, check the next one
 | ||||||
|  | 		if isValid { | ||||||
|  | 			continue | ||||||
|  | 		} else { | ||||||
|  | 			return false, fmt.Errorf("IP %s does not belong to any network addresses of WireGuard server", ip) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return true, nil | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue