Added Options and Path safety

This commit is contained in:
Pablu23
2023-12-11 12:04:20 +01:00
parent 6f60fe37db
commit e19a9ba4f5
5 changed files with 119 additions and 21 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ testFiles/
out/ out/
sha512sums.txt sha512sums.txt
pubkey.pem pubkey.pem
privkey.pem

View File

@@ -5,7 +5,7 @@ server:
go run cmd/uftp/main.go server go run cmd/uftp/main.go server
test: test:
go run cmd/uftp/main.go client testFiles/testFile 0.0.0.0 go run cmd/uftp/main.go client testFile 0.0.0.0
win: win:
GOOS=windows GOARCH=amd64 go build -o bin/app-amd64.exe cmd/uftp/main.go GOOS=windows GOARCH=amd64 go build -o bin/app-amd64.exe cmd/uftp/main.go

View File

@@ -9,11 +9,11 @@ import (
func main() { func main() {
if os.Args[1] == "server" { if os.Args[1] == "server" {
server, err := server.New() server, err := server.New(func(o *server.Options) {
if err != nil { o.SavePrivKey = false
panic(err) o.LoadPrivkey = true
} o.PrivKeyPath = "privkey.pem"
err = server.SavePublicKeyPem() })
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@@ -0,0 +1,22 @@
package server
type Options struct {
Address string
Datapath string
LoadPrivkey bool
PrivKeyPath string
PubKeyPath string
SavePubKey bool
SavePrivKey bool
}
func NewDefaultOptions() *Options {
return &Options{
Address: "0.0.0.0",
Datapath: "./testFiles/",
LoadPrivkey: false,
SavePrivKey: false,
SavePubKey: true,
PubKeyPath: "pubkey.pem",
}
}

View File

@@ -8,10 +8,12 @@ import (
"encoding/hex" "encoding/hex"
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt"
"io" "io"
"net" "net"
"os" "os"
"os/signal" "os/signal"
"path/filepath"
"sync" "sync"
"time" "time"
@@ -32,26 +34,84 @@ type Server struct {
sessions map[common.SessionID]*info sessions map[common.SessionID]*info
mu sync.Mutex mu sync.Mutex
rsa *rsa.PrivateKey rsa *rsa.PrivateKey
options *Options
parentFilePath string
} }
func New() (*Server, error) { func New(opts ...func(*Options)) (*Server, error) {
key, err := rsa.GenerateKey(rand.Reader, 4096) options := NewDefaultOptions()
for _, opt := range opts {
opt(options)
}
var key *rsa.PrivateKey
var err error
if options.LoadPrivkey {
privKey, err := os.ReadFile(options.PrivKeyPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
block, _ := pem.Decode(privKey)
key, _ = x509.ParsePKCS1PrivateKey(block.Bytes)
} else {
key, err = rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
return nil, err
}
}
parentFilePath, err := filepath.Abs(options.Datapath)
if err != nil {
return nil, err
}
server := &Server{
sessions: make(map[common.SessionID]*info),
rsa: key,
options: options,
parentFilePath: parentFilePath,
}
if options.SavePubKey {
err = server.SavePublicKeyPem()
if err != nil {
return nil, err
}
}
if options.SavePrivKey {
err = server.SavePrivateKeyPem()
if err != nil {
return nil, err
}
}
log.SetFormatter(&log.TextFormatter{ log.SetFormatter(&log.TextFormatter{
ForceColors: true, ForceColors: true,
}) })
return &Server{ return server, nil
sessions: make(map[common.SessionID]*info), }
rsa: key,
}, nil func (server *Server) SavePrivateKeyPem() error {
file, err := os.Create(server.options.PrivKeyPath)
if err != nil {
return err
}
defer file.Close()
privateKeyPEM := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(server.rsa),
}
pem.Encode(file, privateKeyPEM)
return nil
} }
func (server *Server) SavePublicKeyPem() error { func (server *Server) SavePublicKeyPem() error {
file, err := os.Create("pubkey.pem") file, err := os.Create(server.options.PubKeyPath)
if err != nil { if err != nil {
return err return err
} }
@@ -179,9 +239,23 @@ func (server *Server) sendPTE(conn *net.UDPConn, addr *net.UDPAddr, pck *common.
return return
} }
fi, err := os.Stat(path) file := filepath.Join(server.parentFilePath, path)
file = filepath.Clean(file)
matched, err := filepath.Match(fmt.Sprintf("%v\\*", server.parentFilePath), file)
if err != nil || !matched {
log.WithFields(log.Fields{
"ParentFilePath": server.parentFilePath,
"RequestedFilePath": path,
"CleanedFilePath": file,
}).WithError(err).Warn("Requesting File out of Path")
return
}
fi, err := os.Stat(file)
if err != nil { if err != nil {
log.WithError(err).WithField("File Path", path).Error("Unable to open File") log.WithError(err).WithField("File Path", file).Error("Unable to open File")
return return
} }
@@ -192,7 +266,7 @@ func (server *Server) sendPTE(conn *net.UDPConn, addr *net.UDPAddr, pck *common.
server.mu.Lock() server.mu.Lock()
if info, ok := server.sessions[pck.Sid]; ok { if info, ok := server.sessions[pck.Sid]; ok {
info.path = path info.path = file
info.lastSync = ptePck.Sync info.lastSync = ptePck.Sync
info.lastPckSend = ptePck.Flag info.lastPckSend = ptePck.Flag
server.mu.Unlock() server.mu.Unlock()
@@ -321,6 +395,7 @@ func (server *Server) handleConnection(conn net.Conn) {
server.mu.Unlock() server.mu.Unlock()
conn.Write([]byte("Yep")) conn.Write([]byte("Yep"))
conn.Close() conn.Close()
log.WithField("SessionID", hex.EncodeToString(rsaPck.Sid[:])).Info("Started Session")
} }
func (server *Server) startManagement() { func (server *Server) startManagement() {
@@ -340,7 +415,7 @@ func (server *Server) startManagement() {
} }
func (server *Server) Serve() { func (server *Server) Serve() {
udpAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:13374") udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%v:13374", server.options.Address))
if err != nil { if err != nil {
log.Fatal("Could not resolve UDP Address") log.Fatal("Could not resolve UDP Address")
} }