Skip to content

Commit cee77c2

Browse files
xaionaro@dx.centerxaionaro@dx.center
authored andcommitted
refactor: remove token auth, use mTLS-only, stop using /data/local/tmp
- Remove TokenAuth and NoAuth (only ACLAuth with mTLS remains) - Remove --token flag from jnicli - Change all file paths from /data/local/tmp/ to /data/adb/jniservice/ - Magisk module stores config/logs/data in its own module directory - JNIService.java uses System.loadLibrary instead of hardcoded path - Default listen address is 127.0.0.1 - Update README to show on-device usage as primary
1 parent fd58869 commit cee77c2

13 files changed

Lines changed: 48 additions & 163 deletions

File tree

Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ endif
5656
ADB ?= $(ANDROID_SDK)/platform-tools/adb
5757
PORT ?= 50051
5858
HOST_PORT ?= $(PORT)
59-
REMOTE_DIR := /data/local/tmp
59+
REMOTE_DIR := /data/adb/jniservice
6060

6161
deploy: push start-server forward
6262

@@ -68,11 +68,15 @@ push:
6868
esac; \
6969
echo "Device arch: $$ARCH -> GOARCH=$$GOARCH ABI=$$ABI"; \
7070
$(MAKE) dist-jniservice dist-dex DIST_GOARCH=$$GOARCH && \
71+
$(ADB) shell "mkdir -p $(REMOTE_DIR)" && \
7172
$(ADB) push build/libjniservice-$$ABI.so $(REMOTE_DIR)/libjniservice.so && \
7273
$(ADB) push build/classes.dex $(REMOTE_DIR)/jniservice.dex
7374

7475
start-server: stop-server
75-
$(ADB) shell "JNISERVICE_PORT=$(PORT) app_process \
76+
$(ADB) shell "JNISERVICE_PORT=$(PORT) \
77+
JNISERVICE_DATA_DIR=$(REMOTE_DIR)/data \
78+
LD_LIBRARY_PATH=$(REMOTE_DIR) \
79+
app_process \
7680
-Djava.class.path=$(REMOTE_DIR)/jniservice.dex \
7781
$(REMOTE_DIR) JNIService" &
7882
@echo "Waiting for jniservice to start..."

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ adb shell su -c "magisk --install-module /sdcard/jniservice-magisk-arm64-v8a.zip
9090
adb reboot # starts on next boot
9191
```
9292

93-
Configuration: create `/data/local/tmp/jniservice.env` on the device:
93+
Configuration (optional): create `jniservice.env` in the Magisk module directory:
9494
```bash
9595
JNISERVICE_PORT=50051
96-
JNISERVICE_TOKEN=my-secret-token
96+
JNISERVICE_LISTEN=0.0.0.0
9797
```
9898

9999
### Non-rooted devices (APK)
@@ -109,6 +109,12 @@ Open "jniservice" from the launcher once to start the service and register the b
109109

110110
### Connecting
111111

112+
On the device itself:
113+
```bash
114+
jnicli --addr localhost:50051 --insecure jni get-version
115+
```
116+
117+
From another machine (via adb port forwarding):
112118
```bash
113119
adb forward tcp:50051 tcp:50051
114120
jnicli --addr localhost:50051 --insecure jni get-version

cmd/jnicli/root.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515

1616
var (
1717
flagAddr string
18-
flagToken string
1918
flagInsecure bool
2019
flagTimeout time.Duration
2120
flagFormat string
@@ -57,10 +56,6 @@ var rootCmd = &cobra.Command{
5756
&tls.Config{InsecureSkipVerify: true})))
5857
}
5958

60-
if flagToken != "" {
61-
opts = append(opts, grpc.WithPerRPCCredentials(tokenCredentials{token: flagToken}))
62-
}
63-
6459
conn, err := grpc.NewClient(flagAddr, opts...)
6560
if err != nil {
6661
return fmt.Errorf("connect to %s: %w", flagAddr, err)
@@ -78,7 +73,6 @@ var rootCmd = &cobra.Command{
7873

7974
func init() {
8075
rootCmd.PersistentFlags().StringVarP(&flagAddr, "addr", "a", "localhost:50051", "gRPC server address")
81-
rootCmd.PersistentFlags().StringVarP(&flagToken, "token", "t", "", "authentication token")
8276
rootCmd.PersistentFlags().BoolVar(&flagInsecure, "insecure", false, "use insecure connection (no TLS)")
8377
rootCmd.PersistentFlags().DurationVar(&flagTimeout, "timeout", 10*time.Second, "request timeout")
8478
rootCmd.PersistentFlags().StringVarP(&flagFormat, "format", "f", "json", "output format (json|text)")
@@ -91,22 +85,6 @@ func requestContext(cmd *cobra.Command) (context.Context, context.CancelFunc) {
9185
return context.WithTimeout(cmd.Context(), flagTimeout)
9286
}
9387

94-
// tokenCredentials implements grpc.PerRPCCredentials for bearer token auth.
95-
type tokenCredentials struct {
96-
token string
97-
}
98-
99-
func (t tokenCredentials) GetRequestMetadata(
100-
_ context.Context,
101-
_ ...string,
102-
) (map[string]string, error) {
103-
return map[string]string{"authorization": "Bearer " + t.token}, nil
104-
}
105-
106-
func (t tokenCredentials) RequireTransportSecurity() bool {
107-
return false
108-
}
109-
11088
func buildMTLSCredentials() (credentials.TransportCredentials, error) {
11189
cert, err := tls.LoadX509KeyPair(flagCert, flagKey)
11290
if err != nil {

cmd/jniservice/JNIService.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
//
33
// Run via app_process on an Android device:
44
//
5-
// app_process -Djava.class.path=/data/local/tmp/jniservice.dex \
6-
// /data/local/tmp JNIService
5+
// LD_LIBRARY_PATH=/path/to/dir app_process \
6+
// -Djava.class.path=/path/to/dir/jniservice.dex /path/to/dir JNIService
77
//
88
// Configuration is via environment variables (set before invoking app_process):
99
//
10-
// JNISERVICE_PORT — TCP port (default 50051)
11-
// JNISERVICE_LISTEN — listen address (default 0.0.0.0)
12-
// JNISERVICE_TOKEN — bearer token for auth (empty = no auth)
10+
// JNISERVICE_PORT — TCP port (default 50051)
11+
// JNISERVICE_LISTEN — listen address (default 127.0.0.1)
12+
// JNISERVICE_DATA_DIR — writable directory for CA, ACL db, etc.
1313
public class JNIService {
1414
public static void main(String[] args) {
1515
System.err.println("jniservice: loading shared library");
1616
try {
17-
System.load("/data/local/tmp/libjniservice.so");
17+
System.loadLibrary("jniservice");
1818
} catch (Throwable t) {
1919
System.err.println("jniservice: load failed: " + t);
2020
System.exit(1);

cmd/jniservice/magisk/customize.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
ui_print "Installing jniservice..."
66
ui_print " gRPC server will start on next boot"
7-
ui_print " Config: /data/local/tmp/jniservice.env"
8-
ui_print " Logs: /data/local/tmp/jniservice.log"
7+
ui_print " Config: <module_dir>/jniservice.env"
8+
ui_print " Logs: <module_dir>/jniservice.log"
9+
ui_print " Data: <module_dir>/data/"
910

1011
# Set permissions on service.sh.
1112
set_perm "$MODPATH/service.sh" 0 0 0755

cmd/jniservice/magisk/service.sh

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,19 @@
44

55
MODDIR="${0%/*}"
66
JNISERVICE_DIR="$MODDIR/jniservice"
7-
LOG="/data/local/tmp/jniservice.log"
7+
LOG="$MODDIR/jniservice.log"
88

99
# Wait for boot to fully complete.
1010
while [ "$(getprop sys.boot_completed)" != "1" ]; do
1111
sleep 1
1212
done
1313
sleep 5
1414

15-
# Read config from /data/local/tmp/jniservice.env if it exists.
15+
# Read config from module directory if it exists.
1616
PORT="${JNISERVICE_PORT:-50051}"
17-
LISTEN="${JNISERVICE_LISTEN:-0.0.0.0}"
18-
TOKEN="${JNISERVICE_TOKEN:-}"
19-
if [ -f /data/local/tmp/jniservice.env ]; then
20-
. /data/local/tmp/jniservice.env
17+
LISTEN="${JNISERVICE_LISTEN:-127.0.0.1}"
18+
if [ -f "$MODDIR/jniservice.env" ]; then
19+
. "$MODDIR/jniservice.env"
2120
fi
2221

2322
# Kill any existing instance.
@@ -27,7 +26,7 @@ sleep 1
2726
# Start jniservice.
2827
export JNISERVICE_PORT="$PORT"
2928
export JNISERVICE_LISTEN="$LISTEN"
30-
export JNISERVICE_TOKEN="$TOKEN"
29+
export JNISERVICE_DATA_DIR="$MODDIR/data"
3130
export LD_LIBRARY_PATH="$JNISERVICE_DIR:$LD_LIBRARY_PATH"
3231

3332
app_process \

cmd/jniservice/server.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// Configuration is via environment variables:
1212
//
1313
// JNISERVICE_PORT TCP port (default "50051")
14-
// JNISERVICE_LISTEN Listen address (default "0.0.0.0")
14+
// JNISERVICE_LISTEN Listen address (default "127.0.0.1")
1515
package main
1616

1717
/*
@@ -144,13 +144,13 @@ func runServer(cvm *C.JavaVM) {
144144
appContextHandle := initAndroidContext(vm, handles)
145145

146146
// Determine data directory. Try the APK's files dir first (writable by the
147-
// app process), fall back to /data/local/tmp (writable by shell user in
148-
// app_process mode).
147+
// app process), fall back to /data/adb/jniservice (writable by root in
148+
// app_process/Magisk mode). JNISERVICE_DATA_DIR env var overrides both.
149149
dataDir := os.Getenv("JNISERVICE_DATA_DIR")
150150
if dataDir == "" {
151151
candidates := []string{
152152
"/data/data/center.dx.jni.jniservice/files/jniservice",
153-
"/data/local/tmp/jniservice",
153+
"/data/adb/jniservice",
154154
}
155155
for _, dir := range candidates {
156156
if err := os.MkdirAll(dir, 0700); err == nil {

cmd/jniserviceadmin/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ var requestsDenyCmd = &cobra.Command{
199199
}
200200

201201
func init() {
202-
rootCmd.PersistentFlags().StringVar(&flagDB, "db", "/data/local/tmp/jniservice/acl.db", "path to SQLite database")
202+
rootCmd.PersistentFlags().StringVar(&flagDB, "db", "/data/adb/jniservice/data/acl.db", "path to SQLite database")
203203

204204
grantsListCmd.Flags().StringVar(&flagGrantsClient, "client", "", "filter grants by client ID")
205205

grpc/server/auth.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"google.golang.org/grpc"
99
"google.golang.org/grpc/codes"
1010
"google.golang.org/grpc/credentials"
11-
"google.golang.org/grpc/metadata"
1211
"google.golang.org/grpc/peer"
1312
"google.golang.org/grpc/status"
1413
)
@@ -18,33 +17,6 @@ type Authorizer interface {
1817
Authorize(ctx context.Context, fullMethod string) error
1918
}
2019

21-
// NoAuth allows all requests.
22-
type NoAuth struct{}
23-
24-
// Authorize always returns nil (all requests are allowed).
25-
func (NoAuth) Authorize(context.Context, string) error { return nil }
26-
27-
// TokenAuth checks for a bearer token in gRPC metadata.
28-
type TokenAuth struct {
29-
Token string
30-
}
31-
32-
// Authorize validates that the incoming context carries a matching bearer token.
33-
func (a TokenAuth) Authorize(ctx context.Context, _ string) error {
34-
md, ok := metadata.FromIncomingContext(ctx)
35-
if !ok {
36-
return status.Error(codes.Unauthenticated, "missing metadata")
37-
}
38-
tokens := md.Get("authorization")
39-
if len(tokens) == 0 {
40-
return status.Error(codes.Unauthenticated, "missing authorization")
41-
}
42-
if tokens[0] != "Bearer "+a.Token {
43-
return status.Error(codes.PermissionDenied, "invalid token")
44-
}
45-
return nil
46-
}
47-
4820
// ACLAuth checks client identity from mTLS peer cert and verifies
4921
// method permissions against the ACL store.
5022
type ACLAuth struct {

grpc/server/auth_test.go

Lines changed: 0 additions & 80 deletions
This file was deleted.

0 commit comments

Comments
 (0)