I have built the latest version of wso2 emm android agent (cdmf-agent-android v3.1.30) and got some initial tests working in BYOD mode with IoT server 3.1.0
When built for COSU it is waiting for provisioning with another device via NFC. But I want to provision devices without NFC. What options do I have? Could I trigger programmatically a custom provisioning option?
There are some options to do this, depending on your android version.
I will start with the simplest option. If you have Android 7+ you can use QR Code provisioning, this follows the exact same process as NFC provisioning. You can see some specifications from Google regarding this.
The second option is a bit trickier and requires some custom dev on your side. First thing to to make your device a Device Owner (Which is needed for COSU mode, read up about Device Owner here). Using the command: adb shell dpm set-device-owner org.wso2.iot.agent/org.wso2.iot.agent.services.AgentDeviceAdminReceiver
Note: Only one device owner can be set, to remove a device owner the device has to be factory reset.
Once this is done you can launch your app using adb shell am start -n "org.wso2.iot.agent/org.wso2.iot.agent.activities.SplashActivity".
The above will get your app to run correctly but now it has to authenticate itself to communicate to the server. When using NFC provisioning an Access Token is delivered in the Extra Bundle as 'android.app.extra.token', you can insert this extra in the launch intent as follows: adb shell am start -n "org.wso2.iot.agent/org.wso2.iot.agent.activities.SplashActivity" --es android.app.extra.token generated_access_token. You will have to edit the SpashActivity class to accept this token and follow the general authentication processes built into the app.
This may be a little bit late but I hope it is still helpful!
Some extra information you may appreciate, here is a string representation of the NFC message used, these are the specifications set in the NFC Provisioning App:
`
#Thu Apr 12 13:42:11 GMT+02:00 2018
android.app.extra.PROVISIONING_LOCAL_TIME=1523533331087
android.app.extra.PROVISIONING_TIME_ZONE=Asia/Colombo
android.app.extra.PROVISIONING_SKIP_ENCRYPTION=true
android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE=WPA
android.app.extra.PROVISIONING_WIFI_PASSWORD=PASSWORD
android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION=LOCATION_OF_APK
android.app.extra.PROVISIONING_WIFI_SSID="WIFI_SSID_NAME"
android.app.extra.PROVISIONING_LOCALE=en_US
android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM=E8PtiqUOcqKi5IXeRBF-5Br0zXg
android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE=\#admin extras bundle\n\#Thu Apr 12 13\:42\:11 GMT+02\:00 2018\nandroid.app.extra.token\=GENERATED_ACCESS_TOKEN\n
android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME=org.wso2.iot.agent
`
An example of a QR Code representation would be:
`
{
"android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME": "org.wso2.iot.agent/org.wso2.iot.agent.services.AgentDeviceAdminReceiver",
"android.app.extra.PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM": "CSGeivCEHdJrPT0qy4W67LZSy32Fus7GyUn0jE5o028",
"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION": "APK_DOWNLOAD_LOCATION",
"android.app.extra.PROVISIONING_SKIP_ENCRYPTION": false,
"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME": "org.wso2.iot.agent",
"android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE": {
"android.app.extra.token":"GENERATED_ACCESS_TOKEN"
}
}
`
Related
I need to execute a realm-cli command (disable or delete a user) from a mobile application that uses RealmDB, i didn't find any part of the docs that was related to do it.
I thought that i can use mongoClient but i didn't find any methods that allows me to execute raw cli commands.
I need to execute commands like:
realm-cli users disable --app=<Your App ID> --user=<User ID>
Font:
https://docs.mongodb.com/realm/users/delete-or-revoke/
Is there any other way ?
You may need to host the realm-cli and write a HTTP interface middleware to make these call.
I don't believe you can run the application on a mobile application as you would need access to spawning libraries. realm-cli is available open source so it would be possible to port the application to something like C++ (from golang) to make it executable for something like Android or iOS - but it may be cheaper to just buy a VPS somewhere (or even host it locally for a spell) and just pass the arguments to a web route.
I am trying to setup Unicenta POS on my Windows 10 64 bit machine.
My configuration:
Idempiere server v5.1 (http://127.0.0.1:8080/)
ActiveMQ v5.15.2
(http://127.0.0.1:8161/)
POS Integration plugin (Available
here)
I followed instructions given Here. ActiveMQ is running fine, Unicenta can also send request to ActiveMQ, I can see that in Queues. Idempiere server is also running fine.
I installed POS integration plugin through Felix Web Console. It shows up in the list and It is active. But, that plugin doesn't show up in Idempiere Menu option. Either that plugin has some problems or I am missing something.
I also performed Role Access Update on GardenWorld Client Admin but that didn't change anything. Menu option is still missing.
Please help.
The real issue was that 2Pack did not Pack in into the Database. I had install 2Pack manually and Pack In in my SystemAdmin. After that I logged out and logged in with SuperUser credentials and with GardenAdmin role. And then menu item appeared!
2Pack zip file location - Download
How to Pack In:
I have a windowed application and windowless helper, sitting inside the app bundle, and working as login item. App can start and stop the helper, everything woks there. The problem is that I need to create some bidirectional communication channel between them. And it should work in both sandboxed and not sandboxed versions, desirably in OS X 10.7+.
I've investigated the topic and find that XPC can provide peer-to-per connection. I've read related Apple docs, as well as few topics below:
Is possible to use Mac OS X XPC like IPC to exchange messages between processes? How?
Communicate with another app using XPC
http://afewguyscoding.com/2012/07/ipc-easy-introducing-xpc-nsxpcconnection/
https://www.objc.io/issues/14-mac/xpc/
But I can't find any description of how should I organize my XCode project. I have two targets: "Main App" and "Helper App". Now I need to add the third one, taking XPC Service, as a template. OK, but what to do next? Where this XPC bundle should be located to be available for both applications? Note, that helper sits in the main app bundle, as it's a login item. So, I need some clear instruction or just a XCode project sample.
Thanks,
Alex
Alright for anyone that has been struggling with this, I was finally able to 100% get communication working between two application processes, using NSXPCConnection
The key to note is that you can only create an NSXPCConnection to three things.
An XPCService. You can connect to an XPCService strictly through
a name
A Mach Service. You can also connect to a Mach Service
strictly through a name
An NSXPCEndpoint. This is what we're
looking for, to communicate between two application processes.
The problem being that we can't directly transfer an NSXPCEndpoint from one application to another.
It involved creating a machservice Launch Agent (See this example for how to do that) that held an NSXPCEndpoint property. One application can connect to the machservice, and set that property to it's own [NSXPCListener anonymousListener].endpoint
Then the other application can connect to the machservice, and ask for that endpoint.
Then using that endpoint, an NSXPCConnection can be created, which successfully established a bridge between the two applications. I have tested sending objects back and forth, and it all works as expected.
Note that if your application is sandboxed, you will have to create an XPCService, as a middle man between your Application and the Machservice
I'm pretty pumped that I got this working-- I'm fairly active in SO, so if anybody is interested in source code, just add a comment and I can go through the effort to post more details
Some hurdles I came across:
You have to launch your machservice, these are the lines:
OSStatus err;
AuthorizationExternalForm extForm;
err = AuthorizationCreate(NULL, NULL, 0, &self->_authRef);
if (err == errAuthorizationSuccess) {
NSLog(#"SUCCESS AUTHORIZING DAEMON");
}
assert(err == errAuthorizationSuccess);
Boolean success;
CFErrorRef error;
success = SMJobBless(
kSMDomainSystemLaunchd,
CFSTR("DAEMON IDENTIFIER HERE"),
self->_authRef,
&error
);
Also, every time you rebuild your daemon, you have to unload the previous launch agent, with these bash commands:
sudo launchctl unload /Library/LaunchDaemons/com.example.apple-samplecode.EBAS.HelperTool.plist
sudo rm /Library/LaunchDaemons/com.example.apple-samplecode.EBAS.HelperTool.plist
sudo rm /Library/PrivilegedHelperTools/com.example.apple-samplecode.EBAS.HelperTool
(With your corresponding identifiers, of course)
I am trying hard to follow the example of SimpleTunnel given by Apple.
I try to track how they make the customized call.
However I cannot link the relationship between the connect button action with starting a new tunnel.
I tried to track it with PacketTunnelProvider but without success.
I know they are override classes. I cannot find the point where the whole VPN connection starts.
My goal is to create a SSL VPN tunnel.
After asking Apple and a few trial and error, I can finally trigger the extension part.
Prerequisite: (Network Extension permission)
Add a new target -> Packet Tunnel Provider
Trigger the extension by
NEVPNConnection *conn = [manager connection];
NSError *connError;
[conn startVPNTunnelWithOptions:settingsDict andReturnError:&connError];
Debug with the following steps
(1) Build & run the app
(2) Stop the app
(3) Debug > attach to process by PID or name > Enter "PacketTunnel"
(4) Start the app from your iPhone screen and you can debug for the extension
Hope the small steps I experienced can help the others to start.
However, there are more upcoming questions and I need to check!
The sample application and Packet Tunnel provider runs as a separate process. sample application is called as container app and the packet tunnel provider runs as app extension. These two components uses IPC for communication.
In sample application whenever connect toggle button is enabled startVPNTunnel() API will be called and the OS starts the packet tunnel provider which in turn calls your overrided method startTunnelWithOptions(). So this is where you start your connection to the VPN server.
To answer your question link the connect action to a method that invokes startVPNTunnel() which in turn triggers packet tunnel provider. You cannot directly invoke start packet tunnel provider without the container application.
Same gets applied to stop your VPN tunnel
Hope this answer helps you
if you are asking about the connect / enable buttons inside the SimpleTunnel app, then startVPNTunnel() is the call used in startStopToggled() method of StatusViewController.swift file
if you are asking about how the extension handles vpn connection start (after configuration is done), then OS network system calls startTunnelWithOptions() in PacketTunnelProvider.swift depending on how the tunnel is configured. for eg: of on-demand is enabled for this tunnel, OS will try to setup/start the tunnel whenever there is network activity. if not, OS will try to start tunnel, when you go to Settings|VPN and try to switch ON the config. This is similar to the iOS8 personal vpn connection stuff.
I'm trying to run a process with elevated privileges - specifically OpenVPN, which requires root privileges to add routes to the system.
Looking around for existing examples around leads me to AuthorizationExecuteWithPrivileges, which seems to be now deprecated.
I tried the new SMJobBless method but I have a few questions regarding its viability for this purpose. As I understand it, I can create a separate privileged tool and communicate with it via sockets to ask the tool to perform privileged commands. However, I can't seem to figure out how I can start the OpenVPN process and capture its standard output in real time doing it this way as the main application would not be starting the process itself.
Another option is to use setuid on the OpenVPN executable. Could I possibly use the helper installed by SMJobBless to set the file permissions and setuid on the executable, then run it normally via NSTask?
Edit:
Lastly is there some way to just run one single command with privileges without having to install anything permanently? Although this new method is more secure, it seems very heavy handed.
I managed to go the SMJobBless method by using a helper and communicating it with XPC (the method shown on Nathan de Vries's Blog). Using this helper I set the permissions on the external process to 04555 (setuid, rx). Then the SMJob is removed as it is no longer required. Essentially emulating an "one-off" privileged job.
Following that I was able to use NSTask to start the process and capture its output in my main application.
Additionally I have a check at the start to see if the permissions are set right on the executable, if not the SMJob helper is re-blessed and permissions set.
If anyone has a cleaner solution, feel free to share. Thanks!
I had the same problem as you, needed it for a OpenVPN Manager App for MacOs X. Your solution is far from optimum because you open the openvpn binary for everyone setting setuid root.
This is a security hole and should be avoided, as it is totally unnecessary when you are using smjobbless helper. This helper runs as root and could do everything you want for you and with administrative privileges, so you can launch openvpn via this helper without setting setuid root on openvpn binary.
Apple designed this process as only your App, the Main App, can communicate with this helper as your Main App and your helper are signed with your developer certificates.
Any malicious App can't use this helper.
When you look at Nathans code you see, that he managed it to send messages to this helper and to get answers from this helper.
In his example there is sth like "Hey there Helper App" and the answer is "Hey there Host App".
So to get sth useful out of this you only have to send commands to the helper app, extract these commands on helper side and launch them with elevated privileges as the helper App runs with elevated privileges.
Look at Nathans code, there is sty like (in smjobblessappcontroller.m):
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
const char* request = "openvpn --config OpenvpnConnection.ovpn";
xpc_dictionary_set_string(message, "request", request);
[self appendLog:[NSString stringWithFormat:#"Sending request: %s", request]];
xpc_connection_send_message_with_reply(connection, message, dispatch_get_main_queue(), ^(xpc_object_t event) {
const char* response = xpc_dictionary_get_string(event, "reply");
[self appendLog:[NSString stringWithFormat:#"Received response: %s.", response]];
});
With this you send the openvpn command to your helper App. You only have to extract this command on helper side to launch the process with elevated privileges.
Look at smjobblesshelper.c and do sth like (in __XPC_Peer_Event_Handler else branch):
const char *response = xpc_dictionary_get_string(event, "request");
In string response you have your openvpn command, now simple launch it:
system(response);
Thats all, this goes with elevated privileges. Now you can use this in your App perhaps in an IBAction push button in your main app, to start openvpn connections as you want every time a user clicks this button.