Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 4 additions & 26 deletions core/auth/jwt.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,3 @@
/*
* Copyright (C) 2019 The "MysteriumNetwork/node" Authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package auth

import (
Expand All @@ -24,21 +7,17 @@ import (
"github.com/pkg/errors"
)

// JWTAuthenticator contains JWT handling methods
type JWTAuthenticator struct {
encryptionKey []byte
}

// JWT contains token details
type JWT struct {
Token string
ExpirationTime time.Time
}

// JWTEncryptionKey contains the encryption key for JWT
type JWTEncryptionKey []byte

// JWTCookieName name of the cookie JWT token is stored in
const JWTCookieName string = "token"

type jwtClaims struct {
Expand All @@ -48,16 +27,13 @@ type jwtClaims struct {

const expiresIn = 48 * time.Hour

// NewJWTAuthenticator creates a new JWT authentication instance
func NewJWTAuthenticator(encryptionKey JWTEncryptionKey) *JWTAuthenticator {
auth := &JWTAuthenticator{
encryptionKey,
}

return auth
}

// CreateToken creates a new JWT token
func (jwtAuth *JWTAuthenticator) CreateToken(username string) (JWT, error) {
expirationTime := jwtAuth.getExpirationTime()
claims := &jwtClaims{
Expand All @@ -76,13 +52,15 @@ func (jwtAuth *JWTAuthenticator) CreateToken(username string) (JWT, error) {
return JWT{Token: tokenString, ExpirationTime: expirationTime}, nil
}

// ValidateToken validates a JWT token
func (jwtAuth *JWTAuthenticator) ValidateToken(token string) (bool, error) {
claims := &jwtClaims{}

tkn, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, errors.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return jwtAuth.encryptionKey, nil
})
}, jwt.WithValidMethods([]string{"HS256"}))
if err != nil {
return false, err
}
Expand Down
20 changes: 19 additions & 1 deletion firewall/incoming_firewall_iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
package firewall

import (
"fmt"
"net"
"net/url"
"regexp"
"strings"
"time"

Expand All @@ -28,6 +30,12 @@ import (
"github.com/rs/zerolog/log"
)

var validDomain = regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?)*$`)

func isValidDomain(hostname string) bool {
return len(hostname) <= 253 && validDomain.MatchString(hostname)
}

const (
incomingFirewallChain = "MYST_PROVIDER_FIREWALL"
incomingFirewallIpset = "myst-provider-dst-whitelist"
Expand Down Expand Up @@ -93,8 +101,18 @@ func (ibi *incomingFirewallIptables) AllowURLAccess(rawURLs ...string) (Incoming
return nil, err
}

hostname := parsed.Hostname()
if strings.ContainsAny(hostname, " \t\n\r!@#$%^&*()=+[]{}|;:'\",.<>/?`~") {
removeAll()
return nil, fmt.Errorf("invalid hostname in URL: %s", rawURL)
}
if net.ParseIP(hostname) == nil && !isValidDomain(hostname) {
removeAll()
return nil, fmt.Errorf("invalid hostname in URL: %s", rawURL)
}

remover, err := iptables.AddRuleWithRemoval(
iptables.InsertAt(incomingFirewallChain, 1).RuleSpec("-d", parsed.Hostname(), "-j", "ACCEPT"),
iptables.InsertAt(incomingFirewallChain, 1).RuleSpec("-d", hostname, "-j", "ACCEPT"),
)
if err != nil {
removeAll()
Expand Down
40 changes: 16 additions & 24 deletions services/wireguard/connection/dns/dns_unix.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,32 @@
//go:build !windows

/*
* Copyright (C) 2020 The "MysteriumNetwork/node" Authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package dns

import (
"os"
"net"
"os/exec"
"path"
)

var defaultScriptDir = "/etc/mysterium-node"

func setDNS(cfg Config) error {
cmd := exec.Command(path.Join(cfg.ScriptDir, "update-resolv-conf"))
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "script_type=up", "dev="+cfg.IfaceName, "foreign_option_1=dhcp-option DNS "+cfg.DNS[0])
dnsIP := net.ParseIP(cfg.DNS[0])
if dnsIP == nil {
return exec.Command("true").Run()
}
cmd := exec.Command(path.Join(defaultScriptDir, "update-resolv-conf"))
cmd.Env = append(cmd.Environ(),
"script_type=up",
"dev="+cfg.IfaceName,
"foreign_option_1=dhcp-option DNS "+dnsIP.String())
return cmd.Run()
}

func cleanDNS(cfg Config) error {
cmd := exec.Command(path.Join(cfg.ScriptDir, "update-resolv-conf"))
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "script_type=down", "dev="+cfg.IfaceName)
cmd := exec.Command(path.Join(defaultScriptDir, "update-resolv-conf"))
cmd.Env = append(cmd.Environ(), "script_type=down", "dev="+cfg.IfaceName)
return cmd.Run()
}


46 changes: 26 additions & 20 deletions services/wireguard/connection/dns/dns_windows.go
Original file line number Diff line number Diff line change
@@ -1,39 +1,45 @@
/*
* Copyright (C) 2020 The "MysteriumNetwork/node" Authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//go:build windows

package dns

import (
"fmt"
"net"
"os/exec"
"strings"
)

func validateInterfaceName(name string) error {
if strings.ContainsAny(name, "\"&|;`$(){}[]<>#~!*?\\") {
return fmt.Errorf("invalid interface name: %s", name)
}
return nil
}

func setDNS(cfg Config) error {
cmd := fmt.Sprintf("netsh interface ipv4 set dnsservers name=%s source=static address=%s validate=no", cfg.IfaceName, cfg.DNS[0])
out, err := exec.Command("powershell", "-Command", cmd).CombinedOutput()
if err := validateInterfaceName(cfg.IfaceName); err != nil {
return fmt.Errorf("could not configure DNS: %w", err)
}
dnsIP := net.ParseIP(cfg.DNS[0])
if dnsIP == nil {
return fmt.Errorf("could not configure DNS: invalid DNS IP address: %s", cfg.DNS[0])
}
out, err := exec.Command("netsh", "interface", "ipv4", "set", "dnsservers",
fmt.Sprintf("name=%s", cfg.IfaceName), "source=static",
fmt.Sprintf("address=%s", dnsIP.String()), "validate=no").CombinedOutput()
if err != nil {
return fmt.Errorf("could not configure DNS, %s:%v", string(out), err)
}
return nil
}

func cleanDNS(cfg Config) error {
cmd := fmt.Sprintf("netsh interface ipv4 set dnsservers name=%s source=static address=none validate=no register=both", cfg.IfaceName)
out, err := exec.Command("powershell", "-Command", cmd).CombinedOutput()
if err := validateInterfaceName(cfg.IfaceName); err != nil {
return fmt.Errorf("could not clean DNS: %w", err)
}
out, err := exec.Command("netsh", "interface", "ipv4", "set", "dnsservers",
fmt.Sprintf("name=%s", cfg.IfaceName), "source=static", "address=none",
"validate=no", "register=both").CombinedOutput()
if err != nil {
return fmt.Errorf("could not clean DNS, %s:%w", string(out), err)
}
Expand Down
Loading