%define commit0 00a90f0997e2863dd218d04f95e24401f2037a4c
%define shortcommit0 00a90f09

Name:           cjdns
# major version is cjdns protocol version:
Version:        16.0
Release:        5%{?dist}
Summary:        The privacy-friendly network without borders
Group:		System Environment/Base
License:        GPL3
URL:            https://hyperboria.net/
Source0: https://github.com/cjdelisle/cjdns/archive/%{commit0}.tar.gz#/%{name}-%{shortcommit0}.tar.gz
# Add targeted selinux policy
Patch0:	 cjdns.selinux.patch
# Allow python2.6 for build.  Python is not used during the build
# process.  The python tools allegedly depend on python2.7, but that can
# be in Requires for the subpackage.
Patch1:	 cjdns.el6.patch
# Fix RLIMIT_NPROC - setuid() bug.   In its low priv process, cjdroute calls 
#
#   setrlimit(RLIMIT_NPROC, &(struct rlimit){ 0, 0 })
#
# which on recent kernels prevents fork() or exec() after the following
# setuid().  This is due to changes discussed here:
#
# https://lwn.net/Articles/451985/
# 
# On the 2.6.32 kernel used by EL6, the above causes setuid() to fail.
# This patch sets RLIMIT_NPROC to { 1, 1 } instead, which prevents
# fork(), but not exec.
Patch2:	 cjdns.nprocs.patch
# Add setgid to Security_setUser().
Patch3:  cjdns.setgid.patch
# Change defaults generated by cjdroute --genconf
Patch4:  cjdns.genconf.patch
# Patch contributed init scripts to put cjdroute in /usr/sbin
Patch5:  cjdns.sbin.patch

# FIXME: selinux prevents cjdroute from writing to /etc/cjdroute.conf
# at first startup when run by the supplied init service scripts.  This is
# probably correct.  But the initial config needs to be generated another way.

# FIXME: getpwuid(uid) fails, because Security_admin has already done chroot.

BuildRequires:  nodejs, make
#Requires:       
Prereq: /usr/sbin/useradd

%description
Cjdns implements an encrypted IPv6 network using public-key cryptography for
address allocation and a distributed hash table for routing. This provides
near-zero-configuration networking, and prevents many of the security and
scalability issues that plague existing networks.

%package selinux
Summary: Targeted SELinux policy module for cjdns
Group: System Environment/Base
BuildRequires: policycoreutils, checkpolicy, selinux-policy-devel
Requires: policycoreutils, selinux-policy, %{name}

%description selinux
Targeted SELinux policy module for cjdns.

# FIXME: keep C tools separate?
%package tools
Summary: Command line tools for cjdns
Group: System Environment/Base
Requires: nodejs

%description tools
C language and nodejs tools for cjdns.

%prep
%setup -qn %{name}-%{commit0}
%patch0 -b .selinux
%if 0%{?rhel} == 6
%patch1 -b .el6
%patch2 -b .nprocs
%endif
%patch3 -b .setgid
%patch4 -b .genconf
%patch5 -b .sbin

# FIXME: grep Version_CURRENT_PROTOCOL util/version/Version.h and
# check that it matches major %{version}

%build
cd contrib/selinux
ln -s /usr/share/selinux/devel/Makefile .
make cjdns.pp
cd -
# nodejs based build system
./do

# FIXME: use system libuv on compatible systems
# bundled libuv is 0.11.4 with changes:
# https://github.com/cjdelisle/cjdns/commits/master/node_build/dependencies/libuv

%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT%{_sbindir}
cp -p cjdroute $RPM_BUILD_ROOT%{_sbindir}

# init support
# FIXME: move cjdroute to /usr/sbin or /usr/lib/cjdns and patch init configs
%if 0%{?rhel} == 6
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/init
cp -p contrib/upstart/cjdns.conf $RPM_BUILD_ROOT/%{_sysconfdir}/init
%else
mkdir -p $RPM_BUILD_ROOT%{_unitdir}
cp -p contrib/systemd/cjdns.service $RPM_BUILD_ROOT%{_unitdir}
%endif

