summary refs log tree commit diff
path: root/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'gnu')
-rw-r--r--gnu/local.mk6
-rw-r--r--gnu/packages/astronomy.scm4
-rw-r--r--gnu/packages/benchmark.scm4
-rw-r--r--gnu/packages/cups.scm9
-rw-r--r--gnu/packages/django.scm4
-rw-r--r--gnu/packages/education.scm56
-rw-r--r--gnu/packages/enlightenment.scm8
-rw-r--r--gnu/packages/gnome.scm2
-rw-r--r--gnu/packages/gnuzilla.scm11
-rw-r--r--gnu/packages/irc.scm4
-rw-r--r--gnu/packages/lisp.scm4
-rw-r--r--gnu/packages/lua.scm4
-rw-r--r--gnu/packages/openbox.scm37
-rw-r--r--gnu/packages/package-management.scm6
-rw-r--r--gnu/packages/patches/mupdf-mujs-CVE-2016-10132.patch188
-rw-r--r--gnu/packages/patches/mupdf-mujs-CVE-2016-10133.patch36
-rw-r--r--gnu/packages/patches/tipp10-fix-compiling.patch213
-rw-r--r--gnu/packages/patches/tipp10-remove-license-code.patch332
-rw-r--r--gnu/packages/pdf.scm16
-rw-r--r--gnu/packages/python.scm4
-rw-r--r--gnu/packages/ruby.scm33
-rw-r--r--gnu/packages/tls.scm11
-rw-r--r--gnu/packages/version-control.scm8
-rw-r--r--gnu/packages/video.scm4
-rw-r--r--gnu/packages/vim.scm4
-rw-r--r--gnu/packages/xfce.scm7
-rw-r--r--gnu/packages/xorg.scm253
-rw-r--r--gnu/services/vpn.scm491
28 files changed, 1537 insertions, 222 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index 13519b0e64..7e816f79af 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -424,6 +424,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/services/spice.scm				\
   %D%/services/ssh.scm				\
   %D%/services/version-control.scm              \
+  %D%/services/vpn.scm				\
   %D%/services/web.scm				\
   %D%/services/xorg.scm				\
 						\
@@ -721,6 +722,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/libxml2-CVE-2016-5131.patch		\
   %D%/packages/patches/libxslt-generated-ids.patch		\
   %D%/packages/patches/libxslt-CVE-2016-4738.patch		\
+  %D%/packages/patches/libxt-guix-search-paths.patch		\
   %D%/packages/patches/linux-pam-no-setfsuid.patch		\
   %D%/packages/patches/lirc-localstatedir.patch			\
   %D%/packages/patches/llvm-for-extempore.patch			\
@@ -753,6 +755,8 @@ dist_patch_DATA =						\
   %D%/packages/patches/multiqc-fix-git-subprocess-error.patch	\
   %D%/packages/patches/mumps-build-parallelism.patch		\
   %D%/packages/patches/mupdf-build-with-openjpeg-2.1.patch	\
+  %D%/packages/patches/mupdf-mujs-CVE-2016-10132.patch		\
+  %D%/packages/patches/mupdf-mujs-CVE-2016-10133.patch		\
   %D%/packages/patches/mupen64plus-ui-console-notice.patch	\
   %D%/packages/patches/musl-CVE-2016-8859.patch			\
   %D%/packages/patches/mutt-store-references.patch		\
@@ -895,6 +899,8 @@ dist_patch_DATA =						\
   %D%/packages/patches/texi2html-i18n.patch			\
   %D%/packages/patches/tidy-CVE-2015-5522+5523.patch		\
   %D%/packages/patches/tinyxml-use-stl.patch			\
+  %D%/packages/patches/tipp10-fix-compiling.patch		\
+  %D%/packages/patches/tipp10-remove-license-code.patch		\
   %D%/packages/patches/tk-find-library.patch			\
   %D%/packages/patches/ttf2eot-cstddef.patch			\
   %D%/packages/patches/ttfautohint-source-date-epoch.patch	\
diff --git a/gnu/packages/astronomy.scm b/gnu/packages/astronomy.scm
index c1b15e1dee..f390ce4486 100644
--- a/gnu/packages/astronomy.scm
+++ b/gnu/packages/astronomy.scm
@@ -58,7 +58,7 @@ in FITS files.")
 (define-public wcslib
   (package
     (name "wcslib")
-    (version "5.15")
+    (version "5.16")
     (source
      (origin
        (method url-fetch)
@@ -66,7 +66,7 @@ in FITS files.")
              "ftp://ftp.atnf.csiro.au/pub/software/wcslib/" name "-" version
              ".tar.bz2"))
        (sha256
-        (base32 "1s2nig327g4bimd9xshlk11ww09a7mrjmsbpdcd8smsmn2kl1glb"))))
+        (base32 "1vwrzkznpig2q40m11j12hsfqvsjz8z44l66pz5fkh6fy461w0zd"))))
     (inputs
      `(("cfitsio" ,cfitsio)))
     (build-system gnu-build-system)
diff --git a/gnu/packages/benchmark.scm b/gnu/packages/benchmark.scm
index 465c81b431..df2be86424 100644
--- a/gnu/packages/benchmark.scm
+++ b/gnu/packages/benchmark.scm
@@ -27,7 +27,7 @@
 (define-public fio
   (package
     (name "fio")
-    (version "2.15")
+    (version "2.16")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -35,7 +35,7 @@
                        "fio-" version ".tar.bz2"))
               (sha256
                (base32
-                "1ggma9c48717z2wz8j9f7jcgb3xqk8qawjl6c9hnabxxry94y130"))))
+                "1v5n5hq500aidwfzmbm3k5d3mhh6ffwbgzq7nys838azga4xd3bx"))))
     (build-system gnu-build-system)
     (arguments
      '(#:tests? #f ; No tests.
diff --git a/gnu/packages/cups.scm b/gnu/packages/cups.scm
index ca16958352..39ab41c192 100644
--- a/gnu/packages/cups.scm
+++ b/gnu/packages/cups.scm
@@ -3,6 +3,7 @@
 ;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Danny Milosavljevic <dannym@scratchpost.org>
+;;; Copyright © 2017 Leo Famulari <leo@famulari.name>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -51,6 +52,7 @@
 (define-public cups-filters
   (package
     (name "cups-filters")
+    (replacement cups-filters/fixed)
     (version "1.13.1")
     (source(origin
               (method url-fetch)
@@ -133,6 +135,13 @@ filters for the PDF-centric printing workflow introduced by OpenPrinting.")
                    license:lgpl2.0+
                    license:expat))))
 
+(define mupdf/fixed-instead-of-mupdf
+  (package-input-rewriting `((,mupdf . ,(@@ (gnu packages pdf) mupdf/fixed)))))
+
+;;; Fix CVE-2016-10132 and CVE-2016-10133. See mupdf/fixed for more information.
+(define cups-filters/fixed
+  (mupdf/fixed-instead-of-mupdf cups-filters))
+
 ;; CUPS on non-MacOS systems requires cups-filters.  Since cups-filters also
 ;; depends on CUPS libraries and binaries, cups-minimal has been added to
 ;; satisfy this dependency.
diff --git a/gnu/packages/django.scm b/gnu/packages/django.scm
index bbb2d71db1..9a3c66c45e 100644
--- a/gnu/packages/django.scm
+++ b/gnu/packages/django.scm
@@ -29,13 +29,13 @@
 (define-public python-django
   (package
     (name "python-django")
-    (version "1.10.3")
+    (version "1.10.5")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "Django" version))
               (sha256
                (base32
-                "0c4c8zs7kzb0bdlpy4vlzv6va26dbazr32h91rldf6waxs6z14kg"))))
+                "12szjsmnfhh2yr54sfynyjr8vl0q9gb6qak3ayqcifcinrs97f0d"))))
     (build-system python-build-system)
     (arguments
      '(#:phases
diff --git a/gnu/packages/education.scm b/gnu/packages/education.scm
index 3a883079fe..5444579059 100644
--- a/gnu/packages/education.scm
+++ b/gnu/packages/education.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2016 Danny Milosavljevic <dannym@scratchpost.org>
-;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2016, 2017 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2016 Hartmut Goebel <h.goebel@crazy-compilers.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -138,3 +139,56 @@ of categories with some of the activities available in that category.
 @end enumerate
 ")
     (license license:gpl3+)))
