You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
1.9 KiB
Go
95 lines
1.9 KiB
Go
8 months ago
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||
|
|
||
8 months ago
|
package libtailscale
|
||
8 months ago
|
|
||
|
import (
|
||
|
"encoding/base64"
|
||
|
|
||
|
"tailscale.com/ipn"
|
||
|
)
|
||
|
|
||
|
// stateStore is the Go interface for a persistent storage
|
||
|
// backend by androidx.security.crypto.EncryptedSharedPreferences (see
|
||
|
// App.java).
|
||
|
type stateStore struct {
|
||
|
// appCtx is the global Android app context.
|
||
8 months ago
|
appCtx AppContext
|
||
8 months ago
|
}
|
||
|
|
||
8 months ago
|
func newStateStore(appCtx AppContext) *stateStore {
|
||
|
return &stateStore{
|
||
8 months ago
|
appCtx: appCtx,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func prefKeyFor(id ipn.StateKey) string {
|
||
|
return "statestore-" + string(id)
|
||
|
}
|
||
|
|
||
|
func (s *stateStore) ReadString(key string, def string) (string, error) {
|
||
|
data, err := s.read(key)
|
||
|
if err != nil {
|
||
|
return def, err
|
||
|
}
|
||
|
if data == nil {
|
||
|
return def, nil
|
||
|
}
|
||
|
return string(data), nil
|
||
|
}
|
||
|
|
||
|
func (s *stateStore) WriteString(key string, val string) error {
|
||
|
return s.write(key, []byte(val))
|
||
|
}
|
||
|
|
||
|
func (s *stateStore) ReadBool(key string, def bool) (bool, error) {
|
||
|
data, err := s.read(key)
|
||
|
if err != nil {
|
||
|
return def, err
|
||
|
}
|
||
|
if data == nil {
|
||
|
return def, nil
|
||
|
}
|
||
|
return string(data) == "true", nil
|
||
|
}
|
||
|
|
||
|
func (s *stateStore) WriteBool(key string, val bool) error {
|
||
|
data := []byte("false")
|
||
|
if val {
|
||
|
data = []byte("true")
|
||
|
}
|
||
|
return s.write(key, data)
|
||
|
}
|
||
|
|
||
|
func (s *stateStore) ReadState(id ipn.StateKey) ([]byte, error) {
|
||
|
state, err := s.read(prefKeyFor(id))
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if state == nil {
|
||
|
return nil, ipn.ErrStateNotExist
|
||
|
}
|
||
|
return state, nil
|
||
|
}
|
||
|
|
||
|
func (s *stateStore) WriteState(id ipn.StateKey, bs []byte) error {
|
||
|
prefKey := prefKeyFor(id)
|
||
|
return s.write(prefKey, bs)
|
||
|
}
|
||
|
|
||
|
func (s *stateStore) read(key string) ([]byte, error) {
|
||
8 months ago
|
b64, err := s.appCtx.DecryptFromPref(key)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if b64 == "" {
|
||
|
return nil, nil
|
||
|
}
|
||
|
return base64.RawStdEncoding.DecodeString(b64)
|
||
8 months ago
|
}
|
||
|
|
||
|
func (s *stateStore) write(key string, value []byte) error {
|
||
|
bs64 := base64.RawStdEncoding.EncodeToString(value)
|
||
8 months ago
|
return s.appCtx.EncryptToPref(key, bs64)
|
||
8 months ago
|
}
|