mirror of https://github.com/cbeuw/Cloak
Allow DatabasePath to be empty if user info database is never used
This commit is contained in:
parent
298e6249e6
commit
0d3f8dd27f
14
README.md
14
README.md
|
|
@ -103,15 +103,13 @@ Example:
|
|||
|
||||
`PrivateKey` is the static curve25519 Diffie-Hellman private key encoded in base64.
|
||||
|
||||
`AdminUID` is the UID of the admin user in base64.
|
||||
|
||||
`BypassUID` is a list of UIDs that are authorised without any bandwidth or credit limit restrictions
|
||||
|
||||
`DatabasePath` is the path to `userinfo.db`. If `userinfo.db` doesn't exist in this directory, Cloak will create one
|
||||
automatically. **If Cloak is started as a Shadowsocks plugin and Shadowsocks is started with its working directory as
|
||||
/ (e.g. starting ss-server with systemctl), you need to set this field as an absolute path to a desired folder. If you
|
||||
leave it as default then Cloak will attempt to create userinfo.db under /, which it doesn't have the permission to do so
|
||||
and will raise an error. See Issue #13.**
|
||||
`AdminUID` is the UID of the admin user in base64. You can leave this empty if you only ever add users to `BypassUID`.
|
||||
|
||||
`DatabasePath` is the path to `userinfo.db`, which is used to store user usage information and restrictions. Cloak will
|
||||
create the file automatically if it doesn't exist. You can leave this empty if you only ever add users to `BypassUID`.
|
||||
This field also has no effect if `AdminUID` isn't a valid UID or is empty.
|
||||
|
||||
`KeepAlive` is the number of seconds to tell the OS to wait after no activity before sending TCP KeepAlive probes to the
|
||||
upstream proxy server. Zero or negative value disables it. Default is 0 (disabled).
|
||||
|
|
@ -184,6 +182,8 @@ Run `ck-server -uid` and add the UID into the `BypassUID` field in `ckserver.jso
|
|||
|
||||
##### Users subject to bandwidth and credit controls
|
||||
|
||||
0. First make sure you have `AdminUID` generated and set in `ckserver.json`, along with a path to `userinfo.db`
|
||||
in `DatabasePath` (Cloak will create this file for you if it didn't already exist).
|
||||
1. On your client, run `ck-client -s <IP of the server> -l <A local port> -a <AdminUID> -c <path-to-ckclient.json>` to
|
||||
enter admin mode
|
||||
2. Visit https://cbeuw.github.io/Cloak-panel (Note: this is a pure-js static site, there is no backend and all data
|
||||
|
|
|
|||
|
|
@ -143,9 +143,14 @@ func InitState(preParse RawConfig, worldState common.WorldState) (sta *State, er
|
|||
err = errors.New("command & control mode not implemented")
|
||||
return
|
||||
} else {
|
||||
manager, err := usermanager.MakeLocalManager(preParse.DatabasePath, worldState)
|
||||
if err != nil {
|
||||
return sta, err
|
||||
var manager usermanager.UserManager
|
||||
if len(preParse.AdminUID) == 0 || preParse.DatabasePath == "" {
|
||||
manager = &usermanager.Voidmanager{}
|
||||
} else {
|
||||
manager, err = usermanager.MakeLocalManager(preParse.DatabasePath, worldState)
|
||||
if err != nil {
|
||||
return sta, err
|
||||
}
|
||||
}
|
||||
sta.Panel = MakeUserPanel(manager)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ const (
|
|||
|
||||
var ErrUserNotFound = errors.New("UID does not correspond to a user")
|
||||
var ErrSessionsCapReached = errors.New("Sessions cap has reached")
|
||||
var ErrMangerIsVoid = errors.New("cannot perform operation with user manager as database path is not specified")
|
||||
|
||||
var ErrNoUpCredit = errors.New("No upload credit left")
|
||||
var ErrNoDownCredit = errors.New("No download credit left")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
package usermanager
|
||||
|
||||
type Voidmanager struct{}
|
||||
|
||||
func (v *Voidmanager) AuthenticateUser(bytes []byte) (int64, int64, error) {
|
||||
return 0, 0, ErrMangerIsVoid
|
||||
}
|
||||
|
||||
func (v *Voidmanager) AuthoriseNewSession(bytes []byte, info AuthorisationInfo) error {
|
||||
return ErrMangerIsVoid
|
||||
}
|
||||
|
||||
func (v *Voidmanager) UploadStatus(updates []StatusUpdate) ([]StatusResponse, error) {
|
||||
return nil, ErrMangerIsVoid
|
||||
}
|
||||
|
||||
func (v *Voidmanager) ListAllUsers() ([]UserInfo, error) {
|
||||
return nil, ErrMangerIsVoid
|
||||
}
|
||||
|
||||
func (v *Voidmanager) GetUserInfo(UID []byte) (UserInfo, error) {
|
||||
return UserInfo{}, ErrMangerIsVoid
|
||||
}
|
||||
|
||||
func (v *Voidmanager) WriteUserInfo(info UserInfo) error {
|
||||
return ErrMangerIsVoid
|
||||
}
|
||||
|
||||
func (v *Voidmanager) DeleteUser(UID []byte) error {
|
||||
return ErrMangerIsVoid
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package usermanager
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var v = &Voidmanager{}
|
||||
|
||||
func Test_Voidmanager_AuthenticateUser(t *testing.T) {
|
||||
_, _, err := v.AuthenticateUser([]byte{})
|
||||
assert.Equal(t, ErrMangerIsVoid, err)
|
||||
}
|
||||
|
||||
func Test_Voidmanager_AuthoriseNewSession(t *testing.T) {
|
||||
err := v.AuthoriseNewSession([]byte{}, AuthorisationInfo{})
|
||||
assert.Equal(t, ErrMangerIsVoid, err)
|
||||
}
|
||||
|
||||
func Test_Voidmanager_DeleteUser(t *testing.T) {
|
||||
err := v.DeleteUser([]byte{})
|
||||
assert.Equal(t, ErrMangerIsVoid, err)
|
||||
}
|
||||
|
||||
func Test_Voidmanager_GetUserInfo(t *testing.T) {
|
||||
_, err := v.GetUserInfo([]byte{})
|
||||
assert.Equal(t, ErrMangerIsVoid, err)
|
||||
}
|
||||
|
||||
func Test_Voidmanager_ListAllUsers(t *testing.T) {
|
||||
_, err := v.ListAllUsers()
|
||||
assert.Equal(t, ErrMangerIsVoid, err)
|
||||
}
|
||||
|
||||
func Test_Voidmanager_UploadStatus(t *testing.T) {
|
||||
_, err := v.UploadStatus([]StatusUpdate{})
|
||||
assert.Equal(t, ErrMangerIsVoid, err)
|
||||
}
|
||||
|
||||
func Test_Voidmanager_WriteUserInfo(t *testing.T) {
|
||||
err := v.WriteUserInfo(UserInfo{})
|
||||
assert.Equal(t, ErrMangerIsVoid, err)
|
||||
}
|
||||
|
|
@ -185,6 +185,9 @@ func (panel *userPanel) commitUpdate() error {
|
|||
panel.usageUpdateQueue = make(map[[16]byte]*usagePair)
|
||||
panel.usageUpdateQueueM.Unlock()
|
||||
|
||||
if len(statuses) == 0 {
|
||||
return nil
|
||||
}
|
||||
responses, err := panel.Manager.UploadStatus(statuses)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -12,10 +12,8 @@ import (
|
|||
"github.com/cbeuw/connutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -24,8 +22,6 @@ import (
|
|||
)
|
||||
|
||||
const numConns = 200 // -race option limits the number of goroutines to 8192
|
||||
const delayBeforeTestingConnClose = 500 * time.Millisecond
|
||||
const connCloseRetries = 3
|
||||
|
||||
func serveTCPEcho(l net.Listener) {
|
||||
for {
|
||||
|
|
@ -137,17 +133,15 @@ func generateClientConfigs(rawConfig client.RawConfig, state common.WorldState)
|
|||
return lcl, rmt, auth
|
||||
}
|
||||
|
||||
func basicServerState(ws common.WorldState, db *os.File) *server.State {
|
||||
func basicServerState(ws common.WorldState) *server.State {
|
||||
var serverConfig = server.RawConfig{
|
||||
ProxyBook: map[string][]string{"shadowsocks": {"tcp", "fake.com:9999"}, "openvpn": {"udp", "fake.com:9999"}},
|
||||
BindAddr: []string{"fake.com:9999"},
|
||||
BypassUID: [][]byte{bypassUID[:]},
|
||||
RedirAddr: "fake.com:9999",
|
||||
PrivateKey: privateKey,
|
||||
AdminUID: nil,
|
||||
DatabasePath: db.Name(),
|
||||
KeepAlive: 15,
|
||||
CncMode: false,
|
||||
ProxyBook: map[string][]string{"shadowsocks": {"tcp", "fake.com:9999"}, "openvpn": {"udp", "fake.com:9999"}},
|
||||
BindAddr: []string{"fake.com:9999"},
|
||||
BypassUID: [][]byte{bypassUID[:]},
|
||||
RedirAddr: "fake.com:9999",
|
||||
PrivateKey: privateKey,
|
||||
KeepAlive: 15,
|
||||
CncMode: false,
|
||||
}
|
||||
state, err := server.InitState(serverConfig, ws)
|
||||
if err != nil {
|
||||
|
|
@ -258,13 +252,11 @@ func runEchoTest(t *testing.T, conns []net.Conn, maxMsgLen int) {
|
|||
}
|
||||
|
||||
func TestUDP(t *testing.T) {
|
||||
var tmpDB, _ = ioutil.TempFile("", "ck_user_info")
|
||||
defer os.Remove(tmpDB.Name())
|
||||
log.SetLevel(log.ErrorLevel)
|
||||
|
||||
worldState := common.WorldOfTime(time.Unix(10, 0))
|
||||
lcc, rcc, ai := generateClientConfigs(basicUDPConfig, worldState)
|
||||
sta := basicServerState(worldState, tmpDB)
|
||||
sta := basicServerState(worldState)
|
||||
|
||||
proxyToCkClientD, proxyFromCkServerL, _, _, err := establishSession(lcc, rcc, ai, sta)
|
||||
if err != nil {
|
||||
|
|
@ -319,9 +311,7 @@ func TestTCPSingleplex(t *testing.T) {
|
|||
log.SetLevel(log.ErrorLevel)
|
||||
worldState := common.WorldOfTime(time.Unix(10, 0))
|
||||
lcc, rcc, ai := generateClientConfigs(singleplexTCPConfig, worldState)
|
||||
var tmpDB, _ = ioutil.TempFile("", "ck_user_info")
|
||||
defer os.Remove(tmpDB.Name())
|
||||
sta := basicServerState(worldState, tmpDB)
|
||||
sta := basicServerState(worldState)
|
||||
proxyToCkClientD, proxyFromCkServerL, _, _, err := establishSession(lcc, rcc, ai, sta)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -381,9 +371,7 @@ func TestTCPMultiplex(t *testing.T) {
|
|||
worldState := common.WorldOfTime(time.Unix(10, 0))
|
||||
|
||||
lcc, rcc, ai := generateClientConfigs(basicTCPConfig, worldState)
|
||||
var tmpDB, _ = ioutil.TempFile("", "ck_user_info")
|
||||
defer os.Remove(tmpDB.Name())
|
||||
sta := basicServerState(worldState, tmpDB)
|
||||
sta := basicServerState(worldState)
|
||||
|
||||
proxyToCkClientD, proxyFromCkServerL, netToCkServerD, redirFromCkServerL, err := establishSession(lcc, rcc, ai, sta)
|
||||
if err != nil {
|
||||
|
|
@ -456,11 +444,8 @@ func TestClosingStreamsFromProxy(t *testing.T) {
|
|||
clientConfig := clientConfig
|
||||
clientConfigName := clientConfigName
|
||||
t.Run(clientConfigName, func(t *testing.T) {
|
||||
var tmpDB, _ = ioutil.TempFile("", "ck_user_info")
|
||||
defer os.Remove(tmpDB.Name())
|
||||
|
||||
lcc, rcc, ai := generateClientConfigs(clientConfig, worldState)
|
||||
sta := basicServerState(worldState, tmpDB)
|
||||
sta := basicServerState(worldState)
|
||||
proxyToCkClientD, proxyFromCkServerL, _, _, err := establishSession(lcc, rcc, ai, sta)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -519,12 +504,10 @@ func TestClosingStreamsFromProxy(t *testing.T) {
|
|||
}
|
||||
|
||||
func BenchmarkThroughput(b *testing.B) {
|
||||
var tmpDB, _ = ioutil.TempFile("", "ck_user_info")
|
||||
defer os.Remove(tmpDB.Name())
|
||||
log.SetLevel(log.ErrorLevel)
|
||||
worldState := common.WorldOfTime(time.Unix(10, 0))
|
||||
lcc, rcc, ai := generateClientConfigs(basicTCPConfig, worldState)
|
||||
sta := basicServerState(worldState, tmpDB)
|
||||
sta := basicServerState(worldState)
|
||||
const bufSize = 16 * 1024
|
||||
|
||||
encryptionMethods := map[string]byte{
|
||||
|
|
|
|||
Loading…
Reference in New Issue