android: add INIT_WITH_AUTHKEY intent

e.g.
adb shell am broadcast  -n com.tailscale.ipn/.IPNReceiver -a com.tailscale.ipn.INIT_WITH_AUTHKEY --es authkey "my-super-secret-authkey"

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
bradfitz/authkey_intent
Brad Fitzpatrick 1 year ago
parent 6348bb254a
commit 33d7ad86a6
No known key found for this signature in database

@ -60,6 +60,7 @@
<intent-filter>
<action android:name="com.tailscale.ipn.CONNECT_VPN" />
<action android:name="com.tailscale.ipn.DISCONNECT_VPN" />
<action android:name="com.tailscale.ipn.INIT_WITH_AUTHKEY" />
</intent-filter>
</receiver>
<service android:name=".IPNService"

@ -9,6 +9,7 @@ import android.content.Context;
import android.content.Intent;
import androidx.work.WorkManager;
import androidx.work.OneTimeWorkRequest;
import android.util.Log;
public class IPNReceiver extends BroadcastReceiver {
@ -21,6 +22,9 @@ public class IPNReceiver extends BroadcastReceiver {
workManager.enqueue(new OneTimeWorkRequest.Builder(StartVPNWorker.class).build());
} else if (intent.getAction() == "com.tailscale.ipn.DISCONNECT_VPN") {
workManager.enqueue(new OneTimeWorkRequest.Builder(StopVPNWorker.class).build());
} else if (intent.getAction() == "com.tailscale.ipn.INIT_WITH_AUTHKEY") {
String key = intent.getStringExtra("authkey");
IPNService.setAuthKeyForNextConnect(key);
}
}
}

@ -119,6 +119,8 @@ public class IPNService extends VpnService {
startForeground(App.STATUS_NOTIFICATION_ID, builder.build());
}
public static native void setAuthKeyForNextConnect(String authKey);
private native void connect();
private native void disconnect();

@ -33,6 +33,9 @@ var (
// onConnectivityChange is notified every time the network
// conditions change.
onConnectivityChange = make(chan bool, 1)
// onSetAuthKeyForNextConnect gets an authkey for use in the next connect
// when IPNReceiver receives one.
onSetAuthKeyForNextConnect = make(chan string, 1)
// onGoogleToken receives google ID tokens.
onGoogleToken = make(chan string)
@ -200,3 +203,13 @@ func Java_com_tailscale_ipn_App_onShareIntent(env *C.JNIEnv, cls C.jclass, nfile
}
onFileShare <- files
}
//export Java_com_tailscale_ipn_IPNService_setAuthKeyForNextConnect
func Java_com_tailscale_ipn_IPNService_setAuthKeyForNextConnect(env *C.JNIEnv, this C.jobject, authKeyJStr C.jobject) {
jenv := (*jni.Env)(unsafe.Pointer(env))
authKey := jni.GoString(jenv, jni.String(authKeyJStr))
select {
case onSetAuthKeyForNextConnect <- authKey:
default:
}
}

@ -164,6 +164,9 @@ type ConnectEvent struct {
Enable bool
}
type SetAuthKeyEvent struct {
AuthKey string
}
type CopyEvent struct {
Text string
}
@ -441,6 +444,27 @@ func (a *App) runBackend() error {
go b.backend.StartLoginInteractive()
signingIn = true
}
case SetAuthKeyEvent:
authKey := e.AuthKey
if b.backend.State() <= ipn.Stopped {
log.Printf("using authkey; state=%v", b.backend.State())
go func() {
prefs := ipn.NewPrefs()
prefs.WantRunning = true
err := b.backend.Start(ipn.Options{
AuthKey: authKey,
UpdatePrefs: prefs,
})
log.Printf("authkey: Start error = %v", err)
if err != nil {
fatalErr(err)
} else {
b.backend.StartLoginInteractive()
}
}()
} else {
log.Printf("ignoring authkey in state=%v", b.backend.State())
}
case SetLoginServerEvent:
state.Prefs.ControlURL = e.URL
b.backend.SetPrefs(state.Prefs)
@ -895,6 +919,9 @@ func (a *App) runUI() error {
w.Invalidate()
}
}
case authKey := <-onSetAuthKeyForNextConnect:
ui.ShowMessage("got authkey")
requestBackend(SetAuthKeyEvent{AuthKey: authKey})
case p := <-a.prefs:
ui.enabled.Value = p.WantRunning
ui.runningExit = p.AdvertisesExitNode()

Loading…
Cancel
Save