-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67 from sameerag/dbsc-e
Dbsc(e)
- Loading branch information
Showing
11 changed files
with
580 additions
and
1 deletion.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
<span style="color:red">!!! DRAFT - Please note this page is still in draft as we work on platform specific details | ||
</span> | ||
|
||
### Local Key Helper on Android | ||
On android platform a Local Key Helper is a protocol interface (`ILocalKeyHelper.java`), and its implementation (`LocalKeyHelperImpl.java`) is yet to be determined. | ||
|
||
Local KeyHelpers on the Android platform are implemented using [content providers](https://developer.android.com/guide/topics/providers/content-providers). These content providers allow browser applications, such as Chrome, to interact with them by querying and accessing specific APIs defined by the Local KeyHelpers. | ||
|
||
#### Registering LocalkeyHelpers with Browser Interaction | ||
To register the localkeyhelpers with a browser (e.g. Chrome), the browser application exports a content provider with the authority `$browserPackageName.localkeyhelpersregistration` in it's manifest file. | ||
|
||
```xml | ||
<provider | ||
android:authorities="com.custombrowser.localkeyhelpersregistration" | ||
android:name="LocalKeyHelpersRegistrationProvider" | ||
android:exported="true" > | ||
</provider> | ||
``` | ||
|
||
##### Implementing localkeyhelpersregistration provider in Browser | ||
Browser application implements `localkeyhelpersregistration` content provider and provides path `/register` for the local key helpers to register themselves. | ||
When the LocalKeyHelper queries the browser's content provider, it register itself with the browser. | ||
Example implementation. | ||
``` java | ||
public class LocalKeyHelperConsumerProvider extends ContentProvider { | ||
public static final String AUTHORITY = "com.custombrowser.localkeyhelpersregistration"; | ||
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); | ||
|
||
static { | ||
uriMatcher.addURI("AUTHORITY", "/register", 1); | ||
} | ||
|
||
@Override | ||
public boolean onCreate() { | ||
return true; | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { | ||
switch (uriMatcher.match(uri)) { | ||
case 1 : | ||
return new MatrixCursor(new String[0]) { | ||
@Override | ||
public Bundle getExtras() { | ||
Bundle bundle = new Bundle(); | ||
bundle.putBoolean("registered", true); | ||
return bundle; | ||
} | ||
}; | ||
default: | ||
throw new IllegalArgumentException("Unknown URI: " + uri); | ||
} | ||
} | ||
... | ||
|
||
} | ||
``` | ||
##### Calling Browser Content Provider to register a local key helper. | ||
LocalKeyhelpers make the browser content provider visible to them by adding queries tag with browser content provider authority to their manifest file. | ||
```xml | ||
<queries> | ||
<provider android:authorities="com.custombrowser.localkeyhelpersregistration" /> | ||
</queries> | ||
``` | ||
|
||
LocalKeyHelper call the browser's content provider to register itself with the browser. | ||
```java | ||
Uri uri = Uri.parse("content://com.custombrowser.localkeyhelpersregistration/register"); | ||
Cursor cursor = getContentResolver().query(uri, null, null, null, null); | ||
if (cursor != null) { | ||
try { | ||
val resultBundle = cursor.extras | ||
if (resultBundle != null) { | ||
val registered = resultBundle.getBoolean("registered") | ||
Log.i("TAG", "Registered: $registered") | ||
} else { | ||
Log.i("TAG", "Failed to register.") | ||
} | ||
} finally { | ||
cursor.close(); | ||
} | ||
} | ||
``` | ||
|
||
#### Calling Local KeyHelpers from Browser | ||
Once a localkeyhelper is registered with the Browser application, the browser can query the Local KeyHelper's content providers without defining the query tag. | ||
To implement the localkeyhelper protocol interface LocalKeyHelper defines a content provider with the authority `$packagename.**localkeyhelper**`. Different APIs are implemented as separate paths on this content provider. | ||
|
||
##### Sample Manifest Entry for Local KeyHelper Content Provider | ||
```xml | ||
<provider | ||
android:authorities="com.contoso.localkeyhelper" | ||
android:name="ContosoLocalKeyHelperProvider" /> | ||
``` | ||
|
||
##### Implementing the ContentProvider in Local KeyHelper | ||
Each Local KeyHelper must implement a ContentProvider to handle the interactions. Below is an example of how to implement a ContentProvider in a Local KeyHelper. | ||
|
||
```java | ||
public class LocalKeyHelperProvider extends ContentProvider { | ||
public static final String AUTHORITY = "com.contoso.localkeyhelper"; | ||
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); | ||
|
||
static { | ||
uriMatcher.addURI(AUTHORITY, "sample_api_path", 1); | ||
// Add more paths as needed | ||
} | ||
|
||
@Override | ||
public boolean onCreate() { | ||
return true; | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { | ||
switch (uriMatcher.match(uri)) { | ||
// call the Implementation specific api based on the path | ||
default: | ||
throw new IllegalArgumentException("Unknown URI: " + uri); | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<span style="color:red">!!! DRAFT - Please note this page is still in draft as we work on platform specific details | ||
</span> | ||
|
||
### Local key helper on Mac | ||
|
||
On macOS, a Local Key Helper is a protocol (`LocalKeyHelper.h`), and its implementation (`LocalKeyHelperImpl.h`/`LocalKeyHelperImpl.m`) is yet to be determined. | ||
|
||
Each _Local key helper_ vendor will implement and ship as an XPC service on macOS. Each vendor will also manage their own lifecycle of the XPC service depending on their specific and other functionality provided by the service. Each XPC service needs to be defined and registered with launchd as a launch agent. Vendors can decided whether to start XPC service on machine startup or on demand. | ||
|
||
Here is an example of the Local Key Helper XPC service plist: | ||
|
||
```xml | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>Label</key> | ||
<string>com.contoso.LocalKeyHelper</string> | ||
<key>Program</key> | ||
<string>/pathToXcpService/LocalKepHelper.xpc/Contents/MacOS/LocalKepHelper</string> | ||
<key>KeepAlive</key> | ||
<true/> | ||
<key>MachServices</key> | ||
<dict> | ||
<key>com.contoso.LocalKeyHelper</key> | ||
<true/> | ||
</dict> | ||
</dict> | ||
</plist> | ||
``` | ||
|
||
Please refer to Apple documentation for building and configuring XPC services. | ||
|
||
When the browser (e.g. Chrome) communicates with this service, it needs to establish a service connection first. | ||
Here is an example of starting a new connection with the Local Key Helper: | ||
|
||
```objective-c | ||
// Start a new connection by providing the Local Key Helper defined in the plist | ||
NSXPCConnection* localKeyhelper = [[NSXPCConnection alloc] initWithMachServiceName:@"com.contoso.LocalKeyHelper"]; | ||
|
||
// Make the connection conform to the defined Local Key Helper protocol | ||
[localKeyhelper setRemoteObjectInterface:[NSXPCInterface interfaceWithProtocol:@protocol(LocalKeyHelper)]]; | ||
``` | ||
The browser (e.g. Chrome) can then call the methods defined in the LocalKeyHelper protocol, and the implementations will be provided by the XPC service. | ||
**Note:** | ||
- It is important to define the LocalKeyHelper protocol exactly the same way in both the browser and the XPC service provider. This allows for easy extension of the protocol in the future (e.g. using a dictionary as an input parameter instead of a strict object type). | ||
- The input and output parameters of the XPC service should follow the `NSSecureCoding` protocol. | ||
- Non-sandboxed applications can communicate directly to the XPC service. | ||
#### Deployment of a 3rd party local key helper | ||
To inform the browser about the Local Key Helper to use, the manifest file is created within the browser's root folder during the LocalKeyHelper's installation (e.g. `/Library/Google/Chrome/LocalKeyHelpers`). This folder contains the following 2 types of files: | ||
**1st type: files that define the Local Key Helpers** | ||
i.e. | ||
```` | ||
com.provider1.LocalKeyHelper.json (if helper was installed) | ||
com.provider2.LocalKeyHelper.json (if helper was installed) | ||
com.provider3.LocalKeyHelper.json (if helper was installed) | ||
```` | ||
For example: | ||
```` | ||
com.contoso.LocalKeyHelper.json | ||
```` | ||
Within the file: | ||
```json | ||
{ | ||
"provider": "contoso", | ||
"xpc": // Local key helper type | ||
{ | ||
"service": "com.contoso.LocalKeyHelper", // Service name/API activation id | ||
"version": "0.0.1", // Helper service version | ||
"Idp_resource":"com.contoso.LocalKeyHelper.idP.json" // File path to IdP URL allow-list | ||
} | ||
} | ||
``` | ||
|
||
**2nd type: files that defines the allow-list for IdP URLs:** | ||
|
||
For example: | ||
```` | ||
com.contoso.LocalKeyHelper.idP.json | ||
```` | ||
|
||
```json | ||
{ | ||
"urls": ["*.contoso1.com", "login.contoso1.net", "login.contoso2.com"], | ||
} | ||
``` | ||
|
||
The MDM service can run an on-device script to update the URLs in this file without changing the Local Key Helper definition file. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
### Local key helper on Windows | ||
|
||
On Windows, a Local key helper is a COM class. A COM interface that the local key helper implements is TBD (working name for this document is ILocalKeyHelper) | ||
|
||
#### Deployment of a 3rd party local key helper. | ||
|
||
Local key helpers will be deployed using registry. | ||
|
||
The base registry key is: | ||
|
||
``` | ||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\<Company>\<Browser>\LocalKeyHelperList] | ||
``` | ||
|
||
i.e. | ||
|
||
``` | ||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\LocalKeyHelperList] | ||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\LocalKeyHelperList] | ||
``` | ||
|
||
Every local key helper has a child key in the above registry key. The entry for the local key is a registry key with the name equals to the local key helper id, the default value stores activation ID, prefixed by an activation scheme. | ||
|
||
``` | ||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\<Company>\<Browser>\LocalKeyHelperList\<LocalKeyHelperId>] | ||
@="<Scheme>:<API activation ID>" | ||
``` | ||
|
||
Here is example: | ||
|
||
``` | ||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\LocalKeyHelperList\login.contoso.com] | ||
@="progid:App.Component.1.0" | ||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\LocalKeyHelperList\login.fabrikam.com] | ||
@="clsid:3AD05D77-6885-4BAF-A727-D30690A2A28A" | ||
``` | ||
|
||
Currently the supported schemes are: | ||
|
||
1. clsid: \<GUID\> - CLSID of a COM class that implements the Local Key Helper. | ||
2. progid:\<ProgId string\> - [a programic identifier](https://learn.microsoft.com/en-us/windows/win32/com/-progid--key) of the local key helper. | ||
|
||
This scheme can be extended by other schemes in future. | ||
The local key helper registry key can have extra values, which we can use for in future. | ||
|
||
Here is a visual example how Local key helper is organized: | ||
|
||
![Local key helper registry key](./images/keyhelper-reg.png) | ||
|
||
When the browser needs to communicate with a local key helper. It uses its ID to locate the registry key, then reads the default value of this registry key and activates the object by the activation scheme (CLSID or ProgId according to the document). After activation it queries ILocalKeyHelper interface and invokes corresponding methods. | ||
|
||
#### Well-known local key helpers on Windows | ||
|
||
A well-known local key helper list on Windows is a list of helperId to clsid, that either harcoded or predefined in the browser settings. | ||
|
Oops, something went wrong.