#!/usr/bin/env bash # ------------------------------------------------------------------------------ # Copyright (c) 2013-2022 Geoffray Levasseur # Protected by the BSD3 license. Please read bellow for details. # # * Redistribution and use in source and binary forms, # * with or without modification, are permitted provided # * that the following conditions are met: # * # * Redistributions of source code must retain the above # * copyright notice, this list of conditions and the # * following disclaimer. # * # * Redistributions in binary form must reproduce the above # * copyright notice, this list of conditions and the following # * disclaimer in the documentation and/or other materials # * provided with the distribution. # * # * Neither the name of the copyright holder nor the names # * of any other contributors may be used to endorse or # * promote products derived from this software without # * specific prior written permission. # * # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # * OF SUCH DAMAGE. # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # genpwd : generate a password with different criteria # Usage: genpwd [options] [--extracars=] [--length=] [nb_passwd] # Options: # -h, --help Display that help screen # -s, --nosymbols Exclude symbols # -n, --nonumbers Exclude numbers # -u, --noup Exclude uppercase letters # -l, --nolow Exclude lowercase letters # -e=, --extracars= # Add the given caracters to the possible caracter list # -L=, --length= # Set length of the password (default is 16) # -o=, --occurences= # Set the maximum occurences of a same caracter (default is 2) # The function is very slow on Windows genpwd() { local length=16 local occurs=2 # Bug, if set to 1, seems to be ignored local symb=1 maj=1 min=1 numb=1 local nbpwd=1 local extcar local PARSED PARSED=$(getopt -o hsnu l e:L:o: --long \ help,nosymbols,nonumbers,noup,nolow,extracars:,length:,occurences: -n 'genpwd' -- "$@") if [[ $? -ne 0 ]]; then return 1; fi eval set -- "$PARSED" while true; do case "$1" in -h|--help) printf "genpwd: Generate secure random password(s).\n\n" printf "Usage: genpwd [options] [nb_passwd]\n\n" printf "Options:\n" printf "\t-h, --help\t\tDisplay this help screen\n" printf "\t-s, --nosymbols\t\tExclude symbols\n" printf "\t-n, --nonumbers\t\tExclude numbers\n" printf "\t-u, --noup\t\tExclude uppercase letters\n" printf "\t-l, --nolow\t\tExclude lowercase letters\n" printf "\t-e, --extracars \tAdd characters to list\n" printf "\t-L, --length \tSet password length (default: 16)\n" printf "\t-o, --occurences \tMax occurences per character (default: 2)\n" return 0 ;; -s|--nosymbols) symb=0 shift ;; -n|--nonumbers) numb=0 shift ;; -u|--noup) maj=0 shift ;; -l|--nolow) min=0 shift ;; -e|--extracars) extcar="$2" shift 2 ;; -L|--length) length="$2" if ! [[ $length =~ ^[0-9]+$ ]]; then disp E "The --length parameter requires a number." return 1 fi shift 2 ;; -o|--occurences) occurs="$2" if ! [[ $occurs =~ ^[1-9]+$ ]]; then disp E "The --occurs parameter requires a number from 1 to 9." return 1 fi shift 2 ;; --) shift; break ;; *) break ;; esac done if [[ -n "$1" ]]; then nbpwd="$1" if ! [[ $nbpwd =~ ^[0-9]+$ ]]; then disp E "The number of password to generate must be a number." return 1 fi fi # Function selecting a random caracter from the list in parameter pickcar() { # When a character is picked we check if it's not appearing already twice # elsewhere, we choose an other char, to compensate weak bash randomizer while [[ -z $char ]]; do local char="${1:RANDOM%${#1}:1} $RANDOM" if [[ $(awk -F"$char" '{print NF-1}' <<<"$picked") -gt $occurs ]]; then unset char fi done picked+="$char" echo "$char" } disp I "Generating $nbpwd passwords, please wait..." for (( n=1; n<=nbpwd; n++ )); do { local carset='' # store final caracter set to use local picked='' # store already used caracter local rlength=0 # store already assigned length of caracters # ?, *, $ and \ impossible to use to my knowledge as it would be interpreted if [[ $symb == 1 ]]; then pickcar '!.@#&%/^-_' carset+='!.@#&%/^-_' ((rlength++)) fi if [[ $numb == 1 ]]; then pickcar '0123456789' carset+='0123456789' ((rlength++)) fi if [[ $maj == 1 ]]; then pickcar 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' carset+='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ((rlength++)) fi if [[ $min == 1 ]]; then pickcar 'abcdefghijklmnopqrstuvwxyz' carset+='abcdefghijklmnopqrstuvwxyz' ((rlength++)) fi if [[ -n $extcar ]]; then pickcar "$extcar" carset+=$extcar ((rlength++)) fi # Check if we have enough car to have something viable if [[ ${#carset} -lt $length ]]; then disp E 'Not enought caracters are authorised for the password length.' disp E 'Please allow more caracter (preferably) or reduce password lentgh.' return 1 fi for i in $(seq 1 $(($length - $rlength))); do pickcar "$carset" done } | sort -R | awk '{printf "%s", $1}' unset picked carset rlength echo done } export -f genpwd # ------------------------------------------------------------------------------ # EOF