mirror of
https://github.com/rclone/rclone.git
synced 2025-08-16 16:41:34 +02:00
serve sftp: Add support for public key with auth proxy - fixes #3572
This commit is contained in:
committed by
Nick Craig-Wood
parent
63128834da
commit
f2a789ea98
@ -1,6 +1,10 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
"log"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@ -10,6 +14,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
@ -68,13 +73,13 @@ func TestRun(t *testing.T) {
|
||||
const testUser = "testUser"
|
||||
const testPass = "testPass"
|
||||
|
||||
t.Run("call", func(t *testing.T) {
|
||||
t.Run("call w/Password", func(t *testing.T) {
|
||||
// check cache empty
|
||||
assert.Equal(t, 0, p.vfsCache.Entries())
|
||||
defer p.vfsCache.Clear()
|
||||
|
||||
passwordBytes := []byte(testPass)
|
||||
value, err := p.call(testUser, testPass, passwordBytes)
|
||||
value, err := p.call(testUser, testPass, false)
|
||||
require.NoError(t, err)
|
||||
entry, ok := value.(cacheEntry)
|
||||
require.True(t, ok)
|
||||
@ -95,12 +100,12 @@ func TestRun(t *testing.T) {
|
||||
assert.Equal(t, value, cacheValue)
|
||||
})
|
||||
|
||||
t.Run("Call", func(t *testing.T) {
|
||||
t.Run("Call w/Password", func(t *testing.T) {
|
||||
// check cache empty
|
||||
assert.Equal(t, 0, p.vfsCache.Entries())
|
||||
defer p.vfsCache.Clear()
|
||||
|
||||
vfs, vfsKey, err := p.Call(testUser, testPass)
|
||||
vfs, vfsKey, err := p.Call(testUser, testPass, false)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, vfs)
|
||||
assert.Equal(t, "proxy-"+testUser, vfs.Fs().Name())
|
||||
@ -121,7 +126,7 @@ func TestRun(t *testing.T) {
|
||||
})
|
||||
|
||||
// now try again from the cache
|
||||
vfs, vfsKey, err = p.Call(testUser, testPass)
|
||||
vfs, vfsKey, err = p.Call(testUser, testPass, false)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, vfs)
|
||||
assert.Equal(t, "proxy-"+testUser, vfs.Fs().Name())
|
||||
@ -131,7 +136,7 @@ func TestRun(t *testing.T) {
|
||||
assert.Equal(t, 1, p.vfsCache.Entries())
|
||||
|
||||
// now try again from the cache but with wrong password
|
||||
vfs, vfsKey, err = p.Call(testUser, testPass+"wrong")
|
||||
vfs, vfsKey, err = p.Call(testUser, testPass+"wrong", false)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "incorrect password")
|
||||
require.Nil(t, vfs)
|
||||
@ -142,4 +147,89 @@ func TestRun(t *testing.T) {
|
||||
|
||||
})
|
||||
|
||||
privateKey, privateKeyErr := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if privateKeyErr != nil {
|
||||
log.Fatal("error generating test private key " + privateKeyErr.Error())
|
||||
}
|
||||
publicKey, publicKeyError := ssh.NewPublicKey(&privateKey.PublicKey)
|
||||
if privateKeyErr != nil {
|
||||
log.Fatal("error generating test public key " + publicKeyError.Error())
|
||||
}
|
||||
|
||||
publicKeyString := base64.StdEncoding.EncodeToString(publicKey.Marshal())
|
||||
|
||||
t.Run("Call w/PublicKey", func(t *testing.T) {
|
||||
// check cache empty
|
||||
assert.Equal(t, 0, p.vfsCache.Entries())
|
||||
defer p.vfsCache.Clear()
|
||||
|
||||
value, err := p.call(testUser, publicKeyString, true)
|
||||
require.NoError(t, err)
|
||||
entry, ok := value.(cacheEntry)
|
||||
require.True(t, ok)
|
||||
|
||||
// check publicKey is correct in entry
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, entry.vfs)
|
||||
f := entry.vfs.Fs()
|
||||
require.NotNil(t, f)
|
||||
assert.Equal(t, "proxy-"+testUser, f.Name())
|
||||
assert.True(t, strings.HasPrefix(f.String(), "Local file system"))
|
||||
|
||||
// check it is in the cache
|
||||
assert.Equal(t, 1, p.vfsCache.Entries())
|
||||
cacheValue, ok := p.vfsCache.GetMaybe(testUser)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, value, cacheValue)
|
||||
})
|
||||
|
||||
t.Run("call w/PublicKey", func(t *testing.T) {
|
||||
// check cache empty
|
||||
assert.Equal(t, 0, p.vfsCache.Entries())
|
||||
defer p.vfsCache.Clear()
|
||||
|
||||
vfs, vfsKey, err := p.Call(
|
||||
testUser,
|
||||
publicKeyString,
|
||||
true,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, vfs)
|
||||
assert.Equal(t, "proxy-"+testUser, vfs.Fs().Name())
|
||||
assert.Equal(t, testUser, vfsKey)
|
||||
|
||||
// check it is in the cache
|
||||
assert.Equal(t, 1, p.vfsCache.Entries())
|
||||
cacheValue, ok := p.vfsCache.GetMaybe(testUser)
|
||||
assert.True(t, ok)
|
||||
cacheEntry, ok := cacheValue.(cacheEntry)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, vfs, cacheEntry.vfs)
|
||||
|
||||
// Test Get works while we have something in the cache
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
assert.Equal(t, vfs, p.Get(testUser))
|
||||
assert.Nil(t, p.Get("unknown"))
|
||||
})
|
||||
|
||||
// now try again from the cache
|
||||
vfs, vfsKey, err = p.Call(testUser, publicKeyString, true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, vfs)
|
||||
assert.Equal(t, "proxy-"+testUser, vfs.Fs().Name())
|
||||
assert.Equal(t, testUser, vfsKey)
|
||||
|
||||
// check cache is at the same level
|
||||
assert.Equal(t, 1, p.vfsCache.Entries())
|
||||
|
||||
// now try again from the cache but with wrong public key
|
||||
vfs, vfsKey, err = p.Call(testUser, publicKeyString+"wrong", true)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "incorrect public key")
|
||||
require.Nil(t, vfs)
|
||||
require.Equal(t, "", vfsKey)
|
||||
|
||||
// check cache is at the same level
|
||||
assert.Equal(t, 1, p.vfsCache.Entries())
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user