mirror of
https://github.com/p1neappleXpress/OpenFlux.git
synced 2026-10-02 05:04:39 +08:00
mobile: derive the encryption context as the maintainer's core does
The core now picks the KDF context with pickSessionContext: --url, else the URL of the highest-priority transport, leaving out cupsonline (its room list only exists once the exit is up) and the "http://#" placeholder, else "http://#". The bridge still let cupsonline in, and a classic channel without a document (oneme, direct) fell back to the transport's name, so the phone and a CLI peer derived different keys.
This commit is contained in:
+4
-4
@@ -152,11 +152,11 @@ func classicTransport(transportType, documentURL, encryptionSecret, codec, maxTo
|
||||
appendLog("[ANDROID] Шифрование транспорта отключено (ключ не задан)")
|
||||
return inner, nil
|
||||
}
|
||||
// Same fallback as the CLI: the KDF context is the document URL, or
|
||||
// the transport name when there isn't one (oneme). Both peers must
|
||||
// derive the same context or the encrypted channel just won't work.
|
||||
// Same context as the core: the document URL, or "http://#" when there
|
||||
// isn't one (oneme, direct). Both peers must derive the same context or
|
||||
// the encrypted channel just won't work.
|
||||
encrypted, err := transport.NewEncryptedTransport(inner, encryptionSecret,
|
||||
classicContext(transportType, documentURL), exit)
|
||||
classicContext(documentURL), exit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+20
-10
@@ -3,7 +3,6 @@ package mobile
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"openflux/transport"
|
||||
"openflux/transport/manager"
|
||||
@@ -121,16 +120,27 @@ func buildSessionWith(specsJSON, secret string, exit bool) (transport.Transport,
|
||||
return demux, sess, nil
|
||||
}
|
||||
|
||||
// sessionContext is the encryption context. The exit derives it from its
|
||||
// --url, so it is the document URL of the highest-priority transport that
|
||||
// has one; "http://#" matches the CLI's --url default when none has.
|
||||
// sessionContext is the encryption context, derived as the core's
|
||||
// pickSessionContext does for an exit without --url: the document URL of the
|
||||
// highest-priority transport that has one, cupsonline aside (its room list
|
||||
// only exists once the exit is up), else "http://#". Equal priorities keep
|
||||
// the first transport, as the core does.
|
||||
func sessionContext(specs []sessionSpec) string {
|
||||
sorted := append([]sessionSpec(nil), specs...)
|
||||
sort.SliceStable(sorted, func(i, j int) bool { return sorted[i].Priority > sorted[j].Priority })
|
||||
for _, s := range sorted {
|
||||
if s.URL != "" {
|
||||
return s.URL
|
||||
best := -1
|
||||
for i, s := range specs {
|
||||
if s.Type == "cupsonline" || s.URL == "" || s.URL == placeholderURL {
|
||||
continue
|
||||
}
|
||||
if best < 0 || s.Priority > specs[best].Priority {
|
||||
best = i
|
||||
}
|
||||
}
|
||||
return "http://#"
|
||||
if best >= 0 {
|
||||
return specs[best].URL
|
||||
}
|
||||
return placeholderURL
|
||||
}
|
||||
|
||||
// placeholderURL is the core's --url default, the context of a channel that
|
||||
// has no document URL.
|
||||
const placeholderURL = "http://#"
|
||||
|
||||
@@ -77,3 +77,27 @@ func TestSessionContextPrefersHighestPriorityURL(t *testing.T) {
|
||||
t.Fatalf("context without URLs = %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
// The exit creates the cupsonline room list only when it starts, so the
|
||||
// core leaves it out of the context; the phone must too.
|
||||
func TestSessionContextSkipsCupsonline(t *testing.T) {
|
||||
specs := []sessionSpec{
|
||||
{Name: "cupsonline", Type: "cupsonline", URL: "room-list", Priority: 100},
|
||||
{Name: "yandex", Type: "yandex", URL: "https://docs.example/d", Priority: 50},
|
||||
}
|
||||
if got := sessionContext(specs); got != "https://docs.example/d" {
|
||||
t.Fatalf("context = %q", got)
|
||||
}
|
||||
if got := sessionContext(specs[:1]); got != "http://#" {
|
||||
t.Fatalf("context of a cupsonline-only session = %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClassicContextFallsBackToPlaceholder(t *testing.T) {
|
||||
if got := classicContext(""); got != "http://#" {
|
||||
t.Fatalf("context without a document = %q", got)
|
||||
}
|
||||
if got := classicContext("https://docs.example/d"); got != "https://docs.example/d" {
|
||||
t.Fatalf("context = %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-10
@@ -56,7 +56,7 @@ func ExitShareLink(host, name string) (string, error) {
|
||||
func exitShareClassic(transportType, documentURL, secret, codec string) *share.Config {
|
||||
c := &share.Config{
|
||||
Secret: secret,
|
||||
Context: classicContext(transportType, documentURL),
|
||||
Context: classicContext(documentURL),
|
||||
Transports: []share.Transport{{Type: transportType, URL: documentURL}},
|
||||
}
|
||||
if codec == "legacy" {
|
||||
@@ -96,14 +96,12 @@ func exitShareSession(specsJSON, secret string) *share.Config {
|
||||
return c
|
||||
}
|
||||
|
||||
// classicContext is the classic mode's encryption context, as the CLI and
|
||||
// classicTransport derive it.
|
||||
func classicContext(transportType, documentURL string) string {
|
||||
if documentURL != "" {
|
||||
return documentURL
|
||||
// classicContext is the classic mode's encryption context, as the core
|
||||
// derives it for --transport with --url: the document URL, or "http://#"
|
||||
// when there is none (oneme, direct).
|
||||
func classicContext(documentURL string) string {
|
||||
if documentURL == "" {
|
||||
return placeholderURL
|
||||
}
|
||||
if transportType == "" {
|
||||
return "yandex"
|
||||
}
|
||||
return transportType
|
||||
return documentURL
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user