Skip to content

Commit

Permalink
Enhancement: Don't use external curl command to do http requests
Browse files Browse the repository at this point in the history
  • Loading branch information
luskaner committed Dec 20, 2024
1 parent 892c20a commit b3ef94c
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 39 deletions.
10 changes: 10 additions & 0 deletions launcher/internal/executor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
"github.com/luskaner/ageLANServer/common/executor"
launcherCommon "github.com/luskaner/ageLANServer/launcher-common"
"github.com/luskaner/ageLANServer/launcher-common/executor/exec"
"github.com/luskaner/ageLANServer/launcher/internal/server/certStore"
)

func RunSetUp(game string, mapIps mapset.Set[string], addUserCertData []byte, addLocalCertData []byte, backupMetadata bool, backupProfiles bool, mapCDN bool, exitAgentOnError bool) (result *exec.Result) {
reloadSystemCertificates := false
args := make([]string, 0)
args = append(args, "setup")
if game != "" {
Expand All @@ -29,10 +31,12 @@ func RunSetUp(game string, mapIps mapset.Set[string], addUserCertData []byte, ad
}
}
if addLocalCertData != nil {
reloadSystemCertificates = true
args = append(args, "-l")
args = append(args, base64.StdEncoding.EncodeToString(addLocalCertData))
}
if addUserCertData != nil {
reloadSystemCertificates = true
args = append(args, "-u")
args = append(args, base64.StdEncoding.EncodeToString(addUserCertData))
}
Expand All @@ -46,13 +50,19 @@ func RunSetUp(game string, mapIps mapset.Set[string], addUserCertData []byte, ad
args = append(args, "-c")
}
result = exec.Options{File: common.GetExeFileName(false, common.LauncherConfig), Wait: true, Args: args, ExitCode: true}.Exec()
if reloadSystemCertificates {
certStore.ReloadSystemCertificates()
}
return
}

func RunRevert(game string, unmapIPs bool, removeUserCert bool, removeLocalCert bool, restoreMetadata bool, restoreProfiles bool, unmapCDN bool) (result *exec.Result) {
args := []string{launcherCommon.ConfigRevertCmd}
args = append(args, RevertFlags(game, unmapIPs, removeUserCert, removeLocalCert, restoreMetadata, restoreProfiles, unmapCDN)...)
result = exec.Options{File: common.GetExeFileName(false, common.LauncherConfig), Wait: true, Args: args, ExitCode: true}.Exec()
if removeUserCert || removeLocalCert {
certStore.ReloadSystemCertificates()
}
return
}

Expand Down
17 changes: 17 additions & 0 deletions launcher/internal/server/certStore/certStore_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//go:build !windows

package certStore

import (
"crypto/x509"
_ "unsafe"
)

// TODO: Check on every minor version release if there is a better way to do it, or, at least, it is compatible

//go:linkname systemRoots crypto/x509.systemRoots
var systemRoots *x509.CertPool

func ReloadSystemCertificates() {
systemRoots, _ = loadSystemRoots()
}
6 changes: 6 additions & 0 deletions launcher/internal/server/certStore/certStore_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package certStore

// ReloadSystemCertificates No need to reload certificates as the validity is checked by the OS
func ReloadSystemCertificates() {

}
20 changes: 20 additions & 0 deletions launcher/internal/server/certStore/root_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Source: https://github.com/golang/go/blob/master/src/crypto/x509/root_linux.go
// TODO: Check on every minor version release if there is a better way to do it, or, at least, update it

package certStore

// Possible certificate files; stop after finding one.
var certFiles = []string{
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/pki/tls/cacert.pem", // OpenELEC
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
"/etc/ssl/cert.pem", // Alpine Linux
}

// Possible directories with certificate files; all will be read.
var certDirectories = []string{
"/etc/ssl/certs", // SLES10/SLES11, https://golang.org/issue/12139
"/etc/pki/tls/certs", // Fedora/RHEL
}
113 changes: 113 additions & 0 deletions launcher/internal/server/certStore/root_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Source: https://github.com/golang/go/blob/master/src/crypto/x509/root_unix.go
// TODO: Check on every minor version release if there is a better way to do it, or, at least, update it.

//go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || wasip1

package certStore

import (
"crypto/x509"
"io/fs"
"os"
"path/filepath"
"reflect"
"strings"
)

const (
// certFileEnv is the environment variable which identifies where to locate
// the SSL certificate file. If set this overrides the system default.
certFileEnv = "SSL_CERT_FILE"

// certDirEnv is the environment variable which identifies which directory
// to check for SSL certificate files. If set this overrides the system default.
// It is a colon separated list of directories.
// See https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html.
certDirEnv = "SSL_CERT_DIR"
)

func loadSystemRoots() (*x509.CertPool, error) {
roots := x509.NewCertPool()

files := certFiles
if f := os.Getenv(certFileEnv); f != "" {
files = []string{f}
}

var firstErr error
for _, file := range files {
data, err := os.ReadFile(file)
if err == nil {
roots.AppendCertsFromPEM(data)
break
}
if firstErr == nil && !os.IsNotExist(err) {
firstErr = err
}
}

dirs := certDirectories
if d := os.Getenv(certDirEnv); d != "" {
// OpenSSL and BoringSSL both use ":" as the SSL_CERT_DIR separator.
// See:
// * https://golang.org/issue/35325
// * https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html
dirs = strings.Split(d, ":")
}

for _, directory := range dirs {
fis, err := readUniqueDirectoryEntries(directory)
if err != nil {
if firstErr == nil && !os.IsNotExist(err) {
firstErr = err
}
continue
}
for _, fi := range fis {
data, err := os.ReadFile(directory + "/" + fi.Name())
if err == nil {
roots.AppendCertsFromPEM(data)
}
}
}

if firstErr != nil {
return roots, nil
}

rootsValue := reflect.ValueOf(roots)
lenMethod := rootsValue.MethodByName("len")
results := lenMethod.Call(nil)

if results[0].Int() > 0 {
return roots, nil
}

return nil, firstErr
}

// readUniqueDirectoryEntries is like os.ReadDir but omits
// symlinks that point within the directory.
func readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) {
files, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
uniq := files[:0]
for _, f := range files {
if !isSameDirSymlink(f, dir) {
uniq = append(uniq, f)
}
}
return uniq, nil
}

// isSameDirSymlink reports whether fi in dir is a symlink with a
// target not containing a slash.
func isSameDirSymlink(f fs.DirEntry, dir string) bool {
if f.Type()&fs.ModeSymlink == 0 {
return false
}
target, err := os.Readlink(filepath.Join(dir, f.Name()))
return err == nil && !strings.Contains(target, "/")
}
30 changes: 0 additions & 30 deletions launcher/internal/server/httpClient.go

This file was deleted.

11 changes: 10 additions & 1 deletion launcher/internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
commonExecutor "github.com/luskaner/ageLANServer/launcher-common/executor/exec"
"golang.org/x/net/ipv4"
"net"
"net/http"
"net/netip"
"os"
"path"
Expand Down Expand Up @@ -81,7 +82,15 @@ func GetExecutablePath(executable string) string {
}

func LanServer(host string, insecureSkipVerify bool) bool {
return HttpGet(fmt.Sprintf("https://%s/test", host), insecureSkipVerify) == common.ErrSuccess
tr := &http.Transport{
TLSClientConfig: TlsConfig(insecureSkipVerify),
}
client := &http.Client{Transport: tr}
resp, err := client.Head(fmt.Sprintf("https://%s/test", host))
if err != nil {
return false
}
return resp.StatusCode == http.StatusOK
}

func announcementConnections(multicastIPs []net.IP, ports []int) []*net.UDPConn {
Expand Down
32 changes: 24 additions & 8 deletions launcher/internal/server/ssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,41 @@ package server
import (
"crypto/tls"
"crypto/x509"
"fmt"
"github.com/luskaner/ageLANServer/common"
"github.com/luskaner/ageLANServer/launcher-common/executor/exec"
"net"
"os"
"path/filepath"
)

func TlsConfig(insecureSkipVerify bool) *tls.Config {
return &tls.Config{
InsecureSkipVerify: insecureSkipVerify,
}
}

func connectToServer(host string, insecureSkipVerify bool) *tls.Conn {
conn, err := tls.Dial("tcp4", net.JoinHostPort(host, "443"), TlsConfig(insecureSkipVerify))
if err != nil {
return nil
}
return conn
}

func CheckConnectionFromServer(host string, insecureSkipVerify bool) bool {
// 22 exit code means the host could be accessed and ssl certificate was tested (if specified)
return HttpGet(fmt.Sprintf("https://%s", host), insecureSkipVerify) == 22
conn := connectToServer(host, insecureSkipVerify)
if conn == nil {
return false
}
defer func() {
_ = conn.Close()
}()
return conn != nil
}

func ReadCertificateFromServer(host string) *x509.Certificate {
conf := &tls.Config{
InsecureSkipVerify: true,
}
conn, err := tls.Dial("tcp4", net.JoinHostPort(host, "443"), conf)
if err != nil {
conn := connectToServer(host, true)
if conn == nil {
return nil
}
defer func() {
Expand Down

0 comments on commit b3ef94c

Please sign in to comment.