Question

I'm still a little new to the bridge , I'm playing around with the new shadow hash on Lion (Mac OS 10.7) and ran into a snag. The script snippet below, when run as root shows me the nested shadow hash as a dictionary, but I want to use this NSData as a string later in the script. I should be able to convert it using the NSString method, but I am getting a Type error, which I think is related to the bridge rather then my code.

#!/usr/bin/python
from Cocoa import NSData,NSDictionary,NSPropertyListSerialization,NSString
from Cocoa import NSUTF8StringEncoding,NSPropertyListImmutable
user = 'foobarbaz'
path = '/var/db/dslocal/nodes/Default/users/%s.plist' % user
# Read the binary plist
plist = NSDictionary.dictionaryWithContentsOfFile_(path)
# Grab the ShadowHashData key
dataShadowHashData = plist['ShadowHashData'][0]
# Convert to dictionary
convertDataToPlist = NSPropertyListSerialization.propertyListWithData_options_format_error_(dataShadowHashData,NSPropertyListImmutable,None,None)

ShadowHashData = convertDataToPlist[0]
print ShadowHashData
for key in ShadowHashData.keys():
  value = NSString.initWithData_encoding_(ShadowHashData[key],NSUTF8StringEncoding)
  print type(value)
  print '%s = %s' % (key,value)

I'm calling the method initWithData for NSString which should convert my NSdata into a NSUTF8StringEncoding string. However I am getting a type error:

Traceback (most recent call last):
  File "./makehash.py", line 16, in <module>
    value = NSString.initWithData_encoding_(ShadowHashData[key],NSUTF8StringEncoding)
TypeError: Expecting instance of NSString as self, got one of __NSCFData

I looked around but as this is a pretty rare occurrence to be using NSData classes in python I could not find what this error means. The syntax looks right to me. Anyone see any obvious issues here?

You can probably tell from the error but incase its not obvious

print type(ShadowHashData[key])

will show you:

<objective-c class __NSCFData at 0x7fff7ef54cc8>

Also , just to let you know, I tried:

value = NSString.alloc().initWithData_encoding_(ShadowHashData[key],NSUTF8StringEncoding)

but that returned None

Thanks for the help

You can find the class documentation for this method here

Here is what the output of print ShadowHashData

Looks like for an example user

{
    "CRAM-MD5" = <f0a37234 5839f75e a9d98039 32e6124f 64e0e85a 31577d43 79d2415a 6d96f381>;
    NT = <52735ecd 048506c2 60b3ed2a 4ba2c4c2>;
    RECOVERABLE = <a3a037d2 0fce0cdb fb4f8158 6da43e0a 65e239cf 7d2216b0 7efdf8d2 1598fa8e ea4eaf00 c7a1a7be 7970cdf9 67102b15 926d1e48 c556cc12 a9285ea5 b31eda0c 4df2c9e4 af50c357 d2c3db46 093ed81d 817172a8 2d7278b7 3f760246 3b440d5a 2a812b5a 81b16db5 f1f4bdb9 c6232145 03e78548 d9c1f092 a7b64ee7 00b3d38d 14f0f6d3 1e2877a8 f06560e1 e184a051 77e7a9be 215cbfa7 6441194f 19982c2b f6afabc1 94cb1cb5 ba1a3e2f 8db170b5 9902d1ec bea60296 a461662f 3599eb8f b91e7905 3279e50d 9616e337 a5d01108 e0d4ec2b d5d8d539 f6780f63 9d298f02 9e57fb8b 330b12f8 ea796ae4 79006215 37b0221e 50f82a55 e202ccb6 e5e2989f 84334041 6fd3bd39 52adc7c9 856a38a0 549662f2 a51aaca6 a1c310ba ac3a0a70 56f3e34d 9fe7063b c3db765b 68a056ac 5a74a8c1 b988854c d647143e 685f470e a76ea2c4 4bf8d952 c8b1c584 a6a7a1c9 ae14ba0c d8038640 a6251836 a5f87ac7 aad7b41f 554fb452 74930645 0e781738 58c36eff ab5c7c6b 0716d951 5467681f e53fe494 67df923d 0cf39d57 36843350 e670c960 bc3ee5b1 d70b37dd 38afca2b c320b136 645122e1 3800c053 9cb927c4 b1ebba4b 23af2544 a86acebc 3927e12a 84e63104 1870a5f7 110fe408 48469da5 fbbdb5e7 fae08d29 07d474de 98088ebe cb845a8e 9679ffc4 db333c6b f8c29fdf aafab45b 7bf8678d b2aa8724 abdb824d>;
    "SALTED-SHA512" = <3aef7ed2 355e259f cdb153ed 4f1c1d63 abff9438 7783dcc2 b282d620 91f247b7 835931e0 e331b5dc 3b46bdb5 f39f37d8 5ba0bfcc 521a0232 85a7e732 5eb362db acdc593d>;
}
Was it helpful?

Solution

This is correct if ShadowHashData[key] is a UTF-8-encoded string:

value = NSString.alloc().initWithData_encoding_(ShadowHashData[key],NSUTF8StringEncoding)

But it returns None if ShadowHashData[key] is not. And none of the values of ShadowHashData is a UTF-8-encoded string. All of them are just arbitrary binary data.

If you just want a hex dump of the data, perhaps this will suffice:

In [1]: from Cocoa import *

In [2]: data = NSData.dataWithBytes_length_('hello', 5) 

In [3]: import binascii

In [4]: binascii.hexlify(data)
Out[4]: '68656c6c6f'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top