From 95aa0863270245480ceac7c75d071b8a38f30fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=BB=D0=B5=D0=B3=20=D0=91=D0=BE=D1=80=D0=BE=D0=B4?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Fri, 30 Jan 2026 00:15:20 +0200 Subject: [PATCH] working commit --- app/config/config.go | 63 ++++++++++++++++++++++++++++++++++++ app/service/service.go | 57 +++++++++++++++++++++++++++----- pkg/auxx509/x509cert.go | 63 ++++++++++++++++++++++++++++++++++++ pkg/auxx509/x509cert_test.go | 15 +++++++++ pkg/client/client.go | 42 +++++++++++++++++------- 5 files changed, 221 insertions(+), 19 deletions(-) create mode 100644 pkg/auxx509/x509cert.go create mode 100644 pkg/auxx509/x509cert_test.go diff --git a/app/config/config.go b/app/config/config.go index d3f0a51..7666ebe 100644 --- a/app/config/config.go +++ b/app/config/config.go @@ -7,6 +7,8 @@ import ( "os" "path/filepath" + "mstore/pkg/auxx509" + "sigs.k8s.io/yaml" ) @@ -31,6 +33,10 @@ type Config struct { Logpath string `json:"logpath" yaml:"logpath"` Runpath string `json:"runpath" yaml:"runpath"` Version string `json:"version" yaml:"version"` + Certpath string `json:"certpath" yaml:"certath"` + Keypath string `json:"keypath" yaml:"keypath"` + X509Cert string `json:"X509cert" yaml:"X509cert"` + X509Key string `json:"X509key" yaml:"X509key"` } func NewConfig() *Config { @@ -40,6 +46,12 @@ func NewConfig() *Config { runfile := fmt.Sprintf("%s.run", srvname) runpath := filepath.Join(rundir, runfile) + certpath := fmt.Sprintf("%s.crt", srvname) + certpath = filepath.Join(confdir, certpath) + + keypath := fmt.Sprintf("%s.crt", srvname) + keypath = filepath.Join(confdir, keypath) + return &Config{ Service: Service{ Address: "0.0.0.0", @@ -55,6 +67,8 @@ func NewConfig() *Config { Logpath: logpath, Runpath: runpath, Version: version, + Certpath: certpath, + Keypath: keypath, } } @@ -98,3 +112,52 @@ func (conf *Config) ReadOptions() error { return err } + +func (conf *Config) ReadX509Cert() error { + var err error + if conf.Certpath != "" && conf.Keypath != "" { + if !filepath.IsAbs(conf.Certpath) { + conf.Certpath = filepath.Join(confdir, conf.Certpath) + } + certBytes, err := os.ReadFile(conf.Certpath) + if err != nil { + return err + } + if !filepath.IsAbs(conf.Keypath) { + conf.Keypath = filepath.Join(confdir, conf.Keypath) + } + keyBytes, err := os.ReadFile(conf.Keypath) + if err != nil { + return err + } + conf.X509Cert = string(certBytes) + conf.X509Key = string(keyBytes) + return err + } + /* + if conf.X509Cert != "" && conf.X509Key != "" { + x509Cert, err := base64.StdEncoding.DecodeString(conf.X509Cert) + if err != nil { + return err + } + conf.X509Cert = string(x509Cert) + x509Key, err := base64.StdEncoding.DecodeString(conf.X509Key) + if err != nil { + return err + } + conf.X509Key = string(x509Key) + } + */ + if conf.X509Cert == "" || conf.X509Key == "" { + certBytes, keyBytes, err := auxx509.CreateSelfSignedCert("localhost") + if err != nil { + return err + } + conf.X509Cert = string(certBytes) + conf.X509Key = string(keyBytes) + return err + + } + + return err +} diff --git a/app/service/service.go b/app/service/service.go index 4196d2f..a5c5e65 100644 --- a/app/service/service.go +++ b/app/service/service.go @@ -15,7 +15,11 @@ import ( const protocol = "tcp" type ServiceParams struct { - Handler *handler.Handler + Handler *handler.Handler + X509Cert []byte + X509Key []byte + Portnum int64 + Address string } type Service struct { @@ -23,16 +27,23 @@ type Service struct { rout *router.Router logg *logger.Logger - address string - portnum int64 - listen net.Listener - hsrv *http.Server + address string + portnum int64 + x509cert []byte + x509key []byte + + listen net.Listener + hsrv *http.Server } func NewService(params *ServiceParams) (*Service, error) { var err error svc := &Service{ - hand: params.Handler, + hand: params.Handler, + x509cert: conf.X509Cert, + x509key: conf.X509Key, + portnum: conf.Portnum, + address: conf.Address, } svc.logg = logger.NewLogger("service") return svc, err @@ -55,8 +66,38 @@ func (svc *Service) Build() error { svc.logg.Infof("%s\t%s", item.Method, item.RawPath) } - listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum) - svc.listen, err = net.Listen(protocol, listenAddress) + const useTLS = true + if useTLS { + tlsCert, err := tls.X509KeyPair(svc.x509cert, svc.x509key) + + if err != nil { + return err + } + + tlsConfig := tls.Config{ + Certificates: []tls.Certificate{tlsCert}, + ClientAuth: tls.NoClientCert, + InsecureSkipVerify: true, + } + + listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum) + svc.listen, err = tls.Listen(svc.protocol, listenAddress, &tlsConfig) + if err != nil { + return err + } + + } else { + listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum) + svc.listen, err = net.Listen(svc.protocol, listenAddress) + if err != nil { + return err + } + } + //listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum) + //svc.listen, err = net.Listen(protocol, listenAddress) + + svc.log.Infof("Service listening at %v", svc.listen.Addr()) + svc.hsrv = &http.Server{ Handler: svc.rout, } diff --git a/pkg/auxx509/x509cert.go b/pkg/auxx509/x509cert.go new file mode 100644 index 0000000..c2cb28f --- /dev/null +++ b/pkg/auxx509/x509cert.go @@ -0,0 +1,63 @@ +package auxx509 + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "math/big" + "time" +) + +func CreateSelfSignedCert(subject string, dnsNames ...string) ([]byte, []byte, error) { + var err error + certPem := make([]byte, 0) + keyPem := make([]byte, 0) + + now := time.Now() + + const yearsAfter int = 10 + const keySize int = 2048 + + key, err := rsa.GenerateKey(rand.Reader, keySize) + if err != nil { + err := fmt.Errorf("Can't create a private key: %v", err) + return certPem, keyPem, err + + } + keyPemBlock := pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(key), + } + keyPem = pem.EncodeToMemory(&keyPemBlock) + + names := make([]string, 0) + names = append(names, subject) + names = append(names, dnsNames...) + tml := x509.Certificate{ + SerialNumber: big.NewInt(now.Unix()), + NotBefore: now, + NotAfter: now.AddDate(yearsAfter, 0, 0), + Subject: pkix.Name{ + CommonName: subject, + }, + DNSNames: names, + BasicConstraintsValid: true, + } + certBytes, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &key.PublicKey, key) + if err != nil { + return certPem, keyPem, fmt.Errorf("Can't create a certificate: %v", err) + + } + certPemBlock := pem.Block{ + Type: "CERTIFICATE", + Bytes: certBytes, + } + certPem = pem.EncodeToMemory(&certPemBlock) + if err != nil { + return certPem, keyPem, err + } + return certPem, keyPem, err +} diff --git a/pkg/auxx509/x509cert_test.go b/pkg/auxx509/x509cert_test.go new file mode 100644 index 0000000..33236db --- /dev/null +++ b/pkg/auxx509/x509cert_test.go @@ -0,0 +1,15 @@ +package auxx509 + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCert(t *testing.T) { + caCert, caKey, err := CreateSelfSignedCert("test1") + require.NoError(t, err) + fmt.Println(string(caCert)) + fmt.Println(string(caKey)) +} diff --git a/pkg/client/client.go b/pkg/client/client.go index a221231..d555834 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -3,6 +3,7 @@ package client import ( "context" "crypto/tls" + "encoding/base64" "fmt" "io" "net/http" @@ -13,22 +14,28 @@ import ( "strings" ) +const fileAPI = "/v3/api/file/" + type Client struct{} func NewClient() *Client { return &Client{} } -func (cli *Client) FileExists(ctx context.Context, reference string) (bool, error) { +func (cli *Client) FileExists(ctx context.Context, ref string) (bool, error) { var res bool var err error - reqpath := fmt.Sprintf("/v3/api/file/%s", reference) - - req, err := http.NewRequestWithContext(ctx, "HEAD", reqpath, nil) + ref, err = convertFileLink(ref) if err != nil { return res, err } + req, err := http.NewRequestWithContext(ctx, "HEAD", ref, nil) + if err != nil { + return res, err + } + authValue := createBasicAuthPair + transport := &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, @@ -48,21 +55,33 @@ func (cli *Client) FileExists(ctx context.Context, reference string) (bool, erro return res, err } -func (cli *Client) GetFile(ctx context.Context, ref, filename string) error { +func createBasicAuthPair(username, password string) string { + auth := username + ":" + password + return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth)) +} + +func convertFileLink(ref string) (string, error) { var err error - - const api = "/v3/api/file/" - + var res string if !strings.Contains(ref, "://") { ref = "https://" + ref } url, err := url.Parse(ref) + if err != nil { + return res, err + } + url.Path = path.Join(fileAPI, url.Path) + url.User = nil + res = url.String() + return res, err +} + +func (cli *Client) GetFile(ctx context.Context, ref, filename string) error { + var err error + ref, err = convertFileLink(ref) if err != nil { return err } - url.Path = path.Join(api, url.Path) - url.User = nil - ref = url.String() req, err := http.NewRequestWithContext(ctx, "GET", ref, nil) if err != nil { @@ -81,6 +100,7 @@ func (cli *Client) GetFile(ctx context.Context, ref, filename string) error { return err } defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { err := fmt.Errorf("Received wrong status code: %s", resp.StatusCode) return err