tell application "Suspicious Package"
set binaryBundles to (find bundles under installed items of theDocument whose name extension is "app" or name extension is "xpc")
if (count of binaryBundles) is not 0 then
set theReport to my makeReport("Entitlement Report for " & (get name of theDocument))
repeat with binaryBundle in binaryBundles
set mainExecFolder to installed item "Contents/MacOS" of binaryBundle
if exists mainExecFolder then
repeat with anExec in installed items of mainExecFolder
try
set entitlementSummary to my entitlementsForExecutable(anExec)
set entitlementStatus to "black"
on error e number n
set entitlementSummary to ("Error: " & e)
set entitlementStatus to "red"
end try
my addToReport(theReport, POSIX path of anExec, entitlementSummary, entitlementStatus)
end repeat
end if
end repeat
tell application "TextEdit" to activate
else
display dialog "Didn't find any app or XPC executables in package"
end if
end tell
on entitlementsForExecutable(execItem)
set tmpPath to POSIX path of (path to temporary items)
set exportPath to tmpPath & "/" & (name of execItem)
set blobPath to tmpPath & "/entitlements.blob"
set plistPath to tmpPath & "/entitlements.plist"
tell application "System Events"
try
delete file exportPath
end try
try
delete file blobPath
end try
end tell
tell application "Suspicious Package"
with timeout of 3000 seconds
export execItem to POSIX file exportPath
end timeout
end tell
do shell script "/usr/bin/codesign --display --entitlements=" & quoted form of blobPath & " " & quoted form of exportPath
tell application "System Events"
set blobInfo to (get properties of file blobPath)
if size of blobInfo is 0 then
error "No entitlements found (not sandboxed)"
end if
end tell
do shell script "/bin/dd if=" & quoted form of blobPath & " of=" & quoted form of plistPath & " bs=1 skip=8"
return (do shell script "/usr/bin/defaults read " & quoted form of plistPath)
end entitlementsForExecutable
on makeReport(title)
tell application "TextEdit"
set r to (make new document at front of documents)
tell r
make new paragraph at end of paragraphs with data title with properties {font:"Helvetica Neue Bold", size:18}
make new paragraph at end of paragraphs with data return & return
end tell
end tell
return r
end makeReport
on addToReport(r, p, summary, status)
tell r
make new paragraph at end of paragraphs with data p with properties {font:"Menlo Bold", size:14}
make new paragraph at end of paragraphs with data return & return
make new paragraph at end of paragraphs with data summary with properties {font:"Menlo Regular", size:12, color:status}
make new paragraph at end of paragraphs with data return & return & return
end tell
end addToReport
var binaryBundles = SuspiciousPackage.find( 'bundles',
{
under: theDocument.installedItems.whose( {
_or:
[
{ nameExtension: 'app' },
{ nameExtension: 'xpc' },
]
} )
} );
if ( binaryBundles.length != 0 )
{
var TextEdit = Application( 'TextEdit' );
var theReport = makeReport( "Entitlement Report for " + theDocument.name() );
for ( var i = 0 ; i < binaryBundles.length ; ++i )
{
var binaryBundle = binaryBundles[ i ];
var mainExecFolder = binaryBundle.installedItems.byName( 'Contents/MacOS' );
if ( mainExecFolder() )
{
var mainExecs = mainExecFolder.installedItems;
for ( var j = 0 ; j < mainExecs.length ; ++j )
{
var anExec = mainExecs[ j ];
var entitlementSummary;
var entitlementStatus;
try
{
entitlementSummary = entitlementsForExecutable( anExec );
entitlementStatus = 'black';
}
catch ( e )
{
entitlementSummary = 'Error: ' + e.toString();
entitlementStatus = 'red';
}
addToReport( theReport, anExec.posixPath(), entitlementSummary, entitlementStatus );
}
}
}
TextEdit.activate();
}
else
{
Standard.displayDialog( "Didn't find any app or XPC executables in package" );
}
"installed item"
function entitlementsForExecutable( execItem )
{
var tmpPath = Standard.pathTo( 'temporary items' );
var exportPath = Path( tmpPath + '/' + execItem.name() );
var blobPath = Path( tmpPath + '/entitlements.blob' );
var plistPath = Path( tmpPath + '/entitlements.plist' );
$.NSFileManager.defaultManager.removeItemAtPathError( exportPath.toString(), undefined );
$.NSFileManager.defaultManager.removeItemAtPathError( blobPath.toString(), undefined );
SuspiciousPackage.export( execItem, { to: exportPath }, { timeout: 3000 } );
't* overwrite an existing file at blobPath (it won'
Standard.doShellScript( '/usr/bin/codesign --display --entitlements="' + blobPath + '" "' + exportPath + '"' );
if ( $.NSFileManager.defaultManager.attributesOfItemAtPathError( blobPath.toString(), undefined ).fileSize == 0 )
throw new Error( "No entitlements found (not sandboxed)" );
Standard.doShellScript( '/bin/dd if="' + blobPath + '" of="' + plistPath + '" bs=1 skip=8' );
return Standard.doShellScript( '/usr/bin/defaults read "' + plistPath + '"' );
}
function makeReport( title )
{
var r = TextEdit.Document().make();
var p = TextEdit.Paragraph( { font: 'Helvetica Neue Bold', size: 18 }, title );
r.paragraphs.push( p );
var p = TextEdit.Paragraph( {}, "\r\r" );
r.paragraphs.push( p );
return r;
}
function addToReport( r, p, summary, stat )
{
var p = TextEdit.Paragraph( { font: 'Menlo Bold', size: 14 }, p );
r.paragraphs.push( p );
var p = TextEdit.Paragraph( {}, "\r\r" );
r.paragraphs.push( p );
var p = TextEdit.Paragraph( { font: 'Menlo Regular', size: 12, color: stat }, summary );
r.paragraphs.push( p );
var p = TextEdit.Paragraph( {}, "\r\r\r" );
r.paragraphs.push( p );
}