Advertisement
Guest User

climbo

a guest
Jul 28th, 2009
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 11.17 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. ##############################
  4. # randy: script para generar una contraseña aleatoria entre 1 y 30 caracteres.
  5. #               Longitud predeterminada 8 caracteres.
  6. #               Forma predeterminada alfanumérica minúsculas.
  7. #
  8. #   Authors: quijote99 & wanako
  9. #   version: 1.4
  10. #   date: 09/04/2007
  11. #   encoding: UTF8
  12. ##############################
  13. ####### VARIABLES ############
  14.  
  15. NAME="${0##*/}" # $(basename $0)
  16. MYNAME='randy'
  17. LMIN='1' # length min
  18. LMAX='30' # length max
  19. LDEF='8' # length default
  20. NL='\n' # newline
  21. TB='\t' # tab
  22. aPass=() # Array de passwords
  23. NPASS='1' # Passwords generadas por defecto
  24. np='0' # variable auxiliar para la generación de varias claves
  25. SVER="$MYNAME versión 1.4 (09/04/2007)"
  26. AUTHOR='Escrito por Manuel Martín (quijote99) y Wanako (guanaco?)'
  27. ##############################
  28. ####### FUNCTIONS ############
  29.  
  30. bd() { # bold color
  31.     echo -en "\E[1m$*\E[0m"
  32.     return
  33. }
  34.  
  35. tb() { # tab tab
  36.     echo -en "$TB$TB"
  37.     return
  38. }
  39.  
  40. nt() { # newline tab
  41.     echo -en "$NL$TB"
  42.     return
  43. }
  44.  
  45. bb() { # bold color + background color
  46.     bd "\E[41m $* " # 41 is red
  47.     return
  48. }
  49.  
  50. helpy() {
  51.     local PAGER OPTS='-[adlu|A][frs] -[L args] [-i args] [-n args]'
  52.     local HELP="$MYNAME(1)$(tb)${TB}User Manual$(tb)$TB$MYNAME(1)
  53.    $NL$(bd NOMBRE)
  54.    $TB$MYNAME - script para generar una contraseña aleatoria.
  55.    $NL$(bd SINOPSIS)$(nt)$(bd $MYNAME) [$(bd $OPTS)]
  56.    $TB$(bd $MYNAME) [$(bd OPCIONES)] [$(bd ARGUMENTOS)]
  57.    $NL$(bd DESCRIPCION)
  58.    ${TB}Pequeña utilidad para generar claves aleatorias basándose en el algorit-
  59.    ${TB}mo $(bd RANDOM) de Bash y en el dispositivo $(bd /dev/urandom).
  60.    $NL$(bd OPCIONES)
  61.    ${TB}Este script utiliza la función $(bd getopts) de Bash y no admite opciones lar-
  62.    ${TB}gas de la forma $(bd --option) como lo haría $(bd getopt), sin embargo algunas opcio
  63.    ${TB}nes largas son predefinidas para emular este comportamiento y sólo son a
  64.    ${TB}plicables como primer argumento pasado al script.
  65.    ${TB}Si no se indicasen opciones la forma predeterminada de la clave es alfa-
  66.    ${TB}numérica con letras minúsculas y una longitud de ocho caracteres.
  67.    $(nt)$(bd CORTAS)
  68.    $(nt)$(bd -a) (accents) acentos
  69.    $(tb)Genera la clave usando como patrón vocales acentuadas.
  70.    $(nt)$(bd -d) (digits) dígitos
  71.    $(tb)Genera la clave usando como patrón dígitos enteros positivos.
  72.    $(nt)$(bd -f) (force) forzar
  73.    $(tb)No solicita confirmación para generar la clave usando un patrón
  74.    $(tb)ingresado por el usuario, útil sólo en combinación con $(bd -m) (ver
  75.    $(tb)más abajo).
  76.    $(nt)$(bd -l) (lows) bajos?
  77.    $(tb)Genera la clave usando como patrón letras minúsculas del alfabe-
  78.    $(tb)to inglés incluidas las letras ñ y ü.
  79.    $(nt)$(bd -i \'args\') (include) caracteres
  80.    $(tb)ARGS es el patrón de caracteres que formará parte de la clave
  81.    $(tb)junto con otras opciones si existiesen, si no es alfanumérico se
  82.    $(tb)solicitará confirmación, debe ser entrecomillado para evitar la
  83.    $(tb)expansión de la shell y no contener espacios.
  84.    $(tb)Utilice esta opción con precaución, la combinación de caracteres
  85.    $(tb)que la shell interprete o expanda pueden dar resultados inespera
  86.    $(tb)dos e incluso provocar la pérdida de datos, de todas formas si
  87.    $(tb)el intérprete es Bash no debería ocurrir.
  88.    $(nt)$(bd -r) (repeat) repetir
  89.    $(tb)Genera la clave sin repetir caracteres del patrón, la longitud
  90.    $(tb)de la clave es la longitud del patrón si no se utiliza la opción
  91.    $(tb)$(bd -L) (ver más abajo) y si no supera el máximo permitido de 30.
  92.    $(nt)$(bd -s) (silent) silencio
  93.    $(tb)Imprime en pantalla sólo la clave generada y sin usar resalto de
  94.    $(tb)color, útil para redirigir o concatenar la salida hacia un fiche
  95.    $(tb)ro o hacia la entrada de otra aplicación.
  96.    $(nt)$(bd -u) (uppers) altos?
  97.    $(tb)Genera la clave usando como patrón letras mayúsculas del alfabe-
  98.    $(tb)to inglés incluidas las letras Ñ y Ü.
  99.    $(nt)$(bd -A) (All) todo
  100.    $(tb)Implica las opciones $(bd -adlu) (ver más arriba).
  101.    $(nt)$(bd -L args) (Length) Longitud
  102.    $(tb)ARGS es un dígito entero positivo que indica la longitud de la
  103.    $(tb)clave y debe ser mayor igual a 1 o menor igual a 30.
  104.    $(nt)$(bd -n arg) (n repeats) n contraseñas
  105.    $(tb)Genera \"n\" claves listadas en una columna. Las claves pueden
  106.    $(tb)aparecer repetidas
  107.    $(nt)$(bd LARGAS)
  108.    $(nt)$(bd --author) (autor)
  109.    $(tb)Imprime el autor y finaliza.
  110.    $(nt)$(bd --help) (ayuda)
  111.    $(tb)Imprime esta ayuda y finaliza.
  112.    $(nt)$(bd --version) (versión)
  113.    $(tb)Imprime la versión y finaliza.
  114.    $NL$(bd EJEMPLOS)
  115.    ${TB}Los ejemplos siguientes son equivalentes:
  116.    $(tb)$MYNAME$(tb)${TB}(predeterminado)
  117.    $(tb)$MYNAME -ldL8$(tb)(similar)
  118.    $(tb)$MYNAME -l -d -L8$(tb)(similar)
  119.    $(tb)$MYNAME -l -d -L '8'${TB}(similar)
  120.    $(nt)Los ejemplos siguientes generan una clave con caracteres ingresados por
  121.    ${TB}el usuario:
  122.    $(tb)$MYNAME -d -i '#'$(tb)(pregunta para utilizar '#')
  123.    $(tb)$MYNAME -df -i'#'$(tb)(no pregunta para utilizar '#')
  124.    $NL$(bd AUTOR)
  125.    $TB$AUTHOR
  126.    $NL$(bd BUGS)
  127.    ${TB}Comunicar bichos a <museo@esdebian.org> :)
  128.    $NL$MYNAME(1)$(tb)$SVER$(tb)$TB$MYNAME(1)"
  129.     if PAGER="$(which less)" ; then
  130. PAGER+=' -R'
  131. ( echo -e "$HELP" | $PAGER ) # ( subshell )
  132. elif PAGER="$(which more)" ; then
  133.     PAGER+=' -f'
  134.     ( echo -e "$HELP" | $PAGER )
  135. else echo -e "$HELP" # auch, no pager
  136.     fi
  137.     exit 0
  138. }
  139.  
  140. escape() {
  141.     echo -n "${*//\\/\\\\}" # \ -> \\
  142.     return
  143. }
  144.  
  145. error() {
  146.     echo -e "$MYNAME: $*$NL$MYNAME: --help para recibir ayuda." > /dev/stderr
  147.     exit 1
  148. }
  149.  
  150. warn() {
  151.     echo "$MYNAME: $*" > /dev/stderr
  152.     return
  153. }
  154.  
  155. isdigit() {
  156.     if [[ "$@" =~ '[^[:digit:]]' ]] ; then
  157. return 1
  158. else return 0
  159.     fi
  160. }
  161.  
  162. separate() {
  163.     local CHARS='' # default IFS=space for read then
  164.     while read -rsn 1 ; do # the space deposited by the user
  165.         CHARS+="$REPLY " # discarded, more safety?
  166.     done <<< "$@" # here string structure
  167.     echo "$CHARS"
  168.     return
  169. }
  170.  
  171. digits() {
  172.     local DIGITS=()
  173.     DIGITS=( {0..9} )
  174.     echo "${DIGITS[*]}" # echo entire array - string
  175.     return
  176. }
  177.  
  178. lowers() {
  179.     local LOWERS=()
  180.     LOWERS=( {a..z} ñ ü )
  181.     echo "${LOWERS[*]}"
  182.     return
  183. }
  184.  
  185. uppers() {
  186.     local UPPERS=()
  187.     UPPERS=( {A..Z} Ñ Ü )
  188.     echo "${UPPERS[*]}"
  189.     return
  190. }
  191.  
  192. accents() {
  193.     local ACCENTS=()
  194.     ACCENTS=( á é í ó ú )
  195.     echo "${ACCENTS[*]}"
  196.     return
  197. }
  198.  
  199. default() {
  200.     local DEFAULT=()
  201.     DEFAULT=( $(digits) $(lowers) )
  202.     echo "${DEFAULT[*]}"
  203.     return
  204. }
  205.  
  206. chkoptions() {
  207.     OPTIND=1 # to be sure that index is initialized to 1 each time
  208.     local OPT OPTIONS FORCE # it is called to getopts
  209.     while getopts ":aAdflL:i:rsun:" OPT ; do
  210. case "$OPT" in
  211.         a|A|d|f|l|L|i|r|s|u|n )
  212. if [[ "$OPTIONS" =~ ".*$OPT.*" ]] ; then
  213.     error "se espera sólo una ocurrencia de $(bd -$OPT)"
  214. fi
  215. OPTIONS+="$OPT" # OPTIONS="$OPTIONS$OPT"
  216. case "$OPT" in
  217.     a|d|l|u )
  218. if [[ "$OPTIONS" =~ 'A' ]] ; then
  219.     error "la opción $(bd -A) implica $(bd -adlu)"
  220. fi
  221.     ;;
  222.     A ) if [[ "$OPTIONS" =~ '(a|d|l|u)' ]] ; then
  223.                         error "la opción $(bd -A) implica $(bd -adlu)"
  224.         fi
  225.     ;;
  226. esac
  227.     ;;
  228.         * ) if [[ "$OPT" == ':' ]] ; then
  229.                 error "se espera un argumento para $(bd -$OPTARG)"
  230.     else error "opción desconocida $(bd -$(escape $OPTARG))"
  231.         fi
  232.     ;;
  233. esac
  234.     done
  235.     if [[ "$OPTIND" -le "${#@}" ]] ; then
  236. error "error de sintáxis $(bd $(escape ${@:$OPTIND:1}))"
  237.     fi
  238.     OPTIND=1 # to be sure again
  239.     while getopts ":aAdflL:i:rsun:" OPT ; do
  240. if [[ "$OPT" == 'L' ]] ; then
  241.     if ( ! isdigit "$OPTARG" ) ; then
  242. error "argumento no válido -L $(bd $(escape $OPTARG))"
  243. elif [[ "$OPTARG" -lt "$LMIN" || "$OPTARG" -gt "$LMAX" ]] ; then
  244. error "longitud fuera de rango $(bd $OPTARG)"
  245.     fi
  246. fi
  247.  
  248. if [[ "$OPT" == 'n' ]] ; then
  249. if ( ! isdigit "$OPTARG" ) ; then
  250. error "argumento no válido -n $(bd $(escape $OPTARG))"
  251.     fi
  252. fi
  253.  
  254.     done
  255.     OPTIND=1 # to be sure again II
  256.     while getopts ":aAdflL:i:rsun:" OPT ; do
  257. case "$OPT" in
  258.     f ) FORCE=true ;;
  259.     L ) LUSER="$OPTARG" ;; # global
  260.     r ) REPEAT=true ;; # global
  261.     s ) SILENT=true ;; # global
  262. n ) NPASS="$OPTARG";; # global
  263. esac
  264.  
  265.     done
  266.     OPTIND=1 # to be sure again III
  267.     while getopts ":aAdflL:i:rsun:" OPT ; do
  268. if [[ "$OPT" == 'i' ]] ; then
  269.     PUSER="${OPTARG//[[:space:]]/}" # global
  270.     if [[ ! "$FORCE" ]] ; then
  271. if [[ "$OPTARG" =~ '([^[:alnum:]])' ]] ; then
  272.     OPTARG="${PUSER//[[:alnum:]]/}"
  273.     echo -n "$MYNAME: utilizar $(bd $(escape $OPTARG)) ? [s/n]"
  274.     read -sn 1
  275.     if [[ "$REPLY" =~ '(s|S)' ]] ; then
  276. echo -e "$NL\E[A\E[M\E[A" # newline-up-clearline-up
  277. else
  278. echo -e "$NL\E[A\E[M\E[A"
  279. echo "$MYNAME: cancelado..."
  280. exit 0
  281.     fi
  282. fi
  283.     fi
  284. fi
  285.     done
  286.     return
  287. }
  288.  
  289. genpattern() {
  290.     OPTIND=1 # to be sure again IV
  291.     local OPT PATTERN=()
  292.     while getopts ":aAdflL:i:rsu" OPT ; do
  293. case "$OPT" in
  294.     a ) PATTERN+=( $(accents) ) ;;
  295.     A ) PATTERN=( $(default) $(uppers) $(accents) ) ;;
  296.     d ) PATTERN+=( $(digits) ) ;;
  297.     l ) PATTERN+=( $(lowers) ) ;;
  298.     i ) PATTERN+=( $(separate $PUSER) ) ;;
  299.     u ) PATTERN+=( $(uppers) ) ;;
  300. esac
  301.     done
  302.     if [[ ! "${PATTERN[0]}" ]] ; then
  303. PATTERN=( $(default) )
  304.     fi
  305.     echo "${PATTERN[*]}"
  306.     return
  307. }
  308.  
  309. ##############################
  310. ####### MAIN #################
  311.  
  312. set -f # no globbing
  313.  
  314. if [[ "$NAME" != "$MYNAME" ]] ; then # my name is randy :)
  315.     echo -e "$NAME ?${NL}Mi nombre es $(bd randy) !"
  316.     exit 1
  317. fi
  318.  
  319. if [[ ! "$1" ]] ; then
  320.     LENGTH="$LDEF"
  321.     PATTERN=( $(default) )
  322.     elif [[ "$1" == '--help' ]] ; then
  323. helpy
  324.     elif [[ "$1" == '--version' ]] ; then
  325. echo "$SVER"
  326. exit 0
  327.     elif [[ "$1" == '--author' ]] ; then
  328. echo "$AUTHOR"
  329. exit 0
  330.     elif [[ "$1" =~ '^[[.-.]][[:alpha:]]' ]] ; then
  331. chkoptions "$@"
  332. PATTERN=( $(genpattern $@) )
  333. LENGTH="${LUSER:-$LDEF}" # LENGTH=($LUSER || $LDEF)
  334.     else error "error de sintáxis $(bd $(escape $1))"
  335. fi
  336.  
  337. LPTN="${#PATTERN[@]}"
  338.  
  339. if [ "$LPTN" -eq '1' -a "$LENGTH" -eq '1' ] ; then
  340.     warn "nada que hacer con $(bd $(escape ${PATTERN[*]}))"
  341. fi
  342.  
  343. if [[ "$REPEAT" ]] ; then
  344.     if [[ "$LUSER" ]] ; then
  345. if [[ "$LUSER" -gt "$LPTN" ]] ; then
  346.     error "longitud de clave $(bd $LUSER) longitud de patrón $(bd $LPTN)"
  347. fi
  348. else
  349. LENGTH="$LPTN"
  350. if [[ "$LENGTH" -gt "$LMAX" ]] ; then
  351.     warn "longitud de clave $(bd $LENGTH) se trunca a $(bd $LMAX)"
  352.     LENGTH="$LMAX"
  353.     elif [[ "$LPTN" -eq '1' ]] ; then
  354.     warn "nada que hacer con $(bd $(escape ${PATTERN[*]}))"
  355. fi
  356.     fi
  357. fi
  358.  
  359. while [[ "$np" -lt "$NPASS" ]]; do
  360. (( BYTES = LENGTH * 2 ))
  361. SEEDS=( $(od -A n -d -N $BYTES < /dev/urandom) )
  362. PASSWORD=''
  363. for (( i=0 ; i < LENGTH ; i++ )) ; do
  364.     RANDOM="${SEEDS[$i]}"
  365.    PTNIND="$(($RANDOM%$LPTN))"
  366.     if [[ "$REPEAT" ]] ; then
  367. PASSWORD+="${PATTERN[$PTNIND]}"
  368. unset PATTERN[PTNIND]
  369. PATTERN=( ${PATTERN[@]} )
  370. LPTN="${#PATTERN[@]}"
  371. else PASSWORD+="${PATTERN[$PTNIND]}"
  372.     fi
  373. done
  374. aPass[np]="${PASSWORD}"
  375. let np++
  376. done
  377.  
  378. for (( i=0 ; i < np ; i++ )); do
  379. if [[ "$SILENT" ]] ; then
  380. echo "${aPass[$i]}"
  381.     else echo "Contraseña: $(bb $(escape "${aPass[$i]}"))"
  382. fi
  383. done
  384.  
  385. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement