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

HelperTool Integration Steps #1

Open
AnujKPatel opened this issue Apr 4, 2015 · 18 comments
Open

HelperTool Integration Steps #1

AnujKPatel opened this issue Apr 4, 2015 · 18 comments

Comments

@AnujKPatel
Copy link

Hello,

I am new to GitHub so I hope that it is the right place to ask for help.

I am working on Mac OS application in which I have to create VPN Connection direct through my application and for that I have to store PASSWORD and SHAREDSECRETKEY in SYSTEM KEYCHAIN.

After lot of research I came to know about this sample code "EvanBetterAuthorizationExample”, I have gone throughout the code but didn't understand how I can implement this sample to my existing application.I have read the readme file but not much idea.

As I am new to this Network Programming can anyone please help me with proper integration steps?
Thanks in advance.

@brenwell
Copy link
Owner

Did you get it working?

If not maybe join this task #2 , someone else is having a problem, maybe they can help or, my helping them can help you

@AnujKPatel
Copy link
Author

Hello,

Thank you for writing back.

Yes, luckily I got it working up to 2 days ago.
But strange, it has started giving me CFErrorDomainLaunchd Code=4 error.
I did check the DevID and it is same when it was working.

Not able to trace the issue why it stop working all of sudden.

I am using this code

#pragma unused(sender)
Boolean success;
CFErrorRef error;

success = SMJobBless(
                     kSMDomainSystemLaunchd,
                     CFSTR("com.example.apple-samplecode.EBAS.HelperTool"),
                     self->_authRef,
                     &error
                     );

if (success) {
    [self logWithFormat:@"success\n"];
} else {
    [self logError:(__bridge NSError *) error];
    CFRelease(error);

}

But every time now it keeps giving me CFErrorDomainLaunchd Code=4 error.

@brenwell
Copy link
Owner

Are you using the provided python tool?

@AnujKPatel
Copy link
Author

I am following EvenBetterAuthorizationSample code provided by apple.

@brenwell
Copy link
Owner

But you are using this correct?

https://github.com/brenwell/EvenBetterAuthorizationSample/blob/master/SMJobBlessUtil.py

Its been a while, but I believe you have to use this to clean and create all the plists

@malavagile
Copy link

Is this tool create all plist file for us so we do not need to create any plist file, right?
We need only 1 plist file which is created by default with every new project.
Please correct me if I am wrong as I had tried so many example and all have some different ways to implement this that's why I am confuse which is the correct way to install helper tool.

@brenwell
Copy link
Owner

I will close this and discuss it on #2 since you both have the same problem, (maybe)

@brenwell
Copy link
Owner

@malavagile, @AnujKPatel

The script helps you build the correct plists. I am gonna go to lunch. When I get back I will try and remember how it is done from my working sample and will write a small how to.

@malavagile
Copy link

Thanks for the help @brenwell
Finally we are now able to install the helper tool.
But next issue is when i call the Helper tool method as block it does not return to block.
Do you have and idea what can be issue?
I am getting this error : NSCocoaErrorDomain Code=4097 "Couldn’t communicate with a helper application." (connection to service named com.example.apple-samplecode.EBAS.HelperTool) UserInfo=0x600001064d00 {NSDebugDescription=connection to service named com.example.apple-samplecode.EBAS.HelperTool}

@brenwell
Copy link
Owner

I assume this is the correct identifier for your tool?
com.example.apple-samplecode.EBAS.HelperTool

It should appear in your XPCService Info.plist. Mine is com.blackwellapps.BrokerHelper

indentifier

@malavagile
Copy link

I have the same identifier as you said in XPCService Info.plist.
My app does not have sandbox as target does that affect?

@brenwell
Copy link
Owner

In capabilities my sandbox stuff is all disabled. I had the intention of sandboxing it. But I have since stopped work on the project. I don't see why it would be an issue though whether its on or off.

can you show me the snippet of the code you are using to communicate with the helper tool?

@malavagile
Copy link

here is the code