+
+(define-public tipp10
+  (package
+    (name "tipp10")
+    (version "2.1.0")
+    (source (origin
+              (method url-fetch)
+              ;; guix download is not able to handle the download links on the
+              ;; home-page, which use '<meta http-equiv="refresh" …>'
+              (uri (string-append "mirror://debian/pool/main/"
+                                  "t/tipp10/tipp10_2.1.0.orig.tar.gz"))
+              (sha256
+               (base32
+                "0d387b404j88gsv6kv0rb7wxr23v5g5vl6s5l7602x8pxf7slbbx"))
+              (patches (search-patches "tipp10-fix-compiling.patch"
+                                       "tipp10-remove-license-code.patch"))))
+    (build-system cmake-build-system)
+    (arguments
+     `(#:tests? #f ; packages has no tests
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'disable-new-version-check
+           (lambda _
+             ;; Make new version check to default to false.
+             ;; TODO: Remove the checkbox from the dialog and the check itself
+             (substitute* '("widget/settingspages.cpp" "widget/mainwindow.cpp")
+               (("settings.value(\"check_new_version\", true)")
+                "settings.value(\"check_new_version\", false)"))
+             #t))
+         (replace 'configure
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let ((out (assoc-ref outputs "out")))
+               ;; Make program honor $PREFIX
+               (substitute* "tipp10.pro"
+                 (("\\.path = /usr/") (string-append ".path = " out "/")))
+               (substitute* "def/defines.h"
+                 (("\"/usr/") (string-append "\"" out "/")))
+               ;; Recreate Makefile
+               (zero? (system* "qmake"))))))))
+    (inputs
+     `(("qt4" ,qt-4)
+       ("sqlite" ,sqlite)))
+    (home-page "https://www.tipp10.com/")
+    (synopsis "Touch typing tutor")
+    (description "Tipp10 is a touch typing tutor.  The ingenious thing about
+the software is its intelligence feature: characters that are mistyped are
+repeated more frequently.  Beginners will find their way around right away so
+they can start practicing without a hitch.
+
+Useful support functions and an extensive progress tracker, topical lessons
+and the ability to create your own practice lessons make learning to type
+easy.")
+    (license license:gpl2)))
diff --git a/gnu/packages/enlightenment.scm b/gnu/packages/enlightenment.scm
index ca97104958..a34578afe7 100644
--- a/gnu/packages/enlightenment.scm
+++ b/gnu/packages/enlightenment.scm
@@ -1,7 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Tomáš Čech <sleep_walker@suse.cz>
 ;;; Copyright © 2015 Daniel Pimentel <d4n1@member.fsf.org>
-;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2015, 2016, 2017 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -146,7 +146,7 @@ removable devices or support for multimedia.")
 (define-public terminology
   (package
     (name "terminology")
-    (version "0.9.1")
+    (version "1.0.0")
     (source (origin
               (method url-fetch)
               (uri
@@ -154,13 +154,13 @@ removable devices or support for multimedia.")
                               "terminology/terminology-" version ".tar.xz"))
               (sha256
                (base32
-                "1kwv9vkhngdm5v38q93xpcykghnyawhjjcb5bgy0p89gpbk7mvpc"))))
+                "1x4j2q4qqj10ckbka0zaq2r2zm66ff1x791kp8slv1ff7fw45vdz"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("pkg-config" ,pkg-config)))
     (inputs
      `(("efl" ,efl)))
-    (home-page "https://www.enlightenment.org")
+    (home-page "https://www.enlightenment.org/about-terminology")
     (synopsis "Powerful terminal emulator based on EFL")
     (description
      "Terminology is fast and feature rich terminal emulator.  It is solely
diff --git a/gnu/packages/gnome.scm b/gnu/packages/gnome.scm
index a3cbe81d69..e279ef7ed6 100644
--- a/gnu/packages/gnome.scm
+++ b/gnu/packages/gnome.scm
@@ -8,7 +8,7 @@
 ;;; Copyright © 2015 Mathieu Lirzin <mthl@openmailbox.org>
 ;;; Copyright © 2015 Andy Wingo <wingo@igalia.com>
 ;;; Copyright © 2015 David Hashe <david.hashe@dhashe.com>
-;;; Copyright © 2015, 2016 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2015, 2016, 2017 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2015, 2016, 2017 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
 ;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
diff --git a/gnu/packages/gnuzilla.scm b/gnu/packages/gnuzilla.scm
index e92d78c88a..e5388b42a3 100644
--- a/gnu/packages/gnuzilla.scm
+++ b/gnu/packages/gnuzilla.scm
@@ -354,7 +354,16 @@ standards.")
         (mozilla-patch "icecat-bug-1297361.patch"        "297c675ddadc" "1jc1b5i69vq1fvz3qfnnv52c9cj17bjbmfyzmqlw5ywna0wfvabz")
         (mozilla-patch "icecat-bug-1325877.patch"        "3cff736e3bb6" "1nxqwnl9zksvkfkmis7zica4xrhwfndjyy2sxc1dvrh9rshk1swq")
         (mozilla-patch "icecat-bug-1285960.patch"        "2732280adabc" "0zrpq3aybaw2yy38vs6883a4nw01x4kxn3lfqn9yhcgjvngmmyia")
-        (mozilla-patch "icecat-bug-1325938.patch"        "81c9fdbd96e8" "0scv1zyi4vbsjdsyj4w70n5jd50baq0dzw3qpxqf1n69nfb9k214")))
+        (mozilla-patch "icecat-bug-1325938.patch"        "81c9fdbd96e8" "0scv1zyi4vbsjdsyj4w70n5jd50baq0dzw3qpxqf1n69nfb9k214")
+        (mozilla-patch "icecat-bug-1322420.patch"        "a386ca6a3013" "1m1scz2pxzmg9wya8is5dcr3mgvkx3g1xlykgigmw2mqs5zcdg9s")
+        (mozilla-patch "icecat-bug-1328834.patch"        "0521b0e4707c" "1mv057p4hcvapibpbd9apryag19aiqdzafc6df2angl97m4mcbjx")
+        (mozilla-patch "icecat-bug-1290037.patch"        "bf0dd9ae6807" "02iw5ngsvvij95arnn69a744d6si27g1x41ixg16l51dbn900b3r")
+        (mozilla-patch "icecat-bug-1322666.patch"        "576f03e362c5" "0m88xs0jwhzx2lg12cvimxjknp7rpsvvhxxblhiqqjwnqip0pyc0")
+        (mozilla-patch "icecat-bug-1304266.patch"        "4d82e7314a72" "1rrrw4rw0xv7c2myiypcqh1fk47rk3fvic79zh6m04bl3knclr1r")
+        (mozilla-patch "icecat-bug-1322315.patch"        "0617dd4b444d" "1ipags2cl2p521pm0qx110h5di2mgif6h1r3g8l9b0rc5m9b1y2j")
+        (mozilla-patch "icecat-bug-1325200.patch"        "ead08c2a6c57" "1nnnwdr7411xpz6n9j869g6sz447cq6xsmds9cw6d24iprcinp5m")
+        (mozilla-patch "icecat-bug-1312001.patch"        "c5e67d41bdd0" "05kwn5zv381lsiw9vbzm8fh6s1lddx47l8f4pwg487h9dj7vbdfq")
+        (mozilla-patch "icecat-bug-1331058.patch"        "2ce94f2ea797" "1yrnjqpafjns68z99s1m6jins3agid7c1z3v9qgk5xzfcddl31pn")))
       (modules '((guix build utils)))
       (snippet
        '(begin
diff --git a/gnu/packages/irc.scm b/gnu/packages/irc.scm
index 44e21af7d6..82eb103688 100644
--- a/gnu/packages/irc.scm
+++ b/gnu/packages/irc.scm
@@ -140,14 +140,14 @@ SILC and ICB protocols via plugins.")
 (define-public weechat
   (package
     (name "weechat")
-    (version "1.6")
+    (version "1.7")
     (source (origin
               (method url-fetch)
               (uri (string-append "http://weechat.org/files/src/weechat-"
                                   version ".tar.xz"))
               (sha256
                (base32
-                "1qqnb9bdi15l30378rnmhf26ndacwi5hmq5vpz4lfyihk17xnryn"))
+                "1crdwlxj5liik32svflfac0s87vm6p8xm208yndigzsbg8rli4sr"))
               (patches (search-patches "weechat-python.patch"))))
     (build-system gnu-build-system)
     (native-inputs `(("autoconf" ,autoconf)
diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index e226443626..80161de01b 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -756,14 +756,14 @@ from other CLXes around the net.")
 (define-public sbcl-stumpwm
   (package
     (name "sbcl-stumpwm")
-    (version "0.9.9")
+    (version "1.0.0")
     (source (origin
               (method url-fetch)
               (uri (string-append
                     "https://github.com/stumpwm/stumpwm/archive/"
                     version ".tar.gz"))
               (sha256
-               (base32 "1fqabij4zcsqg1ywgdv2irp1ys23dwc8ms9ai55lb2i47hgv7z3x"))
+               (base32 "1maxp98gh64az3d9vz9br6zdd6rc9fmj2imvax4by85g6kxvdz1i"))
               (file-name (string-append "stumpwm-" version ".tar.gz"))))
     (build-system asdf-build-system/sbcl)
     (inputs `(("sbcl-cl-ppcre" ,sbcl-cl-ppcre)
diff --git a/gnu/packages/lua.scm b/gnu/packages/lua.scm
index 65c335d373..721eceddf1 100644
--- a/gnu/packages/lua.scm
+++ b/gnu/packages/lua.scm
@@ -371,13 +371,13 @@ Notable examples are GTK+, GStreamer and Webkit.")
 (define-public lua-lpeg
   (package
     (name "lua-lpeg")
-    (version "1.0.0")
+    (version "1.0.1")
     (source (origin
               (method url-fetch)
               (uri (string-append "http://www.inf.puc-rio.br/~roberto/lpeg/lpeg-"
                                   version ".tar.gz"))
               (sha256
-               (base32 "13mz18s359wlkwm9d9iqlyyrrwjc6iqfpa99ai0icam2b3khl68h"))))
+               (base32 "0sq25z3r324a324ky73izgq9mbf66j2xvjp0fxf227rwxalzgnb2"))))
     (build-system gnu-build-system)
     (arguments
      `(#:phases
diff --git a/gnu/packages/openbox.scm b/gnu/packages/openbox.scm
index 36e39d8267..2200c837ba 100644
--- a/gnu/packages/openbox.scm
+++ b/gnu/packages/openbox.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014 Julien Lepiller <julien@lepiller.eu>
 ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2017 ng0 <contact.ng0@cryptolab.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -23,11 +24,13 @@
   #:use-module (guix download)
   #:use-module (guix build-system gnu)
   #:use-module (gnu packages freedesktop)
+  #:use-module (gnu packages gettext)
   #:use-module (gnu packages gnome)
   #:use-module (gnu packages gtk)
   #:use-module (gnu packages image)
   #:use-module (gnu packages pkg-config)
   #:use-module (gnu packages python)
+  #:use-module (gnu packages xdisorg)
   #:use-module (gnu packages xml)
   #:use-module (gnu packages xorg))
 
@@ -67,4 +70,38 @@ implementations.")
     (home-page "http://openbox.org/wiki/Main_Page")
     (license gpl2+)))
 
+(define-public obconf
+  (package
+    (name "obconf")
+    (version "2.0.4")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "http://openbox.org/dist/" name
+                           "/" name "-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1fanjdmd8727kk74x5404vi8v7s4kpq48l583d12fsi4xvsfb8vi"))))
+    (inputs
+     `(("gtk+-2" ,gtk+-2)
+       ("imlib2" ,imlib2)
+       ("libglade" ,libglade)
+       ("openbox" ,openbox)
+       ("startup-notification" ,startup-notification)
+       ("libsm" ,libsm)
+       ("librsvg" ,librsvg)
+       ("libxft" ,libxft)))
+    (native-inputs
+     `(("gettext" ,gettext-minimal)
+       ("pkg-config" ,pkg-config)))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:configure-flags (list "--enable-nls")))
+    (home-page "http://openbox.org/wiki/ObConf:About")
+    (synopsis "Openbox configuration tool")
+    (description
+     "Obconf is a tool for configuring the Openbox window manager.
+You can configure its appearance, themes, and much more.")
+    (license gpl2+)))
+
 ;;; openbox.scm ends here
diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scm
index 673e5f0fb2..92787d76cc 100644
--- a/gnu/packages/package-management.scm
+++ b/gnu/packages/package-management.scm
@@ -224,9 +224,9 @@ the Nix package manager.")
   ;;
   ;; Note: use a very short commit id; with a longer one, the limit on
   ;; hash-bang lines would be exceeded while running the tests.
-  (let ((commit "eefd042e60d9fc1d092b44bf80ecbfe65b291e46"))
+  (let ((commit "d9da3a757d3081403081577c4e07763c9b809043"))
     (package (inherit guix-0.12.0)
-      (version (string-append "0.12.0-3." (string-take commit 4)))
+      (version (string-append "0.12.0-4." (string-take commit 4)))
       (source (origin
                 (method git-fetch)
                 (uri (git-reference
@@ -236,7 +236,7 @@ the Nix package manager.")
                       (commit commit)))
                 (sha256
                  (base32
-                  "1g0042x80q73pb9y39aqbkajl4bacls5c0im9aljmjnsb80fsh8d"))
+                  "17w9jdzm3lvfbchx7qrlkczp2jsfsi6v8cpfqh290cip5gxgz9bn"))
                 (file-name (string-append "guix-" version "-checkout"))))
       (arguments
        (substitute-keyword-arguments (package-arguments guix-0.12.0)
diff --git a/gnu/packages/patches/mupdf-mujs-CVE-2016-10132.patch b/gnu/packages/patches/mupdf-mujs-CVE-2016-10132.patch
new file mode 100644
index 0000000000..e752e57ec5
--- /dev/null
+++ b/gnu/packages/patches/mupdf-mujs-CVE-2016-10132.patch
@@ -0,0 +1,188 @@
+Fix CVE-2016-10132:
+
+https://bugs.ghostscript.com/show_bug.cgi?id=697381
+http://seclists.org/oss-sec/2017/q1/74
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-10132
+
+Patch lifted from upstream source repository:
+
+http://git.ghostscript.com/?p=mujs.git;h=fd003eceda531e13fbdd1aeb6e9c73156496e569
+
+From fd003eceda531e13fbdd1aeb6e9c73156496e569 Mon Sep 17 00:00:00 2001
+From: Tor Andersson <tor@ccxvii.net>
+Date: Fri, 2 Dec 2016 14:56:20 -0500
+Subject: [PATCH] Fix 697381: check allocation when compiling regular
+ expressions.
+
+Also use allocator callback function.
+---
+ thirdparty/mujs/jsgc.c     |  2 +-
+ thirdparty/mujs/jsregexp.c |  2 +-
+ thirdparty/mujs/jsstate.c  |  6 ------
+ thirdparty/mujs/regexp.c   | 45 +++++++++++++++++++++++++++++++++++----------
+ thirdparty/mujs/regexp.h   |  7 +++++++
+ 5 files changed, 44 insertions(+), 18 deletions(-)
+
+diff --git a/thirdparty/mujs/jsgc.c b/thirdparty/mujs/jsgc.c
+index 4f7e7dc..f80111e 100644
+--- a/thirdparty/mujs/jsgc.c
++++ b/thirdparty/mujs/jsgc.c
+@@ -46,7 +46,7 @@ static void jsG_freeobject(js_State *J, js_Object *obj)
+ 		jsG_freeproperty(J, obj->head);
+ 	if (obj->type == JS_CREGEXP) {
+ 		js_free(J, obj->u.r.source);
+-		js_regfree(obj->u.r.prog);
++		js_regfreex(J->alloc, J->actx, obj->u.r.prog);
+ 	}
+ 	if (obj->type == JS_CITERATOR)
+ 		jsG_freeiterator(J, obj->u.iter.head);
+diff --git a/thirdparty/mujs/jsregexp.c b/thirdparty/mujs/jsregexp.c
+index a2d5156..7b09c06 100644
+--- a/thirdparty/mujs/jsregexp.c
++++ b/thirdparty/mujs/jsregexp.c
+@@ -16,7 +16,7 @@ void js_newregexp(js_State *J, const char *pattern, int flags)
+ 	if (flags & JS_REGEXP_I) opts |= REG_ICASE;
+ 	if (flags & JS_REGEXP_M) opts |= REG_NEWLINE;
+ 
+-	prog = js_regcomp(pattern, opts, &error);
++	prog = js_regcompx(J->alloc, J->actx, pattern, opts, &error);
+ 	if (!prog)
+ 		js_syntaxerror(J, "regular expression: %s", error);
+ 
+diff --git a/thirdparty/mujs/jsstate.c b/thirdparty/mujs/jsstate.c
+index 638cab3..fd5bcf6 100644
+--- a/thirdparty/mujs/jsstate.c
++++ b/thirdparty/mujs/jsstate.c
+@@ -9,12 +9,6 @@
+ 
+ static void *js_defaultalloc(void *actx, void *ptr, int size)
+ {
+-	if (size == 0) {
+-		free(ptr);
+-		return NULL;
+-	}
+-	if (!ptr)
+-		return malloc((size_t)size);
+ 	return realloc(ptr, (size_t)size);
+ }
+ 
+diff --git a/thirdparty/mujs/regexp.c b/thirdparty/mujs/regexp.c
+index 9852be2..01c18a3 100644
+--- a/thirdparty/mujs/regexp.c
++++ b/thirdparty/mujs/regexp.c
+@@ -807,23 +807,31 @@ static void dumpprog(Reprog *prog)
+ }
+ #endif
+ 
+-Reprog *regcomp(const char *pattern, int cflags, const char **errorp)
++Reprog *regcompx(void *(*alloc)(void *ctx, void *p, int n), void *ctx,
++	const char *pattern, int cflags, const char **errorp)
+ {
+ 	struct cstate g;
+ 	Renode *node;
+ 	Reinst *split, *jump;
+ 	int i;
+ 
+-	g.prog = malloc(sizeof (Reprog));
+-	g.pstart = g.pend = malloc(sizeof (Renode) * strlen(pattern) * 2);
++	g.pstart = NULL;
++	g.prog = NULL;
+ 
+ 	if (setjmp(g.kaboom)) {
+ 		if (errorp) *errorp = g.error;
+-		free(g.pstart);
+-		free(g.prog);
++		alloc(ctx, g.pstart, 0);
++		alloc(ctx, g.prog, 0);
+ 		return NULL;
+ 	}
+ 
++	g.prog = alloc(ctx, NULL, sizeof (Reprog));
++	if (!g.prog)
++		die(&g, "cannot allocate regular expression");
++	g.pstart = g.pend = alloc(ctx, NULL, sizeof (Renode) * strlen(pattern) * 2);
++	if (!g.pstart)
++		die(&g, "cannot allocate regular expression parse list");
++
+ 	g.source = pattern;
+ 	g.ncclass = 0;
+ 	g.nsub = 1;
+@@ -840,7 +848,9 @@ Reprog *regcomp(const char *pattern, int cflags, const char **errorp)
+ 		die(&g, "syntax error");
+ 
+ 	g.prog->nsub = g.nsub;
+-	g.prog->start = g.prog->end = malloc((count(node) + 6) * sizeof (Reinst));
++	g.prog->start = g.prog->end = alloc(ctx, NULL, (count(node) + 6) * sizeof (Reinst));
++	if (!g.prog->start)
++		die(&g, "cannot allocate regular expression instruction list");
+ 
+ 	split = emit(g.prog, I_SPLIT);
+ 	split->x = split + 3;
+@@ -859,20 +869,35 @@ Reprog *regcomp(const char *pattern, int cflags, const char **errorp)
+ 	dumpprog(g.prog);
+ #endif
+ 
+-	free(g.pstart);
++	alloc(ctx, g.pstart, 0);
+ 
+ 	if (errorp) *errorp = NULL;
+ 	return g.prog;
+ }
+ 
+-void regfree(Reprog *prog)
++void regfreex(void *(*alloc)(void *ctx, void *p, int n), void *ctx, Reprog *prog)
+ {
+ 	if (prog) {
+-		free(prog->start);
+-		free(prog);
++		alloc(ctx, prog->start, 0);
++		alloc(ctx, prog, 0);
+ 	}
+ }
+ 
++static void *default_alloc(void *ctx, void *p, int n)
++{
++	return realloc(p, (size_t)n);
++}
++
++Reprog *regcomp(const char *pattern, int cflags, const char **errorp)
++{
++	return regcompx(default_alloc, NULL, pattern, cflags, errorp);
++}
++
++void regfree(Reprog *prog)
++{
++	regfreex(default_alloc, NULL, prog);
++}
++
+ /* Match */
+ 
+ static int isnewline(int c)
+diff --git a/thirdparty/mujs/regexp.h b/thirdparty/mujs/regexp.h
+index 4bb4615..6bb73e8 100644
+--- a/thirdparty/mujs/regexp.h
++++ b/thirdparty/mujs/regexp.h
+@@ -1,6 +1,8 @@
+ #ifndef regexp_h
+ #define regexp_h
+ 
++#define regcompx js_regcompx
++#define regfreex js_regfreex
+ #define regcomp js_regcomp
+ #define regexec js_regexec
+ #define regfree js_regfree
+@@ -8,6 +10,11 @@
+ typedef struct Reprog Reprog;
+ typedef struct Resub Resub;
+ 
++Reprog *regcompx(void *(*alloc)(void *ctx, void *p, int n), void *ctx,
++	const char *pattern, int cflags, const char **errorp);
++void regfreex(void *(*alloc)(void *ctx, void *p, int n), void *ctx,
++	Reprog *prog);
++
+ Reprog *regcomp(const char *pattern, int cflags, const char **errorp);
+ int regexec(Reprog *prog, const char *string, Resub *sub, int eflags);
+ void regfree(Reprog *prog);
+-- 
+2.9.1
+
diff --git a/gnu/packages/patches/mupdf-mujs-CVE-2016-10133.patch b/gnu/packages/patches/mupdf-mujs-CVE-2016-10133.patch
new file mode 100644
index 0000000000..d73849262c
--- /dev/null
+++ b/gnu/packages/patches/mupdf-mujs-CVE-2016-10133.patch
@@ -0,0 +1,36 @@
+Fix CVE-2016-10133:
+
+https://bugs.ghostscript.com/show_bug.cgi?id=697401
+http://seclists.org/oss-sec/2017/q1/74
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-10133
+
+Patch lifted from upstream source repository:
+
+https://git.ghostscript.com/?p=mujs.git;h=77ab465f1c394bb77f00966cd950650f3f53cb24
+
+From 77ab465f1c394bb77f00966cd950650f3f53cb24 Mon Sep 17 00:00:00 2001
+From: Tor Andersson <tor.andersson@gmail.com>
+Date: Thu, 12 Jan 2017 14:47:01 +0100
+Subject: [PATCH] Fix 697401: Error when dropping extra arguments to
+ lightweight functions.
+
+---
+ thirdparty/mujs/jsrun.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/thirdparty/mujs/jsrun.c b/thirdparty/mujs/jsrun.c
+index ee80845..782a6f9 100644
+--- a/thirdparty/mujs/jsrun.c
++++ b/thirdparty/mujs/jsrun.c
+@@ -937,7 +937,7 @@ static void jsR_calllwfunction(js_State *J, int n, js_Function *F, js_Environmen
+ 	jsR_savescope(J, scope);
+ 
+ 	if (n > F->numparams) {
+-		js_pop(J, F->numparams - n);
++		js_pop(J, n - F->numparams);
+ 		n = F->numparams;
+ 	}
+ 	for (i = n; i < F->varlen; ++i)
+-- 
+2.9.1
+
diff --git a/gnu/packages/patches/tipp10-fix-compiling.patch b/gnu/packages/patches/tipp10-fix-compiling.patch
new file mode 100644
index 0000000000..4c206d4d83
--- /dev/null
+++ b/gnu/packages/patches/tipp10-fix-compiling.patch
@@ -0,0 +1,213 @@
+Description: Debian patches to make tipp10 compile
+Author: Christoph Martin <chrism@debian.org>
+Last-Update: 2016-07-20
+
+https://sources.debian.net/data/main/t/tipp10/2.1.0-2/debian/patches/0001-FixCompiling
+
+--- a/widget/tickerboard.cpp
++++ b/widget/tickerboard.cpp
+@@ -97,7 +97,8 @@ void TickerBoard::startTicker(bool wasPa
+ 

+ 		if (tickerSpeed == 50) {

+ 			scrollOffset = 290;

+-			scroll(-290, 0, QRect::QRect(10, 15, 590, 35)); //contentsRect());

++			const QRect qr = QRect(10, 15, 590, 35);

++			scroll(-290, 0, qr); //contentsRect());

+ 		}

+ 

+ 		startFlag = true;

+@@ -153,7 +154,8 @@ void TickerBoard::changeChar() {
+ 			scrollOffset = 0;

+ 		} else {

+ 			scrollOffset = 290;

+-			scroll(-290, 0, QRect::QRect(10, 15, 590, 35)); //contentsRect());

++			const QRect qr = QRect(10, 15, 590, 35);

++			scroll(-290, 0, qr); //contentsRect());

+ 		}

+ 		splitLesson();

+ 	}

+@@ -242,7 +244,8 @@ void TickerBoard::progress() {
+ 

+ 				// Move ticker 1 pixel to left

+ 				scrollOffset++;

+-				scroll(-1, 0, QRect::QRect(10, 15, 590, 35)); //contentsRect());

++				const QRect qr = QRect(10, 15, 590, 35);

++				scroll(-1, 0, qr); //contentsRect());

+ 

+ 				if ((lessonOffset - scrollOffset) <= 30) {

+ 					setSpeed(tickerSpeed);

+@@ -265,14 +268,16 @@ void TickerBoard::progress() {
+ 			// 160 pixels overage (because the user must see at least the next word)

+ 			if ((lessonOffset - scrollOffset) > 200) {

+ 				scrollOffset += (lessonOffset - scrollOffset) - 200;

+-				scroll(-((lessonOffset - scrollOffset) - 200), 0, QRect::QRect(10, 15, 590, 35)); //contentsRect());

++				const QRect qr = QRect(10, 15, 590, 35);

++				scroll(-((lessonOffset - scrollOffset) - 200), 0, qr); //contentsRect());

+ 			}

+ 		} else {

+ 			// If the user types faster than the ticker, move ticker faster after

+ 			// 160 pixels overage (because the user must see at least the next word)

+ 			if ((lessonOffset - scrollOffset) > 280) {

+ 				scrollOffset += 570;

+-				scroll(-570, 0, QRect::QRect(10, 15, 590, 35)); //contentsRect());

++				const QRect qr = QRect(10, 15, 590, 35);

++				scroll(-570, 0, qr); //contentsRect());

+ 			}

+ 

+ 		}

+--- a/widget/settingspages.cpp
++++ b/widget/settingspages.cpp
+@@ -501,7 +501,7 @@ void DatabasePage::writeSettings() {
+ 	QSettings settings;

+ 	#endif

+ 	settings.beginGroup("database");

+-	settings.setValue("pathpro", lineDatabasePath->text() + "/" + QString::QString(APP_USER_DB));

++	settings.setValue("pathpro", lineDatabasePath->text() + "/" + QString(APP_USER_DB));

+ 	settings.endGroup();

+ }

+ 

+--- a/widget/lessondialog.cpp
++++ b/widget/lessondialog.cpp
+@@ -89,7 +89,7 @@ void LessonDialog::updateContent() {
+ 			*lessonData = lineLessonContent->toPlainText().split("\n", QString::SkipEmptyParts);

+ 			// Delete empty lines

+ 			for (int i = 0; i < lessonData->size(); i++) {

+-				if (QString::QString(lessonData->at(i).toLocal8Bit().constData()).simplified() == "") {

++				if (QString(lessonData->at(i).toLocal8Bit().constData()).simplified() == "") {

+ 					lessonData->removeAt(i);

+ 				}

+ 			}

+@@ -259,7 +259,7 @@ void LessonDialog::clickSave() {
+ 	contentList = lineLessonContent->toPlainText().split("\n", QString::SkipEmptyParts);

+ 	// Delete empty lines

+ 	for (i = 0; i < contentList.size(); i++) {

+-		if (QString::QString(contentList.at(i).toLocal8Bit().constData()).simplified() == "") {

++		if (QString(contentList.at(i).toLocal8Bit().constData()).simplified() == "") {

+ 			contentList.removeAt(i);

+ 		}

+ 	}

+--- a/sql/chartablesql.cpp
++++ b/sql/chartablesql.cpp
+@@ -57,7 +57,7 @@ QVariant CharSqlModel::data(const QModel
+ 			// Read the unicode value

+ 			unicode = value.toInt();

+ 			// Convert unicode to a char

+-			unicodeToChar = QString::QString(QChar(unicode)); //"\'" + QString::QString(QChar(unicode)) + "\'";

++			unicodeToChar = QString(QChar(unicode)); //"\'" + QString::QString(QChar(unicode)) + "\'";

+ 			return unicodeToChar;

+ 		} else {

+ 			// Last column (error weight)

+--- a/sql/startsql.cpp
++++ b/sql/startsql.cpp
+@@ -344,7 +344,7 @@ bool StartSql::updateOwnLesson(QString l
+ 		for (i = 0; i < content.size(); i++) {

+ 			//simplifiedContent = QString::QString(

+ 			//	content.at(i)).replace(QChar(0x27), "''", Qt::CaseSensitive).simplified();

+-			simplifiedContent = trim(QString::QString(

++			simplifiedContent = trim(QString(

+ 				content.at(i)).replace(QChar(0x27), "''", Qt::CaseSensitive));

+ 

+ 			if (!query.exec("INSERT INTO own_content VALUES(NULL,'" +

+--- a/def/defines.h
++++ b/def/defines.h
+@@ -27,9 +27,9 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #define DEFINES_H

+ 

+ // OS constants

+-#define APP_WIN						true

++#define APP_WIN						false

+ #define APP_MAC						false

+-#define APP_X11						false

++#define APP_X11						true

+ #define APP_PORTABLE				false //at least one of the 3 OS must be true too!

+ 

+ // Languages

+@@ -47,6 +47,7 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #define APP_URL 					"http://www.tipp10.com"

+ #define APP_DB 						"tipp10v2.template"

+ #define APP_USER_DB					"tipp10v2.db"

++#define APP_SHARE_DIR					"/usr/share/tipp10"

+ 

+ // Update constants

+ #define UPDATE_URL 					"www.tipp10.com"

+--- a/tipp10.pro
++++ b/tipp10.pro
+@@ -88,3 +88,15 @@ SOURCES         += 	main.cpp \
+                     sql/startsql.cpp \

+                     games/abcrainwidget.cpp \

+                     games/charball.cpp

++

++target.path = /usr/bin/

++INSTALLS += target

++share.path = /usr/share/tipp10/

++share.files = release/* *wav

++INSTALLS += share

++desktop.path = /usr/share/applications/

++desktop.files = tipp10.desktop

++INSTALLS += desktop

++pixmap.path = /usr/share/pixmaps/

++pixmap.files = tipp10.png

++INSTALLS += pixmap

+--- a/sql/connection.h
++++ b/sql/connection.h
+@@ -179,11 +179,13 @@ static bool createConnection() {
+ 				CANCEL_NO, "Betroffener Pfad:\n" + dbPath);*/

+ 			// Try to create new databae in user path

+ 			// Exist a database in the program dir?

+-			if (QFile::exists(QCoreApplication::applicationDirPath() + "/" + dbNameTemplate)) {

++			// if (QFile::exists(QCoreApplication::applicationDirPath() + "/" + dbNameTemplate)) {

++		  	if (QFile::exists(QString(APP_SHARE_DIR) + "/" + dbNameTemplate)) {

+ 			//if (QFile::exists(":/" + dbNameTemplate)) {

+ 				// A database exist in the program dir

+ 				// -> copy database to user home dir

+-				QFile file(QCoreApplication::applicationDirPath() + "/" + dbNameTemplate);

++				// QFile file(QCoreApplication::applicationDirPath() + "/" + dbNameTemplate);

++			  	QFile file(QString(APP_SHARE_DIR) + "/" + dbNameTemplate);

+ 				//QFile file(":/" + dbNameTemplate);

+ 				if (file.copy(dbPath)) {

+ 					QFile::setPermissions(dbPath, QFile::permissions(dbPath) | QFile::WriteUser);

+@@ -229,7 +231,8 @@ static bool createConnection() {
+ 		// Exist a database in user's home dir?

+ 		if (!QFile::exists(dbPath)) {

+ 			// Exist a database template in the program dir?

+-			dbPath = QCoreApplication::applicationDirPath() + "/" + dbNameTemplate;

++			// dbPath = QCoreApplication::applicationDirPath() + "/" + dbNameTemplate;

++		  	dbPath = QString(APP_SHARE_DIR) + "/" + dbNameTemplate;

+ 			//dbPath = ":/" + dbNameTemplate;

+ 			if (QFile::exists(dbPath)) {

+ 				// A database template exist in the program dir

+--- a/widget/helpbrowser.cpp
++++ b/widget/helpbrowser.cpp
+@@ -52,13 +52,15 @@ HelpBrowser::HelpBrowser(QString link, Q
+     textBrowser->setOpenExternalLinks(true);

+ 	

+     textBrowser->setSource(QString("file:///") + 

+-    	QCoreApplication::applicationDirPath() + 

++	// QCoreApplication::applicationDirPath() + 

++    	APP_SHARE_DIR + 

+     	QString("/help/") + language + QString("/index.html"));

+     	

+     if (link != "") {

+     

+ 		textBrowser->setSource(QString("file:///") + 

+-			QCoreApplication::applicationDirPath() + 

++			// QCoreApplication::applicationDirPath() + 

++			APP_SHARE_DIR + 

+ 			QString("/help/") + language + QString("/content/") + link);

+ 			

+ 	}

+--- a/tipp10.desktop
++++ b/tipp10.desktop
+@@ -1,10 +1,10 @@
+ [Desktop Entry]
+-Encoding=UTF-8
+ Name=TIPP10
+ Comment=Touch Typing Tutor
+ Comment[de]=10-Finger-Schreibtrainer
+-Exec=tipp10
++Exec=/usr/bin/tipp10
+ Icon=tipp10.png
+ Terminal=false
+ Type=Application
+ Categories=Education;
++Keywords=learning;touchtyping
diff --git a/gnu/packages/patches/tipp10-remove-license-code.patch b/gnu/packages/patches/tipp10-remove-license-code.patch
new file mode 100644
index 0000000000..4b7487e726
--- /dev/null
+++ b/gnu/packages/patches/tipp10-remove-license-code.patch
@@ -0,0 +1,332 @@
+Description: Remove license dialog and license key checking
+
+https://sources.debian.net/data/main/t/tipp10/2.1.0-2/debian/patches/0002-RemoveLicenseCode
+
+--- a/main.cpp
++++ b/main.cpp
+@@ -33,7 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include "def/defines.h"

+ #include "sql/connection.h"

+ #include "widget/mainwindow.h"

+-#include "widget/licensedialog.h"

+ #include "widget/illustrationdialog.h"

+ 

+ int main(int argc, char *argv[]) {

+@@ -59,7 +58,7 @@ int main(int argc, char *argv[]) {
+ 	QSettings settings;

+ 	#endif

+ 

+-	// Read/write language, license key and show illustration flag

++	// Read/write language and show illustration flag

+ 	settings.beginGroup("general");

+ 	QString languageGui = settings.value("language_gui",

+ 		QLocale::system().name()).toString();

+@@ -101,7 +100,6 @@ int main(int argc, char *argv[]) {
+ 	QString languageLesson = settings.value("language_lesson",

+ 		"").toString();

+ 

+-	QString licenseKey = settings.value("licensekey", "").toString();

+ 	bool showIllustration = settings.value("check_illustration", true).toBool();

+ 	bool useNativeStyle = settings.value("check_native_style", false).toBool();

+ 	settings.endGroup();

+--- a/tipp10.pro
++++ b/tipp10.pro
+@@ -43,7 +43,6 @@ HEADERS         += 	def/defines.h \
+                     widget/helpbrowser.h \

+                     widget/companylogo.h \

+                     widget/errormessage.h \

+-                    widget/licensedialog.h \

+                     widget/txtmessagedialog.h \

+                     widget/checkversion.h \

+                     sql/connection.h \

+@@ -78,7 +77,6 @@ SOURCES         += 	main.cpp \
+                     widget/helpbrowser.cpp \

+                     widget/companylogo.cpp \

+                     widget/errormessage.cpp \

+-                    widget/licensedialog.cpp \

+                     widget/txtmessagedialog.cpp \

+                     widget/checkversion.cpp \

+                     sql/lessontablesql.cpp \

+--- a/widget/licensedialog.cpp
++++ /dev/null
+@@ -1,168 +0,0 @@
+-/*

+-Copyright (c) 2006-2009, Tom Thielicke IT Solutions

+-

+-This program is free software; you can redistribute it and/or

+-modify it under the terms of the GNU General Public License

+-as published by the Free Software Foundation; either version 2

+-of the License.

+-

+-This program is distributed in the hope that it will be useful,

+-but WITHOUT ANY WARRANTY; without even the implied warranty of

+-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+-GNU General Public License for more details.

+-

+-You should have received a copy of the GNU General Public License

+-along with this program; if not, write to the Free Software

+-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

+-02110-1301, USA.

+-*/

+-

+-/****************************************************************

+-**

+-** Implementation of the LicenseDialog class

+-** File name: licensedialog.cpp

+-**

+-****************************************************************/

+-

+-#include <QHBoxLayout>

+-#include <QVBoxLayout>

+-#include <QMessageBox>

+-#include <QSettings>

+-#include <QCoreApplication>

+-

+-#include "licensedialog.h"

+-#include "def/defines.h"

+-

+-LicenseDialog::LicenseDialog(QWidget *parent) : QDialog(parent) {

+-

+-	setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);

+-

+-	setWindowTitle(tr("Lizenznummer"));

+-	setWindowIcon(QIcon(":/img/" + QString(ICON_FILENAME)));

+-

+-	// Create texbox

+-    createLineEdit();

+-

+-	// Create buttons

+-    createButtons();

+-

+-	// Set the layout of all widgets created above

+-	createLayout();

+-

+-	lineLicensing->setFocus();

+-}

+-

+-void LicenseDialog::createButtons() {

+-	//Buttons

+-	buttonOk = new QPushButton(this);

+-	buttonDemo = new QPushButton(this);

+-

+-	buttonOk->setText(tr("&Ok"));

+-	buttonDemo->setText(tr("&Demo starten"));

+-	buttonDemo->setToolTip(tr("Im Demo-Modus koennen pro Lektion nur\n"

+-		"10 Schriftzeichen eingegeben werden"));

+-

+-	buttonOk->setDefault(true);

+-	// Widget connections

+-    connect(buttonOk, SIGNAL(clicked()), this, SLOT(clickOk()));

+-    connect(buttonDemo, SIGNAL(clicked()), this, SLOT(clickDemo()));

+-}

+-

+-void LicenseDialog::createLineEdit() {

+-

+-	lineLicensing = new QLineEdit();

+-	lineLicensing->setInputMask(">NNNNNNNNNNNNNN");

+-

+-	labelLicensing = new QLabel(tr("Bitte geben Sie Ihre Lizenznummer "

+-		"(ohne Leerzeichen) ein, "

+-		"die Sie im Arbeitsbuch (Schulbuch) auf Seite 3 finden:"));

+-

+-	labelLicensing->setWordWrap(true);

+-}

+-

+-void LicenseDialog::createLayout() {

+-	// Button layout horizontal

+-	QHBoxLayout *buttonLayoutHorizontal = new QHBoxLayout;

+-    buttonLayoutHorizontal->addStretch(1);

+-    buttonLayoutHorizontal->addWidget(buttonDemo);

+-    buttonLayoutHorizontal->addWidget(buttonOk);

+-	// Full layout of all widgets vertical

+-	QVBoxLayout *mainLayout = new QVBoxLayout;

+-    mainLayout->addSpacing(1);

+-    mainLayout->addWidget(labelLicensing);

+-    mainLayout->addSpacing(1);

+-    mainLayout->addWidget(lineLicensing);

+-    mainLayout->addSpacing(1);

+-    mainLayout->addLayout(buttonLayoutHorizontal);

+-    mainLayout->setMargin(15);

+-    mainLayout->setSpacing(15);

+-    // Pass layout to parent widget (this)

+-	this->setLayout(mainLayout);

+-}

+-

+-void LicenseDialog::clickOk() {

+-

+-	// Check license key

+-	if (!checkLicenseKey(lineLicensing->text())) {

+-

+-		// License key is wrong

+-

+-		// Message to the user

+-		QMessageBox::information(0, APP_NAME,

+-			tr("Die eingegebene Lizenznummer ist leider nicht "

+-			"korrekt.\nBitte ueberpruefen Sie die Schreibweise."));

+-

+-		lineLicensing->setFocus();

+-

+-	} else {

+-

+-		// License key is ok

+-		writeSettings();

+-		accept();

+-	}

+-}

+-

+-void LicenseDialog::clickDemo() {

+-	accept();

+-}

+-

+-bool LicenseDialog::checkLicenseKey(QString licenseKey) {

+-	if (licenseKey.size() == 14 &&

+-		licenseKey[0].isLetter() &&

+-		licenseKey[1].isLetter() &&

+-		(licenseKey.mid(2, 2) == "39" ||

+-		licenseKey.mid(2, 2) == "41" ||

+-		licenseKey.mid(2, 2) == "43" ||

+-		licenseKey.mid(2, 2) == "49" ||

+-		licenseKey.mid(2, 2) == "99") &&

+-		licenseKey[4].isDigit() &&

+-		licenseKey[5].isDigit() &&

+-		licenseKey[6].isDigit() &&

+-		licenseKey[7].isLetter() &&

+-		licenseKey[8].isDigit() &&

+-		licenseKey[9].isDigit() &&

+-		licenseKey[10].isDigit() &&

+-		licenseKey[11].isDigit() &&

+-		licenseKey[12].isLetter() &&

+-		licenseKey[13].isLetter()) {

+-

+-		return true;

+-	}

+-	return false;

+-}

+-

+-void LicenseDialog::writeSettings() {

+-	// Saves settings of the startwiget

+-	// (uses the default constructor of QSettings, passing

+-	// the application and company name see main function)

+-	#if APP_PORTABLE

+-	QSettings settings(QCoreApplication::applicationDirPath() +

+-    	"/portable/settings.ini", QSettings::IniFormat);

+-    #else

+-	QSettings settings;

+-	#endif

+-

+-	settings.beginGroup("general");

+-	settings.setValue("licensekey", lineLicensing->text());

+-	settings.endGroup();

+-}

+--- a/widget/licensedialog.h
++++ /dev/null
+@@ -1,85 +0,0 @@
+-/*

+-Copyright (c) 2006-2009, Tom Thielicke IT Solutions

+-

+-This program is free software; you can redistribute it and/or

+-modify it under the terms of the GNU General Public License

+-as published by the Free Software Foundation; either version 2

+-of the License.

+-

+-This program is distributed in the hope that it will be useful,

+-but WITHOUT ANY WARRANTY; without even the implied warranty of

+-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+-GNU General Public License for more details.

+-

+-You should have received a copy of the GNU General Public License

+-along with this program; if not, write to the Free Software

+-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

+-02110-1301, USA.

+-*/

+-

+-/****************************************************************

+-**

+-** Definition of the LicenseDialog class

+-** File name: licensedialog.h

+-**

+-****************************************************************/

+-

+-#ifndef LICENSEDIALOG_H

+-#define LICENSEDIALOG_H

+-

+-#include <QDialog>

+-#include <QWidget>

+-#include <QPushButton>

+-#include <QLabel>

+-#include <QLineEdit>

+-#include <QString>

+-

+-//! The LicenseDialog class provides a license input widget.

+-/*!

+-	The LicenseDialog class shows a dialog to enter a license key.

+-

+-	@author Tom Thielicke, s712715

+-	@version 0.0.1

+-	@date 09.09.2008

+-*/

+-class LicenseDialog : public QDialog {

+-	Q_OBJECT

+-

+-	public:

+-

+-		//! Constructor, creates two table objects and provide it in two tabs.

+-		LicenseDialog(QWidget *parent = 0);

+-

+-		bool checkLicenseKey(QString licenseKey);

+-

+-	public slots:

+-

+-	private slots:

+-

+-		//! Start button pressed

+-		void clickOk();

+-

+-		//! Demo button pressed

+-		void clickDemo();

+-

+-	private:

+-

+-		//! Creates a cancel and a ok button.

+-		void createButtons();

+-

+-		//! Creates a textbox.

+-		void createLineEdit();

+-

+-		//! Creates the layout of the complete class.

+-		void createLayout();

+-

+-		//! Writes user settings

+-		void writeSettings();

+-

+-		QPushButton *buttonOk;

+-		QPushButton *buttonDemo;

+-		QLabel *labelLicensing;

+-		QLineEdit *lineLicensing;

+-};

+-

+-#endif //LICENSEDIALOG_H

+--- a/widget/mainwindow.cpp
++++ b/widget/mainwindow.cpp
+@@ -116,11 +116,6 @@ void MainWindow::closeEvent(QCloseEvent
+ 	}

+ }

+ 

+-bool MainWindow::checkLicenseKey(QString licenseKey) {

+-

+-    return false;

+-}

+-

+ void MainWindow::createMenu() {

+ 	//Mac-Version:

+ 	//-----------

+--- a/widget/mainwindow.h
++++ b/widget/mainwindow.h
+@@ -39,7 +39,6 @@ Foundation, Inc., 51 Franklin Street, Fi
+ #include "trainingwidget.h"

+ #include "evaluationwidget.h"

+ #include "illustrationdialog.h"

+-#include "licensedialog.h"

+ #include "games/abcrainwidget.h"

+ #include "helpbrowser.h"

+ 

diff --git a/gnu/packages/pdf.scm b/gnu/packages/pdf.scm
index 9b3571e67b..5e1c0db51e 100644
--- a/gnu/packages/pdf.scm
+++ b/gnu/packages/pdf.scm
@@ -6,10 +6,11 @@
 ;;; Copyright © 2016 Roel Janssen <roel@gnu.org>
 ;;; Coypright © 2016 ng0 <ng0@we.make.ritual.n0.is>
 ;;; Coypright © 2016 Efraim Flashner <efraim@flashner.co.il>
-;;; Coypright © 2016 Marius Bakke <mbakke@fastmail.com>
+;;; Coypright © 2016, 2017 Marius Bakke <mbakke@fastmail.com>
 ;;; Coypright © 2016 Ludovic Courtès <ludo@gnu.org>
 ;;; Coypright © 2016 Julien Lepiller <julien@lepiller.eu>
 ;;; Copyright © 2016 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2017 Leo Famulari <leo@famulari.name>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -480,6 +481,7 @@ extracting content or merging files.")
 (define-public mupdf
   (package
     (name "mupdf")
+    (replacement mupdf/fixed)
     (version "1.10a")
     (source
       (origin
@@ -538,6 +540,18 @@ line tools for batch rendering (pdfdraw), rewriting files (pdfclean),
 and examining the file structure (pdfshow).")
     (license license:agpl3+)))
 
+(define mupdf/fixed
+  (package
+    (inherit mupdf)
+    (source
+      (origin
+        (inherit (package-source mupdf))
+        (patches
+          (append
+            (origin-patches (package-source mupdf))
+            (search-patches "mupdf-mujs-CVE-2016-10132.patch"
+                            "mupdf-mujs-CVE-2016-10133.patch")))))))
+
 (define-public qpdf
   (package
    (name "qpdf")
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 4758606604..ddf276de09 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -8224,13 +8224,13 @@ processes across test runs.")
 (define-public python-icalendar
   (package
     (name "python-icalendar")
-    (version "3.11.1")
+    (version "3.11.2")
     (source (origin
              (method url-fetch)
              (uri (pypi-uri "icalendar" version))
              (sha256
               (base32
-               "1bvi7rzh7scl4nmgj2n2cy7k0v3p29y15cqy2hcdnfq9mnhdr63y"))))
+               "17rcy6rb9kqjf4p707ivmx7phjq7ngcz3bf7zriwxrqgrjagj7ag"))))
     (build-system python-build-system)
     (propagated-inputs
      `(("python-dateutil-2" ,python-dateutil-2)
diff --git a/gnu/packages/ruby.scm b/gnu/packages/ruby.scm
index 8fb22d0060..fb89238bd9 100644
--- a/gnu/packages/ruby.scm
+++ b/gnu/packages/ruby.scm
@@ -5,6 +5,7 @@
 ;;; Copyright © 2014, 2015 David Thompson <davet@gnu.org>
 ;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2015, 2016, 2017 Ben Woodcroft <donttrustben@gmail.com>
+;;; Copyright © 2017 ng0 <contact.ng0@cryptolab.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -4198,3 +4199,35 @@ RFC 2617.  This enables the use of the digest authentication scheme instead
 of the more insecure basic authentication scheme.")
     (home-page "http://github.com/drbrain/net-http-digest_auth")
     (license license:expat)))
+
+(define-public ruby-mail
+  (package
+    (name "ruby-mail")
+    (version "2.6.4")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (rubygems-uri "mail" version))
+       (sha256
+        (base32
+         "0c9vqfy0na9b5096i5i4qvrvhwamjnmajhgqi3kdsdfl8l6agmkp"))))
+    (build-system ruby-build-system)
+    (propagated-inputs
+     `(("ruby-mime-types" ,ruby-mime-types)))
+    (arguments
+     ;; Tests require extra gems not included in the Gemfile.
+     ;; XXX: Try enabling this for the next version with mini_mime.
+     `(#:tests? #f))
+    (synopsis "Mail library for Ruby")
+    (description
+     "Mail is an internet library for Ruby that is designed to handle email
+generation, parsing and sending.  The purpose of this library is to provide
+a single point of access to handle all email functions, including sending
+and receiving emails.  All network type actions are done through proxy
+methods to @code{Net::SMTP}, @code{Net::POP3} etc.
+
+Mail has been designed with a very simple object oriented system that
+really opens up the email messages you are parsing, if you know what you
+are doing, you can fiddle with every last bit of your email directly.")
+    (home-page "https://github.com/mikel/mail")
+    (license license:expat)))
diff --git a/gnu/packages/tls.scm b/gnu/packages/tls.scm
index 90878da933..b6a193de1b 100644
--- a/gnu/packages/tls.scm
+++ b/gnu/packages/tls.scm
@@ -5,6 +5,7 @@
 ;;; Copyright © 2013, 2015 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
 ;;; Copyright © 2015, 2016 Leo Famulari <leo@famulari.name>
+;;; Copyright © 2015, 2016, 2017 Leo Famulari <leo@famulari.name>
 ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 ng0 <ng0@we.make.ritual.n0.is>
 ;;; Copyright © 2016 Hartmut Goebel <h.goebel@crazy-compilers.com>
@@ -470,13 +471,13 @@ security, and applying best practice development processes.")
 (define-public python-acme
   (package
     (name "python-acme")
-    (version "0.9.3")
+    (version "0.10.1")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "acme" version))
       (sha256
-        (base32
-         "16a02bb0apnk1bm68bcabdmmwd6rnvnjzanrmcb46bpbapwz3vx6"))))
+       (base32
+        "04d2464klbhvrsrlmca10qxyd968qz7xizdppr53cihnlfq2y77m"))))
     (build-system python-build-system)
     (arguments
      `(#:phases
@@ -519,13 +520,13 @@ security, and applying best practice development processes.")
 (define-public certbot
   (package
     (name "certbot")
-    (version "0.9.3")
+    (version "0.10.1")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri name version))
               (sha256
                (base32
-                "1c7k4lfq5j78d1rvrwrb9082ngwibz92cwkf4kazaa9b76w9q538"))))
+                "0hx71ba7w8kf8hpg1wy5zf8ggczb57g3kcsdg83kxjpqnfnrkmp0"))))
     (build-system python-build-system)
     (arguments
      `(#:python ,python-2
diff --git a/gnu/packages/version-control.scm b/gnu/packages/version-control.scm
index fdd75a4ecd..fa757ff794 100644
--- a/gnu/packages/version-control.scm
+++ b/gnu/packages/version-control.scm
@@ -6,7 +6,7 @@
 ;;; Copyright © 2015, 2016 Mathieu Lirzin <mthl@gnu.org>
 ;;; Copyright © 2014, 2015, 2016 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2014, 2016 Eric Bavier <bavier@member.fsf.org>
-;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2015, 2016, 2017 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2015 Kyle Meyer <kyle@kyleam.com>
 ;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
@@ -842,19 +842,19 @@ masters from remote CVS hosts.")
 (define-public vc-dwim
   (package
     (name "vc-dwim")
-    (version "1.7")
+    (version "1.8")
     (source (origin
              (method url-fetch)
              (uri (string-append "mirror://gnu/vc-dwim/vc-dwim-"
                                  version ".tar.xz"))
              (sha256
               (base32
-               "094pjwshvazlgagc254in2xvrp93vhcj0kb5ms17qs7sch99x9z2"))))
+               "0d5sqafc40l878m8wjr35jxmalj4kam1m6ph60v08ng4ml5g7931"))))
     (build-system gnu-build-system)
     (inputs `(("perl" ,perl)
               ("inetutils" ,inetutils))) ; for `hostname', used in the tests
     (native-inputs `(("emacs" ,emacs-minimal))) ; for `ctags'
-    (home-page "http://www.gnu.org/software/vc-dwim/")
+    (home-page "https://www.gnu.org/software/vc-dwim/")
     (synopsis "Version-control-agnostic ChangeLog diff and commit tool")
     (description
      "The vc-dwim package contains two tools, \"vc-dwim\" and \"vc-chlog\".
diff --git a/gnu/packages/video.scm b/gnu/packages/video.scm
index a5b35479a0..2cef04d89a 100644
--- a/gnu/packages/video.scm
+++ b/gnu/packages/video.scm
@@ -970,7 +970,7 @@ access to mpv's powerful playback capabilities.")
 (define-public youtube-dl
   (package
     (name "youtube-dl")
-    (version "2017.01.10")
+    (version "2017.01.14")
     (source (origin
               (method url-fetch)
               (uri (string-append "https://yt-dl.org/downloads/"
@@ -978,7 +978,7 @@ access to mpv's powerful playback capabilities.")
                                   version ".tar.gz"))
               (sha256
                (base32
-                "0clr6vj9lg96fffc9xv2apr7an6lljnli1b8clfj4dap1i0d34v4"))))
+                "1jlwz6p7ryj9ygmwqm4r3pykd9qw21rsiqpifbx0p0kcvdvvvj3n"))))
     (build-system python-build-system)
     (arguments
      ;; The problem here is that the directory for the man page and completion
diff --git a/gnu/packages/vim.scm b/gnu/packages/vim.scm
index 7275b980ab..7ba4e6ac31 100644
--- a/gnu/packages/vim.scm
+++ b/gnu/packages/vim.scm
@@ -49,7 +49,7 @@
 (define-public vim
   (package
     (name "vim")
-    (version "8.0.0147")
+    (version "8.0.0187")
     (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/vim/vim/archive/v"
@@ -57,7 +57,7 @@
              (file-name (string-append name "-" version ".tar.gz"))
              (sha256
               (base32
-               "0rjq77n2gj3bb22dhawmbwkknii14gy7akplrplgxl1l789isfpq"))))
+               "1p9wdhksckp741406hnk5yj2lzhixfxzjs102zga0w8qw72p5yc6"))))
     (build-system gnu-build-system)
     (arguments
      `(#:test-target "test"
diff --git a/gnu/packages/xfce.scm b/gnu/packages/xfce.scm
index 5639f1daa3..fce47d93ce 100644
--- a/gnu/packages/xfce.scm
+++ b/gnu/packages/xfce.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2016 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2016 Florian Paul Schmidt <mista.tapas@gmx.net>
 ;;; Copyright © 2016 Kei Kebreau <kei@openmailbox.org>
+;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -661,7 +662,7 @@ devices and folders.")
 (define-public xfce4-terminal
   (package
     (name "xfce4-terminal")
-    (version "0.6.3")
+    (version "0.8.3")
     (source (origin
               (method url-fetch)
               (uri (string-append "http://archive.xfce.org/src/apps/" name "/"
@@ -669,14 +670,14 @@ devices and folders.")
                                   name "-" version ".tar.bz2"))
               (sha256
                (base32
-                "023y0lkfijifh05yz8grimxadqpi98mrivr00sl18nirq8b4fbwi"))))
+                "1w8jvi9nw00aki825mm8f7wpkhxxicw4f6j9v4ka71z8p2ry9rj0"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("pkg-config" ,pkg-config)
        ("intltool" ,intltool)))
     (inputs
      `(("libxfce4ui" ,libxfce4ui)
-       ("vte" ,vte/gtk+-2)))
+       ("vte" ,vte)))
     (home-page "http://www.xfce.org/")
     (synopsis "Xfce terminal emulator")
     (description
diff --git a/gnu/packages/xorg.scm b/gnu/packages/xorg.scm
index a27c431ddf..b780d47c32 100644
--- a/gnu/packages/xorg.scm
+++ b/gnu/packages/xorg.scm
@@ -2,7 +2,7 @@
 ;;; Copyright © 2013, 2014 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2014, 2015 Eric Bavier <bavier@member.fsf.org>
-;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015 Eric Dvorsak <eric@dvorsak.fr>
 ;;; Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
 ;;; Copyright © 2015 Cyrill Schenkel <cyrill.schenkel@gmail.com>
@@ -399,21 +399,31 @@ Resources file.")
     (description "Xorg font encoding files.")
     (license license:public-domain)))
 
+(define (%xorg-font-origin font version hash)
+  (origin
+    (method url-fetch)
+    (uri (string-append "mirror://xorg/individual/font/" font "-"
+                        version ".tar.bz2"))
+    (sha256 hash)
+    (modules '((guix build utils)))
+    (snippet
+     ;; Do not include timestamps in '.pcf.gz' files.
+     '(substitute* "Makefile.in"
+        (("^COMPRESS = (.*)$" _ rest)
+         (string-append "COMPRESS = " (string-trim-right rest)
+                        " --no-name\n"))))))
+
+(define-syntax-rule (xorg-font-origin font version hash)
+  "Expand to the 'origin' form for the given Xorg font package."
+  (%xorg-font-origin font version (base32 hash)))
 
 (define-public font-adobe100dpi
   (package
     (name "font-adobe100dpi")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-adobe-100dpi-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "0m60f5bd0caambrk8ksknb5dks7wzsg7g7xaf0j21jxmx8rq9h5j"))))
+    (source (xorg-font-origin
+             "font-adobe-100dpi" version
+             "0m60f5bd0caambrk8ksknb5dks7wzsg7g7xaf0j21jxmx8rq9h5j"))
     (build-system gnu-build-system)
     (inputs
       `(("bdftopcf" ,bdftopcf)
@@ -436,16 +446,9 @@ Resources file.")
   (package
     (name "font-adobe75dpi")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-adobe-75dpi-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "02advcv9lyxpvrjv8bjh1b797lzg6jvhipclz49z8r8y98g4l0n6"))))
+    (source (xorg-font-origin
+             "font-adobe-75dpi" version
+             "02advcv9lyxpvrjv8bjh1b797lzg6jvhipclz49z8r8y98g4l0n6"))
     (build-system gnu-build-system)
     (inputs
       `(("bdftopcf" ,bdftopcf)
@@ -472,16 +475,9 @@ Resources file.")
   (package
     (name "font-alias")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-alias-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "16ic8wfwwr3jicaml7b5a0sk6plcgc1kg84w02881yhwmqm3nicb"))))
+    (source (xorg-font-origin
+             name version
+             "16ic8wfwwr3jicaml7b5a0sk6plcgc1kg84w02881yhwmqm3nicb"))
     (build-system gnu-build-system)
     (native-inputs `(("pkg-config" ,pkg-config)))
     (arguments
@@ -513,16 +509,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-arabic-misc")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-arabic-misc-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "1x246dfnxnmflzf0qzy62k8jdpkb6jkgspcjgbk8jcq9lw99npah"))))
+    (source (xorg-font-origin
+             name version
+             "1x246dfnxnmflzf0qzy62k8jdpkb6jkgspcjgbk8jcq9lw99npah"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -550,16 +539,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-cronyx-cyrillic")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-cronyx-cyrillic-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "0ai1v4n61k8j9x2a1knvfbl2xjxk3xxmqaq3p9vpqrspc69k31kf"))))
+    (source (xorg-font-origin
+             name version
+             "0ai1v4n61k8j9x2a1knvfbl2xjxk3xxmqaq3p9vpqrspc69k31kf"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -583,16 +565,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-dec-misc")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-dec-misc-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "0yzza0l4zwyy7accr1s8ab7fjqkpwggqydbm2vc19scdby5xz7g1"))))
+    (source (xorg-font-origin
+             name version
+             "0yzza0l4zwyy7accr1s8ab7fjqkpwggqydbm2vc19scdby5xz7g1"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -612,16 +587,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-isas-misc")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-isas-misc-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "0rx8q02rkx673a7skkpnvfkg28i8gmqzgf25s9yi0lar915sn92q"))))
+    (source (xorg-font-origin
+             name version
+             "0rx8q02rkx673a7skkpnvfkg28i8gmqzgf25s9yi0lar915sn92q"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -642,16 +610,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-micro-misc")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-micro-misc-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "1dldxlh54zq1yzfnrh83j5vm0k4ijprrs5yl18gm3n9j1z0q2cws"))))
+    (source (xorg-font-origin
+             name version
+             "1dldxlh54zq1yzfnrh83j5vm0k4ijprrs5yl18gm3n9j1z0q2cws"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -668,16 +629,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-misc-cyrillic")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-misc-cyrillic-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "0q2ybxs8wvylvw95j6x9i800rismsmx4b587alwbfqiw6biy63z4"))))
+    (source (xorg-font-origin
+             name version
+             "0q2ybxs8wvylvw95j6x9i800rismsmx4b587alwbfqiw6biy63z4"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -694,16 +648,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-misc-ethiopic")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-misc-ethiopic-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "19cq7iq0pfad0nc2v28n681fdq3fcw1l1hzaq0wpkgpx7bc1zjsk"))))
+    (source (xorg-font-origin
+             name version
+             "19cq7iq0pfad0nc2v28n681fdq3fcw1l1hzaq0wpkgpx7bc1zjsk"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -724,16 +671,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-misc-misc")
     (version "1.1.2")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-misc-misc-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "150pq6n8n984fah34n3k133kggn9v0c5k07igv29sxp1wi07krxq"))))
+    (source (xorg-font-origin
+             name version
+             "150pq6n8n984fah34n3k133kggn9v0c5k07igv29sxp1wi07krxq"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -754,16 +694,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-mutt-misc")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-mutt-misc-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "13qghgr1zzpv64m0p42195k1kc77pksiv059fdvijz1n6kdplpxx"))))
+    (source (xorg-font-origin
+             name version
+             "13qghgr1zzpv64m0p42195k1kc77pksiv059fdvijz1n6kdplpxx"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -780,16 +713,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-schumacher-misc")
     (version "1.1.2")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-schumacher-misc-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "0nkym3n48b4v36y4s927bbkjnsmicajarnf6vlp7wxp0as304i74"))))
+    (source (xorg-font-origin
+             name version
+             "0nkym3n48b4v36y4s927bbkjnsmicajarnf6vlp7wxp0as304i74"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -810,16 +736,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-screen-cyrillic")
     (version "1.0.4")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-screen-cyrillic-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "0yayf1qlv7irf58nngddz2f1q04qkpr5jwp4aja2j5gyvzl32hl2"))))
+    (source (xorg-font-origin
+             name version
+             "0yayf1qlv7irf58nngddz2f1q04qkpr5jwp4aja2j5gyvzl32hl2"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -836,16 +755,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-sony-misc")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-sony-misc-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "1xfgcx4gsgik5mkgkca31fj3w72jw9iw76qyrajrsz1lp8ka6hr0"))))
+    (source (xorg-font-origin
+             name version
+             "1xfgcx4gsgik5mkgkca31fj3w72jw9iw76qyrajrsz1lp8ka6hr0"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -862,16 +774,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-sun-misc")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-sun-misc-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "1q6jcqrffg9q5f5raivzwx9ffvf7r11g6g0b125na1bhpz5ly7s8"))))
+    (source (xorg-font-origin
+             name version
+             "1q6jcqrffg9q5f5raivzwx9ffvf7r11g6g0b125na1bhpz5ly7s8"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -911,16 +816,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-winitzki-cyrillic")
     (version "1.0.3")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-winitzki-cyrillic-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "181n1bgq8vxfxqicmy1jpm1hnr6gwn1kdhl6hr4frjigs1ikpldb"))))
+    (source (xorg-font-origin
+             name version
+             "181n1bgq8vxfxqicmy1jpm1hnr6gwn1kdhl6hr4frjigs1ikpldb"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
@@ -937,16 +835,9 @@ For example: '6x10', '9x15bold', etc.")
   (package
     (name "font-xfree86-type1")
     (version "1.0.4")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/font/font-xfree86-type1-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-            "0jp3zc0qfdaqfkgzrb44vi9vi0a8ygb35wp082yz7rvvxhmg9sya"))))
+    (source (xorg-font-origin
+             name version
+             "0jp3zc0qfdaqfkgzrb44vi9vi0a8ygb35wp082yz7rvvxhmg9sya"))
     (build-system gnu-build-system)
     (inputs
       `(("mkfontdir" ,mkfontdir)
diff --git a/gnu/services/vpn.scm b/gnu/services/vpn.scm
new file mode 100644
index 0000000000..c21995453e
--- /dev/null
+++ b/gnu/services/vpn.scm
@@ -0,0 +1,491 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Julien Lepiller <julien@lepiller.eu>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu services vpn)
+  #:use-module (gnu services)
+  #:use-module (gnu services configuration)
+  #:use-module (gnu services shepherd)
+  #:use-module (gnu system shadow)
+  #:use-module (gnu packages admin)
+  #:use-module (gnu packages vpn)
+  #:use-module (guix packages)
+  #:use-module (guix records)
+  #:use-module (guix gexp)
+  #:use-module (srfi srfi-1)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 regex)
+  #:export (openvpn-client-service
+            openvpn-server-service
+            openvpn-client-service-type
+            openvpn-server-service-type
+            openvpn-client-configuration
+            openvpn-server-configuration
+            openvpn-remote-configuration
+            openvpn-ccd-configuration
+            generate-openvpn-client-documentation
+            generate-openvpn-server-documentation))
+
+;;;
+;;; OpenVPN.
+;;;
+
+(define (uglify-field-name name)
+  (match name
+         ('verbosity "verb")
+         (_ (let ((str (symbol->string name)))
+              (if (string-suffix? "?" str)
+                  (substring str 0 (1- (string-length str)))
+                  str)))))
+
+(define (serialize-field field-name val)
+  (if (eq? field-name 'pid-file)
+      (format #t "")
+      (format #t "~a ~a\n" (uglify-field-name field-name) val)))
+(define serialize-string serialize-field)
+(define (serialize-boolean field-name val)
+  (if val
+      (serialize-field field-name val)
+      (format #t "")))
+
+(define (ip-mask? val)
+  (and (string? val)
+       (if (string-match "^([0-9]+\\.){3}[0-9]+ ([0-9]+\\.){3}[0-9]+$" val)
+           (let ((numbers (string-tokenize val char-set:digit)))
+             (all-lte numbers (list 255 255 255 255 255 255 255 255)))
+           #f)))
+(define serialize-ip-mask serialize-string)
+
+(define-syntax define-enumerated-field-type
+  (lambda (x)
+    (define (id-append ctx . parts)
+      (datum->syntax ctx (apply symbol-append (map syntax->datum parts))))
+    (syntax-case x ()
+      ((_ name (option ...))
+       #`(begin
+           (define (#,(id-append #'name #'name #'?) x)
+             (memq x '(option ...)))
+           (define (#,(id-append #'name #'serialize- #'name) field-name val)
+             (serialize-field field-name val)))))))
+
+(define-enumerated-field-type proto
+  (udp tcp udp6 tcp6))
+(define-enumerated-field-type dev
+  (tun tap))
+
+(define key-usage? boolean?)
+(define (serialize-key-usage field-name value)
+  (if value
+      (format #t "remote-cert-tls server\n")
+      #f))
+
+(define bind? boolean?)
+(define (serialize-bind field-name value)
+  (if value
+      #f
+      (format #t "nobind\n")))
+
+(define resolv-retry? boolean?)
+(define (serialize-resolv-retry field-name value)
+  (if value
+      (format #t "resolv-retry infinite\n")
+      #f))
+
+(define (serialize-tls-auth role location)
+  (serialize-field 'tls-auth
+                   (string-append location " " (match role
+                                                      ('server "0")
+                                                      ('client "1")))))
+(define (tls-auth? val)
+  (or (eq? val #f)
+      (string? val)))
+(define (serialize-tls-auth-server field-name val)
+  (serialize-tls-auth 'server val))
+(define (serialize-tls-auth-client field-name val)
+  (serialize-tls-auth 'client val))
+(define tls-auth-server? tls-auth?)
+(define tls-auth-client? tls-auth?)
+
+(define (serialize-number field-name val)
+  (serialize-field field-name (number->string val)))
+
+(define (all-lte left right)
+  (if (eq? left '())
+      (eq? right '())
+      (and (<= (string->number (car left)) (car right))
+           (all-lte (cdr left) (cdr right)))))
+
+(define (cidr4? val)
+  (if (string? val)
+      (if (string-match "^([0-9]+\\.){3}[0-9]+/[0-9]+$" val)
+          (let ((numbers (string-tokenize val char-set:digit)))
+            (all-lte numbers (list 255 255 255 255 32)))
+          #f)
+      (eq? val #f)))
+
+(define (cidr6? val)
+  (if (string? val)
+      (string-match "^([0-9a-f]{0,4}:){0,8}/[0-9]{1,3}$" val)
+      (eq? val #f)))
+
+(define (serialize-cidr4 field-name val)
+  (if (eq? val #f) #f (serialize-field field-name val)))
+
+(define (serialize-cidr6 field-name val)
+  (if (eq? val #f) #f (serialize-field field-name val)))
+
+(define (ip? val)
+  (if (string? val)
+      (if (string-match "^([0-9]+\\.){3}[0-9]+$" val)
+          (let ((numbers (string-tokenize val char-set:digit)))
+            (all-lte numbers (list 255 255 255 255)))
+          #f)
+      (eq? val #f)))
+(define (serialize-ip field-name val)
+  (if (eq? val #f) #f (serialize-field field-name val)))
+
+(define (keepalive? val)
+  (and (list? val)
+       (and (number? (car val))
+            (number? (car (cdr val))))))
+(define (serialize-keepalive field-name val)
+  (format #t "~a ~a ~a\n" (uglify-field-name field-name)
+          (number->string (car val)) (number->string (car (cdr val)))))
+
+(define gateway? boolean?)
+(define (serialize-gateway field-name val)
+  (and val
+       (format #t "push \"redirect-gateway\"\n")))
+
+
+(define-configuration openvpn-remote-configuration
+  (name
+   (string "my-server")
+   "Server name.")
+  (port
+   (number 1194)
+   "Port number the server listens to."))
+
+(define-configuration openvpn-ccd-configuration
+  (name
+   (string "client")
+   "Client name.")
+  (iroute
+   (ip-mask #f)
+   "Client own network")
+  (ifconfig-push
+   (ip-mask #f)
+   "Client VPN IP."))
+
+(define (openvpn-remote-list? val)
+  (and (list? val)
+       (or (eq? val '())
+           (and (openvpn-remote-configuration? (car val))
+                (openvpn-remote-list? (cdr val))))))
+(define (serialize-openvpn-remote-list field-name val)
+  (for-each (lambda (remote)
+              (format #t "remote ~a ~a\n" (openvpn-remote-configuration-name remote)
+                      (number->string (openvpn-remote-configuration-port remote))))
+            val))
+
+(define (openvpn-ccd-list? val)
+  (and (list? val)
+       (or (eq? val '())
+           (and (openvpn-ccd-configuration? (car val))
+                (openvpn-ccd-list? (cdr val))))))
+(define (serialize-openvpn-ccd-list field-name val)
+  #f)
+
+(define (create-ccd-directory val)
+  "Create a ccd directory containing files for the ccd configuration option
+of OpenVPN.  Each file in this directory represents particular settings for a
+client.  Each file is named after the name of the client."
+  (let ((files (map (lambda (ccd)
+                      (list (openvpn-ccd-configuration-name ccd)
+                            (with-output-to-string
+                              (lambda ()
+                                (serialize-configuration
+                                 ccd openvpn-ccd-configuration-fields)))))
+                    val)))
+    (computed-file "ccd"
+                   (with-imported-modules '((guix build utils))
+                     #~(begin
+                         (use-modules (guix build utils))
+                         (use-modules (ice-9 match))
+                         (mkdir-p #$output)
+                         (for-each
+                          (lambda (ccd)
+                            (match ccd
+                                   ((name config-string)
+                                    (call-with-output-file
+                                        (string-append #$output "/" name)
+                                      (lambda (port) (display config-string port))))))
+                          '#$files))))))
+
+(define-syntax define-split-configuration
+  (lambda (x)
+    (syntax-case x ()
+      ((_ name1 name2 (common-option ...) (first-option ...) (second-option ...))
+       #`(begin
+           (define-configuration #,#'name1
+             common-option ...
+             first-option ...)
+           (define-configuration #,#'name2
+             common-option ...
+             second-option ...))))))
+
+(define-split-configuration openvpn-client-configuration
+  openvpn-server-configuration
+  ((openvpn
+    (package openvpn)
+    "The OpenVPN package.")
+
+   (pid-file
+    (string "/var/run/openvpn/openvpn.pid")
+    "The OpenVPN pid file.")
+
+   (proto
+    (proto 'udp)
+    "The protocol (UDP or TCP) used to open a channel between clients and
+servers.")
+
+   (dev
+    (dev 'tun)
+    "The device type used to represent the VPN connection.")
+
+   (ca
+    (string "/etc/openvpn/ca.crt")
+    "The certificate authority to check connections against.")
+
+   (cert
+    (string "/etc/openvpn/client.crt")
+    "The certificate of the machine the daemon is running on. It should be signed
+by the authority given in @code{ca}.")
+
+   (key
+    (string "/etc/openvpn/client.key")
+    "The key of the machine the daemon is running on. It must be the whose
+certificate is @code{cert}.")
+
+   (comp-lzo?
+    (boolean #t)
+    "Whether to use the lzo compression algorithm.")
+
+   (persist-key?
+    (boolean #t)
+    "Don't re-read key files across SIGUSR1 or --ping-restart.")
+
+   (persist-tun?
+    (boolean #t)
+    "Don't close and reopen TUN/TAP device or run up/down scripts across
+SIGUSR1 or --ping-restart restarts.")
+
+   (verbosity
+    (number 3)
+    "Verbosity level."))
+  ;; client-specific configuration
+  ((tls-auth
+    (tls-auth-client #f)
+    "Add an additional layer of HMAC authentication on top of the TLS control
+channel to protect against DoS attacks.")
+
+   (verify-key-usage?
+    (key-usage #t)
+    "Whether to check the server certificate has server usage extension.")
+
+   (bind?
+    (bind #f)
+    "Bind to a specific local port number.")
+
+   (resolv-retry?
+    (resolv-retry #t)
+    "Retry resolving server address.")
+
+   (remote
+    (openvpn-remote-list '())
+    "A list of remote servers to connect to."))
+  ;; server-specific configuration
+  ((tls-auth
+    (tls-auth-server #f)
+    "Add an additional layer of HMAC authentication on top of the TLS control
+channel to protect against DoS attacks.")
+
+   (port
+    (number 1194)
+    "Specifies the port number on which the server listens.")
+
+   (server
+    (ip-mask "10.8.0.0 255.255.255.0")
+    "An ip and mask specifying the subnet inside the virtual network.")
+
+   (server-ipv6
+    (cidr6 #f)
+    "A CIDR notation specifying the IPv6 subnet inside the virtual network.")
+
+   (dh
+    (string "/etc/openvpn/dh2048.pem")
+    "The Diffie-Hellman parameters file.")
+
+   (ifconfig-pool-persist
+    (string "/etc/openvpn/ipp.txt")
+    "The file that records client IPs.")
+
+   (redirect-gateway?
+    (gateway #f)
+    "When true, the server will act as a gateway for its clients.")
+
+   (client-to-client?
+    (boolean #f)
+    "When true, clients are alowed to talk to each other inside the VPN.")
+
+   (keepalive
+    (keepalive '(10 120))
+    "Causes ping-like messages to be sent back and forth over the link so that
+each side knows when the other side has gone down. @code{keepalive} requires
+a pair. The first element is the period of the ping sending, and the second
+element is the timeout before considering the other side down.")
+
+   (max-clients
+    (number 100)
+    "The maximum number of clients.")
+
+   (status
+    (string "/var/run/openvpn/status")
+    "The status file. This file shows a small report on current connection. It
+is trunkated and rewritten every minute.")
+
+   (client-config-dir
+    (openvpn-ccd-list '())
+    "The list of configuration for some clients.")))
+
+(define (openvpn-config-file role config)
+  (let ((config-str
+         (with-output-to-string
+           (lambda ()
+             (serialize-configuration config
+                                      (match role
+                                             ('server
+                                              openvpn-server-configuration-fields)
+                                             ('client
+                                              openvpn-client-configuration-fields))))))
+        (ccd-dir (match role
+                        ('server (create-ccd-directory
+                                  (openvpn-server-configuration-client-config-dir
+                                   config)))
+                        ('client #f))))
+    (computed-file "openvpn.conf"
+                   #~(begin
+                       (use-modules (ice-9 match))
+                       (call-with-output-file #$output
+                         (lambda (port)
+                           (match '#$role
+                                  ('server (display "" port))
+                                  ('client (display "client\n" port)))
+                           (display #$config-str port)
+                           (match '#$role
+                                  ('server (display
+                                            (string-append "client-config-dir "
+                                                           #$ccd-dir "\n") port))
+                                  ('client (display "" port)))))))))
+
+(define (openvpn-shepherd-service role)
+  (lambda (config)
+    (let* ((config-file (openvpn-config-file role config))
+           (pid-file ((match role
+                             ('server openvpn-server-configuration-pid-file)
+                             ('client openvpn-client-configuration-pid-file))
+                      config))
+           (openvpn ((match role
+                            ('server openvpn-server-configuration-openvpn)
+                            ('client openvpn-client-configuration-openvpn))
+                     config))
+           (log-file (match role
+                            ('server "/var/log/openvpn-server.log")
+                            ('client "/var/log/openvpn-client.log"))))
+      (list (shepherd-service
+             (documentation (string-append "Run the OpenVPN "
+                                           (match role
+                                                  ('server "server")
+                                                  ('client "client"))
+                                           " daemon."))
+             (provision (match role
+                               ('server '(vpn-server))
+                               ('client '(vpn-client))))
+             (requirement '(networking))
+             (start #~(make-forkexec-constructor
+                       (list (string-append #$openvpn "/sbin/openvpn")
+                             "--writepid" #$pid-file "--config" #$config-file
+                             "--daemon")
+                       #:pid-file #$pid-file))
+             (stop #~(make-kill-destructor)))))))
+
+(define %openvpn-accounts
+  (list (user-group (name "openvpn") (system? #t))
+        (user-account
+         (name "openvpn")
+         (group "openvpn")
+         (system? #t)
+         (comment "Openvpn daemon user")
+         (home-directory "/var/empty")
+         (shell (file-append shadow "/sbin/nologin")))))
+
+(define %openvpn-activation
+  #~(mkdir-p "/var/run/openvpn"))
+
+(define openvpn-server-service-type
+  (service-type (name 'openvpn-server)
+                (extensions
+                 (list (service-extension shepherd-root-service-type
+                                          (openvpn-shepherd-service 'server))
+                       (service-extension account-service-type
+                                          (const %openvpn-accounts))
+                       (service-extension activation-service-type
+                                          (const %openvpn-activation))))))
+
+(define openvpn-client-service-type
+  (service-type (name 'openvpn-client)
+                (extensions
+                 (list (service-extension shepherd-root-service-type
+                                          (openvpn-shepherd-service 'client))
+                       (service-extension account-service-type
+                                          (const %openvpn-accounts))
+                       (service-extension activation-service-type
+                                          (const %openvpn-activation))))))
+
+(define* (openvpn-client-service #:key (config (openvpn-client-configuration)))
+  (validate-configuration config openvpn-client-configuration-fields)
+  (service openvpn-client-service-type config))
+
+(define* (openvpn-server-service #:key (config (openvpn-server-configuration)))
+  (validate-configuration config openvpn-server-configuration-fields)
+  (service openvpn-server-service-type config))
+
+(define (generate-openvpn-server-documentation)
+  (generate-documentation
+   `((openvpn-server-configuration
+      ,openvpn-server-configuration-fields
+      (ccd openvpn-ccd-configuration))
+     (openvpn-ccd-configuration ,openvpn-ccd-configuration-fields))
+   'openvpn-server-configuration))
+
+(define (generate-openvpn-client-documentation)
+  (generate-documentation
+   `((openvpn-client-configuration
+      ,openvpn-client-configuration-fields
+      (remote openvpn-remote-configuration))
+     (openvpn-remote-configuration ,openvpn-remote-configuration-fields))
+   'openvpn-client-configuration))