summaryrefslogtreecommitdiff
path: root/solenv/bin/macosx-codesign-app-bundle
blob: db2f6ffc55d28ce6cba8b3b4eddc965bb6e7df26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/bin/bash

# Exit on errors
set -e
# Use of unset variable is an error
set -u
# If any part of a pipeline of commands fails, the whole pipeline fails
set -o pipefail

# Script to sign executables, dylibs and frameworks in an app bundle plus the bundle itself. Called
# from installer::simplepackage::create_package() in solenv/bin/modules/installer/simplepackage.pm
# and the test-install target in Makefile.in.

test `uname` = Darwin || { echo This is for macOS only; exit 1; }

test $# = 1 || { echo Usage: $0 app-bundle; exit 1; }

for V in \
    BUILDDIR \
    MACOSX_BUNDLE_IDENTIFIER \
    MACOSX_CODESIGNING_IDENTITY; do
    if test -z "$(eval echo '$'$V)"; then
       echo No '$'$V "environment variable! This should be run in a build only"
       exit 1
    fi
done

APP_BUNDLE="$1"
entitlements=
if test -n "$ENABLE_MACOSX_SANDBOX"; then
    # In a sandboxed build executables need the entitlements
    entitlements="--entitlements $BUILDDIR/lo.xcent"
    # We use --enable-canonical-installation-tree-structure so all
    # data files in Resources are included in the app bundle signature
    # through that. I think.
    other_files=''
else
    # We then want to sign data files, too, hmm.
    entitlements="--entitlements $SRCDIR/hardened_runtime.xcent"
    other_files="\
 -or -name '*.fodt' -or -name 'schema.strings' -or -name 'schema.xml' \
 -or -name '*.jar' -or -name 'LICENSE' -or -name 'LICENSE.html' \
 -or -name '*.applescript' -or -name '*.odt'"
fi

# Sign jnilibs first as workaround for signing issue on old baseline
# order matters/screws things up otherwise
find -d "$APP_BUNDLE" \( -name '*.jnilib' \) ! -type l |
    while read file; do
    id=`echo ${file#${APP_BUNDLE}/Contents/} | sed -e 's,/,.,g'`
    codesign --verbose --force --identifier=$MACOSX_BUNDLE_IDENTIFIER.$id --sign "$MACOSX_CODESIGNING_IDENTITY" "$file" > "/tmp/codesign_$(basename "$file").log" 2>&1
    if [ "$?" != "0" ] ; then
	exit 1
    fi
    rm "/tmp/codesign_$(basename "$file").log"
done

# Sign dylibs
#
# The dylibs in the Python framework are called *.so. Go figure
#
# On Mavericks also would like to have data files signed...
# add some where it makes sense. Make a depth-first search to sign the contents
# of e.g. the spotlight plugin before attempting to sign the plugin itself

find "$APP_BUNDLE" \( -name '*.dylib' -or -name '*.dylib.*' -or -name '*.so' \
        $other_files \) ! -type l |
while read file; do
    id=`echo ${file#${APP_BUNDLE}/Contents/} | sed -e 's,/,.,g'`
    codesign --verbose --force --identifier=$MACOSX_BUNDLE_IDENTIFIER.$id --sign "$MACOSX_CODESIGNING_IDENTITY" "$file" > "/tmp/codesign_$(basename "$file").log" 2>&1
    if [ "$?" != "0" ] ; then
	exit 1
    fi
    rm "/tmp/codesign_$(basename "$file").log"
done

# Sign included bundles. First .app ones (i.e. the Python.app inside
# the LibreOfficePython.framework. Be generic for kicks...)

find "$APP_BUNDLE"/Contents -name '*.app' -type d |
while read app; do
    fn=`basename "$app"`
    fn=${fn%.*}
    # Assume the app has a XML (and not binary) Info.plist
    id=`grep -A 1 '<key>CFBundleIdentifier</key>' $app/Contents/Info.plist | tail -1 | sed -e 's,.*<string>,,' -e 's,</string>.*,,'`
    codesign --verbose --options=runtime --force --identifier=$id --sign "$MACOSX_CODESIGNING_IDENTITY" $entitlements "$app" > "/tmp/codesign_${fn}.log" 2>&1
    if [ "$?" != "0" ] ; then
	exit 1
    fi
    rm "/tmp/codesign_${fn}.log"
done

# Then .framework ones. Again, be generic just for kicks.

find "$APP_BUNDLE" -name '*.framework' -type d |
while read framework; do
    fn=`basename "$framework"`
    fn=${fn%.*}
    for version in "$framework"/Versions/*; do
        if test ! -L "$version" -a -d "$version"; then
	    # Assume the framework has a XML (and not binary) Info.plist
	    id=`grep -A 1 '<key>CFBundleIdentifier</key>' $version/Resources/Info.plist | tail -1 | sed -e 's,.*<string>,,' -e 's,</string>.*,,'`
            # files in bin are not covered by signing the framework...
            for scriptorexecutable in $(find $version/bin/ -type f); do
                codesign --verbose --options=runtime --force --identifier=$id --sign "$MACOSX_CODESIGNING_IDENTITY" "$scriptorexecutable" >> "/tmp/codesign_${fn}.log" 2>&1
            done
            codesign --verbose --force --identifier=$id --sign "$MACOSX_CODESIGNING_IDENTITY" "$version" >> "/tmp/codesign_${fn}.log" 2>&1
	    if [ "$?" != "0" ] ; then
		exit 1
	    fi
	    rm "/tmp/codesign_${fn}.log"
	fi
    done
done

# Then mdimporters

find "$APP_BUNDLE" -name '*.mdimporter' -type d |
while read bundle; do
    codesign --verbose --force --prefix=$MACOSX_BUNDLE_IDENTIFIER. --sign "$MACOSX_CODESIGNING_IDENTITY" "$bundle" > "/tmp/codesign_$(basename "${bundle}").log" 2>&1
    if [ "$?" != "0" ] ; then
	exit 1
    fi
    rm "/tmp/codesign_$(basename "${bundle}").log"
done

# Sign executables

find "$APP_BUNDLE/Contents/MacOS" -type f |
while read file; do
    case "$file" in
	*/soffice)
	    ;;
	*)
	    id=`echo ${file#${APP_BUNDLE}/Contents/} | sed -e 's,/,.,g'`
	    codesign --force --verbose --options=runtime --identifier=$MACOSX_BUNDLE_IDENTIFIER.$id --sign "$MACOSX_CODESIGNING_IDENTITY" $entitlements "$file"  > "/tmp/codesign_${MACOSX_BUNDLE_IDENTIFIER}.${id}.log" 2>&1
	    if [ "$?" != "0" ] ; then
		exit 1
	    fi
	    rm "/tmp/codesign_${MACOSX_BUNDLE_IDENTIFIER}.${id}.log"
	    ;;
    esac
done

# Sign the app bundle as a whole which means (re-)signing the
# CFBundleExecutable from Info.plist, i.e. soffice, plus the contents
# of the Resources tree (which unless you used
# --enable-canonical-installation-tree-structure is not much, far from
# all of our non-code "resources").
#
# At this stage we also attach the entitlements in the sandboxing case
#
# Also omit some files from the Bundle's seal via the resource-rules
# (bootstraprc and similar that the user might adjust and image files)
# See also https://developer.apple.com/library/mac/technotes/tn2206/

id=`echo ${PRODUCTNAME} | tr ' ' '-'`

codesign --force --verbose --options=runtime --identifier="${MACOSX_BUNDLE_IDENTIFIER}" --sign "$MACOSX_CODESIGNING_IDENTITY" $entitlements "$APP_BUNDLE" > "/tmp/codesign_${MACOSX_BUNDLE_IDENTIFIER}.log" 2>&1
if [ "$?" != "0" ] ; then
    exit 1
fi
rm "/tmp/codesign_${MACOSX_BUNDLE_IDENTIFIER}.log"
exit 0