Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fsim test #648

Merged
merged 20 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions component-samples/demo/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,38 @@ The FDO PRI HTTP Java Device Sample currently supports `fdo_sys` module for inte

The FDO PRI Owner Sample currently supports `fdo_sys` module for sending serviceInfo to the PRI Device and `devmod` module to store the received Device ServiceInfo. When device information is inserted into the database table 'ONBOARDING_CONFIG', it'll not have any association with the ServiceInfo values, and so by default, no ServiceInfo is transferred to the Device.

# Preview implementation of FSIM ServiceInfo modules

The FDO PRI Owner and PRI Java Device currently supports FSIM modules: `fdo.download`, `fdo.command`.

*fdo.download* - sends payload/content (script, binaries, and others) from Owner to the device. Upon receiving this, device writes the content into the open stream as given by the preceding 'filedesc' message.

*fdo.command* - The command that will be executed at the device. Device executes the command as received.

### Configuring FSIM ServiceInfo modules

Activate the following workers in Device's `service.yml`:
```yaml
- org.fidoalliance.fdo.sample.FdoSimDownloadDeviceModule
- org.fidoalliance.fdo.sample.FdoSimCommandDeviceModule
```
and Activate the following workers in Owner's `service.yml`

```yaml
- org.fidoalliance.fdo.sample.FdoSimDownloadOwnerModule
- org.fidoalliance.fdo.sample.FdoSimCommandOwnerModule
```

### Sample SVI instruction :

`[{"filedesc" : "script.bat","resource" : "script.bat", "module":"fdo.download"}]`

or

`[{"filedesc" : "script.bat","resource" : "script.bat", "module":"fdo.download"}, {"exec_cb" : ["cmd", "/c", "script.bat"], "module":"fdo.command"}]`

***NOTE***: You can filter SVI transfer based on Device parameters. [Learn more](aio/README.md#service-info-filters)

# Executing cURL request with mTLS

Generic sample Digest authentication call:
Expand Down
72 changes: 39 additions & 33 deletions component-samples/demo/aio/service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ http-server:
http_port: 8080
https_port: 8443
http_schemes:
- http
- https
- http
- https
http_timeout: 20000
server_cert: $(secrets.path)/server-cert.pem
server_key: $(secrets.path)/server-key.pem
Expand All @@ -51,32 +51,32 @@ http-server:
certificate_verification_depth: 2

manufacturer:
keystore:
path: manufacturer.p12
store-type: PKCS12
password: $(encrypt_password)
rv-instruction:
dns: host.docker.internal
ip: 172.17.0.1
protocol: 1
ownerport: 8443
devport: 8080
keystore:
path: manufacturer.p12
store-type: PKCS12
password: $(encrypt_password)
rv-instruction:
dns: host.docker.internal
ip: 172.17.0.1
protocol: 1
ownerport: 8443
devport: 8080

owner:
keystore:
path: owner.p12
store-type: PKCS12
password: $(encrypt_password)
replacement:
keystore:
path: replacement.p12
store-type: PKCS12
password: $(encrypt_password)
to0-scheduler:
keystore:
path: owner.p12
store-type: PKCS12
password: $(encrypt_password)
replacement:
keystore:
path: replacement.p12
store-type: PKCS12
password: $(encrypt_password)
to0-scheduler:
thread-count: 5
interval: 120


epid:
# WARNING: do not set testmode to true in production environments
# if testmode is true, EPID signature verification will only
Expand All @@ -89,10 +89,10 @@ epid:

#cbor Web Token (cwt) used for to0 and to1 sessions
cwt:
keystore:
path: ctw.p12
store-type: PKCS12
password: $(encrypt_password)
keystore:
path: ctw.p12
store-type: PKCS12
password: $(encrypt_password)

# *********************** NOTE **********************************************
#
Expand Down Expand Up @@ -126,7 +126,7 @@ workers:
- org.fidoalliance.fdo.protocol.StandardCwtKeySupplier
- org.fidoalliance.fdo.protocol.StandardReplacementKeySupplier
- org.fidoalliance.fdo.protocol.StandardHttpClientSupplier
- org.fidoalliance.fdo.protocol.StandardOwnerSchemeSupplier
- org.fidoalliance.fdo.protocol.StandardOwnerSchemeSupplier
#- org.fidoalliance.fdo.protocol.UntrustedRendezvousAcceptFunction
- org.fidoalliance.fdo.protocol.db.TrustedRendezvousAcceptFunction
- org.fidoalliance.fdo.protocol.db.StandardServiceInfoClientSupplier
Expand All @@ -148,10 +148,16 @@ workers:
- org.fidoalliance.fdo.protocol.db.StandardVoucherQueryFunction
- org.fidoalliance.fdo.protocol.db.StandardRvBlobQueryFunction
- org.fidoalliance.fdo.protocol.db.StandardRvBlobStorageFunction
#- org.fidoalliance.fdo.protocol.db.ReuseVoucherReplacementFunction
#- org.fidoalliance.fdo.protocol.db.ReuseVoucherReplacementFunction
- org.fidoalliance.fdo.protocol.db.StandardVoucherReplacementFunction
- org.fidoalliance.fdo.protocol.db.StandardReplacementVoucherStorageFunction
- org.fidoalliance.fdo.protocol.db.StandardReplacementVoucherStorageFunction
- org.fidoalliance.fdo.protocol.db.StandardRendezvousWaitSecondsSupplier
- org.fidoalliance.fdo.protocol.db.StandardOwnerInfoSizeSupplier
- org.fidoalliance.fdo.protocol.db.ConformanceOwnerModule
- org.fidoalliance.fdo.protocol.db.FdoSysOwnerModule
#- org.fidoalliance.fdo.protocol.db.ConformanceOwnerModule
- org.fidoalliance.fdo.protocol.db.StandardServiceInfoDocumentSupplier
- org.fidoalliance.fdo.protocol.db.FdoSimDownloadOwnerModule
#- org.fidoalliance.fdo.protocol.db.FdoSimUploadOwnerModule
- org.fidoalliance.fdo.protocol.db.FdoSimCommandOwnerModule
#- org.fidoalliance.fdo.protocol.db.FdoSimWebGetOwnerModule
#- org.fidoalliance.fdo.protocol.db.FdoSimCsrOwnerModule
- org.fidoalliance.fdo.protocol.db.FdoSysOwnerModule
8 changes: 7 additions & 1 deletion component-samples/demo/device/service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,17 @@ workers:
- org.fidoalliance.fdo.sample.StandardCredReuseFunction
#- org.fidoalliance.fdo.sample.UnsupportedCredReuseFunction
- org.fidoalliance.fdo.sample.StandardDeviceModule
- org.fidoalliance.fdo.sample.ConformanceDeviceModule
#- org.fidoalliance.fdo.sample.ConformanceDeviceModule
- org.fidoalliance.fdo.sample.FdoSimDownloadDeviceModule
#- org.fidoalliance.fdo.sample.FdoSimUploadDeviceModule
- org.fidoalliance.fdo.sample.FdoSimCommandDeviceModule
#- org.fidoalliance.fdo.sample.FdoSimWebGetDeviceModule
#- org.fidoalliance.fdo.sample.FdoSimCsrDeviceModule
- org.fidoalliance.fdo.sample.FdoSysDeviceModule




system-properties:
log4j.configurationFile: log4j2.xml
app-data.dir: ./app-data
Expand Down
6 changes: 6 additions & 0 deletions component-samples/demo/owner/service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ workers:
- org.fidoalliance.fdo.protocol.db.StandardRendezvousWaitSecondsSupplier
- org.fidoalliance.fdo.protocol.db.StandardOwnerInfoSizeSupplier
- org.fidoalliance.fdo.protocol.db.ConformanceOwnerModule
- org.fidoalliance.fdo.protocol.db.StandardServiceInfoDocumentSupplier
- org.fidoalliance.fdo.protocol.db.FdoSimDownloadOwnerModule
- org.fidoalliance.fdo.protocol.db.FdoSimUploadOwnerModule
- org.fidoalliance.fdo.protocol.db.FdoSimCommandOwnerModule
- org.fidoalliance.fdo.protocol.db.FdoSimWebGetOwnerModule
- org.fidoalliance.fdo.protocol.db.FdoSimCsrOwnerModule
- org.fidoalliance.fdo.protocol.db.FdoSysOwnerModule


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public void receive(ServiceInfoModuleState state, ServiceInfoKeyValuePair kvPair
}
}

@Override
public void keepAlive() throws IOException {

}

@Override
public void send(ServiceInfoModuleState state, ServiceInfoSendFunction sendFunction)
throws IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package org.fidoalliance.fdo.sample;

import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.fidoalliance.fdo.protocol.Config;
import org.fidoalliance.fdo.protocol.LoggerService;
import org.fidoalliance.fdo.protocol.Mapper;
import org.fidoalliance.fdo.protocol.db.FdoSimCommandOwnerModule;
import org.fidoalliance.fdo.protocol.dispatch.ServiceInfoModule;
import org.fidoalliance.fdo.protocol.dispatch.ServiceInfoSendFunction;
import org.fidoalliance.fdo.protocol.message.ServiceInfoKeyValuePair;
import org.fidoalliance.fdo.protocol.message.ServiceInfoModuleState;
import org.fidoalliance.fdo.protocol.message.ServiceInfoQueue;

public class FdoSimCommandDeviceModule implements ServiceInfoModule {

private static final LoggerService logger = new LoggerService(FdoSimCommandDeviceModule.class);

private final ProcessBuilder.Redirect execOutputRedirect = ProcessBuilder.Redirect.PIPE;
private final ProcessBuilder.Redirect execNoOutput = Redirect.DISCARD;

private final ServiceInfoQueue queue = new ServiceInfoQueue();

private String command;
private String[] commandArgs;
private Process execProcess;
private boolean mayFail;
private boolean returnStdOut;
private boolean returnStdErr;

@Override
public String getName() {
return FdoSimCommandOwnerModule.MODULE_NAME;
}

@Override
public void prepare(ServiceInfoModuleState state) throws IOException {

command = null;
commandArgs = null;
mayFail = false;
returnStdOut = false;
returnStdErr = false;
}

@Override
public void receive(ServiceInfoModuleState state, ServiceInfoKeyValuePair kvPair)
throws IOException {

switch (kvPair.getKey()) {
case FdoSimCommandOwnerModule.ACTIVE:
logger.info(FdoSimCommandOwnerModule.ACTIVE + " = "
+ Mapper.INSTANCE.readValue(kvPair.getValue(), Boolean.class));
state.setActive(Mapper.INSTANCE.readValue(kvPair.getValue(), Boolean.class));
break;
case FdoSimCommandOwnerModule.RETURN_STDOUT:
if (state.isActive()) {
returnStdOut = Mapper.INSTANCE.readValue(kvPair.getValue(), Boolean.class);
}
break;
case FdoSimCommandOwnerModule.RETURN_STDERR:
if (state.isActive()) {
returnStdErr = Mapper.INSTANCE.readValue(kvPair.getValue(), Boolean.class);
}
break;
case FdoSimCommandOwnerModule.MAY_FAIL:
if (state.isActive()) {
mayFail = Mapper.INSTANCE.readValue(kvPair.getValue(), Boolean.class);
}
break;
case FdoSimCommandOwnerModule.SIG:
if (state.isActive()) {
int sigValue = Mapper.INSTANCE.readValue(kvPair.getValue(), Integer.class);
logger.info("Process Signal received : " + sigValue);
if ((sigValue == 9 || sigValue == 15) && execProcess != null) {
execProcess.destroyForcibly();
}
}
break;
case FdoSimCommandOwnerModule.COMMAND:
if (state.isActive()) {
command = Mapper.INSTANCE.readValue(kvPair.getValue(), String.class);
logger.info("command " + command);
}
break;
case FdoSimCommandOwnerModule.ARGS:
if (state.isActive()) {
commandArgs = Mapper.INSTANCE.readValue(kvPair.getValue(), String[].class);
logger.info("with args: " + Arrays.asList(commandArgs));
}
break;
case FdoSimCommandOwnerModule.EXECUTE:
if (state.isActive()) {
execute();
}
break;

default:
checkStatus();
break;
}
}

@Override
public void keepAlive() throws IOException {
checkStatus();
}


@Override
public void send(ServiceInfoModuleState state, ServiceInfoSendFunction sendFunction)
throws IOException {
while (queue.size() > 0) {
boolean sent = sendFunction.apply(queue.peek());
if (sent) {
queue.poll();
} else {
break;
}
}

}

private void checkStatus() throws IOException {

if (execProcess != null) {
if (execProcess.isAlive()) {
if (returnStdErr) {

execProcess.getErrorStream();

}
if (returnStdOut) {
execProcess.getOutputStream();
}
} else {
ServiceInfoKeyValuePair kv = new ServiceInfoKeyValuePair();
kv.setKeyName(FdoSimCommandOwnerModule.EXIT_CODE);
kv.setValue(Mapper.INSTANCE.writeValue(execProcess.exitValue()));
queue.add(kv);
execProcess.destroy();
execProcess = null;

}
}
}

private void execute() {
List<String> argList = new ArrayList<>();
argList.add(command);
for (int i = 0; i < commandArgs.length; i++) {
argList.add(commandArgs[i]);
}

try {
ProcessBuilder builder = new ProcessBuilder(argList);
builder.directory(new File(getAppData()));
builder.redirectErrorStream(returnStdErr);

builder.redirectOutput(getExecOutputRedirect());
execProcess = builder.start();
} catch (IOException e) {
logger.error("IO Operation Failed" + e.getMessage());
throw new RuntimeException(e);
}
}

private String getAppData() {
DeviceConfig config = Config.getConfig(RootConfig.class).getRoot();
File file = new File(config.getCredentialFile());
return file.getParent();
}

private ProcessBuilder.Redirect getExecOutputRedirect() {
if (returnStdOut) {
return execOutputRedirect;
}
return execNoOutput;
}
}
Loading