From 6eb3bf641d021f5803123aa56c576f9006a0733d Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Thu, 12 Jan 2012 11:44:08 +0000 Subject: main/acf-core: backport password salt support and acfpasswd tool --- ...ew-tool-to-set-passwords-from-comman-line.patch | 99 ++++++++++++++++++++++ ...enticator-use-salt-and-sha-512-encryption.patch | 89 +++++++++++++++++++ ...02-Fixed-mksalt-to-use-correct-characters.patch | 37 ++++++++ main/acf-core/APKBUILD | 27 +++++- 4 files changed, 248 insertions(+), 4 deletions(-) create mode 100644 main/acf-core/0001-acfpasswd-new-tool-to-set-passwords-from-comman-line.patch create mode 100644 main/acf-core/0001-authenticator-use-salt-and-sha-512-encryption.patch create mode 100644 main/acf-core/0002-Fixed-mksalt-to-use-correct-characters.patch diff --git a/main/acf-core/0001-acfpasswd-new-tool-to-set-passwords-from-comman-line.patch b/main/acf-core/0001-acfpasswd-new-tool-to-set-passwords-from-comman-line.patch new file mode 100644 index 000000000..405ff0c66 --- /dev/null +++ b/main/acf-core/0001-acfpasswd-new-tool-to-set-passwords-from-comman-line.patch @@ -0,0 +1,99 @@ +From a55d954939799cd35efffa896cebaa17d7393e7f Mon Sep 17 00:00:00 2001 +From: Natanael Copa +Date: Thu, 12 Jan 2012 11:21:20 +0100 +Subject: [PATCH] acfpasswd: new tool to set passwords from comman line + +This tool allows users to set/reset an ACF password from command line. + +It also allows user to syncronize the ACF password with the system +password so the ACF password becomes same as shell login password. This +requires that the username exists in both /etc/acf/passwd and /etc/shadow + +diff --git a/bin/acfpasswd b/bin/acfpasswd +new file mode 100644 +index 0000000..e25b966 +--- /dev/null ++++ b/bin/acfpasswd +@@ -0,0 +1,79 @@ ++#!/bin/sh ++ ++# tool for managing the ACF passwords ++ ++passwdfile=${ACFPASSWD:-/etc/acf/passwd} ++shadow=${SHADOW:-/etc/shadow} ++ ++usage() { ++ echo "usage: acfpasswd [-s] USER" ++ echo "" ++ exit 1 ++} ++ ++die() { ++ echo "$@" >&2 ++ exit 1 ++} ++ ++find_user_or_die() { ++ local user="$1" ++ grep -q "^${user}:" "$passwdfile" \ ++ || die "user '$user' was not found in $passwdfile" ++} ++ ++set_pw_hash() { ++ local user="$1" ++ local pwhash="$2" ++ # use : as sed separator since its guaranteed to no be valid in shadow ++ sed -i -e "s:^${user}\:[^\:]*\::${user}\:${pwhash}\::" "$passwdfile" ++} ++ ++syncpasswd() { ++ local user="$1" ++ local pwhash=$(awk -F: -v user="$user" '$1 == user { print $2 }' \ ++ $shadow) || exit ++ find_user_or_die "$user" ++ [ -z "$pwhash" ] && die "user '$user' was not found in $shadow" ++ set_pw_hash "$user" "$pwhash" ++ exit ++} ++ ++sync_with_system= ++while getopts "hs" opt; do ++ case "$opt" in ++ h) usage;; ++ s) sync_with_system=yes;; ++ esac ++done ++ ++shift $(($OPTIND - 1)) ++ ++user="$1" ++[ -z "$user" ] && usage ++ ++[ -n "$sync_with_system" ] && syncpasswd "$user" ++ ++# set password for given user ++find_user_or_die "$user" ++tries=0 ++while true; do ++ echo -n "Enter new ACF password for $user (will not echo): " ++ hash=$(mkpasswd -m sha | tail -n1) ++ salt=$(echo "$hash" | cut -d$ -f3) ++ echo "" ++ echo -n "Re-enter the ACF password (will not echo): " ++ hash2=$(mkpasswd -S "$salt" -m sha | tail -n1) ++ echo "" ++ [ "$hash" = "$hash2" ] && break ++ echo -n "The entered passwords does not match. " ++ tries=$(( $tries + 1)) ++ if [ $tries -gt 3 ]; then ++ die "ACF password was NOT changed" ++ else ++ echo "Please try again." ++ fi ++done ++ ++set_pw_hash "$user" "$hash" && echo "ACF password for $user was changed." ++ +-- +1.7.8.2 + diff --git a/main/acf-core/0001-authenticator-use-salt-and-sha-512-encryption.patch b/main/acf-core/0001-authenticator-use-salt-and-sha-512-encryption.patch new file mode 100644 index 000000000..5c38cc38a --- /dev/null +++ b/main/acf-core/0001-authenticator-use-salt-and-sha-512-encryption.patch @@ -0,0 +1,89 @@ +From eb4221096cc581a41f64d7d6b99e8d5be0d470b0 Mon Sep 17 00:00:00 2001 +From: Natanael Copa +Date: Thu, 27 Oct 2011 18:52:11 +0200 +Subject: [PATCH 1/2] authenticator: use salt and sha-512 encryption + +--- + lib/authenticator.lua | 45 +++++++++++++++++++++++++++++++++++++++++++-- + 1 files changed, 43 insertions(+), 2 deletions(-) + +diff --git a/lib/authenticator.lua b/lib/authenticator.lua +index 724b854..f3af4e3 100644 +--- a/lib/authenticator.lua ++++ b/lib/authenticator.lua +@@ -6,6 +6,8 @@ module (..., package.seeall) + require("modelfunctions") + require("format") + require("md5") ++require("posix") ++require("session") + + -- This is the sub-authenticator + -- In the future, this will be set based upon configuration +@@ -61,6 +63,45 @@ local get_id = function(self, userid) + return authstruct[userid] + end + ++-- verify a plaintextword against a hash ++-- returns: ++-- true if password matches or ++-- false if password does not match ++local verify_password = function(plaintext, pwhash) ++ --[[ ++ from man crypt(3): ++ ++ If salt is a character string starting with the characters "$id$" fol- ++ lowed by a string terminated by "$": ++ ++ $id$salt$encrypted ++ ++ then instead of using the DES machine, id identifies the encryption ++ method used and this then determines how the rest of the password ++ string is interpreted. The following values of id are supported: ++ ++ ID | Method ++ --------------------------------------------------------- ++ 1 | MD5 ++ 2a | Blowfish (not in mainline glibc; added in some ++ | Linux distributions) ++ 5 | SHA-256 (since glibc 2.7) ++ 6 | SHA-512 (since glibc 2.7) ++ ]]-- ++ local algo_salt, hash = string.match(pwhash, "^(%$%d%$[a-zA-Z0-9./]+%$)(.*)") ++ if algo_salt ~= nil and hash ~= nil then ++ return (pwhash == posix.crypt(plaintext, algo_salt)) ++ end ++ -- fall back to old style md5 checksum ++ return (pwhash == md5.sumhexa(plaintext)) ++end ++ ++-- generate a salt string ++local mksalt = function() ++ -- use sha-512 algorithm (no 6) ++ return "$6$"..session.random_hash(96).."$" ++end ++ + --- public methods + + -- This function returns true or false, and +@@ -75,7 +116,7 @@ authenticate = function(self, userid, password) + + if not id then + errtxt = "Userid not found" +- elseif id.password ~= md5.sumhexa(password) then ++ elseif not verify_password(password, id.password) then + errtxt = "Invalid password" + end + end +@@ -110,7 +151,7 @@ write_userinfo = function(self, userinfo) + -- Username, password, roles, skin, home are allowed to not exist, just leave the same + id.userid = userinfo.userid + if userinfo.username then id.username = userinfo.username end +- if userinfo.password then id.password = md5.sumhexa(userinfo.password) end ++ if userinfo.password then id.password = posix.crypt(userinfo.password, mksalt()) end + if userinfo.roles then id.roles = table.concat(userinfo.roles, ",") end + if userinfo.skin then id.skin = userinfo.skin end + if userinfo.home then id.home = userinfo.home end +-- +1.7.8.2 + diff --git a/main/acf-core/0002-Fixed-mksalt-to-use-correct-characters.patch b/main/acf-core/0002-Fixed-mksalt-to-use-correct-characters.patch new file mode 100644 index 000000000..a228e97c5 --- /dev/null +++ b/main/acf-core/0002-Fixed-mksalt-to-use-correct-characters.patch @@ -0,0 +1,37 @@ +From f41fd7182d71427d7a0adf54e55df3a3c97a667e Mon Sep 17 00:00:00 2001 +From: Ted Trask +Date: Thu, 27 Oct 2011 18:51:08 +0000 +Subject: [PATCH 2/2] Fixed mksalt to use correct characters + +--- + lib/authenticator.lua | 13 ++++++++++--- + 1 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/lib/authenticator.lua b/lib/authenticator.lua +index f3af4e3..43814c1 100644 +--- a/lib/authenticator.lua ++++ b/lib/authenticator.lua +@@ -96,10 +96,17 @@ local verify_password = function(plaintext, pwhash) + return (pwhash == md5.sumhexa(plaintext)) + end + +--- generate a salt string ++local b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./" ++ + local mksalt = function() +- -- use sha-512 algorithm (no 6) +- return "$6$"..session.random_hash(96).."$" ++ local file = io.open("/dev/urandom") ++ local str = "" ++ if file == nil then return nil end ++ for i = 1,16 do ++ local offset = (string.byte(file:read(1)) % 64) + 1 ++ str = str .. string.sub (b64, offset, offset) ++ end ++ return "$6$"..str.."$" + end + + --- public methods +-- +1.7.8.2 + diff --git a/main/acf-core/APKBUILD b/main/acf-core/APKBUILD index e9d11fc00..becedf5d4 100644 --- a/main/acf-core/APKBUILD +++ b/main/acf-core/APKBUILD @@ -2,17 +2,36 @@ # Maintainer: Ted Trask pkgname=acf-core pkgver=0.13.5 -pkgrel=0 +pkgrel=1 pkgdesc="A web-based system administration interface framework" url="http://git.alpinelinux.org/cgit/acf-core" arch="noarch" license="GPL-2" install="$pkgname.post-upgrade" depends="acf-jquery acf-lib acf-skins haserl lua lua-posix lua-md5" -source="http://git.alpinelinux.org/cgit/$pkgname/snapshot/$pkgname-$pkgver.tar.bz2" +source="http://git.alpinelinux.org/cgit/$pkgname/snapshot/$pkgname-$pkgver.tar.bz2 + 0001-authenticator-use-salt-and-sha-512-encryption.patch + 0002-Fixed-mksalt-to-use-correct-characters.patch + 0001-acfpasswd-new-tool-to-set-passwords-from-comman-line.patch +" + +prepare() { + cd "$srcdir/$pkgname-$pkgver" + for i in $source; do + case $i in + *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;; + esac + done +} package() { cd "$srcdir/$pkgname-$pkgver" - make DESTDIR="$pkgdir" install + make DESTDIR="$pkgdir" install || return 1 + # remove those lines when 'make install' installs bin/acfpasswd + [ -f "$pkgdir"/bin/acfpasswd ] && return 1 + install -Dm755 bin/acfpasswd "$pkgdir"/bin/acfpasswd } -md5sums="2122ea39dbb6d35bc59c4eb821b4baae acf-core-0.13.5.tar.bz2" +md5sums="2122ea39dbb6d35bc59c4eb821b4baae acf-core-0.13.5.tar.bz2 +09cd615dfb441cb9e34459daa214e3bb 0001-authenticator-use-salt-and-sha-512-encryption.patch +ea61fe424c6e85e867a947f99c01ed04 0002-Fixed-mksalt-to-use-correct-characters.patch +186de27cd4bf66454ede177ae723c321 0001-acfpasswd-new-tool-to-set-passwords-from-comman-line.patch" -- cgit v1.2.3