chiark / gitweb /
devscripts (2.10.69+squeeze4) stable-security; urgency=high
[devscripts.git] / scripts / debrsign.sh
1 #! /bin/bash
2
3 # This program is used to REMOTELY sign a .dsc and .changes file
4 # pair in the form needed for a legal Debian upload.  It is based on
5 # dpkg-buildpackage and debsign (which is also part of the devscripts
6 # package).
7 #
8 # In order for this program to work, debsign must be installed
9 # on the REMOTE machine which will be used to sign your package.
10 # You should run this program from within the package directory on
11 # the build machine.
12 #
13 # Usage: debrsign [options] [user@]remotehost [changes or dsc file]
14 # You may also provide the following options, which will be passed
15 # on to signchanges:
16 #  -m<maintainer>  Sign using key of <maintainer>
17 #  -k<key>     The PGP/GPG key ID to use; overrides -m
18 #  -p<type>    <type> is either pgp or gpg to specify which to use
19 #  -spgp,-sgpg The program takes arguments like pgp or gpg respectively
20 #  -S          Source-only .changes file
21 #  -a<arch>    Debian architecture
22 #  -t<type>    GNU machine type
23 #  --multi     Search for multiarch .changes files
24 #  --help, --version
25
26 # Debian GNU/Linux debrsign.
27 # Copyright 1999 Mike Goldman, all rights reserved
28 # Modifications copyright 1999 Julian Gilbey <jdg@debian.org>,
29 # all rights reserved.
30 #
31 # This program is free software; you can redistribute it and/or modify
32 # it under the terms of the GNU General Public License as published by
33 # the Free Software Foundation; either version 2 of the License, or
34 # (at your option) any later version.
35 #
36 # This program is distributed in the hope that it will be useful,
37 # but WITHOUT ANY WARRANTY; without even the implied warranty of
38 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
39 # GNU General Public License for more details.
40 #
41 # You should have received a copy of the GNU General Public License
42 # along with this program. If not, see <http://www.gnu.org/licenses/>.
43
44 # Abort if anything goes wrong
45 set -e
46
47 PROGNAME=`basename $0`
48
49 usage () {
50     echo \
51 "Usage: debrsign [options] [username@]remotehost [changes or dsc]
52   Options:
53     -sgpg, -spgp    Sign takes options like GPG, PGP respectively
54     -pgpg, -ppgp    Sign using GPG, PGP respectively
55     -e<maintainer>  Sign using key of <maintainer> (takes precedence over -m)
56     -m<maintainer>  The same as -e
57     -k<keyid>       The key to use for signing
58     -S              Use changes file made for source-only upload
59     -a<arch>        Use changes file made for Debian target architecture <arch>
60     -t<target>      Use changes file made for GNU target architecture <target>
61     --multi         Use most recent multiarch .changes file found
62     --path          Specify directory GPG/PGP binary is located on remote host
63     --help          Show this message
64     --version       Show version and copyright information
65   If a changes or dscfile is specified, it is signed, otherwise
66   debian/changelog is parsed to find the changes file.  The signing
67   is performed on remotehost using ssh and debsign."
68 }
69
70 version () {
71     echo \
72 "This is debrsign, from the Debian devscripts package, version ###VERSION###
73 This code is copyright 1999 by Mike Goldman and Julian Gilbey,
74 all rights reserved.  This program comes with ABSOLUTELY NO WARRANTY.
75 You are free to redistribute this code under the terms of the
76 GNU General Public License, version 2 or later."
77 }
78
79 mustsetvar () {
80     if [ "x$2" = x ]
81     then
82         echo >&2 "$PROGNAME: unable to determine $3"
83         exit 1
84     else
85         # echo "$PROGNAME: $3 is $2"
86         eval "$1=\"\$2\""
87     fi
88 }
89
90 withecho () {
91     echo " $@"
92     "$@"
93 }
94
95 # --- main script
96
97 # For partial security, even though we know it doesn't work :(
98 # I guess maintainers will have to be careful, and there's no way around
99 # this in a shell script.
100 unset IFS
101 PATH=/usr/local/bin:/usr/bin:/bin
102 umask `perl -e 'printf "%03o\n", umask | 022'`
103
104 eval $(
105     set +e
106     for var in $VARS; do
107         eval "$var=\$DEFAULT_$var"
108     done
109     for file in /etc/devscripts.conf ~/.devscripts; do
110       [ -r $file ] && . $file
111     done
112
113     set | egrep '^DEBRSIGN_')
114
115 signargs=
116 while [ $# != 0 ]
117 do
118     value="`echo x\"$1\" | sed -e 's/^x-.//'`"
119     case "$1" in
120         -S)     sourceonly="true" ;;
121         -a*)    targetarch="$value" ;;
122         -t*)    targetgnusystem="$value" ;;
123         --multi) multiarch="true" ;;
124         --help) usage; exit 0 ;;
125         --version)
126                 version; exit 0 ;;
127         --path) DEBRSIGN_PGP_PATH="$value" ;;
128         -*)     signargs="$signargs '$1'" ;;
129         *)      break ;;
130     esac
131     shift
132 done
133
134 # Command line parameters are remote host (mandatory) and changes file
135 # name (optional).  If there is no changes file name, we must be at the
136 # top level of a source tree and will figure out its name from
137 # debian/changelog
138 case $# in
139     2)  remotehost="$1"
140         case "$2" in
141             *.dsc)
142                 changes=
143                 dsc=$2
144                 ;;
145             *.changes)
146                 changes=$2
147                 dsc=`echo $changes | \
148                     perl -pe 's/\.changes$/.dsc/; s/(.*)_(.*)_(.*)\.dsc/\1_\2.dsc/'`
149                 ;;
150             *)  echo "$PROGNAME: Only a .changes or .dsc file is allowed as second argument!" >&2
151                 exit 1 ;;
152         esac
153         ;;
154
155     1)  remotehost="$1"
156         case "$1" in
157         *.changes)
158                 echo "$PROGNAME: You must pass the address of the signing host as as the first argument" >&2
159                 exit 1
160         ;;
161         *)
162                 # We have to parse debian/changelog to find the current version
163                 if [ ! -r debian/changelog ]; then
164                         echo "$PROGNAME: Must be run from top of source dir or a .changes file given as arg" >&2
165                         exit 1
166                 fi
167         ;;
168         esac
169         
170
171         mustsetvar package "`dpkg-parsechangelog | sed -n 's/^Source: //p'`" \
172             "source package"
173         mustsetvar version "`dpkg-parsechangelog | sed -n 's/^Version: //p'`" \
174             "source version"
175
176         if [ "x$sourceonly" = x ]
177         then
178             mustsetvar arch "`dpkg-architecture -a${targetarch} -t${targetgnusystem} -qDEB_HOST_ARCH`" "build architecture"
179         else
180             arch=source
181         fi
182
183         sversion=`echo "$version" | perl -pe 's/^\d+://'`
184         pv="${package}_${sversion}"
185         pva="${package}_${sversion}${arch:+_${arch}}"
186         dsc="../$pv.dsc"
187         changes="../$pva.changes"
188         if [ -n "$multiarch" -o ! -r $changes ]; then
189             changes=$(ls "../${package}_${sversion}_*+*.changes" "../${package}_${sversion}_multi.changes" 2>/dev/null | head -1)
190             if [ -z "$multiarch" ]; then
191                 if [ -n "$changes" ]; then
192                     echo "$PROGNAME: could not find normal .changes file but found multiarch file:" >&2
193                     echo "  $changes" >&2
194                     echo "Using this changes file instead." >&2
195                 else 
196                     echo "$PROGNAME: Can't find or can't read changes file $changes!" >&2
197                     exit 1
198                 fi
199             elif [ -n "$multiarch" -a -z "$changes" ]; then
200                 echo "$PROGNAME: could not find any multiarch .changes file with name" >&2
201                 echo "../${package}_${sversion}_*.changes" >&2
202                 exit 1
203             fi
204         fi
205         ;;
206
207     *)  echo "Usage: $PROGNAME [options] [user@]remotehost [.changes or .dsc file]" >&2
208         exit 1 ;;
209 esac
210
211 if [ "x$remotehost" == "x" ]
212 then
213         echo "No [user@]remotehost specified!" >&2
214         exit 1
215 fi
216
217 changesbase=`basename "$changes"`
218 dscbase=`basename "$dsc"`
219
220 if [ -n "$changes" ]
221 then
222     if [ ! -f "$changes" -o ! -r "$changes" ]
223     then
224         echo "Can't find or can't read changes file $changes!" >&2
225         exit 1
226     fi
227
228     # Is there a dsc file listed in the changes file?
229     if grep -q "$dscbase" "$changes"
230     then
231         if [ ! -f "$dsc" -o ! -r "$dsc" ]
232         then
233             echo "Can't find or can't read dsc file $dsc!" >&2
234             exit 1
235         fi
236
237         # Now do the real work
238         withecho scp "$changes" "$dsc" "$remotehost:\$HOME"
239         withecho ssh -t "$remotehost" "debsign $signargs $changesbase"
240         withecho scp "$remotehost:\$HOME/$changesbase" "$changes"
241         withecho scp "$remotehost:\$HOME/$dscbase" "$dsc"
242         withecho ssh "$remotehost" "rm -f $changesbase $dscbase"
243     else
244         withecho scp "$changes" "$remotehost:\$HOME"
245         withecho ssh -t "$remotehost" "debsign $signargs $changesbase"
246         withecho scp "$remotehost:\$HOME/$changesbase" "$changes"
247         withecho ssh "$remotehost" "rm -f $changesbase"
248     fi
249
250     echo "Successfully signed changes file"
251 else
252     if [ ! -f "$dsc" -o ! -r "$dsc" ]
253     then
254         echo "Can't find or can't read dsc file $dsc!" >&2
255         exit 1
256     fi
257
258     withecho scp "$dsc" "$remotehost:\$HOME"
259     withecho ssh -t "$remotehost" "${DEBRSIGN_PGP_PATH}debsign $signargs $dscbase"
260     withecho scp "$remotehost:\$HOME/$dscbase" "$dsc"
261     withecho ssh "$remotehost" "rm -f $dscbase"
262
263     echo "Successfully signed dsc file"
264 fi
265 exit 0