mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-21 23:20:24 +00:00
add an util method to convert []byte to string
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
65753fe23e
commit
5d24d665bd
23 changed files with 70 additions and 40 deletions
2
go.mod
2
go.mod
|
@ -79,7 +79,7 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.112.2 // indirect
|
cloud.google.com/go v0.112.2 // indirect
|
||||||
cloud.google.com/go/auth v0.3.0 // indirect
|
cloud.google.com/go/auth v0.4.0 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||||
cloud.google.com/go/iam v1.1.8 // indirect
|
cloud.google.com/go/iam v1.1.8 // indirect
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -3,8 +3,11 @@ cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw=
|
||||||
cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms=
|
cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms=
|
||||||
cloud.google.com/go/auth v0.3.0 h1:PRyzEpGfx/Z9e8+lHsbkoUVXD0gnu4MNmm7Gp8TQNIs=
|
cloud.google.com/go/auth v0.3.0 h1:PRyzEpGfx/Z9e8+lHsbkoUVXD0gnu4MNmm7Gp8TQNIs=
|
||||||
cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w=
|
cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w=
|
||||||
|
cloud.google.com/go/auth v0.4.0 h1:vcJWEguhY8KuiHoSs/udg1JtIRYm3YAWPBE1moF1m3U=
|
||||||
|
cloud.google.com/go/auth v0.4.0/go.mod h1:tO/chJN3obc5AbRYFQDsuFbL4wW5y8LfbPtDCfgwOVE=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
|
cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
|
cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
|
||||||
|
cloud.google.com/go/compute v1.26.0 h1:uHf0NN2nvxl1Gh4QO83yRCOdMK4zivtMS5gv0dEX0hg=
|
||||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||||
cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0=
|
cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0=
|
||||||
|
@ -236,6 +239,7 @@ github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD
|
||||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
||||||
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||||
|
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
|
||||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
|
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
|
||||||
|
|
|
@ -329,7 +329,7 @@ func (c *Configuration) getLockTime() (time.Time, error) {
|
||||||
acmeLog(logger.LevelError, "unable to read lock file %q: %v", c.lockPath, err)
|
acmeLog(logger.LevelError, "unable to read lock file %q: %v", c.lockPath, err)
|
||||||
return time.Time{}, err
|
return time.Time{}, err
|
||||||
}
|
}
|
||||||
msec, err := strconv.ParseInt(strings.TrimSpace(string(content)), 10, 64)
|
msec, err := strconv.ParseInt(strings.TrimSpace(util.BytesToString(content)), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
acmeLog(logger.LevelError, "unable to parse lock time: %v", err)
|
acmeLog(logger.LevelError, "unable to parse lock time: %v", err)
|
||||||
return time.Time{}, fmt.Errorf("unable to parse lock time: %w", err)
|
return time.Time{}, fmt.Errorf("unable to parse lock time: %w", err)
|
||||||
|
|
|
@ -196,7 +196,7 @@ Please take a look at the usage below to customize the serving parameters`,
|
||||||
fmt.Printf("Unable to read password file %q: %v", portablePasswordFile, err)
|
fmt.Printf("Unable to read password file %q: %v", portablePasswordFile, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
pwd = strings.TrimSpace(string(content))
|
pwd = strings.TrimSpace(util.BytesToString(content))
|
||||||
}
|
}
|
||||||
service.SetGraceTime(graceTime)
|
service.SetGraceTime(graceTime)
|
||||||
service := service.Service{
|
service := service.Service{
|
||||||
|
@ -523,7 +523,7 @@ func getFileContents(name string) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return string(contents), nil
|
return util.BytesToString(contents), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertFsProvider() string {
|
func convertFsProvider() string {
|
||||||
|
|
|
@ -345,7 +345,7 @@ func notificationAsEnvVars(event *notifier.FsEvent) []string {
|
||||||
if len(event.Metadata) > 0 {
|
if len(event.Metadata) > 0 {
|
||||||
data, err := json.Marshal(event.Metadata)
|
data, err := json.Marshal(event.Metadata)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
result = append(result, fmt.Sprintf("SFTPGO_ACTION_METADATA=%s", string(data)))
|
result = append(result, fmt.Sprintf("SFTPGO_ACTION_METADATA=%s", util.BytesToString(data)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -479,7 +479,7 @@ func (c *RetentionCheck) sendHookNotification(elapsed time.Duration, errCheck er
|
||||||
|
|
||||||
cmd := exec.CommandContext(ctx, Config.DataRetentionHook, args...)
|
cmd := exec.CommandContext(ctx, Config.DataRetentionHook, args...)
|
||||||
cmd.Env = append(env,
|
cmd.Env = append(env,
|
||||||
fmt.Sprintf("SFTPGO_DATA_RETENTION_RESULT=%s", string(jsonData)))
|
fmt.Sprintf("SFTPGO_DATA_RETENTION_RESULT=%s", util.BytesToString(jsonData)))
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
|
|
||||||
c.conn.Log(logger.LevelDebug, "notified result using command: %q, elapsed: %s err: %v",
|
c.conn.Log(logger.LevelDebug, "notified result using command: %q, elapsed: %s err: %v",
|
||||||
|
|
|
@ -811,7 +811,7 @@ func (p *EventParams) getStringReplacements(addObjectData, jsonEscaped bool) []s
|
||||||
if addObjectData {
|
if addObjectData {
|
||||||
data, err := p.Object.RenderAsJSON(p.Event != operationDelete)
|
data, err := p.Object.RenderAsJSON(p.Event != operationDelete)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
dataString := string(data)
|
dataString := util.BytesToString(data)
|
||||||
replacements[len(replacements)-3] = p.getStringReplacement(dataString, false)
|
replacements[len(replacements)-3] = p.getStringReplacement(dataString, false)
|
||||||
replacements[len(replacements)-1] = p.getStringReplacement(dataString, true)
|
replacements[len(replacements)-1] = p.getStringReplacement(dataString, true)
|
||||||
}
|
}
|
||||||
|
@ -826,7 +826,7 @@ func (p *EventParams) getStringReplacements(addObjectData, jsonEscaped bool) []s
|
||||||
if len(p.Metadata) > 0 {
|
if len(p.Metadata) > 0 {
|
||||||
data, err := json.Marshal(p.Metadata)
|
data, err := json.Marshal(p.Metadata)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
dataString := string(data)
|
dataString := util.BytesToString(data)
|
||||||
replacements[len(replacements)-3] = p.getStringReplacement(dataString, false)
|
replacements[len(replacements)-3] = p.getStringReplacement(dataString, false)
|
||||||
replacements[len(replacements)-1] = p.getStringReplacement(dataString, true)
|
replacements[len(replacements)-1] = p.getStringReplacement(dataString, true)
|
||||||
}
|
}
|
||||||
|
@ -1466,7 +1466,8 @@ func executeHTTPRuleAction(c dataprovider.EventActionHTTPConfig, params *EventPa
|
||||||
endpoint, time.Since(startTime), resp.StatusCode)
|
endpoint, time.Since(startTime), resp.StatusCode)
|
||||||
if resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusNoContent {
|
if resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusNoContent {
|
||||||
if rb, err := io.ReadAll(io.LimitReader(resp.Body, 2048)); err == nil {
|
if rb, err := io.ReadAll(io.LimitReader(resp.Body, 2048)); err == nil {
|
||||||
eventManagerLog(logger.LevelDebug, "error notification response from endpoint %q: %s", endpoint, string(rb))
|
eventManagerLog(logger.LevelDebug, "error notification response from endpoint %q: %s",
|
||||||
|
endpoint, util.BytesToString(rb))
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,7 @@ func executeNotificationCommand(operation, executor, ip, objectType, objectName,
|
||||||
fmt.Sprintf("SFTPGO_PROVIDER_IP=%s", ip),
|
fmt.Sprintf("SFTPGO_PROVIDER_IP=%s", ip),
|
||||||
fmt.Sprintf("SFTPGO_PROVIDER_ROLE=%s", role),
|
fmt.Sprintf("SFTPGO_PROVIDER_ROLE=%s", role),
|
||||||
fmt.Sprintf("SFTPGO_PROVIDER_TIMESTAMP=%d", util.GetTimeAsMsSinceEpoch(time.Now())),
|
fmt.Sprintf("SFTPGO_PROVIDER_TIMESTAMP=%d", util.GetTimeAsMsSinceEpoch(time.Now())),
|
||||||
fmt.Sprintf("SFTPGO_PROVIDER_OBJECT=%s", string(objectAsJSON)))
|
fmt.Sprintf("SFTPGO_PROVIDER_OBJECT=%s", util.BytesToString(objectAsJSON)))
|
||||||
|
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
|
|
|
@ -297,7 +297,7 @@ func (a *Admin) hashPassword() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
a.Password = string(pwd)
|
a.Password = util.BytesToString(pwd)
|
||||||
} else {
|
} else {
|
||||||
pwd, err := argon2id.CreateHash(a.Password, argon2Params)
|
pwd, err := argon2id.CreateHash(a.Password, argon2Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -118,7 +118,7 @@ func (k *APIKey) hashKey() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
k.Key = string(hashed)
|
k.Key = util.BytesToString(hashed)
|
||||||
} else {
|
} else {
|
||||||
hashed, err := argon2id.CreateHash(k.Key, argon2Params)
|
hashed, err := argon2id.CreateHash(k.Key, argon2Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -3255,7 +3255,7 @@ func hashPlainPassword(plainPwd string) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("bcrypt hashing error: %w", err)
|
return "", fmt.Errorf("bcrypt hashing error: %w", err)
|
||||||
}
|
}
|
||||||
return string(pwd), nil
|
return util.BytesToString(pwd), nil
|
||||||
}
|
}
|
||||||
pwd, err := argon2id.CreateHash(plainPwd, argon2Params)
|
pwd, err := argon2id.CreateHash(plainPwd, argon2Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4115,7 +4115,7 @@ func getPreLoginHookResponse(loginMethod, ip, protocol string, userAsJSON []byte
|
||||||
|
|
||||||
cmd := exec.CommandContext(ctx, config.PreLoginHook, args...)
|
cmd := exec.CommandContext(ctx, config.PreLoginHook, args...)
|
||||||
cmd.Env = append(env,
|
cmd.Env = append(env,
|
||||||
fmt.Sprintf("SFTPGO_LOGIND_USER=%s", string(userAsJSON)),
|
fmt.Sprintf("SFTPGO_LOGIND_USER=%s", util.BytesToString(userAsJSON)),
|
||||||
fmt.Sprintf("SFTPGO_LOGIND_METHOD=%s", loginMethod),
|
fmt.Sprintf("SFTPGO_LOGIND_METHOD=%s", loginMethod),
|
||||||
fmt.Sprintf("SFTPGO_LOGIND_IP=%s", ip),
|
fmt.Sprintf("SFTPGO_LOGIND_IP=%s", ip),
|
||||||
fmt.Sprintf("SFTPGO_LOGIND_PROTOCOL=%s", protocol),
|
fmt.Sprintf("SFTPGO_LOGIND_PROTOCOL=%s", protocol),
|
||||||
|
@ -4162,7 +4162,7 @@ func executePreLoginHook(username, loginMethod, ip, protocol string, oidcTokenFi
|
||||||
recoveryCodes := u.Filters.RecoveryCodes
|
recoveryCodes := u.Filters.RecoveryCodes
|
||||||
err = json.Unmarshal(out, &u)
|
err = json.Unmarshal(out, &u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return u, fmt.Errorf("invalid pre-login hook response %q, error: %v", string(out), err)
|
return u, fmt.Errorf("invalid pre-login hook response %q, error: %v", util.BytesToString(out), err)
|
||||||
}
|
}
|
||||||
u.ID = userID
|
u.ID = userID
|
||||||
u.UsedQuotaSize = userUsedQuotaSize
|
u.UsedQuotaSize = userUsedQuotaSize
|
||||||
|
@ -4257,7 +4257,7 @@ func ExecutePostLoginHook(user *User, loginMethod, ip, protocol string, err erro
|
||||||
|
|
||||||
cmd := exec.CommandContext(ctx, config.PostLoginHook, args...)
|
cmd := exec.CommandContext(ctx, config.PostLoginHook, args...)
|
||||||
cmd.Env = append(env,
|
cmd.Env = append(env,
|
||||||
fmt.Sprintf("SFTPGO_LOGIND_USER=%s", string(userAsJSON)),
|
fmt.Sprintf("SFTPGO_LOGIND_USER=%s", util.BytesToString(userAsJSON)),
|
||||||
fmt.Sprintf("SFTPGO_LOGIND_IP=%s", ip),
|
fmt.Sprintf("SFTPGO_LOGIND_IP=%s", ip),
|
||||||
fmt.Sprintf("SFTPGO_LOGIND_METHOD=%s", loginMethod),
|
fmt.Sprintf("SFTPGO_LOGIND_METHOD=%s", loginMethod),
|
||||||
fmt.Sprintf("SFTPGO_LOGIND_STATUS=%s", status),
|
fmt.Sprintf("SFTPGO_LOGIND_STATUS=%s", status),
|
||||||
|
@ -4326,7 +4326,7 @@ func getExternalAuthResponse(username, password, pkey, keyboardInteractive, ip,
|
||||||
cmd := exec.CommandContext(ctx, config.ExternalAuthHook, args...)
|
cmd := exec.CommandContext(ctx, config.ExternalAuthHook, args...)
|
||||||
cmd.Env = append(env,
|
cmd.Env = append(env,
|
||||||
fmt.Sprintf("SFTPGO_AUTHD_USERNAME=%s", username),
|
fmt.Sprintf("SFTPGO_AUTHD_USERNAME=%s", username),
|
||||||
fmt.Sprintf("SFTPGO_AUTHD_USER=%s", string(userAsJSON)),
|
fmt.Sprintf("SFTPGO_AUTHD_USER=%s", util.BytesToString(userAsJSON)),
|
||||||
fmt.Sprintf("SFTPGO_AUTHD_IP=%s", ip),
|
fmt.Sprintf("SFTPGO_AUTHD_IP=%s", ip),
|
||||||
fmt.Sprintf("SFTPGO_AUTHD_PASSWORD=%s", password),
|
fmt.Sprintf("SFTPGO_AUTHD_PASSWORD=%s", password),
|
||||||
fmt.Sprintf("SFTPGO_AUTHD_PUBLIC_KEY=%s", pkey),
|
fmt.Sprintf("SFTPGO_AUTHD_PUBLIC_KEY=%s", pkey),
|
||||||
|
|
|
@ -99,7 +99,7 @@ func (n *NodeData) validate() error {
|
||||||
if n.Proto != NodeProtoHTTP && n.Proto != NodeProtoHTTPS {
|
if n.Proto != NodeProtoHTTP && n.Proto != NodeProtoHTTPS {
|
||||||
return util.NewValidationError(fmt.Sprintf("invalid node proto: %s", n.Proto))
|
return util.NewValidationError(fmt.Sprintf("invalid node proto: %s", n.Proto))
|
||||||
}
|
}
|
||||||
n.Key = kms.NewPlainSecret(string(util.GenerateRandomBytes(32)))
|
n.Key = kms.NewPlainSecret(util.BytesToString(util.GenerateRandomBytes(32)))
|
||||||
n.Key.SetAdditionalData(n.Host)
|
n.Key.SetAdditionalData(n.Host)
|
||||||
if err := n.Key.Encrypt(); err != nil {
|
if err := n.Key.Encrypt(); err != nil {
|
||||||
return fmt.Errorf("unable to encrypt node key: %w", err)
|
return fmt.Errorf("unable to encrypt node key: %w", err)
|
||||||
|
@ -191,7 +191,7 @@ func (n *Node) generateAuthToken(username, role string) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("unable to sign authentication token: %w", err)
|
return "", fmt.Errorf("unable to sign authentication token: %w", err)
|
||||||
}
|
}
|
||||||
return string(payload), nil
|
return util.BytesToString(payload), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) prepareRequest(ctx context.Context, username, role, relativeURL, method string,
|
func (n *Node) prepareRequest(ctx context.Context, username, role, relativeURL, method string,
|
||||||
|
|
|
@ -155,7 +155,7 @@ func (s *Share) hashPassword() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Password = string(hashed)
|
s.Password = util.BytesToString(hashed)
|
||||||
} else {
|
} else {
|
||||||
hashed, err := argon2id.CreateHash(s.Password, argon2Params)
|
hashed, err := argon2id.CreateHash(s.Password, argon2Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -63,7 +63,7 @@ func NewServer(config *Configuration, configDir string, binding Binding, id int)
|
||||||
}
|
}
|
||||||
bannerContent, err := os.ReadFile(bannerFilePath)
|
bannerContent, err := os.ReadFile(bannerFilePath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
server.initialMsg = string(bannerContent)
|
server.initialMsg = util.BytesToString(bannerContent)
|
||||||
} else {
|
} else {
|
||||||
logger.WarnToConsole("unable to read FTPD banner file: %v", err)
|
logger.WarnToConsole("unable to read FTPD banner file: %v", err)
|
||||||
logger.Warn(logSender, "", "unable to read banner file: %v", err)
|
logger.Warn(logSender, "", "unable to read banner file: %v", err)
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
|
|
||||||
"github.com/drakkan/sftpgo/v2/internal/common"
|
"github.com/drakkan/sftpgo/v2/internal/common"
|
||||||
"github.com/drakkan/sftpgo/v2/internal/dataprovider"
|
"github.com/drakkan/sftpgo/v2/internal/dataprovider"
|
||||||
|
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getDefenderHosts(w http.ResponseWriter, r *http.Request) {
|
func getDefenderHosts(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -76,7 +77,7 @@ func getIPFromID(r *http.Request) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("invalid host id")
|
return "", errors.New("invalid host id")
|
||||||
}
|
}
|
||||||
ip := string(decoded)
|
ip := util.BytesToString(decoded)
|
||||||
err = validateIPAddress(ip)
|
err = validateIPAddress(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
|
@ -1594,7 +1594,7 @@ func getGCSConfig(r *http.Request) (vfs.GCSFsConfig, error) {
|
||||||
}
|
}
|
||||||
return config, err
|
return config, err
|
||||||
}
|
}
|
||||||
config.Credentials = kms.NewPlainSecret(string(fileBytes))
|
config.Credentials = kms.NewPlainSecret(util.BytesToString(fileBytes))
|
||||||
config.AutomaticCredentials = 0
|
config.AutomaticCredentials = 0
|
||||||
return config, err
|
return config, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||||
sdkkms "github.com/sftpgo/sdk/kms"
|
sdkkms "github.com/sftpgo/sdk/kms"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -132,7 +133,7 @@ func (s *builtinSecret) Decrypt() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Status = sdkkms.SecretStatusPlain
|
s.Status = sdkkms.SecretStatusPlain
|
||||||
s.Payload = string(plaintext)
|
s.Payload = util.BytesToString(plaintext)
|
||||||
s.Key = ""
|
s.Key = ""
|
||||||
s.AdditionalData = ""
|
s.AdditionalData = ""
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||||
sdkkms "github.com/sftpgo/sdk/kms"
|
sdkkms "github.com/sftpgo/sdk/kms"
|
||||||
"gocloud.dev/secrets/localsecrets"
|
"gocloud.dev/secrets/localsecrets"
|
||||||
"golang.org/x/crypto/hkdf"
|
"golang.org/x/crypto/hkdf"
|
||||||
|
@ -104,7 +105,7 @@ func (s *localSecret) Decrypt() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Status = sdkkms.SecretStatusPlain
|
s.Status = sdkkms.SecretStatusPlain
|
||||||
s.Payload = string(plaintext)
|
s.Payload = util.BytesToString(plaintext)
|
||||||
s.Key = ""
|
s.Key = ""
|
||||||
s.AdditionalData = ""
|
s.AdditionalData = ""
|
||||||
s.Mode = 0
|
s.Mode = 0
|
||||||
|
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
ftpserverlog "github.com/fclairamb/go-log"
|
ftpserverlog "github.com/fclairamb/go-log"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
@ -283,7 +284,7 @@ func (l *StdLoggerWrapper) Write(p []byte) (n int, err error) {
|
||||||
p = p[0 : n-1]
|
p = p[0 : n-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(LevelError, l.Sender, "", string(p))
|
Log(LevelError, l.Sender, "", bytesToString(p))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,3 +364,12 @@ func (l *LeveledLogger) With(keysAndValues ...any) ftpserverlog.Logger {
|
||||||
additionalKeyVals: append(l.additionalKeyVals, keysAndValues...),
|
additionalKeyVals: append(l.additionalKeyVals, keysAndValues...),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func bytesToString(b []byte) string {
|
||||||
|
// unsafe.SliceData relies on cap whereas we want to rely on len
|
||||||
|
if len(b) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
// https://github.com/golang/go/blob/4ed358b57efdad9ed710be7f4fc51495a7620ce2/src/strings/builder.go#L41
|
||||||
|
return unsafe.String(unsafe.SliceData(b), len(b))
|
||||||
|
}
|
||||||
|
|
|
@ -513,7 +513,7 @@ func (c *Configuration) configureLoginBanner(serverConfig *ssh.ServerConfig, con
|
||||||
}
|
}
|
||||||
bannerContent, err := os.ReadFile(bannerFilePath)
|
bannerContent, err := os.ReadFile(bannerFilePath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
banner := string(bannerContent)
|
banner := util.BytesToString(bannerContent)
|
||||||
serverConfig.BannerCallback = func(_ ssh.ConnMetadata) string {
|
serverConfig.BannerCallback = func(_ ssh.ConnMetadata) string {
|
||||||
return banner
|
return banner
|
||||||
}
|
}
|
||||||
|
@ -603,7 +603,8 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve
|
||||||
|
|
||||||
logger.Log(logger.LevelInfo, common.ProtocolSSH, connectionID,
|
logger.Log(logger.LevelInfo, common.ProtocolSSH, connectionID,
|
||||||
"User %q logged in with %q, from ip %q, client version %q, negotiated algorithms: %+v",
|
"User %q logged in with %q, from ip %q, client version %q, negotiated algorithms: %+v",
|
||||||
user.Username, loginType, ipAddr, string(sconn.ClientVersion()), sconn.Conn.(ssh.AlgorithmsConnMetadata).Algorithms())
|
user.Username, loginType, ipAddr, util.BytesToString(sconn.ClientVersion()),
|
||||||
|
sconn.Conn.(ssh.AlgorithmsConnMetadata).Algorithms())
|
||||||
dataprovider.UpdateLastLogin(&user)
|
dataprovider.UpdateLastLogin(&user)
|
||||||
|
|
||||||
sshConnection := common.NewSSHConnection(connectionID, conn)
|
sshConnection := common.NewSSHConnection(connectionID, conn)
|
||||||
|
@ -639,12 +640,12 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve
|
||||||
|
|
||||||
switch req.Type {
|
switch req.Type {
|
||||||
case "subsystem":
|
case "subsystem":
|
||||||
if string(req.Payload[4:]) == "sftp" {
|
if util.BytesToString(req.Payload[4:]) == "sftp" {
|
||||||
ok = true
|
ok = true
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolSFTP, conn.LocalAddr().String(),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolSFTP, conn.LocalAddr().String(),
|
||||||
conn.RemoteAddr().String(), user),
|
conn.RemoteAddr().String(), user),
|
||||||
ClientVersion: string(sconn.ClientVersion()),
|
ClientVersion: util.BytesToString(sconn.ClientVersion()),
|
||||||
RemoteAddr: conn.RemoteAddr(),
|
RemoteAddr: conn.RemoteAddr(),
|
||||||
LocalAddr: conn.LocalAddr(),
|
LocalAddr: conn.LocalAddr(),
|
||||||
channel: channel,
|
channel: channel,
|
||||||
|
@ -656,7 +657,7 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve
|
||||||
connection := Connection{
|
connection := Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, "sshd_exec", conn.LocalAddr().String(),
|
BaseConnection: common.NewBaseConnection(connID, "sshd_exec", conn.LocalAddr().String(),
|
||||||
conn.RemoteAddr().String(), user),
|
conn.RemoteAddr().String(), user),
|
||||||
ClientVersion: string(sconn.ClientVersion()),
|
ClientVersion: util.BytesToString(sconn.ClientVersion()),
|
||||||
RemoteAddr: conn.RemoteAddr(),
|
RemoteAddr: conn.RemoteAddr(),
|
||||||
LocalAddr: conn.LocalAddr(),
|
LocalAddr: conn.LocalAddr(),
|
||||||
channel: channel,
|
channel: channel,
|
||||||
|
@ -816,7 +817,7 @@ func loginUser(user *dataprovider.User, loginMethod, publicKey string, conn ssh.
|
||||||
}
|
}
|
||||||
p := &ssh.Permissions{}
|
p := &ssh.Permissions{}
|
||||||
p.Extensions = make(map[string]string)
|
p.Extensions = make(map[string]string)
|
||||||
p.Extensions["sftpgo_user"] = string(json)
|
p.Extensions["sftpgo_user"] = util.BytesToString(json)
|
||||||
p.Extensions["sftpgo_login_method"] = loginMethod
|
p.Extensions["sftpgo_login_method"] = loginMethod
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
@ -1180,7 +1181,7 @@ func (c *Configuration) validatePasswordCredentials(conn ssh.ConnMetadata, pass
|
||||||
var sshPerm *ssh.Permissions
|
var sshPerm *ssh.Permissions
|
||||||
|
|
||||||
ipAddr := util.GetIPFromRemoteAddress(conn.RemoteAddr().String())
|
ipAddr := util.GetIPFromRemoteAddress(conn.RemoteAddr().String())
|
||||||
if user, err = dataprovider.CheckUserAndPass(conn.User(), string(pass), ipAddr, common.ProtocolSSH); err == nil {
|
if user, err = dataprovider.CheckUserAndPass(conn.User(), util.BytesToString(pass), ipAddr, common.ProtocolSSH); err == nil {
|
||||||
sshPerm, err = loginUser(&user, method, "", conn)
|
sshPerm, err = loginUser(&user, method, "", conn)
|
||||||
}
|
}
|
||||||
user.Username = conn.User()
|
user.Username = conn.User()
|
||||||
|
|
|
@ -367,7 +367,7 @@ func (e *I18nError) Args() string {
|
||||||
if len(e.args) > 0 {
|
if len(e.args) > 0 {
|
||||||
data, err := json.Marshal(e.args)
|
data, err := json.Marshal(e.args)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return string(data)
|
return BytesToString(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "{}"
|
return "{}"
|
||||||
|
|
|
@ -44,6 +44,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/lithammer/shortuuid/v3"
|
"github.com/lithammer/shortuuid/v3"
|
||||||
|
@ -288,6 +289,16 @@ func ParseBytes(s string) (int64, error) {
|
||||||
return 0, fmt.Errorf("unhandled size name: %v", extra)
|
return 0, fmt.Errorf("unhandled size name: %v", extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BytesToString converts []byte to string without allocations.
|
||||||
|
func BytesToString(b []byte) string {
|
||||||
|
// unsafe.SliceData relies on cap whereas we want to rely on len
|
||||||
|
if len(b) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
// https://github.com/golang/go/blob/4ed358b57efdad9ed710be7f4fc51495a7620ce2/src/strings/builder.go#L41
|
||||||
|
return unsafe.String(unsafe.SliceData(b), len(b))
|
||||||
|
}
|
||||||
|
|
||||||
// GetIPFromRemoteAddress returns the IP from the remote address.
|
// GetIPFromRemoteAddress returns the IP from the remote address.
|
||||||
// If the given remote address cannot be parsed it will be returned unchanged
|
// If the given remote address cannot be parsed it will be returned unchanged
|
||||||
func GetIPFromRemoteAddress(remoteAddress string) string {
|
func GetIPFromRemoteAddress(remoteAddress string) string {
|
||||||
|
@ -660,7 +671,7 @@ func EncodeTLSCertToPem(tlsCert *x509.Certificate) (string, error) {
|
||||||
Type: "CERTIFICATE",
|
Type: "CERTIFICATE",
|
||||||
Bytes: tlsCert.Raw,
|
Bytes: tlsCert.Raw,
|
||||||
}
|
}
|
||||||
return string(pem.EncodeToMemory(&publicKeyBlock)), nil
|
return BytesToString(pem.EncodeToMemory(&publicKeyBlock)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckTCP4Port quits the app if bind on the given IPv4 port fails.
|
// CheckTCP4Port quits the app if bind on the given IPv4 port fails.
|
||||||
|
@ -704,7 +715,7 @@ func GetSSHPublicKeyAsString(pubKey []byte) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return string(ssh.MarshalAuthorizedKey(k)), nil
|
return BytesToString(ssh.MarshalAuthorizedKey(k)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRealIP returns the ip address as result of parsing the specified
|
// GetRealIP returns the ip address as result of parsing the specified
|
||||||
|
@ -880,7 +891,7 @@ func JSONEscape(val string) string {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return string(b[1 : len(b)-1])
|
return BytesToString(b[1 : len(b)-1])
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadConfigFromFile reads a configuration parameter from the specified file
|
// ReadConfigFromFile reads a configuration parameter from the specified file
|
||||||
|
@ -901,5 +912,5 @@ func ReadConfigFromFile(name, configDir string) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(string(val)), nil
|
return strings.TrimSpace(BytesToString(val)), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -448,10 +448,10 @@ func (f *webDavFile) Patch(patches []webdav.Proppatch) ([]webdav.Propstat, error
|
||||||
for _, p := range patch.Props {
|
for _, p := range patch.Props {
|
||||||
if status == http.StatusForbidden && !hasError {
|
if status == http.StatusForbidden && !hasError {
|
||||||
if !patch.Remove && util.Contains(lastModifiedProps, p.XMLName.Local) {
|
if !patch.Remove && util.Contains(lastModifiedProps, p.XMLName.Local) {
|
||||||
parsed, err := parseTime(string(p.InnerXML))
|
parsed, err := parseTime(util.BytesToString(p.InnerXML))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.Connection.Log(logger.LevelWarn, "unsupported last modification time: %q, err: %v",
|
f.Connection.Log(logger.LevelWarn, "unsupported last modification time: %q, err: %v",
|
||||||
string(p.InnerXML), err)
|
util.BytesToString(p.InnerXML), err)
|
||||||
hasError = true
|
hasError = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue