java/syncbase: Modify Android Login to be safer

This change is needed because we now persist blessings and load them
from disk whenever appropriate.

MultiPart: 1/2
Change-Id: I12dc83c6b96b76da8fd1c8bdb224d1167d1fc257
diff --git a/services/syncbase/bridge/cgo/impl.go b/services/syncbase/bridge/cgo/impl.go
index 3eda95f..1d7e620 100644
--- a/services/syncbase/bridge/cgo/impl.go
+++ b/services/syncbase/bridge/cgo/impl.go
@@ -28,6 +28,7 @@
 package main
 
 import (
+	"fmt"
 	"os"
 	"strings"
 
@@ -45,6 +46,7 @@
 	"v.io/v23/verror"
 	"v.io/v23/vom"
 	"v.io/x/lib/vlog"
+	vsecurity "v.io/x/ref/lib/security"
 	_ "v.io/x/ref/runtime/factories/roaming"
 	"v.io/x/ref/services/syncbase/bridge"
 	"v.io/x/ref/services/syncbase/bridge/cgo/ptrmap"
@@ -145,20 +147,37 @@
 	// Strip all flags beyond the binary name; otherwise, v23.Init will fail when it encounters
 	// unknown flags passed by Xcode, e.g. NSTreatUnknownArgumentsAsOpen.
 	os.Args = os.Args[:1]
+
+	// Prepare the principal.
+	rootDir = opts.rootDir
+	principalRootDir := fmt.Sprintf("%s/principal", rootDir)
+
+	// TODO(alexfandrianto): https://github.com/vanadium/issues/issues/1389
+	// How secure does this principal need to be? Instead of 'nil', we could
+	// require that the init options pass us a fixed passphrase/private key.
+	principal, err := vsecurity.LoadPersistentPrincipal(principalRootDir, nil)
+	if err != nil {
+		principal, err = vsecurity.CreatePersistentPrincipal(principalRootDir, nil)
+		if err != nil {
+			panic(err)
+		}
+	}
+
+	// After initializing, apply the loaded/created principal.
 	ctx, shutdown := v23.Init()
+	ctx, err = v23.WithPrincipal(ctx, principal)
+	if err != nil {
+		panic(err)
+	}
+
 	if opts.verboseLevel > 0 {
 		vlog.Log.Configure(vlog.OverridePriorConfiguration(true), vlog.Level(opts.verboseLevel))
 		vlog.Info("Verbose logging turned on")
 	}
 	b = &bridge.Bridge{Ctx: ctx, Shutdown: shutdown}
-	rootDir = opts.rootDir
 	clientUnderstandsVOM = opts.clientUnderstandsVOM
 	testLogin = opts.testLogin
-	if isLoggedIn() {
-		// This cErr will always be nil since we just checked isLoggedIn.
-		var cErr C.v23_syncbase_VError
-		v23_syncbase_Serve(&cErr)
-	}
+
 	neighborhoodAdStatus = newAdStatus()
 }
 
@@ -168,9 +187,7 @@
 		cErr.init(verror.New(verror.ErrInternal, nil, "not logged in"))
 	}
 	srv, disp, cleanup := syncbaselib.Serve(b.Ctx, syncbaselib.Opts{
-		// TODO(sadovsky): Make and pass a subdir of rootDir here, so
-		// that rootDir can also be used for credentials persistence.
-		RootDir: rootDir,
+		RootDir: fmt.Sprintf("%s/db", rootDir),
 	})
 	b.Srv = srv
 	b.Disp = disp
diff --git a/services/syncbase/bridge/cgo/jni.go b/services/syncbase/bridge/cgo/jni.go
index c60ffc2..c7f042c 100644
--- a/services/syncbase/bridge/cgo/jni.go
+++ b/services/syncbase/bridge/cgo/jni.go
@@ -123,12 +123,14 @@
 //export Java_io_v_syncbase_internal_Service_Init
 func Java_io_v_syncbase_internal_Service_Init(env *C.JNIEnv, cls C.jclass, initRoot C.jstring, testLogin C.jboolean) {
 	cInitRoot := newVStringFromJava(env, initRoot)
-	v23_syncbase_Init(initOpts{
+	var cInitOpts C.v23_syncbase_InitOpts
+	(&cInitOpts).init(initOpts{
 		clientUnderstandsVOM: true,
 		rootDir:              cInitRoot.extract(),
-		testLogin:            bool(testLogin),
+		testLogin:            int(testLogin) != 0,
 		verboseLevel:         0,
 	})
+	v23_syncbase_Init(cInitOpts)
 }
 
 //export Java_io_v_syncbase_internal_Service_Serve
@@ -154,9 +156,9 @@
 
 //export Java_io_v_syncbase_internal_Service_IsLoggedIn
 func Java_io_v_syncbase_internal_Service_IsLoggedIn(env *C.JNIEnv, cls C.jclass) C.jboolean {
-	var r C.v23_syncbase_Bool
+	var r C.bool
 	v23_syncbase_IsLoggedIn(&r)
-	return C.jboolean(r)
+	return r.extractToJava()
 }
 
 //export Java_io_v_syncbase_internal_Service_GetPermissions
@@ -242,11 +244,11 @@
 //export Java_io_v_syncbase_internal_Database_Exists
 func Java_io_v_syncbase_internal_Database_Exists(env *C.JNIEnv, cls C.jclass, name C.jstring) C.jboolean {
 	cName := newVStringFromJava(env, name)
-	var r C.v23_syncbase_Bool
+	var r C.bool
 	var cErr C.v23_syncbase_VError
 	v23_syncbase_DbExists(cName, &r, &cErr)
 	maybeThrowException(env, &cErr)
-	return C.jboolean(r)
+	return r.extractToJava()
 }
 
 //export Java_io_v_syncbase_internal_Database_BeginBatch
@@ -560,11 +562,11 @@
 func Java_io_v_syncbase_internal_Collection_Exists(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) C.jboolean {
 	cName := newVStringFromJava(env, name)
 	cHandle := newVStringFromJava(env, handle)
-	var r C.v23_syncbase_Bool
+	var r C.bool
 	var cErr C.v23_syncbase_VError
 	v23_syncbase_CollectionExists(cName, cHandle, &r, &cErr)
 	maybeThrowException(env, &cErr)
-	return C.jboolean(r)
+	return r.extractToJava()
 }
 
 //export Java_io_v_syncbase_internal_Collection_DeleteRange
@@ -651,9 +653,9 @@
 
 //export Java_io_v_syncbase_internal_Neighborhood_IsAdvertising
 func Java_io_v_syncbase_internal_Neighborhood_IsAdvertising(env *C.JNIEnv, cls C.jclass) C.jboolean {
-	var x C.v23_syncbase_Bool
+	var x C.bool
 	v23_syncbase_NeighborhoodIsAdvertising(&x)
-	return C.jboolean(x)
+	return x.extractToJava()
 }
 
 //export v23_syncbase_internal_onPeer
@@ -704,11 +706,11 @@
 func Java_io_v_syncbase_internal_Row_Exists(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring) C.jboolean {
 	cName := newVStringFromJava(env, name)
 	cHandle := newVStringFromJava(env, handle)
-	var r C.v23_syncbase_Bool
+	var r C.bool
 	var cErr C.v23_syncbase_VError
 	v23_syncbase_RowExists(cName, cHandle, &r, &cErr)
 	maybeThrowException(env, &cErr)
-	return C.jboolean(r)
+	return r.extractToJava()
 }
 
 //export Java_io_v_syncbase_internal_Row_Get