gale: init at 1.1happy

This commit is contained in:
Mark Laws 2015-08-03 10:04:10 -07:00
parent c1df52d021
commit e7ba7fba01
6 changed files with 557 additions and 0 deletions

View file

@ -244,6 +244,7 @@
postsrsd = 220;
opendkim = 221;
dspam = 222;
gale = 223;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
@ -465,6 +466,7 @@
postsrsd = 220;
opendkim = 221;
dspam = 222;
gale = 223;
# When adding a gid, make sure it doesn't match an existing
# uid. Users and groups with the same name should have equal

View file

@ -301,6 +301,7 @@
./services/networking/firewall.nix
./services/networking/flashpolicyd.nix
./services/networking/freenet.nix
./services/networking/gale.nix
./services/networking/gateone.nix
./services/networking/git-daemon.nix
./services/networking/gnunet.nix

View file

@ -0,0 +1,182 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.gale;
# we convert the path to a string to avoid it being copied to the nix store,
# otherwise users could read the private key as all files in the store are
# world-readable
keyPath = toString cfg.keyPath;
# ...but we refer to the pubkey file using a path so that we can ensure the
# config gets rebuilt if the public key changes (we can assume the private key
# will never change without the public key having changed)
gpubFile = cfg.keyPath + "/${cfg.domain}.gpub";
home = "/var/lib/gale";
keysPrepared = cfg.keyPath != null && lib.pathExists cfg.keyPath;
in
{
options = {
services.gale = {
enable = mkEnableOption "the Gale messaging daemon";
user = mkOption {
default = "gale";
type = types.str;
description = "Username for the Gale daemon.";
};
group = mkOption {
default = "gale";
type = types.str;
description = "Group name for the Gale daemon.";
};
setuidWrapper = mkOption {
default = null;
description = "Configuration for the Gale gksign setuid wrapper.";
};
domain = mkOption {
default = "";
type = types.str;
description = "Domain name for the Gale system.";
};
keyPath = mkOption {
default = null;
type = types.nullOr types.path;
description = ''
Directory containing the key pair for this Gale domain. The expected
filename will be taken from the domain option with ".gpri" and ".gpub"
appended.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional text to be added to <filename>/etc/gale/conf</filename>.
'';
};
};
};
config = mkMerge [
(mkIf cfg.enable {
assertions = [{
assertion = cfg.domain != "";
message = "A domain must be set for Gale.";
}];
warnings = mkIf (!keysPrepared) [
"You must run gale-install in order to generate a domain key."
];
system.activationScripts.gale = mkIf cfg.enable (
stringAfter [ "users" "groups" ] ''
chmod -R 755 ${home}
mkdir -m 0777 -p ${home}/auth/cache
mkdir -m 1777 -p ${home}/auth/local # GALE_DOMAIN.gpub
mkdir -m 0700 -p ${home}/auth/private # ROOT.gpub
mkdir -m 0755 -p ${home}/auth/trusted # ROOT
mkdir -m 0700 -p ${home}/.gale
mkdir -m 0700 -p ${home}/.gale/auth
mkdir -m 0700 -p ${home}/.gale/auth/private # GALE_DOMAIN.gpri
ln -sf ${pkgs.gale}/etc/gale/auth/trusted/ROOT "${home}/auth/trusted/ROOT"
chown -R ${cfg.user}:${cfg.group} ${home}
''
);
environment = {
etc = {
"gale/auth".source = home + "/auth"; # symlink /var/lib/gale/auth
"gale/conf".text = ''
GALE_USER ${cfg.user}
GALE_DOMAIN ${cfg.domain}
${cfg.extraConfig}
'';
};
systemPackages = [ pkgs.gale ];
};
users.extraUsers = [{
name = cfg.user;
description = "Gale daemon";
uid = config.ids.uids.gale;
group = cfg.group;
home = home;
createHome = true;
}];
users.extraGroups = [{
name = cfg.group;
gid = config.ids.gids.gale;
}];
})
(mkIf (cfg.enable && keysPrepared) {
assertions = [
{
assertion = cfg.keyPath != null
&& lib.pathExists (cfg.keyPath + "/${cfg.domain}.gpub");
message = "Couldn't find a Gale public key for ${cfg.domain}.";
}
{
assertion = cfg.keyPath != null
&& lib.pathExists (cfg.keyPath + "/${cfg.domain}.gpri");
message = "Couldn't find a Gale private key for ${cfg.domain}.";
}
];
services.gale.setuidWrapper = {
program = "gksign";
source = "${pkgs.gale}/bin/gksign";
owner = cfg.user;
group = cfg.group;
setuid = true;
setgid = false;
};
security.setuidOwners = [ cfg.setuidWrapper ];
systemd.services.gale-galed = {
description = "Gale messaging daemon";
wantedBy = [ "multi-user.target" ];
wants = [ "gale-gdomain.service" ];
after = [ "network.target" ];
preStart = ''
install -m 0640 ${keyPath}/${cfg.domain}.gpri "${home}/.gale/auth/private/"
install -m 0644 ${gpubFile} "${home}/.gale/auth/private/${cfg.domain}.gpub"
install -m 0644 ${gpubFile} "${home}/auth/local/${cfg.domain}.gpub"
chown -R ${cfg.user}:${cfg.group} ${home}
'';
serviceConfig = {
Type = "forking";
ExecStart = "@${pkgs.gale}/bin/galed galed";
User = cfg.user;
Group = cfg.group;
PermissionsStartOnly = true;
};
};
systemd.services.gale-gdomain = {
description = "Gale AKD daemon";
wantedBy = [ "multi-user.target" ];
requires = [ "gale-galed.service" ];
after = [ "gale-galed.service" ];
serviceConfig = {
Type = "forking";
ExecStart = "@${pkgs.gale}/bin/gdomain gdomain";
User = cfg.user;
Group = cfg.group;
};
};
})
];
}