# chroot 
mkdir -p %{buildroot}/var/empty/cjdns

# install selinux modules
mkdir -p %{buildroot}%{_datadir}/selinux/targeted
cp -p contrib/selinux/cjdns.pp %{buildroot}%{_datadir}/selinux/targeted
ln contrib/selinux/cjdns.{te,fc} .	# for doc dir

# install c and nodejs tools
mkdir -p %{buildroot}%{_prefix}/lib/cjdns/{node_build,contrib}
cp -pr tools $RPM_BUILD_ROOT%{_prefix}/lib/cjdns
cp -p node_build/Semaphore.js $RPM_BUILD_ROOT%{_prefix}/lib/cjdns/node_build
cp -pr contrib/nodejs $RPM_BUILD_ROOT%{_prefix}/lib/cjdns/contrib
# symlinks for selected nodejs tools
mkdir -p %{buildroot}%{_bindir}
for t in peerStats sessionStats cjdnslog publictoip6; do
  ln -sf %{_prefix}/lib/cjdns/tools/$t %{buildroot}%{_bindir}
done

%files
%{!?_licensedir:%global license %%doc}
%license LICENSE
%doc README.md README_RU.md HACKING.md 
%attr(0100,root,root) /var/empty/cjdns
%{_sbindir}/cjdroute
%dir %{_prefix}/lib/cjdns
%if 0%{?rhel} == 6
/%{_sysconfdir}/init/*
%else
%{_unitdir}/*
%endif

%pre
getent passwd cjdns > /dev/null || /usr/sbin/useradd -c "" \
        -r -d %{_prefix}/lib/cjdns -s /sbin/nologin %{name} 

# FIXME: how do you get upstart on EL6 to reload the service?
%post
%if 0%{?rhel} != 6
%systemd_post cjdns.service
%endif

%preun
%if 0%{?rhel} == 6
if [ "$1" -eq 0 ]; then
  /sbin/initctl stop cjdns
fi
%else
%systemd_preun cjdns.service
%endif

%postun
%if 0%{?rhel} == 6
if [ "$1" -ge 1 ]; then
  /sbin/initctl restart cjdns
fi
%else
%systemd_postun_with_restart cjdns.service
%endif

%files selinux
%doc cjdns.te cjdns.fc 
%{_datadir}/selinux/targeted/*

%post selinux
/usr/sbin/semodule -s targeted -i %{_datadir}/selinux/targeted/cjdns.pp \
        &>/dev/null || :

%postun selinux
if [ $1 -eq 0 ] ; then
/usr/sbin/semodule -s targeted -r cjdns &> /dev/null || :
fi

%files tools
%{_prefix}/lib/cjdns
%{_bindir}/*

%changelog
* Thu Sep 24 2015 Stuart D. Gathman <stuart@gathman.org> 16.0-5
- Restart cjdroute on update, stop on uninstall
- symlink selected tools to bin
- use /var/empty/cjdns for chroot
- patch genconf to change chroot and setuser
- TODO: patch cjdroute to remove module request, handle externally

* Wed Sep 23 2015 Stuart D. Gathman <stuart@gathman.org> 16.0-4
- Remove doc subpackage - only a meg of docs, and protocol is experimental.
- Fix for RLIMIT_NPROC - setuid bug.
- Add setgid to Security.c
- add contrib/nodejs so tools work

* Wed Sep 23 2015 Stuart D. Gathman <stuart@gathman.org> 16.0-3
- Add selinux, doc and tools subpackages
- Support EL6

* Mon Sep 21 2015 Stuart D. Gathman <stuart@gathman.org> 16.0-2
- nodejs not a runtime dependency of main package
- move binaries to /usr/bin (good idea?)

* Mon Sep 21 2015 Stuart D. Gathman <stuart@gathman.org> 16.0-1
- Initial RPM
