Thread: [Pyobjc-dev] Wrapping SecKeychainFindInternetPassword (using Xcode3 and Pyobjc2)
Brought to you by:
ronaldoussoren
|
From: Michael M. <mic...@gm...> - 2007-12-12 20:12:24
|
Hi, I wrote a C extension module to use
SecKeychainFindInternetPassword, and I wanted to ask here if anyone
else wanted it, and if there was a better way to do the wrapping.
If there's a preferred technique that'll make it more general, I don't
mind putting that wrapper together for public use - especially if it's
automated :)
I didn't use the ObjC Keychain.framework because I really only needed
the one function, and this seemed like less work...
What I did was using the XCode 3 template, I simply added a C file to
munge the strings back and forth, and initialized it in main.m
To wit:
SecKeychainWrapperModule.c:
// include Python.h, Security/Security.h, and Core{Foundation, Services}.h
static PyObject *
SecKeychainWrapperModule_findPasword(PyObject *self __attribute__((unused)),
PyObject *args)
{ ...do some stuff to unwrap username, pass, and protocol, call
SecKeychainFindInternetPassword, then rewrap and return password
data...
}
static PyMethodDef SecKeychainWrapperModuleMethods[] = {
{"findPassword", SecKeychainWrapperModule_findPasword, METH_VARARGS,
"Find a password in the Keychain for a server/username/protocol tuple." },
{NULL, NULL, 0, NULL } /* Sentinel */
};
PyMODINIT_FUNC
initSecKeychainWrapperModule(void)
{
PyObject* mod = Py_InitModule3("SecKeychainWrapperModule",
SecKeychainWrapperModuleMethods,
"Wrapper for part of the
SecKeychain C API" );
if(mod == NULL) return;
}
Then in main.m I added this:
/* Init wrapper for SecKeychain functions */
initSecKeychainWrapperModule();
Just after Py_Initialize().
And that's it. This works pretty well for me, but if there's a better
way to wrap the whole of SecKeychain*, I'd be glad to do it for the
public good.
(Also, if there needs to be some docs on how to do that in the new
pyobjc2 world, I don't mind helping with them)
Thanks,
-mike
--
Michael McCracken
UCSD CSE PhD Candidate
research: http://www.cse.ucsd.edu/~mmccrack/
misc: http://michael-mccracken.net/wp/
|
|
From: James R E. <ea...@ba...> - 2007-12-12 23:07:57
|
On Dec 12, 2007, at 15:12 , Michael McCracken wrote: > Hi, I wrote a C extension module to use > SecKeychainFindInternetPassword, and I wanted to ask here if anyone > else wanted it, and if there was a better way to do the wrapping. > If there's a preferred technique that'll make it more general, I don't > mind putting that wrapper together for public use - especially if it's > automated :) Hi Mike :-) I found myself in a similar situation, but unlike you, I never contributed back to the community. Kudos to you! In my case, I found it much easier to write an ObjC wrapper around the C functions I needed and then use PyObjC to slurp them into Python. The code's really short, so I'll attach it to this email (just to demonstrate an alternative approach, if you care to pursue your project further). Cheers! James |
|
From: Ronald O. <ron...@ma...> - 2007-12-13 06:20:33
|
On 12 Dec, 2007, at 21:12, Michael McCracken wrote:
> Hi, I wrote a C extension module to use
> SecKeychainFindInternetPassword, and I wanted to ask here if anyone
> else wanted it, and if there was a better way to do the wrapping.
> If there's a preferred technique that'll make it more general, I don't
> mind putting that wrapper together for public use - especially if it's
> automated :)
Thanks for the offer :-)
>
>
> I didn't use the ObjC Keychain.framework because I really only needed
> the one function, and this seemed like less work...
>
> What I did was using the XCode 3 template, I simply added a C file to
> munge the strings back and forth, and initialized it in main.m
>
> To wit:
>
> SecKeychainWrapperModule.c:
> // include Python.h, Security/Security.h, and Core{Foundation,
> Services}.h
>
> static PyObject *
> SecKeychainWrapperModule_findPasword(PyObject *self
> __attribute__((unused)),
> PyObject *args)
> { ...do some stuff to unwrap username, pass, and protocol, call
> SecKeychainFindInternetPassword, then rewrap and return password
> data...
> }
>
> static PyMethodDef SecKeychainWrapperModuleMethods[] = {
> {"findPassword", SecKeychainWrapperModule_findPasword,
> METH_VARARGS,
> "Find a password in the Keychain for a server/username/protocol
> tuple." },
> {NULL, NULL, 0, NULL } /* Sentinel */
> };
>
> PyMODINIT_FUNC
> initSecKeychainWrapperModule(void)
> {
> PyObject* mod = Py_InitModule3("SecKeychainWrapperModule",
> SecKeychainWrapperModuleMethods,
> "Wrapper for part of the
> SecKeychain C API" );
> if(mod == NULL) return;
> }
>
> Then in main.m I added this:
> /* Init wrapper for SecKeychain functions */
> initSecKeychainWrapperModule();
>
> Just after Py_Initialize().
>
> And that's it. This works pretty well for me, but if there's a better
> way to wrap the whole of SecKeychain*, I'd be glad to do it for the
> public good.
>
> (Also, if there needs to be some docs on how to do that in the new
> pyobjc2 world, I don't mind helping with them)
This should be a lot easier in pyobjc2: it should be possible to wrap
most if not all of the security framework without writing a single
line of C code. You "just" have to generate an XML file that describes
the API and include that in a
small wrapper package.
The official way for generating said metadata is through
gen_bridge_metadata(1), a commandline tool on Leopard. An alternative
way is to use 'pyobjc-wrapper-gen', which will appear when you install
the pyobjc-metadata package from pyobjc's Subversion repository.
When you use the latter tool it will create the required python
packages, setup.py and metadata files for you. You will have to
examine and update the file Exceptions/Security.bridgesupport. This
contains a description of all metadata that might require manual
attention, see the BridgeSuppport(5) manualpage for information on the
format of that file. Then add unittests, examples and documentation to
taste.
I'm currently pyobjc-wrapper-gen to see how much output that generates
and how much work it would be to create a good wrapper.
Ronald
P.S. pyobjc-wrapper-gen takes rather a long amount of time due to
compiling and running loads and loads of small C programs.
|
|
From: Michael M. <mic...@gm...> - 2007-12-18 02:37:32
|
For the list archives, I'm going to sum up what Ronald and I discussed off-list after this email: 1. The pyobjc-wrapper-gen script is the right way to go to wrap the whole framework, but it currently doesn't quite work on Security.framework. 2. The pyobjc-wrapper-gen script requires an x86_64 machine to run on, so that it can get the correct values of header constants for all platforms, which involves running the probes natively and under Rosetta. 3. The script could get around this with a custom C/ObjC parser - potentially written using clang ( http://clang.llvm.org/ ) but there's little time to do that. It'd probably be a great project for a student looking to test their chops and add a resume item, though. Working on Security.framework may now be on Ronald's long to-do list, but since I've only got G4 systems, I'm not going to be able to help. So I'll stick with my single function wrapper, at least until I get my hands on a mac pro. (I'd accept donations :) Thanks, -mike On Dec 12, 2007 10:13 PM, Ronald Oussoren <ron...@ma...> wrote: > > On 12 Dec, 2007, at 21:12, Michael McCracken wrote: > > > Hi, I wrote a C extension module to use > > SecKeychainFindInternetPassword, and I wanted to ask here if anyone > > else wanted it, and if there was a better way to do the wrapping. > > If there's a preferred technique that'll make it more general, I don't > > mind putting that wrapper together for public use - especially if it's > > automated :) > > Thanks for the offer :-) > > > > > > > > I didn't use the ObjC Keychain.framework because I really only needed > > the one function, and this seemed like less work... > > > > What I did was using the XCode 3 template, I simply added a C file to > > munge the strings back and forth, and initialized it in main.m > > > > To wit: > > > > SecKeychainWrapperModule.c: > > // include Python.h, Security/Security.h, and Core{Foundation, > > Services}.h > > > > static PyObject * > > SecKeychainWrapperModule_findPasword(PyObject *self > > __attribute__((unused)), > > PyObject *args) > > { ...do some stuff to unwrap username, pass, and protocol, call > > SecKeychainFindInternetPassword, then rewrap and return password > > data... > > } > > > > static PyMethodDef SecKeychainWrapperModuleMethods[] = { > > {"findPassword", SecKeychainWrapperModule_findPasword, > > METH_VARARGS, > > "Find a password in the Keychain for a server/username/protocol > > tuple." }, > > {NULL, NULL, 0, NULL } /* Sentinel */ > > }; > > > > PyMODINIT_FUNC > > initSecKeychainWrapperModule(void) > > { > > PyObject* mod = Py_InitModule3("SecKeychainWrapperModule", > > SecKeychainWrapperModuleMethods, > > "Wrapper for part of the > > SecKeychain C API" ); > > if(mod == NULL) return; > > } > > > > Then in main.m I added this: > > /* Init wrapper for SecKeychain functions */ > > initSecKeychainWrapperModule(); > > > > Just after Py_Initialize(). > > > > And that's it. This works pretty well for me, but if there's a better > > way to wrap the whole of SecKeychain*, I'd be glad to do it for the > > public good. > > > > (Also, if there needs to be some docs on how to do that in the new > > pyobjc2 world, I don't mind helping with them) > > This should be a lot easier in pyobjc2: it should be possible to wrap > most if not all of the security framework without writing a single > line of C code. You "just" have to generate an XML file that describes > the API and include that in a > small wrapper package. > > The official way for generating said metadata is through > gen_bridge_metadata(1), a commandline tool on Leopard. An alternative > way is to use 'pyobjc-wrapper-gen', which will appear when you install > the pyobjc-metadata package from pyobjc's Subversion repository. > > When you use the latter tool it will create the required python > packages, setup.py and metadata files for you. You will have to > examine and update the file Exceptions/Security.bridgesupport. This > contains a description of all metadata that might require manual > attention, see the BridgeSuppport(5) manualpage for information on the > format of that file. Then add unittests, examples and documentation to > taste. > > I'm currently pyobjc-wrapper-gen to see how much output that generates > and how much work it would be to create a good wrapper. > > Ronald > > P.S. pyobjc-wrapper-gen takes rather a long amount of time due to > compiling and running loads and loads of small C programs. > -- Michael McCracken UCSD CSE PhD Candidate research: http://www.cse.ucsd.edu/~mmccrack/ misc: http://michael-mccracken.net/wp/ |