View file

@ -0,0 +1,31 @@
{ stdenv, fetchFromGitHub, adns, boehmgc, openssl, automake, m4, autoconf
, libtool, pkgconfig }:
stdenv.mkDerivation {
name = "gale-1.1happy";
src = fetchFromGitHub {
owner = "grawity";
repo = "gale";
rev = "b34a67288e8bd6f0b51b60abb704858172a3665c";
sha256 = "19mcisxxqx70m059rqwv7wpmp94fgyckzjwywpmdqd7iwvppnsqf";
};
nativeBuildInputs = [ m4 libtool automake autoconf ];
buildInputs = [ boehmgc openssl adns pkgconfig ];
patches = [ ./gale-install.in.patch ];
preConfigure = ''
substituteInPlace configure.ac --replace \$\{sysconfdir\} /etc
./bootstrap
'';
configureArgs = [ "--sysconfdir=/etc" ];
meta = with stdenv.lib; {
homepage = "http://gale.org/";
description = "chat/messaging system (server and client)";
platforms = platforms.all;
license = licenses.gpl2Plus;
};
}

View file

@ -0,0 +1,339 @@
diff --git a/gale-install.in b/gale-install.in
index 50e8ad8..eec0ed2 100644
--- a/gale-install.in
+++ b/gale-install.in
@@ -29,22 +29,78 @@ testkey_stdin() {
gkinfo -x 2>/dev/null | qgrep "^Public key: <$1>"
}
-if [ -n "$GALE_SYS_DIR" ]; then
- SYS_DIR="$GALE_SYS_DIR"
-elif [ -n "$sysconfdir" ]; then
- SYS_DIR="$sysconfdir/gale"
+INST_SYS_DIR="$sysconfdir/gale"
+
+if [ `id -u` -eq 0 ]; then
+ is_root=yes
+ SYS_DIR=/etc/gale
+else
+ is_root=no
+ SYS_DIR="$HOME/.gale"
+fi
+
+if [ -f /etc/NIXOS ]; then
+ is_nixos=yes
+else
+ is_nixos=no
+fi
+
+if [ -u /var/setuid-wrappers/gksign ]; then
+ cat <<EOM
+
+Gale appears to have already been set up via the NixOS module system (check
+/etc/nixos/configuration.nix).
+
+EOM
+
+ exit 0
+fi
+
+if [ $is_root = yes ]; then
+ cat <<EOM
+
+You are running gale-install as root, so I'm going to assume you want to set up
+Gale for system-wide use. Unfortunately, Gale expects to be able to run the
+"gksign" program via setuid, and we can't change gksign's permissions once it's
+already been installed because the Nix store is immutable by design.
+
+EOM
+
+ if [ $is_nixos = no ]; then
+ cat <<EOM
+
+This isn't a NixOS system. Gale can only be installed for a single user on
+non-NixOS systems. If you want a system-wide installation, you'll have to
+install Gale the old-fashioned way. Sorry.
+
+EOM
+
+ exit 1
+ fi
+ cat <<EOM
+
+This script will generate a domain key for you, and after you get it signed, you
+can finish the setup process by configuring Gale via the NixOS module system
+(i.e. /etc/nixos/configuration.nix).
+
+EOM
+
else
- echo "Error: cannot locate Gale system configuration directory."
- exit 1
+ cat <<EOM
+
+Hi. You are running gale-install as a normal user, so I'm going to assume you
+want to set up Gale for your own (i.e. non-system-wide) use.
+
+EOM
+
fi
-CONF="$SYS_DIR/conf"
umask 022
-PATH="$bindir:$sbindir:$PATH:/usr/ucb"
+PATH="$bindir:$sbindir:$PATH"
export PATH
-if [ -f "$CONF" ]; then
- exec 3<"$CONF"
+if [ -n "$SYS_DIR" ] && [ -f "$SYS_DIR/conf" ]; then
+ exec 3<"$SYS_DIR/conf"
while read var value <&3 ; do
case "$var" in
@@ -58,52 +114,14 @@ if [ -f "$CONF" ]; then
exec 3<&-
fi
-USER="`whoami`"
-if [ -z "$USER" ]; then
- echo "Error: cannot determine your username."
- exit 1
-fi
-
-# -----------------------------------------------------------------------------
-# check directory structure
-
-if [ ! -d "$SYS_DIR" ]; then
- echo "Error: Invalid SYS_DIR: \"$SYS_DIR\"."
- exit 1
-fi
-
# -----------------------------------------------------------------------------
-# get settings for important variables: user, domain, server
+# get settings for important variables: domain, server
-[ -n "$CONF_GALE_USER" ] && GALE_USER="$CONF_GALE_USER"
[ -n "$CONF_GALE_DOMAIN" ] && GALE_DOMAIN="$CONF_GALE_DOMAIN"
[ -n "$CONF_GALE_SERVER" ] && GALE_SERVER="$CONF_GALE_SERVER"
-if [ -z "$GALE_USER" ]; then
-cat << EOM
-
-Hi. You need to denote a user to own the Gale domain secret key. You must
-trust this user with Gale authentication for your domain; the "gksign" program
-will run as this user. I recommend using a special "gale" user; if you don't
-have administrative privileges here, you'll probably have to use your own
-account. I do not recommend the use of "root".
-
-No harm done if you stop this script now to set up such a user.
-
-EOM
-
- printf "Enter the Gale username: "
- read GALE_USER
- if [ -z "$GALE_USER" ]; then
- echo "Error: Invalid username or no home dir: \"$GALE_USER\"."
- exit 1
- fi
-else
- echo "Using \"$GALE_USER\" as the Gale owner."
-fi
-
if [ -z "$GALE_DOMAIN" ] ; then
-cat << EOM
+ cat << EOM
You need to identify the name of your Gale domain for two purposes:
@@ -140,97 +158,56 @@ else
fi
# -----------------------------------------------------------------------------
-# create configuration file
-
-if [ ! -f "$CONF" ]; then
-cat > "$CONF" <<EOM
-# $CONF -- created by Gale installer; edit to suit.
-EOM
+# create configuration file (if this is a single-user setup)
+
+if [ $is_root = no ]; then
+ CONF="$SYS_DIR/conf"
+
+ if [ ! -d "$SYS_DIR" ]; then
+ run mkdir -m 0700 -p "$SYS_DIR"
+ run mkdir -m 0700 -p "$SYS_DIR/auth"
+ run mkdir -m 0755 -p "$SYS_DIR/auth/trusted"
+ run cp -f "$INST_SYS_DIR/auth/trusted/ROOT" "$SYS_DIR/auth/trusted"
+ run mkdir -m 0700 -p "$SYS_DIR/auth/private"
+ run mkdir -p "$SYS_DIR/auth/local" "$SYS_DIR/auth/cache"
+ fi
-cat <<EOM
+ if [ ! -f "$CONF" ]; then
+ cat <<EOM
*** Creating "$CONF".
Examine and edit this file to your taste and local needs.
If you want to recreate it from scratch, remove it and re-run this.
-EOM
-fi
-
-[ -n "$CONF_GALE_USER" ] || cat >> "$CONF" <<EOM
-# The user who owns the domain secret key. (Used in installation and upgrade)
-GALE_USER $GALE_USER
EOM
-[ -n "$CONF_GALE_DOMAIN" ] || cat >> "$CONF" << EOM
+ cat > "$CONF" <<EOF
+# $CONF -- created by Gale installer; edit to suit.
# The authentication domain to use. (Mandatory)
GALE_DOMAIN $GALE_DOMAIN
-EOM
-
-# -----------------------------------------------------------------------------
-# make gksign setuid
+EOF
-gksign="$sbindir/gksign"
-readlink="`which readlink 2>/dev/null`"
-[ -x "$readlink" ] && gksignlink="`"$readlink" "$gksign" 2>/dev/null`"
-[ -f "$gksignlink" ] && gksign="$gksignlink"
-
-echo ""
-if copy chown "$GALE_USER" "$gksign" ; then
- :
-else
- echo "*** We need to chown $GALE_USER '$gksign'."
- echo " Please run this script as a user that can do so,"
- echo " or do so yourself and re-run this script."
- exit 1
+ fi
fi
-run chmod 4755 "$gksign"
-# -----------------------------------------------------------------------------
-# create a domain, if necessary
+if [ $is_root = no ]; then
+ GALE_SYS_DIR="$SYS_DIR"
+ export GALE_SYS_DIR
-echo ""
-if test -u "$gksign" || copy chmod u+s "$gksign" ; then
- :
+ testkey "$GALE_DOMAIN" && exit 0
+ echo "*** You lack a signed key for your domain, \"$GALE_DOMAIN\"."
+ GALE="$SYS_DIR"
else
- echo "*** We need to chmod u+s '$gksign'."
- echo " Please run this script as a user that can do so,"
- echo " or do so yourself and re-run this script."
- exit 1
-fi
-
-testkey "$GALE_DOMAIN" && exit 0
-echo "*** You lack a signed key for your domain, \"$GALE_DOMAIN\"."
-
-if [ "x$GALE_USER" != "x$USER" ]; then
-cat <<EOM
-Become user "$GALE_USER" (you are now "$USER") and run this script again
-to create a new domain; contact your domain administrator if you wish to
-become part of an existing domain.
-EOM
- exit 1
-fi
-
-if [ -z "$HOME" ]; then
- cd
- HOME="`pwd`"
- echo "Warning: \$HOME not set, assuming \"$HOME\"."
-fi
-
-GALE="$HOME/.gale"
-mkdir -p "$GALE"
-if [ ! -w "$GALE" ]; then
- echo "Error: Cannot create \"$GALE\"."
- exit 1
+ GALE="`pwd`"
fi
unsigned="$GALE/$GALE_DOMAIN.unsigned"
signer="`echo "$GALE_DOMAIN" | sed 's%^[^.@:/]*[.@:/]%%'`"
[ -z "$signer" ] && signer="ROOT"
-if [ -f "$unsigned" ]; then
-
-cat << EOM
+if [ $is_root = no ] && [ -f "$unsigned" ]; then
+ cat << EOM
Okay, so we've already been here. Last time, I created the file
"$unsigned" for you to have signed.
@@ -275,16 +252,12 @@ EOM
exit 1
fi
-cat << EOM
-
-The domain should be properly configured now. Assuming users can access a
-version of "gksign" setuid to "$GALE_USER" (this user), they should be
-able to start running clients and generating IDs for themselves.
+ cat << EOM
-The installation process is complete!
+The domain should be properly configured now. The installation process is
+complete!
EOM
-
exit 0
fi
@@ -300,7 +273,10 @@ printf "Enter the description: "
read descr
echo "We will generate the key now. Have patience."
-gkgen -r "$GALE/auth/private/$GALE_DOMAIN.gpri" \
+if [ $is_root = no ]; then
+ install_gpri=auth/private/
+fi
+gkgen -r "$GALE/${install_gpri}$GALE_DOMAIN.gpri" \
-u "$unsigned" "$GALE_DOMAIN" /"$descr" || exit 1
cat << EOM
@@ -311,8 +284,29 @@ the owner of the "$signer" domain through appropriate means.
Take care to preseve the file's binary data; you may need to uuencode it.
Assuming they trust you with your subdomain, they should pass the key through
-"gksign" as a filter, returning the signed output to you. When you have this
-signed key file available, re-run this script, and we will move on to the
-next step.
+"gksign" as a filter, returning the signed output to you.
+
+EOM
+
+if [ $is_nixos = yes ]; then
+ cat <<EOM
+
+When you have this signed key file available, you can finish the setup process
+by placing the private key and signed public key in a directory (they will be
+copied) and setting "services.gale.keyPath" in /etc/nixos/configuration.nix.
EOM
+else
+ cat <<EOM
+
+When you have this signed key file available, re-run this script, and we will
+move on to the next step.
+
+*** IMPORTANT ***
+You must set GALE_SYS_DIR="$GALE_SYS_DIR" in your environment before re-running
+this script and before running any Gale programs once setup is finished! Make
+sure to set it now, and consider setting it via your shell initialization files
+so that you don't forget to do it next login.
+
+EOM
+fi

View file

@ -15380,6 +15380,8 @@ let
gajim = callPackage ../applications/networking/instant-messengers/gajim { };
gale = callPackage ../applications/networking/instant-messengers/gale { };
gammu = callPackage ../applications/misc/gammu { };
gensgs = callPackage_i686 ../misc/emulators/gens-gs { };