Skip to content

Commit 7c6078c

Browse files
committed
rpn: did token
1 parent 9030761 commit 7c6078c

4 files changed

Lines changed: 68 additions & 20 deletions

File tree

intra/backend/ipn_proxies.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ const ( // see ipn/proxies.go
8585

8686
type Rpn interface {
8787
// EntitlementFrom returns the RpnEntitlement represented by entitlementOrStateJson.
88-
EntitlementFrom(entitlementOrStateJson []byte, rpnProviderID string) (RpnEntitlement, error)
88+
// `did` is the device identifier to use for this entitlement, if applicable; and `rpnProviderID` is the RPN provider for this entitlement, if applicable.
89+
// `rpnProviderID` is the RPN provider to use with this entitlement (ex: RpnWin, RpnSE, etc).
90+
EntitlementFrom(entitlementOrStateJson []byte, rpnProviderID, did string) (RpnEntitlement, error)
8991
// RegisterSE registers a new SurfEasy user.
9092
RegisterSE() error
9193
// RegisterWin is alias for RegisterWin.
92-
RegisterWin(entitlementOrStateJson []byte) (json []byte, err error)
94+
RegisterWin(entitlementOrStateJson []byte, did string) (json []byte, err error)
9395
// UnregisterWin unregisters a Windscribe installation.
9496
UnregisterWin() bool
9597
// UnregisterSE unregisters a SurfEasy user.
@@ -171,8 +173,10 @@ type RpnAcc interface {
171173
type RpnEntitlement interface {
172174
// ProviderID is RPN provider for this entitlement.
173175
ProviderID() string
174-
// Cid is the Client identifier
176+
// Cid is the Client identifier.
175177
CID() string
178+
// DID is the Device identifier, if any.
179+
DID() string
176180
// Token is the entitlement token, if any.
177181
Token() string
178182
// Expiry is ISO 8601 string of the expiry time of this entitlement, if any.
@@ -183,6 +187,8 @@ type RpnEntitlement interface {
183187
AllowRestore() bool
184188
// Test is set if this entitlement is valid only in the test domain.
185189
Test() bool
190+
// Json returns entitlement (but not the state) as json.
191+
Json() ([]byte, error)
186192
}
187193

188194
type Proxies interface {

intra/dns53/dot_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ type fakeObs struct {
110110

111111
func (*fakeObs) OnProxyAdded(string) {}
112112
func (*fakeObs) OnProxyRemoved(string) {}
113-
func (*fakeObs) OnProxiesStopped() {}
113+
func (*fakeObs) OnProxiesStopped() {}
114114

115115
type fakeBdg struct {
116116
protect.Controller
@@ -125,10 +125,10 @@ var (
125125

126126
func (*fakeBdg) OnQuery(_, _, _ string, _ int) *x.DNSOpts { return autoNsOpts }
127127
func (*fakeBdg) OnUpstreamAnswer(_ *x.DNSSummary, _ string) *x.DNSOpts { return nil }
128-
func (*fakeBdg) OnResponse(*x.DNSSummary) {}
128+
func (*fakeBdg) OnResponse(*x.DNSSummary) {}
129129
func (*fakeBdg) OnDNSAdded(string) {}
130130
func (*fakeBdg) OnDNSRemoved(string) {}
131-
func (*fakeBdg) OnDNSStopped() {}
131+
func (*fakeBdg) OnDNSStopped() {}
132132

133133
func (*fakeBdg) Route(a, b, c, d, e string) *x.Tab { return baseTab }
134134
func (*fakeBdg) OnComplete(*x.ServerSummary) {}
@@ -440,8 +440,9 @@ func TestWinReaches(t *testing.T) {
440440
}
441441
ko(t, err)
442442

443+
const did = "deadbeefdeadbeefdeadbeefdeadbeef" // some device id
443444
ilog.D("ws: read ent (sess? %t): %d", readWinJson, len(entjson))
444-
if wreg, err := pxr.RegisterWin(entjson); err != nil {
445+
if wreg, err := pxr.RegisterWin(entjson, did); err != nil {
445446
t.Fatal(err)
446447
} else {
447448
entjson = wreg

intra/ipn/proxies.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ var (
129129
errHopGlobalProxy = errors.New("proxy: hop must be global proxy")
130130
errHopNotConnected = errors.New("proxy: set but not connected over hop")
131131
errNilWinCfg = errors.New("proxy: win cfg nil")
132+
errNilWinDevice = errors.New("proxy: missing win device id")
132133
errNilSEProxy = errors.New("proxy: se proxy nil")
133134
errNotRpnProxy = errors.New("proxy: rpn not found")
134135
errNotRpnID = errors.New("proxy: not rpn id")
@@ -1236,23 +1237,30 @@ func (px *proxifier) Reaches(urlOrHostPortOrIPPortCsv string) bool {
12361237
return false
12371238
}
12381239

1239-
func (px *proxifier) EntitlementFrom(entitlementOrStateJson []byte, id string) (x.RpnEntitlement, error) {
1240+
func (px *proxifier) EntitlementFrom(entitlementOrStateJson []byte, did, id string) (ent x.RpnEntitlement, err error) {
12401241
switch id {
12411242
case RpnWin:
1242-
return px.extc.MakeWsEntitlement(entitlementOrStateJson)
1243+
ent, err = px.extc.MakeWsEntitlement(entitlementOrStateJson, did)
1244+
default:
1245+
err = errNotRpnAcc
12431246
}
1244-
return nil, errNotRpnAcc
1247+
return
12451248
}
12461249

12471250
// RegisterWin implements x.Rpn.
1248-
func (px *proxifier) RegisterWin(entitlementOrState []byte) (stateJson []byte, err error) {
1251+
func (px *proxifier) RegisterWin(entitlementOrState []byte, did string) (stateJson []byte, err error) {
12491252
defer func() {
12501253
px.lastWinErr.Store(err) // may be nil
12511254
}()
1255+
1256+
if len(did) <= 0 {
1257+
return nil, errNilWinDevice
1258+
}
1259+
12521260
existingStateJson := entitlementOrState
12531261
restore := len(existingStateJson) > 0
12541262

1255-
win, err := px.registerWin(existingStateJson)
1263+
win, err := px.registerWin(existingStateJson, did)
12561264
if err != nil || core.IsNil(win) {
12571265
log.E("proxy: ws: make failed: %v", err)
12581266
return nil, core.JoinErr(err, errNilWinCfg)
@@ -1276,8 +1284,8 @@ func (px *proxifier) RegisterWin(entitlementOrState []byte) (stateJson []byte, e
12761284
return state, nil
12771285
}
12781286

1279-
func (px *proxifier) registerWin(entitlementOrStateJson []byte) (RpnAcc, error) {
1280-
return px.extc.MakeWsWgFrom(entitlementOrStateJson)
1287+
func (px *proxifier) registerWin(entitlementOrStateJson []byte, did string) (RpnAcc, error) {
1288+
return px.extc.MakeWsWgFrom(entitlementOrStateJson, did)
12811289
}
12821290

12831291
// RegisterSE implements x.Rpn.

intra/ipn/rpn/yegor.go

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ var (
128128
errWsNoEntitlement = errors.New("ws: missing entitlement")
129129
errWsNoToken = errors.New("ws: missing token")
130130
errWsNoCid = errors.New("ws: missing cid")
131+
errWsNoDid = errors.New("ws: missing device id")
131132
errWsNoResponse = errors.New("ws: no response")
132133
errWsNoLocHash = errors.New("ws: no loc hash")
133134
errWsNoServerList = errors.New("ws: no server list")
@@ -702,6 +703,7 @@ type WsWgConfig struct {
702703
type WsEntitlement struct {
703704
Kind string `json:"kind"` // e.g. "ws#v1"
704705
Cid string `json:"cid"` // Client ID
706+
Did string `json:"did,omitempty"` // Device ID, if any
705707
Pid string `json:"pid,omitempty"` // Share ID
706708
SessionToken string `json:"sessiontoken"` // Encrypted session token
707709
// Expiry date of the entitlement; go.dev/play/p/d2gshytEF61
@@ -718,6 +720,10 @@ func (e *WsEntitlement) ProviderID() string {
718720
return x.RpnWin
719721
}
720722

723+
func (e *WsEntitlement) DID() string {
724+
return e.Did
725+
}
726+
721727
func (e *WsEntitlement) CID() string {
722728
return e.Cid
723729
}
@@ -742,6 +748,19 @@ func (e *WsEntitlement) Test() bool {
742748
return e.TestDomain
743749
}
744750

751+
func (e *WsEntitlement) Json() ([]byte, error) {
752+
if e == nil {
753+
return nil, errWsNoEntitlement
754+
}
755+
var w core.ByteWriter
756+
enc := json.NewEncoder(&w)
757+
if err := enc.Encode(e); err != nil {
758+
return nil, fmt.Errorf("ws: entitlement encode err: %w", err)
759+
}
760+
// Bytes not recycled as these are crossing into cgo
761+
return w.Bytes(), nil
762+
}
763+
745764
func (a *WsWgConfig) Json() ([]byte, error) {
746765
if a == nil {
747766
return nil, errWsNoConfig
@@ -751,7 +770,7 @@ func (a *WsWgConfig) Json() ([]byte, error) {
751770
if err := a.writeJson(&w); err != nil {
752771
return nil, err
753772
}
754-
// Bytes not recycled
773+
// Bytes not recycled as these are crossing into cgo
755774
return w.Bytes(), nil
756775
}
757776

@@ -1539,17 +1558,21 @@ func newWsGw(c *WsWgConfig, h *http.Client) (*WsClient, error) {
15391558
return a, nil
15401559
}
15411560

1542-
func (w *BaseClient) MakeWsWg(entitlement []byte) (*WsClient, error) {
1561+
func (w *BaseClient) MakeWsWg(entitlement []byte, did string) (*WsClient, error) {
15431562
if len(entitlement) <= 0 {
15441563
return nil, errWsNoEntitlement
15451564
}
1565+
if len(did) <= 0 {
1566+
return nil, errWsNoDid
1567+
}
15461568

15471569
var ent WsEntitlement
15481570
err := json.Unmarshal(entitlement, &ent)
15491571
if err != nil {
15501572
return nil, err
15511573
}
15521574

1575+
(&ent).Did = did
15531576
return makeWsWg(&w.h2, &ent)
15541577
}
15551578

@@ -1585,28 +1608,37 @@ func makeWsWg(h *http.Client, ent *WsEntitlement) (*WsClient, error) {
15851608
return newWsGw(cfg, h)
15861609
}
15871610

1588-
func (w *BaseClient) MakeWsEntitlement(entitlementOrStateJson []byte) (x.RpnEntitlement, error) {
1611+
func (w *BaseClient) MakeWsEntitlement(entitlementOrStateJson []byte, did string) (x.RpnEntitlement, error) {
15891612
if len(entitlementOrStateJson) <= 0 {
15901613
return nil, errWsNoEntitlement
15911614
}
1615+
if len(did) <= 0 {
1616+
return nil, errWsNoDid
1617+
}
15921618

15931619
var ent WsEntitlement
15941620
err1 := json.Unmarshal(entitlementOrStateJson, &ent)
15951621
if err1 == nil {
1622+
(&ent).Did = did
15961623
return &ent, nil
15971624
}
15981625
var existingConf WsWgConfig
15991626
err2 := json.Unmarshal(entitlementOrStateJson, &existingConf)
16001627
if err2 == nil && existingConf.Entitlement != nil && len(existingConf.Entitlement.SessionToken) > 0 {
1601-
return existingConf.Entitlement, nil
1628+
ent := existingConf.Entitlement
1629+
(ent).Did = did
1630+
return ent, nil
16021631
}
16031632
return nil, core.JoinErr(err1, err2)
16041633
}
16051634

1606-
func (w *BaseClient) MakeWsWgFrom(entitlementOrWsConfigJson []byte) (*WsClient, error) {
1635+
func (w *BaseClient) MakeWsWgFrom(entitlementOrWsConfigJson []byte, did string) (*WsClient, error) {
16071636
if len(entitlementOrWsConfigJson) <= 0 {
16081637
return nil, errWsNoJsonConfig
16091638
}
1639+
if len(did) <= 0 {
1640+
return nil, errWsNoDid
1641+
}
16101642

16111643
var existingConf WsWgConfig
16121644
err := json.Unmarshal(entitlementOrWsConfigJson, &existingConf)
@@ -1618,8 +1650,9 @@ func (w *BaseClient) MakeWsWgFrom(entitlementOrWsConfigJson []byte) (*WsClient,
16181650
// may be this is an entitlement and not conf?
16191651
log.W("ws: make: unmarshal config (sz %d / hasEnt %t / hasTok %t) err? %v; retry as entitlement",
16201652
sz, hasEnt, hasTok, err)
1621-
return w.MakeWsWg(entitlementOrWsConfigJson)
1653+
return w.MakeWsWg(entitlementOrWsConfigJson, did)
16221654
}
1655+
(existingConf.Entitlement).Did = did
16231656
return w.makeWsWgFrom(&existingConf)
16241657
}
16251658

0 commit comments

Comments
 (0)