#!/bin/bash # Copyright 2020 Security Onion Solutions. All rights reserved. # # This program is distributed under the terms of version 2 of the # GNU General Public License. See LICENSE for further details. # # 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. got_root() { # Make sure you are root if [ "$(id -u)" -ne 0 ]; then echo "This script must be run using sudo!" exit 1 fi } # Make sure the user is root got_root if [[ $# < 1 || $# > 2 ]]; then echo "Usage: $0 [email]" echo "Note that checkpw only checks that the given password meets the minimum requirements, it does not test that it matches for an existing user." exit 1 fi operation=$1 email=$2 kratosUrl=${KRATOS_URL:-http://127.0.0.1:4434} databasePath=${KRATOS_DB_PATH:-/opt/so/conf/kratos/db/db.sqlite} argon2Iterations=${ARGON2_ITERATIONS:-3} argon2Memory=${ARGON2_MEMORY:-14} argon2Parallelism=${ARGON2_PARALLELISM:-2} argon2HashSize=${ARGON2_HASH_SIZE:-32} function fail() { msg=$1 echo "$1" exit 1 } function require() { cmd=$1 which "$1" 2>&1 > /dev/null [[ $? != 0 ]] && fail "This script requires the following command be installed: ${cmd}" } # Verify this environment is capable of running this script require "argon2" require "jq" require "curl" require "openssl" require "sqlite3" [[ ! -f $databasePath ]] && fail "Unable to find database file; specify path via KRATOS_DB_PATH environment variable" response=$(curl -Ss ${kratosUrl}/) [[ "$response" != "404 page not found" ]] && fail "Unable to communicate with Kratos; specify URL via KRATOS_URL environment variable" function findIdByEmail() { email=$1 response=$(curl -Ss ${kratosUrl}/identities) identityId=$(echo "${response}" | jq ".[] | select(.addresses[0].value == \"$email\") | .id") echo $identityId } function validatePassword() { password=$1 len=$(expr length "$password") if [[ $len -lt 6 ]]; then echo "Password does not meet the minimum requirements" exit 2 fi } function updatePassword() { identityId=$1 # Read password from stdin (show prompt only if no stdin was piped in) test -t 0 if [[ $? == 0 ]]; then echo "Enter new password:" fi read -s password validatePassword "$password" if [[ -n $identityId ]]; then # Generate password hash salt=$(openssl rand -hex 8) passwordHash=$(echo "${password}" | argon2 ${salt} -id -t $argon2Iterations -m $argon2Memory -p $argon2Parallelism -l $argon2HashSize -e) # Update DB with new hash echo "update identity_credentials set config=CAST('{\"hashed_password\":\"${passwordHash}\"}' as BLOB) where identity_id=${identityId};" | sqlite3 "$databasePath" [[ $? != 0 ]] && fail "Unable to update password" fi } function listUsers() { response=$(curl -Ss ${kratosUrl}/identities) [[ $? != 0 ]] && fail "Unable to communicate with Kratos" echo "${response}" | jq -r ".[] | .addresses[0].value" | sort } function createUser() { email=$1 now=$(date -u +%FT%TZ) addUserJson=$(cat <