[self connectAndExecuteCommandBlock:^(NSError * connectError) {
        if (connectError != nil) {
            [self logError:connectError];
        } else {
            [[self.helperToolConnection remoteObjectProxyWithErrorHandler:^(NSError * proxyError) {
                [self logError:proxyError];
                [self callAlert:proxyError.localizedDescription andDelegate:nil withAlertTitle:@""];
            }] writeLicenseKey:licenseKey authorization:self.authorization withReply:^(NSError *error) {
              #pragma unused(licenseKey)
                if (error != nil) {
                    [self callAlert:@"Helper Tool Connection Error" andDelegate:nil withAlertTitle:@""];
                } else {
                    [self logWithFormat:@"success\n"];

@brenwell
Copy link
Owner

Alright I decided to share my HelperManager.m this file is used in my main app to wrap all communication with my helper app.

https://gist.github.com/brenwell/03fad0a7f79dee564ea1

I have add 3 methods to the HelperTool.h, as I was trying to achieve something different

https://github.com/brenwell/EvenBetterAuthorizationSample/blob/master/HelperTool/HelperTool.h

HelperTool.h

- (void)toggleProxyWithReply:(void(^)(BOOL enabled, BOOL success))reply;
- (void)turnOnProxyWithReply:(void(^)(BOOL success))reply;
- (void)turnOffProxyWithReply:(void(^)(BOOL success))reply;

HelperTool.m

- (void)toggleProxyWithReply:(void(^)(BOOL enabled, BOOL success))reply
{
    BOOL setProxyResult = YES;

    if(_proxyEnabled)
    {
        setProxyResult = [self setGlobalProxyHost:ProxyHost port:ProxyPort enable:NO];

        if (setProxyResult) {
            _proxyEnabled = NO;
        }

    }
    else
    {
        setProxyResult = [self setGlobalProxyHost:ProxyHost port:ProxyPort enable:YES];

        if (setProxyResult) {
            _proxyEnabled = YES;
        }
    }

    if (setProxyResult) {
        reply(_proxyEnabled,YES);
    }else{
        reply(_proxyEnabled,NO);
    }
}

////////////////////////////////////////////////////////////////

- (void)turnOnProxyWithReply:(void(^)(BOOL success))reply
{
    BOOL setProxyResult = [self setGlobalProxyHost:ProxyHost port:ProxyPort enable:YES];

    if (setProxyResult) {
        _proxyEnabled = YES;
        reply(YES);
    }else{
        reply(NO);
    }
}

////////////////////////////////////////////////////////////////


- (void)turnOffProxyWithReply:(void(^)(BOOL success))reply
{
    BOOL setProxyResult = [self setGlobalProxyHost:ProxyHost port:ProxyPort enable:NO];

    if (setProxyResult) {
        _proxyEnabled = NO;
        reply(YES);
    }else{
        reply(NO);
    }
}

@brenwell
Copy link
Owner

Does this look right to you guys?

HelperTool + XPCService Project Setup

In this example the 3 identifiers for the 3 targets are

Name Identifier
Broker (Main app) com.blackwellapps.Broker
BrokerHelper (HelperTool) com.blackwellapps.BrokerHelper
XPCService com.blackwellapps.XPCService

1 Add Copy File build phase

Main App
Add Copy File build phase to main app target:
Destination: Wrapper
Subpath: Contents/LibraryXPCServices,
Codesign on Copy:Disable.

screen shot 2015-04-17 at 15 35 48

XPCService
Add Copy File build phase to XPCService target:
Destination: Wrapper
Subpath: Contents/Library/LaunchServices,
Codesign on Copy:Disable.

screen shot 2015-04-17 at 15 37 12


2 Modify Info.plists

XPCService-Info.plist (Tools owned after installation)

Add a new key value pair to the XPCService's Info.plist

  • Key: "Tools owned after installation"
  • Type: dictionary

Inside this new dictionary add a another key value pair:

  • Key: Your helper's bundle identifier
  • Type: string
  • Value: "anchor apple generic and certificate leaf[subject.CN] = Certificate Name and certificate 1[field.1.2.840.113635.100.6.2.1] / exists /"

screen shot 2015-04-17 at 15 55 47

HelperTool-Info.plist (Clients allowed to add and remove tool)

Add a new key value pair the HelperTools's Info.plist

  • Key: "Clients allowed to add and remove tool"
  • Type: array

As this is an array, we will add a new item to the 0 index:

  • Key/Position: "Item 0"
  • Type: string
  • Value: "identifier XPCService identifier and anchor apple generic and certificate leaf[subject.CN] = Certificate Name and certificate 1[field.1.2.840.113635.100.6.2.1] / exists /"

screen shot 2015-04-17 at 15 38 38


3 Developer ID

Choose Developer ID:* in Code Signing Identity in build settings for each targets.

Main App

screen shot 2015-04-17 at 15 46 53

XPCService

screen shot 2015-04-17 at 15 46 45

HelperTool

screen shot 2015-04-17 at 15 46 59


4 Build

Build the app.


5 SMJobBlessUtil.py

Use SMJobBlessUtil.py cli script

Update Info.plist:

Format: $ ./SMJobBlessUtil.py setreq <XPCService path> <XPCService's Info.plist path> <Helper's Info.plist>

./SMJobBlessUtil.py setreq Build/Products/Debug/com.blackwellapps.XPCService.xpc XPCService/XPCService-Info.plist BrokerHelper/HelperTool-Info.plist HelperTool/HelperTool-Info.plist

Check Code Signing status:

Format: $ ./SMJobBlessUtil.py check <XPCservice path>

./SMJobBlessUtil.py check Build/Products/Debug/com.blackwellapps.XPCService.xpc

Troubleshooting

  • If it doesn't pass the CLI check then make sure error NSPOSIXErrorDomain / 25 #3 is correct
  • Also Make sure each .plist file is set as Info.plist in the corresponding Target's Build settings.

Credit

Got some of this from this gist https://gist.github.com/xiao99xiao/0509091001bdd6259249

@malavagile
Copy link

Thanks for your help Yesterday.
Your steps are perfect to implement.
Now it's working here.
Just a small issue I found here is when I create entry in network first time and start VPN connection in application it's say connecting and then state change to connected but actually it doesn't but when I try to again start connection it will start working and VPN Actually connected.
Do you have any idea regarding this?

@malavagile
Copy link

Can you tell me what is your target dependency for all the target for your application?

@malavagile
Copy link

Can you tell me how did you add new methods in helper tool as i tried to add new method but it always returns : CocoaDomainError 4097 "Couldn’t communicate with a helper application mac application"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants