--- /dev/null
+# For COPR builds directly from git.
+#
+# https://docs.pagure.org/copr.copr/user_documentation.html#make-srpm
+#
+
+srpm: /usr/bin/git
+ ./mkspec.sh
+ set -x; if grep -q "global gitsnapshot 1" openconnect.spec; then \
+ tarprefix=$$(sed -n '/^%global snapcommit /s/.* //p' openconnect.spec); \
+ tarname=$${tarprefix:0:7}; \
+ else \
+ tarprefix=$$(sed -n '/^%global tagver /s/.* //p' openconnect.spec); \
+ tarname=$${tarprefix}; \
+ fi; \
+ git archive --prefix=openconnect-$${tarprefix}/ HEAD -o .copr/openconnect-$${tarname}.tar.gz
+ rpmbuild -bs openconnect.spec --define "_sourcedir .copr" --define "_srcrpmdir $(outdir)"
+
+/usr/bin/git:
+ dnf install git
+
+build: srpm
+ rpmbuild -bb openconnect.spec --define "_sourcedir `pwd`/.copr"
--- /dev/null
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mQINBE6NcQEBEADN5LtGr/flvrjd17mCOlqtRB26tj6G4jAc5VURYbejQGbbYzP5
+L+fCLfDo01MYLI6jffklfpcDRHh2r/ACvA+NBTTVrP+XX8+s8+Y49Ke/39rt4NUW
+C/t9UaIkV+0gP3DPYQA2GseOGwaF8V7v3BXq6VrwoyV2KlD4vAYUahJ52VxsZG+/
+IhrvZn2MjmAyb1fjzZYr/7GX568CKdRY5VaVFqLKXdC7ZzRZObgzR83zaa3coC7l
+3cFRtmGRmttDgUJ8R3Oqp2X9oe+eylzpmndEZkzGPZiI90VmZchvt1XUJ/VRpRwP
+xmJvrz+NJWVktzDU1koauyOmiyB2cO6+RcSMaoQIX+TpyqJZ96rd6KsHCyTodF39
+3xs730V24pRJXSbqJpyBNTOjd2T856MI9CIQ0SRvTUJGsp4x82j+3rJvSKGTClPw
+FOJkJ0KaQyPMIaudP0PdsqULSoHXiBk3k+yj6tg9Ca84TrsSrLx1fvM4sAZpqo5p
+LriDbl7ji6tUZovqW06MRT7rFCMjJW0Bk8jPp2r/5ASdjv33Ljxvr+9weYHJ5/rN
+J9MUVw3rXmyDbUh7+uAm/2e24z26xE6LsxJB8JzdRqRSMqXdf8JsiuQLWpKZBwYo
+hLD+EKK+bfpqvTAHH39XLPz+Hx1Pyg3+nkcQJIHsZOiH5uneQyf5oId0MQARAQAB
+tCVEYXZpZCBXb29kaG91c2UgPGR3bXcyQGluZnJhZGVhZC5vcmc+iQI7BBMBAgAl
+AhsDAh4BAheAAhkBBQJOz8SvBgsJCAcDAgYVCAIJCgsEFgIDAQAKCRBjdizaZ+Lz
+WY5QD/9EJrnssxVTZVAt/OeX4ecgy6Z7nEsAq68QWc7nUbumzG3d3kzWn9li5yLL
+R6kEvj1g5w6t7X9pOG7UTqpCYs0jw72ozBPrJTNJk8rk00/R24ROVX4Bjb1tBUdL
+EuIne9lS7MnI2oaNTT9vyTV07OLc/aorKv3hyI6dryW43IDVAXQBqFL7H+iPzt0m
+STOo+uCwY1G5pusmWUlLUAk83AfenBJCgj6F0WrcxY9MRxBpgghBVq07hynM2wul
+U4EHxjitzfVHmkqZa0dZhAYo/jOdU+K16kL2+dpKPy/1KADzbpNE4kULOmL0E8te
+nEBLM5Cb8QWVE0t4n0phFX2lrfH/bG1X3lj5uVEiBvx8LIjTcve+8G22qATtuQvt
+6wuFu6xSqs2LEV5yigVok1bQ7O4L0AXRqlkcCTI9XK0wxYCNPRp/jf17YSHAv0k7
+yXQ4GqJsbr/aFKjPUDJtcfI1Q/uJ5xGD1qVeJrcY6APoCFvlb9TxiUvt/fnZQNkx
+LQ8yXxjxN2BdI48vMnKsPsvWq+vp57Kcqy2nwlMm1wmn0NdtfhfsyFX0eiiq/l8u
+W3R1FbkVnj/hH1p2mLnr0aDLGPtvXlETuoYdUtWWLpKQDST+zbtqJwDzjj9nvF/E
+xdt2XGHDjdP7J3jJ5wrli0P2fdWY0w7vAY2wmD1qoFLg+n/ENrQgRGF2aWQgV29v
+ZGhvdXNlIDxkd213MkBleGltLm9yZz6JAjgEEwECACICGwMCHgECF4AFAk7PxLgG
+CwkIBwMCBhUIAgkKCwQWAgMBAAoJEGN2LNpn4vNZhm4QALEBYT7YFCeywswA3PH8
+8h951uia3Cc5Gn4XBKbQxQQ4QRWHkrRhmINRqc7SMBUfxUtYnT+T2/Ei07OtRzKX
+1AjKN74mF+p7s8i7JCM2t7Kc+/xSIZIhpwgbf4OOjtUQ3RJoYjlL+ke8YomX6geM
+ZV/IXN2nqj4a8CYkmzXCi2dg7uWf8v/p/hyk/DLYlD+HwxpRG6ANUkQ6zxTxgnzw
+ihrnhaNsu2PAnWJo9G/Tfk8o5JuTRBn5qGr7SyQ0PUG5s8D2IPgMaABHhpoT9mYv
+VOundroC2RyusS9xzrTJC+BEvLZ+J3idAvT7/TfjJuOrPpkr2BUIZYr4MF+acG0Q
+QUstsJdp7V27iINNN0jmlybbCl7RiIO8nCSfVRssgKbfJMnThvMGjYSSFPUz25gI
+gH95t8a/2rGR5nnBJQYbd+1Toj0vqc4PIuSALk8bF/fr0s1DwKUJGgbiUYA4moIY
+165he7/RVGVwm5qM49YgSaJWwintDCGox7kDJMBfOz1n0FVi5LLGCHmWosLt/CRp
+b+F+r0ix2g4d5kIU/JedT1kU8dOugLVb5bLuisK28h5J06k48VfTkzkSjOb8Nn4w
+7q78RUZ2zx8Ny5Y5+BFEKtmu7Bs9Pzs6698DHSaeZzqIuSTgn8ddu8iBjHZF/sw7
+wrZO1z2cKj6FW6bMen/bX+HbtCJEYXZpZCBXb29kaG91c2UgPGRhdmlkQHdvb2Ro
+b3Uuc2U+iQI4BBMBAgAiAhsDAh4BAheABQJOz8S4BgsJCAcDAgYVCAIJCgsEFgID
+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
+jlk6HJE=
+=8HB8
+-----END PGP PUBLIC KEY BLOCK-----
--- /dev/null
+# The gpg_verify macro is defined further down in this document.
+
+# gpg_verify takes one option and a list of 2- or 3-tuples.
+#
+# With no arguments, attempts to figure everything out. Finds one keyring and
+# tries to pair each signature file with a source. If there is no source found
+# which matches a signature, the build is aborted.
+#
+# -k gives a common keyring to verify all signatures against, except when an
+# argument specifies its own keyring.
+#
+# Each argument must be of the form "F,S,K" or "F,S", where each of F, S and K
+# is either the number or the filename of one of the source files in the
+# package. A pathname including directories is not allowed.
+# F is a source file to check.
+# S is a signature.
+# K is a keyring.
+#
+# When an argument specifies a keyring, that signature will be verified against
+# the keys in that keyring. For arguments that don't specify a keyring, the one
+# specified with -k will be used, if any. If no keyring is specified either
+# way, the macro will default to the first one it finds in the source list.
+#
+# It is assumed that all the keys in all keyrings, whether automatically found
+# or explicitly specified, are trusted to authenticate the source files. There
+# must not be any untrusted keys included.
+
+# Some utility functions to the global namespace
+# Most of these should come from the utility macros in the other repo.
+%define gpg_macros_init %{lua:
+ function db(str)
+ io.stderr:write(tostring(str) .. '\\n')
+ end
+\
+ -- Simple basename clone
+ function basename(str)
+ local name = string.gsub(str, "(.*/)(.*)", "%2")
+ return name
+ end
+\
+ -- Get the numbered or source file.
+ -- The spec writer can use any numbering scheme. The sources table
+ -- always counts from 1 and has no gaps, so we have to go back to the
+ -- SOURCEN macros.
+ function get_numbered_source(num)
+ local macro = "%SOURCE" .. num
+ local val = rpm.expand(macro)
+ if val == macro then
+ return nil
+ end
+ return val
+ end
+ -- Get the named source file. This returns the full path to a source file,
+ -- or nil if no such source exists.
+ function get_named_source(name)
+ local path
+ for _,path in ipairs(sources) do
+ if name == basename(path) then
+ return path
+ end
+ end
+ return nil
+ end
+\
+ -- Determine whether the supplied filename contains a signature
+ -- Assumes the file will be closed when the handle goes out of scope
+ function is_signature(fname)
+ -- I don't really like this, but you can have completely binary sigs
+ if string.find(fname, '%.sig$') then
+ return true
+ end
+ local file = io.open(fname, 'r')
+ if file == nil then return false end
+\
+ local c = 1
+ while true do
+ local line = file:read('*line')
+ if (line == nil or c > 10) then break end
+ if string.find(line, "BEGIN PGP SIGNATURE") then
+ return true
+ end
+ c = c+1
+ end
+ return false
+ end
+\
+ -- Determine whether the supplied filename looks like a keyring
+ -- Ends in .gpg (might be binary data)? Contains "BEGIN PGP PUBLIC KEY BLOCK"
+ function is_keyring(fname)
+ -- XXX Have to hack this now to make it not find macros.gpg while we're testing.
+ if string.find(fname, '%.gpg$') and not string.find(fname, 'macros.gpg$') then
+ return true
+ end
+\
+ local file = io.open(fname, 'r')
+ if file == nil then return false end
+ io.input(file)
+ local c = 1
+ while true do
+ local line = io.read('*line')
+ if (line == nil or c > 10) then break end
+ if string.find(line, "BEGIN PGP PUBLIC KEY BLOCK") then
+ return true
+ end
+ c = c+1
+ end
+ return false
+ end
+\
+ -- Output code to have the current scriptlet echo something
+ function echo(str)
+ print("echo " .. str .. "\\n")
+ end
+\
+ -- Output an exit statement with nonzero return to the current scriptlet
+ function exit()
+ print("exit 1\\n")
+ end
+\
+ -- Call the RPM %error macro
+ function rpmerror(str)
+ echo("gpg_verify: " .. str)
+ rpm.expand("%{error:gpg_verify: " .. str .. "}")
+ exit(1)
+ end
+\
+ -- XXX How to we get just a flag and no option?
+ function getflag(flag)
+ return nil
+ end
+\
+ -- Extract the value of a passed option
+ function getoption(opt)
+ out = rpm.expand("%{-" .. opt .. "*}")
+ -- if string.len(out) == 0 then
+ if #out == 0 then
+ return nil
+ end
+ return out
+ end
+\
+ function unknownarg(a)
+ rpmerror("Unknown argument to %%gpg_verify: " .. a)
+ end
+\
+ function rprint(s, l, i) -- recursive Print (structure, limit, indent)
+ l = (l) or 100; i = i or ""; -- default item limit, indent string
+ if (l<1) then db("ERROR: Item limit reached."); return l-1 end;
+ local ts = type(s);
+ if (ts ~= "table") then db(i,ts,s); return l-1 end
+ db(i,ts); -- print "table"
+ for k,v in pairs(s) do -- db("[KEY] VALUE")
+ l = rprint(v, l, i.."\t["..tostring(k).."]");
+ if (l < 0) then break end
+ end
+ return l
+ end
+\
+ -- Given a list of source file numbers or file names, validate them and
+ -- convert them to a list of full filenames.
+ function check_sources_list(arr)
+ local files = {}
+ local src,fpath
+ for _, src in ipairs(arr) do
+ if tonumber(src) then
+ -- We have a number; turn it to a full path to the corresponding source file
+ fpath = get_numbered_source(src)
+ else
+ fpath = get_named_source(src)
+ end
+ if not src then
+ err = 'Not a valid source: ' .. src
+ if src == '1' then
+ err = err .. '. Note that "Source:" is the 0th source file, not the 1st.'
+ end
+ rpmerror(err)
+ end
+ table.insert(files, fpath)
+ end
+ return files
+ end
+ rpm.define("gpg_macros_init %{nil}")
+}#
+
+# The actual macro
+%define gpg_verify(k:) %gpg_macros_init%{lua:
+ -- RPM will ignore the first thing we output unless we give it a newline.
+ print('\\n')
+\
+ local defkeyspec = getoption("k")
+ local args = rpm.expand("%*")
+ local sourcefiles = {}
+ local signature_table = {}
+ local signatures = {}
+ local keyrings = {}
+ local defkey, match, captures, s
+\
+ local function storematch(m, c)
+ match = m; captures = c
+ end
+\
+ -- Scan all of the sources and try to categorize them.
+ -- Move to a function
+ for i,s in pairs(sources) do
+ sourcefiles[s] = true
+ -- db('File: ' .. i .. ", " .. s)
+ if is_signature(s) then
+ table.insert(signatures, s)
+ signature_table[s] = true
+ db('Found signature: ' .. s)
+ elseif is_keyring(s) then
+ table.insert(keyrings, s)
+ db('Found keyring: ' .. s)
+ else
+ -- Must be a source
+ db('Found source: ' .. s)
+ end
+ end
+\
+ if defkeyspec then
+ defkey = check_sources_list({defkeyspec})[1]
+ if not defkey then
+ rpmerror('The provided keyring ' .. defkeyspec .. ' is not a valid source number or filename.')
+ end
+ end
+\
+ if defkey then
+ db('Defkey: ' .. defkey)
+ else
+ db('No common key yet')
+ if keyrings[1] then
+ defkey = keyrings[1]
+ db('Using first found keyring file: '..defkey)
+ end
+ end
+\
+ -- Check over any given args to make sure they're valid, and to see if a
+ -- common key is required.
+ local needdefkey = false
+ local double = rex.newPOSIX('^([^,]+),([^,]+)$')
+ local triple = rex.newPOSIX('^([^,]+),([^,]+),([^,]+)$')
+ local arglist = {}
+\
+ -- RPM gives us the arguments in a single string.
+ -- Split on spaces and iterate
+ for arg in args:gmatch('%S+') do
+ db('Checking ' .. arg)
+ if triple:gmatch(arg, storematch) > 0 then
+ db('Looks OK')
+ local parsed = {srcnum=captures[1], signum=captures[2], keynum=captures[3]}
+ s = check_sources_list({captures[1], captures[2], captures[3]})
+ parsed.srcfile = s[1]
+ parsed.sigfile = s[2]
+ parsed.keyfile = s[3]
+ table.insert(arglist, parsed)
+ elseif double:gmatch(arg, storematch) > 0 then
+ db('Looks OK; needs common key')
+ needdefkey = true
+ local parsed = {srcnum=captures[1], signum=captures[2], keynum=defkeyspec, keyfile=defkey}
+ s = check_sources_list({captures[1], captures[2]})
+ parsed.srcfile = s[1]
+ parsed.sigfile = s[2]
+ table.insert(arglist, parsed)
+ else
+ rpmerror('Provided argument '..arg..' is not valid.')
+ end
+ end
+\
+ -- So we now know if one of those args needs a common key
+ if needdefkey and not defkey then
+ rpmerror('No common key was specified or found, yet the arguments require one.')
+ end
+\
+ -- And if we have no arguments at all and no common key was found,
+ -- then we can't do an automatic check
+ if not defkey and args == '' then
+ rpmerror('No keyring specified and none found; cannot auto-check.')
+ end
+\
+ -- Nothing to check means automatic mode
+ if #arglist == 0 then
+ local noext
+ for i,_ in pairs(signature_table) do
+ -- Find the name without the extension
+ noext = string.gsub(i, '%.[^.]+$', '')
+ if sourcefiles[noext] then
+ table.insert(arglist, {srcfile=noext, sigfile=i, keyfile=defkey})
+ else
+ rpmerror('Found signature ' .. i .. ' with no matching source file.')
+ end
+ end
+ end
+\
+ -- Now actually check things
+ for _,arg in ipairs(arglist) do
+ local gpgfile = '$GPGHOME/' .. basename(arg.keyfile) .. '.gpg'
+ echo('Checking signature: file ' .. arg.srcfile .. ' sig ' .. arg.sigfile .. ' key ' .. arg.keyfile)
+\
+ -- We need a secure temp directorry
+ print('GPGHOME=$(mktemp -qd)\\n')
+\
+ -- Call gpg2 to generate the dearmored key
+ print('gpg2 --homedir $GPGHOME --no-default-keyring --quiet --yes ')
+ print('--output '.. gpgfile .. ' --dearmor ' .. arg.keyfile .. "\\n")
+\
+ -- Call gpgv2 to verify the signature against the source file with the dearmored key
+ print('gpgv2 --homedir $GPGHOME --keyring ' .. gpgfile .. ' ' .. arg.sigfile .. ' ' .. arg.srcfile .. '\\n')
+\
+ print('rm -rf $GPGHOME\\n')
+ echo('')
+ end
+\
+ db('------------')
+}#
+
+# vim: set filetype=spec:
--- /dev/null
+#!/bin/bash
+
+GITCOMMIT="$(git rev-parse HEAD)"
+GITDESC="$(git describe --tags HEAD)"
+
+GITTAG="$(echo $GITDESC | cut -f1 -d-)"
+GITTAG="${GITTAG#v}"
+
+if [ "v$GITTAG" = "$GITDESC" ]; then
+ ISSNAP=0
+ GITCOUNT=0
+else
+ ISSNAP=1
+ GITCOUNT="$(echo $GITDESC | cut -f2 -d-)"
+fi
+
+sed -e "s/@ISSNAP@/${ISSNAP}/" \
+ -e "s/@VERSION@/${GITTAG}/" \
+ -e "s/@SNAPCOMMIT@/${GITCOMMIT}/" \
+ -e "s/@SNAPCOUNT@/${GITCOUNT}/" \
+ openconnect.spec.in > openconnect.spec
--- /dev/null
+%global gitsnapshot @ISSNAP@
+%if 0%{?gitsnapshot}
+%global snapcommit @SNAPCOMMIT@
+%global snapcount @SNAPCOUNT@
+%global shortcommit %(c=%{snapcommit}; echo ${c:0:7})
+%global snapver .git.%{snapcount}.%{shortcommit}
+%endif
+
+%global tagver @VERSION@
+
+# RHEL6 still has ancient GnuTLS
+%define use_gnutls 0%{?fedora} || 0%{?rhel} >= 7
+
+# RHEL5 has no libproxy, and no %%make_install macro
+%if 0%{?rhel} && 0%{?rhel} <= 5
+%define use_libproxy 0
+%define make_install %{__make} install DESTDIR=%{?buildroot}
+%define use_tokens 0
+%else
+%define use_libproxy 1
+%define use_tokens 1
+%endif
+
+# Fedora has tss2-sys from F29 onwards
+%if 0%{?fedora} >= 29
+%define use_tss2_esys 1
+%else
+%define use_tss2_esys 0
+%endif
+
+%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}}
+
+Name: openconnect
+Version: %{tagver}%{?snapver}
+Release: 0%{?dist}
+Summary: Open client for Cisco AnyConnect VPN, Juniper Network Connect/Pulse, PAN GlobalProtect
+
+License: LGPLv2
+URL: http://www.infradead.org/openconnect.html
+%if 0%{?gitsnapshot}
+Source0: https://github.com/openconnect/%{name}/archive/%{snapcommit}/%{name}-%{shortcommit}.tar.gz
+%else
+Source0: ftp://ftp.infradead.org/pub/%{name}/%{name}-%{version}.tar.gz
+%endif
+Source2: gpgkey-BE07D9FD54809AB2C4B0FF5F63762CDA67E2F359.asc
+Source3: macros.gpg
+
+
+BuildRequires: pkgconfig(libxml-2.0) pkgconfig(libpcsclite) krb5-devel gnupg2
+BuildRequires: autoconf automake libtool gettext pkgconfig(liblz4)
+BuildRequires: pkgconfig(uid_wrapper) pkgconfig(socket_wrapper) softhsm
+%if 0%{?fedora} || 0%{?rhel} >= 7
+Obsoletes: openconnect-lib-compat < %{version}-%{release}
+Requires: vpnc-script
+%else
+Requires: vpnc
+%endif
+
+%if 0%{?fedora} >= 30
+BuildRequires: glibc-langpack-cs
+%endif
+%if %{use_gnutls}
+BuildRequires: pkgconfig(gnutls) trousers-devel
+# Anywhere we use GnuTLS ,there should be an ocserv package too
+BuildRequires: ocserv
+%else
+BuildRequires: pkgconfig(openssl) pkgconfig(libp11) pkgconfig(p11-kit-1)
+%endif
+%if %{use_libproxy}
+BuildRequires: pkgconfig(libproxy-1.0)
+%endif
+%if %{use_tokens}
+BuildRequires: pkgconfig(stoken) pkgconfig(libpskc)
+%endif
+%if %{use_tss2_esys}
+# https://bugzilla.redhat.com/show_bug.cgi?id=1638961
+BuildRequires: pkgconfig(tss2-esys) libgcrypt-devel
+%endif
+
+%description
+This package provides a multiprotocol VPN client for Cisco AnyConnect,
+Juniper SSL VPN / Pulse Connect Secure, and Palo Alto Networks GlobalProtect
+SSL VPN.
+
+%package devel
+Summary: Development package for OpenConnect VPN authentication tools
+Requires: %{name}%{?_isa} = %{version}-%{release}
+# RHEL5 needs these spelled out because it doesn't automatically infer from pkgconfig
+%if 0%{?rhel} && 0%{?rhel} <= 5
+Requires: openssl-devel zlib-devel
+%endif
+
+%description devel
+This package provides the core HTTP and authentication support from
+the OpenConnect VPN client, to be used by GUI authentication dialogs
+for NetworkManager etc.
+
+%include %SOURCE3
+%prep
+%if 0%{?gitsnapshot}
+%setup -q -n %{name}-%{snapcommit}
+NOCONFIGURE=x ./autogen.sh
+%else
+%gpg_verify
+%setup -q
+if [ ! -x configure ]; then
+ NOCONFIGURE=x ./autogen.sh
+fi
+%endif
+
+%build
+%configure --with-vpnc-script=/etc/vpnc/vpnc-script \
+ --disable-dsa-tests \
+%if %{use_gnutls}
+ --with-default-gnutls-priority="@OPENCONNECT,SYSTEM" \
+%else
+ --with-openssl --without-openssl-version-check \
+%endif
+ --htmldir=%{_pkgdocdir}
+make %{?_smp_mflags} V=1
+
+
+%install
+%make_install
+mkdir -p $RPM_BUILD_ROOT/%{_pkgdocdir}
+rm -f $RPM_BUILD_ROOT/%{_libdir}/libopenconnect.la
+rm -f $RPM_BUILD_ROOT/%{_libexecdir}/openconnect/tncc-wrapper.py
+%find_lang %{name}
+
+%check
+# Checks fail on EPEL 7 and below for environmental reasons we don't care about
+%if 0%{?fedora} || 0%{?rhel} >= 8
+make VERBOSE=1 check
+%endif
+
+%ldconfig_scriptlets
+
+%files -f %{name}.lang
+%{_libdir}/libopenconnect.so.5*
+%{_sbindir}/openconnect
+%{_libexecdir}/openconnect/
+%{_mandir}/man8/*
+%doc TODO COPYING.LGPL
+%doc %{_pkgdocdir}
+
+%files devel
+%{_libdir}/libopenconnect.so
+%{_includedir}/openconnect.h
+%{_libdir}/pkgconfig/openconnect.pc
+
+%changelog
+* Tue Jul 16 2019 David Woodhouse <dwmw2@infradead.org> - %{version}-%{release}
+- Autopackaging for COPR