Skip to content

Commit

Permalink
sdk: add a logger interface
Browse files Browse the repository at this point in the history
we are now ready to make the sdk a separate module

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
  • Loading branch information
drakkan committed Jan 4, 2022
1 parent a6fe802 commit 2912b2e
Show file tree
Hide file tree
Showing 30 changed files with 225 additions and 134 deletions.
1 change: 0 additions & 1 deletion common/protocol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import (
"github.com/drakkan/sftpgo/v2/dataprovider"
"github.com/drakkan/sftpgo/v2/httpclient"
"github.com/drakkan/sftpgo/v2/httpdtest"
_ "github.com/drakkan/sftpgo/v2/kms"
"github.com/drakkan/sftpgo/v2/logger"
"github.com/drakkan/sftpgo/v2/mfa"
"github.com/drakkan/sftpgo/v2/sdk"
Expand Down
1 change: 0 additions & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/drakkan/sftpgo/v2/ftpd"
"github.com/drakkan/sftpgo/v2/httpclient"
"github.com/drakkan/sftpgo/v2/httpd"
_ "github.com/drakkan/sftpgo/v2/kms"
"github.com/drakkan/sftpgo/v2/mfa"
"github.com/drakkan/sftpgo/v2/sdk/kms"
"github.com/drakkan/sftpgo/v2/sdk/plugin"
Expand Down
3 changes: 2 additions & 1 deletion dataprovider/dataprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import (
"github.com/drakkan/sftpgo/v2/sdk"
"github.com/drakkan/sftpgo/v2/sdk/kms"
"github.com/drakkan/sftpgo/v2/sdk/plugin"
sdkutil "github.com/drakkan/sftpgo/v2/sdk/util"
"github.com/drakkan/sftpgo/v2/util"
"github.com/drakkan/sftpgo/v2/vfs"
)
Expand Down Expand Up @@ -2889,7 +2890,7 @@ func getExternalAuthResponse(username, password, pkey, keyboardInteractive, ip,
var tlsCert string
if cert != nil {
var err error
tlsCert, err = util.EncodeTLSCertToPem(cert)
tlsCert, err = sdkutil.EncodeTLSCertToPem(cert)
if err != nil {
return nil, err
}
Expand Down
1 change: 0 additions & 1 deletion ftpd/ftpd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"github.com/drakkan/sftpgo/v2/dataprovider"
"github.com/drakkan/sftpgo/v2/ftpd"
"github.com/drakkan/sftpgo/v2/httpdtest"
_ "github.com/drakkan/sftpgo/v2/kms"
"github.com/drakkan/sftpgo/v2/logger"
"github.com/drakkan/sftpgo/v2/mfa"
"github.com/drakkan/sftpgo/v2/sdk"
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZo
github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.38.68/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.40.34/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
github.com/aws/aws-sdk-go v1.42.25 h1:BbdvHAi+t9LRiaYUyd53noq9jcaAcfzOhSVbKfr6Avs=
github.com/aws/aws-sdk-go v1.42.25/go.mod h1:gyRszuZ/icHmHAVE4gc/r+cfCmhA1AD+vqfWbgI+eHs=
github.com/aws/aws-sdk-go v1.42.26 h1:3+GcxzyI+kvqoASDNeeLZfqGkvyNMrE9IDuErxPRtCA=
github.com/aws/aws-sdk-go v1.42.26/go.mod h1:gyRszuZ/icHmHAVE4gc/r+cfCmhA1AD+vqfWbgI+eHs=
github.com/aws/aws-sdk-go-v2 v1.7.0/go.mod h1:tb9wi5s61kTDA5qCkcDbt3KRVV74GGslQkl/DRdX/P4=
Expand Down Expand Up @@ -271,8 +269,6 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.0.8-0.20220103230436-7dbe9a0bd10f h1:6kLofhLkWj7lgCc+mvcVLnwhTzQYgL/yW/Y0e/JYwjg=
github.com/go-chi/chi/v5 v5.0.8-0.20220103230436-7dbe9a0bd10f/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/jwtauth/v5 v5.0.2 h1:CSKtr+b6Jnfy5T27sMaiBPxaVE/bjnjS3ramFQ0526w=
Expand Down
1 change: 0 additions & 1 deletion httpd/httpd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import (
"github.com/drakkan/sftpgo/v2/httpclient"
"github.com/drakkan/sftpgo/v2/httpd"
"github.com/drakkan/sftpgo/v2/httpdtest"
_ "github.com/drakkan/sftpgo/v2/kms"
"github.com/drakkan/sftpgo/v2/logger"
"github.com/drakkan/sftpgo/v2/mfa"
"github.com/drakkan/sftpgo/v2/sdk"
Expand Down
3 changes: 2 additions & 1 deletion httpd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/drakkan/sftpgo/v2/logger"
"github.com/drakkan/sftpgo/v2/mfa"
"github.com/drakkan/sftpgo/v2/sdk"
sdklogger "github.com/drakkan/sftpgo/v2/sdk/logger"
"github.com/drakkan/sftpgo/v2/smtp"
"github.com/drakkan/sftpgo/v2/util"
"github.com/drakkan/sftpgo/v2/version"
Expand Down Expand Up @@ -75,7 +76,7 @@ func (s *httpdServer) listenAndServe() error {
WriteTimeout: 60 * time.Second,
IdleTimeout: 60 * time.Second,
MaxHeaderBytes: 1 << 16, // 64KB
ErrorLog: log.New(&logger.StdLoggerWrapper{Sender: logSender}, "", 0),
ErrorLog: log.New(&sdklogger.StdLoggerWrapper{Sender: logSender}, "", 0),
}
if certMgr != nil && s.binding.EnableHTTPS {
config := &tls.Config{
Expand Down
2 changes: 0 additions & 2 deletions kms/kms.go

This file was deleted.

61 changes: 44 additions & 17 deletions logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ import (
"time"

ftpserverlog "github.com/fclairamb/go-log"
"github.com/hashicorp/go-hclog"
"github.com/rs/zerolog"
lumberjack "gopkg.in/natefinch/lumberjack.v2"

sdklogger "github.com/drakkan/sftpgo/v2/sdk/logger"
)

const (
Expand All @@ -41,22 +44,25 @@ var (
rollingLogger *lumberjack.Logger
)

// StdLoggerWrapper is a wrapper for standard logger compatibility
type StdLoggerWrapper struct {
Sender string
type logWrapper struct{}

// LogWithKeyVals logs at the specified level for the specified sender adding the specified key vals
func (l *logWrapper) LogWithKeyVals(level hclog.Level, sender, msg string, args ...interface{}) {
LogWithKeyVals(level, sender, msg, args...)
}

// Write implements the io.Writer interface. This is useful to set as a writer
// for the standard library log.
func (l *StdLoggerWrapper) Write(p []byte) (n int, err error) {
n = len(p)
if n > 0 && p[n-1] == '\n' {
// Trim CR added by stdlog.
p = p[0 : n-1]
// Log logs at the specified level for the specified sender
func (l *logWrapper) Log(level hclog.Level, sender, format string, v ...interface{}) {
switch level {
case hclog.Info:
Log(LevelInfo, sender, "", format, v...)
case hclog.Warn:
Log(LevelWarn, sender, "", format, v...)
case hclog.Error:
Log(LevelError, sender, "", format, v...)
default:
Log(LevelDebug, sender, "", format, v...)
}

Log(LevelError, l.Sender, "", string(p))
return
}

// LeveledLogger is a logger that accepts a message string and a variadic number of key-value pairs
Expand Down Expand Up @@ -176,6 +182,7 @@ func InitLogger(logFilePath string, logMaxSize int, logMaxBackups int, logMaxAge
consoleLogger = zerolog.Nop()
}
logger = logger.Level(level)
sdklogger.SetLogger(&logWrapper{})
}

// InitStdErrLogger configures the logger to write to stderr
Expand All @@ -184,13 +191,15 @@ func InitStdErrLogger(level zerolog.Level) {
output: os.Stderr,
}).Level(level)
consoleLogger = zerolog.Nop()
sdklogger.SetLogger(&logWrapper{})
}

// DisableLogger disable the main logger.
// ConsoleLogger will not be affected
func DisableLogger() {
logger = zerolog.Nop()
rollingLogger = nil
sdklogger.DisableLogger()
}

// EnableConsoleLogger enables the console logger
Expand All @@ -210,6 +219,24 @@ func RotateLogFile() error {
return errors.New("logging to file is disabled")
}

// LogWithKeyVals logs at the specified level for the specified sender adding the specified key vals
func LogWithKeyVals(level hclog.Level, sender, msg string, args ...interface{}) {
var ev *zerolog.Event
switch level {
case hclog.Info:
ev = logger.Info()
case hclog.Warn:
ev = logger.Warn()
case hclog.Error:
ev = logger.Error()
default:
ev = logger.Debug()
}
ev.Timestamp().Str("sender", sender)
addKeysAndValues(ev, args...)
ev.Msg(msg)
}

// Log logs at the specified level for the specified sender
func Log(level LogLevel, sender string, connectionID string, format string, v ...interface{}) {
var ev *zerolog.Event
Expand All @@ -231,22 +258,22 @@ func Log(level LogLevel, sender string, connectionID string, format string, v ..
}

// Debug logs at debug level for the specified sender
func Debug(sender string, connectionID string, format string, v ...interface{}) {
func Debug(sender, connectionID, format string, v ...interface{}) {
Log(LevelDebug, sender, connectionID, format, v...)
}

// Info logs at info level for the specified sender
func Info(sender string, connectionID string, format string, v ...interface{}) {
func Info(sender, connectionID, format string, v ...interface{}) {
Log(LevelInfo, sender, connectionID, format, v...)
}

// Warn logs at warn level for the specified sender
func Warn(sender string, connectionID string, format string, v ...interface{}) {
func Warn(sender, connectionID, format string, v ...interface{}) {
Log(LevelWarn, sender, connectionID, format, v...)
}

// Error logs at error level for the specified sender
func Error(sender string, connectionID string, format string, v ...interface{}) {
func Error(sender, connectionID, format string, v ...interface{}) {
Log(LevelError, sender, connectionID, format, v...)
}

Expand Down
1 change: 0 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"go.uber.org/automaxprocs/maxprocs"

"github.com/drakkan/sftpgo/v2/cmd"
_ "github.com/drakkan/sftpgo/v2/kms"
)

func main() {
Expand Down
28 changes: 13 additions & 15 deletions kms/builtin.go → sdk/kms/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,21 @@ import (
"encoding/hex"
"errors"
"io"

sdkkms "github.com/drakkan/sftpgo/v2/sdk/kms"
)

var (
errMalformedCiphertext = errors.New("malformed ciphertext")
)

type builtinSecret struct {
sdkkms.BaseSecret
BaseSecret
}

func init() {
sdkkms.RegisterSecretProvider(sdkkms.SchemeBuiltin, sdkkms.SecretStatusAES256GCM, newBuiltinSecret)
RegisterSecretProvider(SchemeBuiltin, SecretStatusAES256GCM, newBuiltinSecret)
}

func newBuiltinSecret(base sdkkms.BaseSecret, url, masterKey string) sdkkms.SecretProvider {
func newBuiltinSecret(base BaseSecret, url, masterKey string) SecretProvider {
return &builtinSecret{
BaseSecret: base,
}
Expand All @@ -35,7 +33,7 @@ func (s *builtinSecret) Name() string {
}

func (s *builtinSecret) IsEncrypted() bool {
return s.Status == sdkkms.SecretStatusAES256GCM
return s.Status == SecretStatusAES256GCM
}

func (s *builtinSecret) deriveKey(key []byte) []byte {
Expand All @@ -51,10 +49,10 @@ func (s *builtinSecret) deriveKey(key []byte) []byte {

func (s *builtinSecret) Encrypt() error {
if s.Payload == "" {
return sdkkms.ErrInvalidSecret
return ErrInvalidSecret
}
switch s.Status {
case sdkkms.SecretStatusPlain:
case SecretStatusPlain:
key := make([]byte, 32)
if _, err := io.ReadFull(rand.Reader, key); err != nil {
return err
Expand All @@ -78,16 +76,16 @@ func (s *builtinSecret) Encrypt() error {
ciphertext := gcm.Seal(nonce, nonce, []byte(s.Payload), aad)
s.Key = hex.EncodeToString(key)
s.Payload = hex.EncodeToString(ciphertext)
s.Status = sdkkms.SecretStatusAES256GCM
s.Status = SecretStatusAES256GCM
return nil
default:
return sdkkms.ErrWrongSecretStatus
return ErrWrongSecretStatus
}
}

func (s *builtinSecret) Decrypt() error {
switch s.Status {
case sdkkms.SecretStatusAES256GCM:
case SecretStatusAES256GCM:
encrypted, err := hex.DecodeString(s.Payload)
if err != nil {
return err
Expand Down Expand Up @@ -117,18 +115,18 @@ func (s *builtinSecret) Decrypt() error {
if err != nil {
return err
}
s.Status = sdkkms.SecretStatusPlain
s.Status = SecretStatusPlain
s.Payload = string(plaintext)
s.Key = ""
s.AdditionalData = ""
return nil
default:
return sdkkms.ErrWrongSecretStatus
return ErrWrongSecretStatus
}
}

func (s *builtinSecret) Clone() sdkkms.SecretProvider {
baseSecret := sdkkms.BaseSecret{
func (s *builtinSecret) Clone() SecretProvider {
baseSecret := BaseSecret{
Status: s.Status,
Payload: s.Payload,
Key: s.Key,
Expand Down
12 changes: 6 additions & 6 deletions sdk/kms/kms.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"strings"
"sync"

"github.com/drakkan/sftpgo/v2/logger"
"github.com/drakkan/sftpgo/v2/util"
"github.com/drakkan/sftpgo/v2/sdk/logger"
"github.com/drakkan/sftpgo/v2/sdk/util"
)

// SecretProvider defines the interface for a KMS secrets provider
Expand Down Expand Up @@ -141,7 +141,7 @@ func (c *Configuration) Initialize() error {
config.Secrets.URL = SchemeLocal + "://"
}
for k, v := range secretProviders {
logger.Debug(logSender, "", "secret provider registered for scheme: %#v, encrypted status: %#v",
logger.Debug(logSender, "secret provider registered for scheme: %#v, encrypted status: %#v",
k, v.encryptedStatus)
}
return nil
Expand All @@ -166,8 +166,8 @@ func (c *Configuration) getSecretProvider(base BaseSecret) SecretProvider {
}
}
// we assume that SchemeLocal is always registered
logger.Warn(logSender, "", "no secret provider registered for URL %v, fallback to local provider", c.Secrets.URL)
return secretProviders[SchemeLocal].newFn(base, c.Secrets.URL, c.Secrets.masterKey)
logger.Warn(logSender, "no secret provider registered for URL %v, fallback to local provider", c.Secrets.URL)
return NewLocalSecret(base, c.Secrets.URL, c.Secrets.masterKey)
}

// Secret defines the struct used to store confidential data
Expand Down Expand Up @@ -217,7 +217,7 @@ func (s *Secret) UnmarshalJSON(data []byte) error {
return nil
}
}
logger.Debug(logSender, "", "no provider registered for status %#v", baseSecret.Status)
logger.Debug(logSender, "no provider registered for status %#v", baseSecret.Status)

return ErrInvalidSecret
}
Expand Down

0 comments on commit 2912b2e

Please sign in to comment.