medusa-2.1.1/0000755000175000001440000000000011760001577007772 500000000000000medusa-2.1.1/TODO0000644000175000001440000000041711723732130010377 00000000000000Future Plans: *Account lockout Microsoft SMB services can often be queried for the account lockout policy or how many attempts are remaining on an account before it is locked. Medusa should be able to auto-detect these values and tested up to the lockout threshold. medusa-2.1.1/Makefile.am0000644000175000001440000000035611760001552011743 00000000000000AUTOMAKE_OPTIONS = gnu SUBDIRS = src man_MANS = doc/medusa.1 EXTRA_DIST = doc/medusa.1 doc/*.html misc/rdesktop/rdp-brute-force.diff misc/rdesktop/rdesktop-1.5.0-brute-force.patch misc/net-analyzer/medusa-2.1.1.ebuild misc/zsh/_medusa medusa-2.1.1/configure0000755000175000001440000074770111760000304011624 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="src/medusa.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS DEFAULT_MOD_PATH MODULE_LIBS BUILD_MODULE_WEB_FORM_FALSE BUILD_MODULE_WEB_FORM_TRUE BUILD_MODULE_WRAPPER_FALSE BUILD_MODULE_WRAPPER_TRUE BUILD_MODULE_VNC_FALSE BUILD_MODULE_VNC_TRUE BUILD_MODULE_VMAUTHD_FALSE BUILD_MODULE_VMAUTHD_TRUE BUILD_MODULE_TELNET_FALSE BUILD_MODULE_TELNET_TRUE BUILD_MODULE_SVN_FALSE BUILD_MODULE_SVN_TRUE APR_INCLUDE_DIR APR_CONFIG BUILD_MODULE_SSH_FALSE BUILD_MODULE_SSH_TRUE BUILD_MODULE_SNMP_FALSE BUILD_MODULE_SNMP_TRUE BUILD_MODULE_SMTP_VRFY_FALSE BUILD_MODULE_SMTP_VRFY_TRUE BUILD_MODULE_SMTP_FALSE BUILD_MODULE_SMTP_TRUE BUILD_MODULE_SMBNT_FALSE BUILD_MODULE_SMBNT_TRUE BUILD_MODULE_RSH_FALSE BUILD_MODULE_RSH_TRUE BUILD_MODULE_RLOGIN_FALSE BUILD_MODULE_RLOGIN_TRUE BUILD_MODULE_REXEC_FALSE BUILD_MODULE_REXEC_TRUE BUILD_MODULE_POSTGRES_FALSE BUILD_MODULE_POSTGRES_TRUE BUILD_MODULE_POP3_FALSE BUILD_MODULE_POP3_TRUE BUILD_MODULE_PCANYWHERE_FALSE BUILD_MODULE_PCANYWHERE_TRUE BUILD_MODULE_NNTP_FALSE BUILD_MODULE_NNTP_TRUE BUILD_MODULE_NCP_FALSE BUILD_MODULE_NCP_TRUE BUILD_MODULE_MYSQL_FALSE BUILD_MODULE_MYSQL_TRUE BUILD_MODULE_MSSQL_FALSE BUILD_MODULE_MSSQL_TRUE BUILD_MODULE_IMAP_FALSE BUILD_MODULE_IMAP_TRUE BUILD_MODULE_HTTP_FALSE BUILD_MODULE_HTTP_TRUE BUILD_MODULE_FTP_FALSE BUILD_MODULE_FTP_TRUE BUILD_MODULE_CVS_FALSE BUILD_MODULE_CVS_TRUE BUILD_MODULE_AFP_FALSE BUILD_MODULE_AFP_TRUE EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking enable_debug with_postgresql with_afpfsng enable_module_afp enable_module_cvs enable_module_ftp enable_module_http enable_module_imap enable_module_mssql enable_module_mysql enable_module_ncp enable_module_nntp enable_module_pcanywhere enable_module_pop3 enable_module_postgres enable_module_rexec enable_module_rlogin enable_module_rsh enable_module_smbnt enable_module_smtp enable_module_smtp_vrfy enable_module_snmp enable_module_ssh enable_module_svn enable_module_telnet enable_module_vmauthd enable_module_vnc enable_module_wrapper enable_module_web_form with_default_mod_path ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-debug=no/yes turn on debugging (default=yes) --enable-module-afp=no/yes Enable AFP module (default=no) --enable-module-cvs=no/yes Enable CVS module (default=yes) --enable-module-ftp=no/yes Enable FTP module (default=yes) --enable-module-http=no/yes Enable HTTP module (default=yes) --enable-module-imap=no/yes Enable IMAP module (default=yes) --enable-module-mssql=no/yes Enable MSSQL module (default=yes) --enable-module-mysql=no/yes Enable MYSQL module (default=yes) --enable-module-ncp=no/yes Enable NCP module (default=yes) --enable-module-nntp=no/yes Enable NNTP module (default=yes) --enable-module-pcanywhere=no/yes Enable PCANYWHERE module (default=yes) --enable-module-pop3=no/yes Enable POP3 module (default=yes) --enable-module-postgres=no/yes Enable POSTGRES module (default=yes) --enable-module-rexec=no/yes Enable REXEC module (default=yes) --enable-module-rlogin=no/yes Enable RLOGIN module (default=yes) --enable-module-rsh=no/yes Enable RSH module (default=yes) --enable-module-smbnt=no/yes Enable SMBNT module (default=yes) --enable-module-smtp=no/yes Enable SMTP module (default=yes) --enable-module-smtp-vrfy=no/yes Enable SMTP-VRFY module (default=yes) --enable-module-snmp=no/yes Enable SNMP module (default=yes) --enable-module-ssh=no/yes Enable SSH module (default=yes) --enable-module-svn=no/yes Enable SVN module (default=yes) --enable-module-telnet=no/yes Enable TELNET module (default=yes) --enable-module-vmauthd=no/yes Enable VMAUTHD module (default=yes) --enable-module-vnc=no/yes Enable VNC module (default=yes) --enable-module-wrapper=no/yes Enable WRAPPER module (default=yes) --enable-module-web-form=no/yes Enable WEB-FORM module (default=yes) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-postgresql=prefix Prefix for postgresql include directory (default = /usr) --with-afpfsng=prefix Prefix for afpfs-ng include directory (default = /usr) --with-default-mod-path=path Location of medusa module files (default = /usr/local/lib/medusa/modules) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 &5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- am__api_version='1.11' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=medusa VERSION=2.1.1 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : else if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 $as_echo_n "checking size of long... " >&6; } if ${ac_cv_sizeof_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 $as_echo "$ac_cv_sizeof_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 $as_echo_n "checking size of long long... " >&6; } if ${ac_cv_sizeof_long_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 $as_echo "$ac_cv_sizeof_long_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 $as_echo_n "checking size of short... " >&6; } if ${ac_cv_sizeof_short+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : else if test "$ac_cv_type_short" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (short) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_short=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 $as_echo "$ac_cv_sizeof_short" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT $ac_cv_sizeof_short _ACEOF CFLAGS="${CFLAGS=}" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable debugging" >&5 $as_echo_n "checking whether to enable debugging... " >&6; } debug_default="yes" # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; else enable_debug=$debug_default fi if test "x$enable_debug" = "xyes"; then CPPFLAGS="$CPPFLAGS -g -DDEBUG" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Check whether --with-postgresql was given. if test "${with_postgresql+set}" = set; then : withval=$with_postgresql; postgresql_prefix="$withval" else postgresql_prefix="/usr" fi # Check whether --with-afpfsng was given. if test "${with_afpfsng+set}" = set; then : withval=$with_afpfsng; afpfsng_prefix="$withval" else afpfsng_prefix="/usr" fi if test -d "/usr/local/lib" then LDFLAGS="$LDFLAGS -L/usr/local/lib" fi if test -d "/usr/local/ssl/lib" then LDFLAGS="$LDFLAGS -L/usr/local/ssl/lib" fi CPPFLAGS="$CPPFLAGS -fPIC" CPPFLAGS="$CPPFLAGS -I/usr/include -I/usr/local/include -I/usr/local/ssl/include \ -I${postgresql_prefix}/include/postgresql -I${postgresql_prefix}/include/pgsql -I${afpfsng_prefix}/include/afpfs-ng" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread support..." >&5 $as_echo "$as_me: checking for pthread support..." >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5 $as_echo_n "checking for main in -lpthread... " >&6; } if ${ac_cv_lib_pthread_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_main=yes else ac_cv_lib_pthread_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5 $as_echo "$ac_cv_lib_pthread_main" >&6; } if test "x$ac_cv_lib_pthread_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" else as_fn_error $? " *** Application requires pthread support *** " "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen/dlclose..." >&5 $as_echo "$as_me: checking for dlopen/dlclose..." >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlclose in -ldl" >&5 $as_echo_n "checking for dlclose in -ldl... " >&6; } if ${ac_cv_lib_dl_dlclose+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlclose (); int main () { return dlclose (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlclose=yes else ac_cv_lib_dl_dlclose=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlclose" >&5 $as_echo "$ac_cv_lib_dl_dlclose" >&6; } if test "x$ac_cv_lib_dl_dlclose" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlclose in -lc" >&5 $as_echo_n "checking for dlclose in -lc... " >&6; } if ${ac_cv_lib_c_dlclose+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlclose (); int main () { return dlclose (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_dlclose=yes else ac_cv_lib_c_dlclose=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_dlclose" >&5 $as_echo "$ac_cv_lib_c_dlclose" >&6; } if test "x$ac_cv_lib_c_dlclose" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBC 1 _ACEOF LIBS="-lc $LIBS" else as_fn_error $? " *** Application requires dlopen/dlclose (e.g. libdl) *** " "$LINENO" 5 fi fi if test -d "/opt/local"; then CPPFLAGS="$CPPFLAGS -I/opt/local/include" LDFLAGS="$LDFLAGS -L/opt/local/lib" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 $as_echo_n "checking for library containing clock_gettime... " >&6; } if ${ac_cv_search_clock_gettime+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF for ac_lib in '' rt; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_clock_gettime=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_clock_gettime+:} false; then : break fi done if ${ac_cv_search_clock_gettime+:} false; then : else ac_cv_search_clock_gettime=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 $as_echo "$ac_cv_search_clock_gettime" >&6; } ac_res=$ac_cv_search_clock_gettime if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi for ac_func in clock_gettime do : ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" if test "x$ac_cv_func_clock_gettime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CLOCK_GETTIME 1 _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No clock_gettime(), using gettimeofday() instead " >&5 $as_echo "$as_me: WARNING: No clock_gettime(), using gettimeofday() instead " >&2;} fi done check_libssl="false" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL Library and Header files..." >&5 $as_echo "$as_me: checking for OpenSSL Library and Header files..." >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_lock in -lcrypto" >&5 $as_echo_n "checking for CRYPTO_lock in -lcrypto... " >&6; } if ${ac_cv_lib_crypto_CRYPTO_lock+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char CRYPTO_lock (); int main () { return CRYPTO_lock (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypto_CRYPTO_lock=yes else ac_cv_lib_crypto_CRYPTO_lock=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_CRYPTO_lock" >&5 $as_echo "$ac_cv_lib_crypto_CRYPTO_lock" >&6; } if test "x$ac_cv_lib_crypto_CRYPTO_lock" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPTO 1 _ACEOF LIBS="-lcrypto $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** LibCrypto may be required for *BSD ***" >&5 $as_echo "$as_me: WARNING: *** LibCrypto may be required for *BSD ***" >&2;} fi ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_ssl_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lssl" >&5 $as_echo_n "checking for main in -lssl... " >&6; } if ${ac_cv_lib_ssl_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ssl_main=yes else ac_cv_lib_ssl_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_main" >&5 $as_echo "$ac_cv_lib_ssl_main" >&6; } if test "x$ac_cv_lib_ssl_main" = xyes; then : $as_echo "#define HAVE_LIBSSL 1" >>confdefs.h LIBS="$LIBS -lssl -lcrypto" check_libssl="true" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** OpenSSL library required for SSL support. *** Many of the Medusa modules depend on the OpenSSL library and header files. If multiple modules are unexpectedly disabled, this is likely the cause. Make sure to install libssl-dev, openssl-devel or whatever package your distribution uses to distribute these files. " >&5 $as_echo "$as_me: WARNING: *** OpenSSL library required for SSL support. *** Many of the Medusa modules depend on the OpenSSL library and header files. If multiple modules are unexpectedly disabled, this is likely the cause. Make sure to install libssl-dev, openssl-devel or whatever package your distribution uses to distribute these files. " >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** OpenSSL header files required for SSL support. *** Many of the Medusa modules depend on the OpenSSL library and header files. If multiple modules are unexpectedly disabled, this is likely the cause. Make sure to install libssl-dev, openssl-devel or whatever package your distribution uses to distribute these files. " >&5 $as_echo "$as_me: WARNING: *** OpenSSL header files required for SSL support. *** Many of the Medusa modules depend on the OpenSSL library and header files. If multiple modules are unexpectedly disabled, this is likely the cause. Make sure to install libssl-dev, openssl-devel or whatever package your distribution uses to distribute these files. " >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: *** Checking module dependencies and enabling accordingly ***" >&5 $as_echo "$as_me: *** Checking module dependencies and enabling accordingly ***" >&6;} check_module_afp="false" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AFPFS-NG Library and Header files..." >&5 $as_echo "$as_me: checking for AFPFS-NG Library and Header files..." >&6;} ac_fn_c_check_header_mongrel "$LINENO" "afpfs-ng/afp_protocol.h" "ac_cv_header_afpfs_ng_afp_protocol_h" "$ac_includes_default" if test "x$ac_cv_header_afpfs_ng_afp_protocol_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lafpclient" >&5 $as_echo_n "checking for main in -lafpclient... " >&6; } if ${ac_cv_lib_afpclient_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lafpclient $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_afpclient_main=yes else ac_cv_lib_afpclient_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_afpclient_main" >&5 $as_echo "$ac_cv_lib_afpclient_main" >&6; } if test "x$ac_cv_lib_afpclient_main" = xyes; then : $as_echo "#define HAVE_LIBAFPFS 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS /usr/lib/libafpclient.so.0" check_module_afp="true" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** AFPFS-NG library required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. " >&5 $as_echo "$as_me: WARNING: *** AFPFS-NG library required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. " >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** AFPFS-NG header files required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. " >&5 $as_echo "$as_me: WARNING: *** AFPFS-NG header files required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. " >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable AFP module" >&5 $as_echo_n "checking whether to enable AFP module... " >&6; } # Check whether --enable-module-afp was given. if test "${enable_module_afp+set}" = set; then : enableval=$enable_module_afp; case "${enableval}" in yes) enable_module_afp=true ;; no) enable_module_afp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-afp" "$LINENO" 5 ;; esac else enable_module_afp=$check_module_afp fi if test x"$enable_module_afp" = "xtrue"; then BUILD_MODULE_AFP_TRUE= BUILD_MODULE_AFP_FALSE='#' else BUILD_MODULE_AFP_TRUE='#' BUILD_MODULE_AFP_FALSE= fi if test x"$enable_module_afp" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable CVS module" >&5 $as_echo_n "checking whether to enable CVS module... " >&6; } # Check whether --enable-module-cvs was given. if test "${enable_module_cvs+set}" = set; then : enableval=$enable_module_cvs; case "${enableval}" in yes) enable_module_cvs=true ;; no) enable_module_cvs=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-cvs" "$LINENO" 5 ;; esac else enable_module_cvs="true" fi if test x"$enable_module_cvs" = "xtrue"; then BUILD_MODULE_CVS_TRUE= BUILD_MODULE_CVS_FALSE='#' else BUILD_MODULE_CVS_TRUE='#' BUILD_MODULE_CVS_FALSE= fi if test x"$enable_module_cvs" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable FTP module" >&5 $as_echo_n "checking whether to enable FTP module... " >&6; } # Check whether --enable-module-ftp was given. if test "${enable_module_ftp+set}" = set; then : enableval=$enable_module_ftp; case "${enableval}" in yes) enable_module_ftp=true ;; no) enable_module_ftp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-ftp" "$LINENO" 5 ;; esac else enable_module_ftp="true" fi if test x"$enable_module_ftp" = "xtrue"; then BUILD_MODULE_FTP_TRUE= BUILD_MODULE_FTP_FALSE='#' else BUILD_MODULE_FTP_TRUE='#' BUILD_MODULE_FTP_FALSE= fi if test x"$enable_module_ftp" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi check_module_http=$check_libssl { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable HTTP module" >&5 $as_echo_n "checking whether to enable HTTP module... " >&6; } # Check whether --enable-module-http was given. if test "${enable_module_http+set}" = set; then : enableval=$enable_module_http; case "${enableval}" in yes) enable_module_http=true ;; no) enable_module_http=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-http" "$LINENO" 5 ;; esac else enable_module_http=$check_module_http fi if test x"$enable_module_http" = "xtrue"; then BUILD_MODULE_HTTP_TRUE= BUILD_MODULE_HTTP_FALSE='#' else BUILD_MODULE_HTTP_TRUE='#' BUILD_MODULE_HTTP_FALSE= fi if test x"$enable_module_http" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable IMAP module" >&5 $as_echo_n "checking whether to enable IMAP module... " >&6; } # Check whether --enable-module-imap was given. if test "${enable_module_imap+set}" = set; then : enableval=$enable_module_imap; case "${enableval}" in yes) enable_module_imap=true ;; no) enable_module_imap=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-imap" "$LINENO" 5 ;; esac else enable_module_imap="true" fi if test x"$enable_module_imap" = "xtrue"; then BUILD_MODULE_IMAP_TRUE= BUILD_MODULE_IMAP_FALSE='#' else BUILD_MODULE_IMAP_TRUE='#' BUILD_MODULE_IMAP_FALSE= fi if test x"$enable_module_imap" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi check_module_mssql=$check_libssl { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable MSSQL module" >&5 $as_echo_n "checking whether to enable MSSQL module... " >&6; } # Check whether --enable-module-mssql was given. if test "${enable_module_mssql+set}" = set; then : enableval=$enable_module_mssql; case "${enableval}" in yes) enable_module_mssql=true ;; no) enable_module_mssql=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-mssql" "$LINENO" 5 ;; esac else enable_module_mssql=$check_module_mssql fi if test x"$enable_module_mssql" = "xtrue"; then BUILD_MODULE_MSSQL_TRUE= BUILD_MODULE_MSSQL_FALSE='#' else BUILD_MODULE_MSSQL_TRUE='#' BUILD_MODULE_MSSQL_FALSE= fi if test x"$enable_module_mssql" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable MYSQL module" >&5 $as_echo_n "checking whether to enable MYSQL module... " >&6; } # Check whether --enable-module-mysql was given. if test "${enable_module_mysql+set}" = set; then : enableval=$enable_module_mysql; case "${enableval}" in yes) enable_module_mysql=true ;; no) enable_module_mysql=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-mysql" "$LINENO" 5 ;; esac else enable_module_mysql="true" fi if test x"$enable_module_mysql" = "xtrue"; then BUILD_MODULE_MYSQL_TRUE= BUILD_MODULE_MYSQL_FALSE='#' else BUILD_MODULE_MYSQL_TRUE='#' BUILD_MODULE_MYSQL_FALSE= fi if test x"$enable_module_mysql" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi check_module_ncp="false" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NCPFS Library and Header files..." >&5 $as_echo "$as_me: checking for NCPFS Library and Header files..." >&6;} ac_fn_c_check_header_mongrel "$LINENO" "ncp/nwcalls.h" "ac_cv_header_ncp_nwcalls_h" "$ac_includes_default" if test "x$ac_cv_header_ncp_nwcalls_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lncp" >&5 $as_echo_n "checking for main in -lncp... " >&6; } if ${ac_cv_lib_ncp_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lncp $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ncp_main=yes else ac_cv_lib_ncp_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncp_main" >&5 $as_echo "$ac_cv_lib_ncp_main" >&6; } if test "x$ac_cv_lib_ncp_main" = xyes; then : $as_echo "#define HAVE_LIBNCP 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lncp" check_module_ncp="true" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** NCPFS library required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using \"make install-dev\" within the NCPFS source. The NCP module will NOT be built. " >&5 $as_echo "$as_me: WARNING: *** NCPFS library required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using \"make install-dev\" within the NCPFS source. The NCP module will NOT be built. " >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** NCPFS header files required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using \"make install-dev\" within the NCPFS source. The NCP module will NOT be built. " >&5 $as_echo "$as_me: WARNING: *** NCPFS header files required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using \"make install-dev\" within the NCPFS source. The NCP module will NOT be built. " >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable NCP module" >&5 $as_echo_n "checking whether to enable NCP module... " >&6; } # Check whether --enable-module-ncp was given. if test "${enable_module_ncp+set}" = set; then : enableval=$enable_module_ncp; case "${enableval}" in yes) enable_module_ncp=true ;; no) enable_module_ncp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-ncp" "$LINENO" 5 ;; esac else enable_module_ncp=$check_module_ncp fi if test x"$enable_module_ncp" = "xtrue"; then BUILD_MODULE_NCP_TRUE= BUILD_MODULE_NCP_FALSE='#' else BUILD_MODULE_NCP_TRUE='#' BUILD_MODULE_NCP_FALSE= fi if test x"$enable_module_ncp" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable NNTP module" >&5 $as_echo_n "checking whether to enable NNTP module... " >&6; } # Check whether --enable-module-nntp was given. if test "${enable_module_nntp+set}" = set; then : enableval=$enable_module_nntp; case "${enableval}" in yes) enable_module_nntp=true ;; no) enable_module_nntp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-nntp" "$LINENO" 5 ;; esac else enable_module_nntp="true" fi if test x"$enable_module_nntp" = "xtrue"; then BUILD_MODULE_NNTP_TRUE= BUILD_MODULE_NNTP_FALSE='#' else BUILD_MODULE_NNTP_TRUE='#' BUILD_MODULE_NNTP_FALSE= fi if test x"$enable_module_nntp" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable PCANYWHERE module" >&5 $as_echo_n "checking whether to enable PCANYWHERE module... " >&6; } # Check whether --enable-module-pcanywhere was given. if test "${enable_module_pcanywhere+set}" = set; then : enableval=$enable_module_pcanywhere; case "${enableval}" in yes) enable_module_pcanywhere=true ;; no) enable_module_pcanywhere=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-pcanywhere" "$LINENO" 5 ;; esac else enable_module_pcanywhere="true" fi if test x"$enable_module_pcanywhere" = "xtrue"; then BUILD_MODULE_PCANYWHERE_TRUE= BUILD_MODULE_PCANYWHERE_FALSE='#' else BUILD_MODULE_PCANYWHERE_TRUE='#' BUILD_MODULE_PCANYWHERE_FALSE= fi if test x"$enable_module_pcanywhere" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable POP3 module" >&5 $as_echo_n "checking whether to enable POP3 module... " >&6; } # Check whether --enable-module-pop3 was given. if test "${enable_module_pop3+set}" = set; then : enableval=$enable_module_pop3; case "${enableval}" in yes) enable_module_pop3=true ;; no) enable_module_pop3=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-pop3" "$LINENO" 5 ;; esac else enable_module_pop3="true" fi if test x"$enable_module_pop3" = "xtrue"; then BUILD_MODULE_POP3_TRUE= BUILD_MODULE_POP3_FALSE='#' else BUILD_MODULE_POP3_TRUE='#' BUILD_MODULE_POP3_FALSE= fi if test x"$enable_module_pop3" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi check_module_postgres="false" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PostgreSQL Library and Header files..." >&5 $as_echo "$as_me: checking for PostgreSQL Library and Header files..." >&6;} ac_fn_c_check_header_mongrel "$LINENO" "libpq-fe.h" "ac_cv_header_libpq_fe_h" "$ac_includes_default" if test "x$ac_cv_header_libpq_fe_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpq" >&5 $as_echo_n "checking for main in -lpq... " >&6; } if ${ac_cv_lib_pq_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpq $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pq_main=yes else ac_cv_lib_pq_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_main" >&5 $as_echo "$ac_cv_lib_pq_main" >&6; } if test "x$ac_cv_lib_pq_main" = xyes; then : $as_echo "#define HAVE_LIBPQ 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lpq" check_module_postgres="true" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** LIBPQ library required for PostgreSQL module. *** The PostgreSQL package must be installed for the PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. " >&5 $as_echo "$as_me: WARNING: *** LIBPQ library required for PostgreSQL module. *** The PostgreSQL package must be installed for the PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. " >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** LIBPQ header files required for PostgreSQL module. *** The PostgreSQL package must be installed for PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. " >&5 $as_echo "$as_me: WARNING: *** LIBPQ header files required for PostgreSQL module. *** The PostgreSQL package must be installed for PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. " >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable POSTGRES module" >&5 $as_echo_n "checking whether to enable POSTGRES module... " >&6; } # Check whether --enable-module-postgres was given. if test "${enable_module_postgres+set}" = set; then : enableval=$enable_module_postgres; case "${enableval}" in yes) enable_module_postgres=true ;; no) enable_module_postgres=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-postgres" "$LINENO" 5 ;; esac else enable_module_postgres=$check_module_postgres fi if test x"$enable_module_postgres" = "xtrue"; then BUILD_MODULE_POSTGRES_TRUE= BUILD_MODULE_POSTGRES_FALSE='#' else BUILD_MODULE_POSTGRES_TRUE='#' BUILD_MODULE_POSTGRES_FALSE= fi if test x"$enable_module_postgres" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable REXEC module" >&5 $as_echo_n "checking whether to enable REXEC module... " >&6; } # Check whether --enable-module-rexec was given. if test "${enable_module_rexec+set}" = set; then : enableval=$enable_module_rexec; case "${enableval}" in yes) enable_module_rexec=true ;; no) enable_module_rexec=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-rexec" "$LINENO" 5 ;; esac else enable_module_rexec="true" fi if test x"$enable_module_rexec" = "xtrue"; then BUILD_MODULE_REXEC_TRUE= BUILD_MODULE_REXEC_FALSE='#' else BUILD_MODULE_REXEC_TRUE='#' BUILD_MODULE_REXEC_FALSE= fi if test x"$enable_module_rexec" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable RLOGIN module" >&5 $as_echo_n "checking whether to enable RLOGIN module... " >&6; } # Check whether --enable-module-rlogin was given. if test "${enable_module_rlogin+set}" = set; then : enableval=$enable_module_rlogin; case "${enableval}" in yes) enable_module_rlogin=true ;; no) enable_module_rlogin=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-rlogin" "$LINENO" 5 ;; esac else enable_module_rlogin="true" fi if test x"$enable_module_rlogin" = "xtrue"; then BUILD_MODULE_RLOGIN_TRUE= BUILD_MODULE_RLOGIN_FALSE='#' else BUILD_MODULE_RLOGIN_TRUE='#' BUILD_MODULE_RLOGIN_FALSE= fi if test x"$enable_module_rlogin" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable RSH module" >&5 $as_echo_n "checking whether to enable RSH module... " >&6; } # Check whether --enable-module-rsh was given. if test "${enable_module_rsh+set}" = set; then : enableval=$enable_module_rsh; case "${enableval}" in yes) enable_module_rsh=true ;; no) enable_module_rsh=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-rsh" "$LINENO" 5 ;; esac else enable_module_rsh="true" fi if test x"$enable_module_rsh" = "xtrue"; then BUILD_MODULE_RSH_TRUE= BUILD_MODULE_RSH_FALSE='#' else BUILD_MODULE_RSH_TRUE='#' BUILD_MODULE_RSH_FALSE= fi if test x"$enable_module_rsh" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi check_module_smbnt=$check_libssl { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable SMBNT module" >&5 $as_echo_n "checking whether to enable SMBNT module... " >&6; } # Check whether --enable-module-smbnt was given. if test "${enable_module_smbnt+set}" = set; then : enableval=$enable_module_smbnt; case "${enableval}" in yes) enable_module_smbnt=true ;; no) enable_module_smbnt=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-smbnt" "$LINENO" 5 ;; esac else enable_module_smbnt=$check_module_smbnt fi if test x"$enable_module_smbnt" = "xtrue"; then BUILD_MODULE_SMBNT_TRUE= BUILD_MODULE_SMBNT_FALSE='#' else BUILD_MODULE_SMBNT_TRUE='#' BUILD_MODULE_SMBNT_FALSE= fi if test x"$enable_module_smbnt" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable SMTP module" >&5 $as_echo_n "checking whether to enable SMTP module... " >&6; } # Check whether --enable-module-smtp was given. if test "${enable_module_smtp+set}" = set; then : enableval=$enable_module_smtp; case "${enableval}" in yes) enable_module_smtp=true ;; no) enable_module_smtp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-smtp" "$LINENO" 5 ;; esac else enable_module_smtp="true" fi if test x"$enable_module_smtp" = "xtrue"; then BUILD_MODULE_SMTP_TRUE= BUILD_MODULE_SMTP_FALSE='#' else BUILD_MODULE_SMTP_TRUE='#' BUILD_MODULE_SMTP_FALSE= fi if test x"$enable_module_smtp" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable SMTP-VRFY module" >&5 $as_echo_n "checking whether to enable SMTP-VRFY module... " >&6; } # Check whether --enable-module-smtp-vrfy was given. if test "${enable_module_smtp_vrfy+set}" = set; then : enableval=$enable_module_smtp_vrfy; case "${enableval}" in yes) enable_module_smtp_vrfy=true ;; no) enable_module_smtp_vrfy=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-smtp-vrfy" "$LINENO" 5 ;; esac else enable_module_smtp_vrfy="true" fi if test x"$enable_module_smtp_vrfy" = "xtrue"; then BUILD_MODULE_SMTP_VRFY_TRUE= BUILD_MODULE_SMTP_VRFY_FALSE='#' else BUILD_MODULE_SMTP_VRFY_TRUE='#' BUILD_MODULE_SMTP_VRFY_FALSE= fi if test x"$enable_module_smtp_vrfy" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable SNMP module" >&5 $as_echo_n "checking whether to enable SNMP module... " >&6; } # Check whether --enable-module-snmp was given. if test "${enable_module_snmp+set}" = set; then : enableval=$enable_module_snmp; case "${enableval}" in yes) enable_module_snmp=true ;; no) enable_module_snmp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-snmp" "$LINENO" 5 ;; esac else enable_module_snmp="true" fi if test x"$enable_module_snmp" = "xtrue"; then BUILD_MODULE_SNMP_TRUE= BUILD_MODULE_SNMP_FALSE='#' else BUILD_MODULE_SNMP_TRUE='#' BUILD_MODULE_SNMP_FALSE= fi if test x"$enable_module_snmp" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi check_module_ssh="false" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Libssh2 Library files..." >&5 $as_echo "$as_me: checking for Libssh2 Library files..." >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lssh2" >&5 $as_echo_n "checking for main in -lssh2... " >&6; } if ${ac_cv_lib_ssh2_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssh2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ssh2_main=yes else ac_cv_lib_ssh2_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssh2_main" >&5 $as_echo "$ac_cv_lib_ssh2_main" >&6; } if test "x$ac_cv_lib_ssh2_main" = xyes; then : $as_echo "#define HAVE_LIBSSH2 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lssh2" check_module_ssh="true" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Libssh2 required for SSH2 module. *** Libssh2 (http://www.libssh2.org) is not the same as libssh (http://0xbadc0de.be). Make sure you have the correct library. The SSH2 module will NOT be built. " >&5 $as_echo "$as_me: WARNING: *** Libssh2 required for SSH2 module. *** Libssh2 (http://www.libssh2.org) is not the same as libssh (http://0xbadc0de.be). Make sure you have the correct library. The SSH2 module will NOT be built. " >&2;} fi if test x"$check_module_ssh" = "xtrue"; then check_libgcrypt="false" if test -f "/usr/lib/libssh2.so"; then LIBSSH2_PATH="/usr/lib/libssh2.so" elif test -f "/usr/local/lib/libssh2.so"; then LIBSSH2_PATH="/usr/local/lib/libssh2.so" elif test -f "/opt/local/lib/libssh2.dylib"; then LIBSSH2_PATH="/opt/local/lib/libssh2.dylib" elif test -f "/usr/local/lib/libssh2.dylib"; then LIBSSH2_PATH="/usr/local/lib/libssh2.dylib" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: LIBSSH2 path not found. Assuming it was... " >&5 $as_echo "$as_me: WARNING: LIBSSH2 path not found. Assuming it was... " >&2;} fi if test -f "`which ldd`"; then LDD="ldd" elif test -f "`which otool`"; then LDD="otool -L" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No ldd detected. Unable to test whether Libssh2 was compiled to use libgcrypt. Assuming it was... " >&5 $as_echo "$as_me: WARNING: No ldd detected. Unable to test whether Libssh2 was compiled to use libgcrypt. Assuming it was... " >&2;} check_libgcrypt="true" fi if test ! -z "`$LDD $LIBSSH2_PATH |grep libgcrypt`"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libssh2 compiled using libgcrypt. Checking additional dependencies. " >&5 $as_echo "$as_me: WARNING: Libssh2 compiled using libgcrypt. Checking additional dependencies. " >&2;} check_libgcrypt="true" fi if test x"$check_libgcrypt" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Libgrcypt Library files..." >&5 $as_echo "$as_me: checking for Libgrcypt Library files..." >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcry_control in -lgcrypt" >&5 $as_echo_n "checking for gcry_control in -lgcrypt... " >&6; } if ${ac_cv_lib_gcrypt_gcry_control+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gcry_control (); int main () { return gcry_control (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gcrypt_gcry_control=yes else ac_cv_lib_gcrypt_gcry_control=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gcrypt_gcry_control" >&5 $as_echo "$ac_cv_lib_gcrypt_gcry_control" >&6; } if test "x$ac_cv_lib_gcrypt_gcry_control" = xyes; then : $as_echo "#define HAVE_LIBGCRYPT 1" >>confdefs.h LIBS="$LIBS -lgcrypt" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Libgcrypt required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgcrypt11-dev). The SSH2 module will NOT be built. " >&5 $as_echo "$as_me: WARNING: *** Libgcrypt required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgcrypt11-dev). The SSH2 module will NOT be built. " >&2;} check_module_ssh="false" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GnuTLS Library files..." >&5 $as_echo "$as_me: checking for GnuTLS Library files..." >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gnutls_handshake in -lgnutls" >&5 $as_echo_n "checking for gnutls_handshake in -lgnutls... " >&6; } if ${ac_cv_lib_gnutls_gnutls_handshake+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgnutls $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gnutls_handshake (); int main () { return gnutls_handshake (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gnutls_gnutls_handshake=yes else ac_cv_lib_gnutls_gnutls_handshake=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gnutls_gnutls_handshake" >&5 $as_echo "$ac_cv_lib_gnutls_gnutls_handshake" >&6; } if test "x$ac_cv_lib_gnutls_gnutls_handshake" = xyes; then : $as_echo "#define HAVE_GNUTLS 1" >>confdefs.h LIBS="$LIBS -lgnutls" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** GnuTLS required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgnutls-dev). The SSH2 module will NOT be built. " >&5 $as_echo "$as_me: WARNING: *** GnuTLS required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgnutls-dev). The SSH2 module will NOT be built. " >&2;} check_module_ssh="false" fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable SSH module" >&5 $as_echo_n "checking whether to enable SSH module... " >&6; } # Check whether --enable-module-ssh was given. if test "${enable_module_ssh+set}" = set; then : enableval=$enable_module_ssh; case "${enableval}" in yes) enable_module_ssh=true ;; no) enable_module_ssh=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-ssh" "$LINENO" 5 ;; esac else enable_module_ssh=$check_module_ssh fi if test x"$enable_module_ssh" = "xtrue"; then BUILD_MODULE_SSH_TRUE= BUILD_MODULE_SSH_FALSE='#' else BUILD_MODULE_SSH_TRUE='#' BUILD_MODULE_SSH_FALSE= fi if test x"$enable_module_ssh" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi check_module_svn="false" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Subversion Library and Header files..." >&5 $as_echo "$as_me: checking for Subversion Library and Header files..." >&6;} # Extract the first word of "apr-1-config", so it can be a program name with args. set dummy apr-1-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_APR_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $APR_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_APR_CONFIG="$APR_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_APR_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi APR_CONFIG=$ac_cv_path_APR_CONFIG if test -n "$APR_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $APR_CONFIG" >&5 $as_echo "$APR_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$APR_CONFIG"; then # Extract the first word of "apr-config", so it can be a program name with args. set dummy apr-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_APR_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $APR_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_APR_CONFIG="$APR_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_APR_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi APR_CONFIG=$ac_cv_path_APR_CONFIG if test -n "$APR_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $APR_CONFIG" >&5 $as_echo "$APR_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$APR_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** apr-config/apr-1-config not found and required for SVN module *** Make sure to install libapr1-dev or whatever package your distribution uses to distribute this file. " >&5 $as_echo "$as_me: WARNING: *** apr-config/apr-1-config not found and required for SVN module *** Make sure to install libapr1-dev or whatever package your distribution uses to distribute this file. " >&2;} fi fi if test -n "$APR_CONFIG"; then if test x`$APR_CONFIG --cc` = "xcc"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Apache (apr) was compiled using Sun C compiler and not GNU gcc. *** \"$APR_CONFIG --cc\" responded with \"cc\", which usually means that your build of Apache was compiled with Sun C compiler and not with gcc. This means that the version of libtool embedded within Apache installation is also configured for Sun C compiler and not gcc. The Sun C compiler setup is incompatible because the options to each compiler are different for building shared objects and libraries. Specifically, the Sun compiler supports the \"-mt\" flag, whereas gcc does not. In order to build the SVN Medusa module, rebuild $APR_CONFIG using gcc, or remove the \"-mt\" CPPFLAGS flag from the autogenerated Medusa configuration files. " >&5 $as_echo "$as_me: WARNING: *** Apache (apr) was compiled using Sun C compiler and not GNU gcc. *** \"$APR_CONFIG --cc\" responded with \"cc\", which usually means that your build of Apache was compiled with Sun C compiler and not with gcc. This means that the version of libtool embedded within Apache installation is also configured for Sun C compiler and not gcc. The Sun C compiler setup is incompatible because the options to each compiler are different for building shared objects and libraries. Specifically, the Sun compiler supports the \"-mt\" flag, whereas gcc does not. In order to build the SVN Medusa module, rebuild $APR_CONFIG using gcc, or remove the \"-mt\" CPPFLAGS flag from the autogenerated Medusa configuration files. " >&2;} else APR_INCLUDE_DIR=`$APR_CONFIG --includedir` CPPFLAGS="$CPPFLAGS `$APR_CONFIG --includes --cppflags`" as_ac_Header=`$as_echo "ac_cv_header_$APR_INCLUDE_DIR/apr_tables.h" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$APR_INCLUDE_DIR/apr_tables.h" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : ac_fn_c_check_header_mongrel "$LINENO" "subversion-1/svn_client.h" "ac_cv_header_subversion_1_svn_client_h" "$ac_includes_default" if test "x$ac_cv_header_subversion_1_svn_client_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsvn_client-1" >&5 $as_echo_n "checking for main in -lsvn_client-1... " >&6; } if ${ac_cv_lib_svn_client_1_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvn_client-1 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svn_client_1_main=yes else ac_cv_lib_svn_client_1_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svn_client_1_main" >&5 $as_echo "$ac_cv_lib_svn_client_1_main" >&6; } if test "x$ac_cv_lib_svn_client_1_main" = xyes; then : $as_echo "#define HAVE_LIBSVN_CLIENT_1 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lsvn_client-1" check_module_svn="true" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Subversion libsvn library required for SVN module. *** " >&5 $as_echo "$as_me: WARNING: *** Subversion libsvn library required for SVN module. *** " >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Subversion header files required for SVN module. (e.g., libsvn-dev) *** " >&5 $as_echo "$as_me: WARNING: *** Subversion header files required for SVN module. (e.g., libsvn-dev) *** " >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** APR header files required for SVN module. (e.g., libapr1-dev) *** " >&5 $as_echo "$as_me: WARNING: *** APR header files required for SVN module. (e.g., libapr1-dev) *** " >&2;} fi fi else check_module_svn="false" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable SVN module" >&5 $as_echo_n "checking whether to enable SVN module... " >&6; } # Check whether --enable-module-svn was given. if test "${enable_module_svn+set}" = set; then : enableval=$enable_module_svn; case "${enableval}" in yes) enable_module_svn=true ;; no) enable_module_svn=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-svn" "$LINENO" 5 ;; esac else enable_module_svn=$check_module_svn fi if test x"$enable_module_svn" = "xtrue"; then BUILD_MODULE_SVN_TRUE= BUILD_MODULE_SVN_FALSE='#' else BUILD_MODULE_SVN_TRUE='#' BUILD_MODULE_SVN_FALSE= fi if test x"$enable_module_svn" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable TELNET module" >&5 $as_echo_n "checking whether to enable TELNET module... " >&6; } # Check whether --enable-module-telnet was given. if test "${enable_module_telnet+set}" = set; then : enableval=$enable_module_telnet; case "${enableval}" in yes) enable_module_telnet=true ;; no) enable_module_telnet=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-telnet" "$LINENO" 5 ;; esac else enable_module_telnet="true" fi if test x"$enable_module_telnet" = "xtrue"; then BUILD_MODULE_TELNET_TRUE= BUILD_MODULE_TELNET_FALSE='#' else BUILD_MODULE_TELNET_TRUE='#' BUILD_MODULE_TELNET_FALSE= fi if test x"$enable_module_telnet" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable VMAUTHD module" >&5 $as_echo_n "checking whether to enable VMAUTHD module... " >&6; } # Check whether --enable-module-vmauthd was given. if test "${enable_module_vmauthd+set}" = set; then : enableval=$enable_module_vmauthd; case "${enableval}" in yes) enable_module_vmauthd=true ;; no) enable_module_vmauthd=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-vmauthd" "$LINENO" 5 ;; esac else enable_module_vmauthd="true" fi if test x"$enable_module_vmauthd" = "xtrue"; then BUILD_MODULE_VMAUTHD_TRUE= BUILD_MODULE_VMAUTHD_FALSE='#' else BUILD_MODULE_VMAUTHD_TRUE='#' BUILD_MODULE_VMAUTHD_FALSE= fi if test x"$enable_module_vmauthd" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi check_module_vnc=$check_libssl { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable VNC module" >&5 $as_echo_n "checking whether to enable VNC module... " >&6; } # Check whether --enable-module-vnc was given. if test "${enable_module_vnc+set}" = set; then : enableval=$enable_module_vnc; case "${enableval}" in yes) enable_module_vnc=true ;; no) enable_module_vnc=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-vnc" "$LINENO" 5 ;; esac else enable_module_vnc=$check_module_vnc fi if test x"$enable_module_vnc" = "xtrue"; then BUILD_MODULE_VNC_TRUE= BUILD_MODULE_VNC_FALSE='#' else BUILD_MODULE_VNC_TRUE='#' BUILD_MODULE_VNC_FALSE= fi if test x"$enable_module_vnc" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable WRAPPER module" >&5 $as_echo_n "checking whether to enable WRAPPER module... " >&6; } # Check whether --enable-module-wrapper was given. if test "${enable_module_wrapper+set}" = set; then : enableval=$enable_module_wrapper; case "${enableval}" in yes) enable_module_wrapper=true ;; no) enable_module_wrapper=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-wrapper" "$LINENO" 5 ;; esac else enable_module_wrapper="true" fi if test x"$enable_module_wrapper" = "xtrue"; then BUILD_MODULE_WRAPPER_TRUE= BUILD_MODULE_WRAPPER_FALSE='#' else BUILD_MODULE_WRAPPER_TRUE='#' BUILD_MODULE_WRAPPER_FALSE= fi if test x"$enable_module_wrapper" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi check_module_web_form=$check_libssl { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable WEB-FORM module" >&5 $as_echo_n "checking whether to enable WEB-FORM module... " >&6; } # Check whether --enable-module-web-form was given. if test "${enable_module_web_form+set}" = set; then : enableval=$enable_module_web_form; case "${enableval}" in yes) enable_module_web_form=true ;; no) enable_module_web_form=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-web-form" "$LINENO" 5 ;; esac else enable_module_web_form=$check_module_web_form fi if test x"$enable_module_web_form" = "xtrue"; then BUILD_MODULE_WEB_FORM_TRUE= BUILD_MODULE_WEB_FORM_FALSE='#' else BUILD_MODULE_WEB_FORM_TRUE='#' BUILD_MODULE_WEB_FORM_FALSE= fi if test x"$enable_module_web_form" = "xtrue"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 $as_echo "$as_me: " >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: *******************************************************" >&5 $as_echo "$as_me: *******************************************************" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Medusa Module Build Summary" >&5 $as_echo "$as_me: Medusa Module Build Summary" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 $as_echo "$as_me: " >&6;} show_build_status() { if test "$1" = "true" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: $2 Enabled" >&5 $as_echo "$as_me: $2 Enabled" >&6;} else { $as_echo "$as_me:${as_lineno-$LINENO}: $2 ** Disabled **" >&5 $as_echo "$as_me: $2 ** Disabled **" >&6;} fi } show_build_status "${enable_module_afp}" " AFP " show_build_status "${enable_module_cvs}" " CVS " show_build_status "${enable_module_ftp}" " FTP " show_build_status "${enable_module_http}" " HTTP " show_build_status "${enable_module_imap}" " IMAP " show_build_status "${enable_module_mssql}" " MSSQL " show_build_status "${enable_module_mysql}" " MYSQL " show_build_status "${enable_module_ncp}" " NCP " show_build_status "${enable_module_nntp}" " NNTP " show_build_status "${enable_module_pcanywhere}" " PCANYWHERE " show_build_status "${enable_module_pop3}" " POP3 " show_build_status "${enable_module_postgres}" " POSTGRES " show_build_status "${enable_module_rexec}" " REXEC " show_build_status "${enable_module_rlogin}" " RLOGIN " show_build_status "${enable_module_rsh}" " RSH " show_build_status "${enable_module_smbnt}" " SMBNT " show_build_status "${enable_module_smtp}" " SMTP " show_build_status "${enable_module_smtp_vrfy}" " SMTP-VRFY " show_build_status "${enable_module_snmp}" " SNMP " show_build_status "${enable_module_ssh}" " SSH " show_build_status "${enable_module_svn}" " SVN " show_build_status "${enable_module_telnet}" " TELNET " show_build_status "${enable_module_vmauthd}" " VMAUTHD " show_build_status "${enable_module_vnc}" " VNC " show_build_status "${enable_module_wrapper}" " WRAPPER " show_build_status "${enable_module_web_form}" " WEB-FORM " { $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 $as_echo "$as_me: " >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: If a module is unexpectedly marked as disabled, check " >&5 $as_echo "$as_me: If a module is unexpectedly marked as disabled, check " >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: above output and verify dependancies were satisfied. " >&5 $as_echo "$as_me: above output and verify dependancies were satisfied. " >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 $as_echo "$as_me: " >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: It should also be noted that, by default, not all of " >&5 $as_echo "$as_me: It should also be noted that, by default, not all of " >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: the modules are built. Incomplete modules or modules " >&5 $as_echo "$as_me: the modules are built. Incomplete modules or modules " >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: which have not been sufficiently tested may be " >&5 $as_echo "$as_me: which have not been sufficiently tested may be " >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: disabled. To enable non-default modules, use the " >&5 $as_echo "$as_me: disabled. To enable non-default modules, use the " >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: \"--enable-module-MODULE_NAME\" configure option." >&5 $as_echo "$as_me: \"--enable-module-MODULE_NAME\" configure option." >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: *******************************************************" >&5 $as_echo "$as_me: *******************************************************" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 $as_echo "$as_me: " >&6;} for ac_func in strcasestr do : ac_fn_c_check_func "$LINENO" "strcasestr" "ac_cv_func_strcasestr" if test "x$ac_cv_func_strcasestr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRCASESTR 1 _ACEOF fi done for ac_func in asprintf do : ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf" if test "x$ac_cv_func_asprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ASPRINTF 1 _ACEOF fi done for ac_func in vasprintf do : ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf" if test "x$ac_cv_func_vasprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VASPRINTF 1 _ACEOF fi done case "$target" in *linux*) LIBDL="-ldl -lrt -lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *freebsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *netbsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *openbsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="-g -Wl,-E" ;; *apple-darwin*) # Modules will segfault when executed (show usage works) if medusa core # is not linked to CoreFoundation (starting with 10.6). This is believed to # be due to libsvn linking to CoreFoundation and our modules linked via # "-lsvn_client-1". See http://www.openradar.me/7209349 for more info. LIBDL="-ldl -framework CoreFoundation" RDYNAMIC="" MODULE_LIBS="$MODULE_LIBS -bundle -flat_namespace -undefined suppress" EXTRA_LDFLAGS="" ;; *solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" LDFLAGS="$LDFLAGS -R/usr/local/lib -R/usr/local/ssl/lib -L/usr/local/ssl/lib" LIBDL="-ldl -lm -lrt -lnsl -lsocket" RDYNAMIC="-Rdynamic" EXTRA_LDFLAGS="" MODULE_LIBS="$MODULE_LIBS -G" ;; *cygwin*) CPPFLAGS="$CPPFLAGS -DCYGWIN" LIBDL="-ldl" RDYNAMIC="" MODULE_LIBS="$MODULE_LIBS -shared" ;; *) LIBDL="-ldl -lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; esac LDFLAGS="$LDFLAGS $RDYNAMIC $EXTRA_LDFLAGS" LIBS="$LIBS $LIBDL" test "$prefix" = NONE && prefix=${ac_default_prefix} _default_mod_path="${prefix}/lib/medusa/modules" # Check whether --with-default-mod-path was given. if test "${with_default_mod_path+set}" = set; then : withval=$with_default_mod_path; _default_mod_path="$withval" fi cat >>confdefs.h <<_ACEOF #define DEFAULT_MOD_PATH "$_default_mod_path" _ACEOF ac_config_files="$ac_config_files Makefile src/Makefile src/modsrc/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_AFP_TRUE}" && test -z "${BUILD_MODULE_AFP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_AFP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_CVS_TRUE}" && test -z "${BUILD_MODULE_CVS_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_CVS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_FTP_TRUE}" && test -z "${BUILD_MODULE_FTP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_FTP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_HTTP_TRUE}" && test -z "${BUILD_MODULE_HTTP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_HTTP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_IMAP_TRUE}" && test -z "${BUILD_MODULE_IMAP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_IMAP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_MSSQL_TRUE}" && test -z "${BUILD_MODULE_MSSQL_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_MSSQL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_MYSQL_TRUE}" && test -z "${BUILD_MODULE_MYSQL_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_MYSQL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_NCP_TRUE}" && test -z "${BUILD_MODULE_NCP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_NCP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_NNTP_TRUE}" && test -z "${BUILD_MODULE_NNTP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_NNTP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_PCANYWHERE_TRUE}" && test -z "${BUILD_MODULE_PCANYWHERE_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_PCANYWHERE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_POP3_TRUE}" && test -z "${BUILD_MODULE_POP3_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_POP3\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_POSTGRES_TRUE}" && test -z "${BUILD_MODULE_POSTGRES_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_POSTGRES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_REXEC_TRUE}" && test -z "${BUILD_MODULE_REXEC_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_REXEC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_RLOGIN_TRUE}" && test -z "${BUILD_MODULE_RLOGIN_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_RLOGIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_RSH_TRUE}" && test -z "${BUILD_MODULE_RSH_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_RSH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SMBNT_TRUE}" && test -z "${BUILD_MODULE_SMBNT_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SMBNT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SMTP_TRUE}" && test -z "${BUILD_MODULE_SMTP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SMTP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SMTP_VRFY_TRUE}" && test -z "${BUILD_MODULE_SMTP_VRFY_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SMTP_VRFY\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SNMP_TRUE}" && test -z "${BUILD_MODULE_SNMP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SNMP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SSH_TRUE}" && test -z "${BUILD_MODULE_SSH_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SSH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SVN_TRUE}" && test -z "${BUILD_MODULE_SVN_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SVN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_TELNET_TRUE}" && test -z "${BUILD_MODULE_TELNET_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_TELNET\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_VMAUTHD_TRUE}" && test -z "${BUILD_MODULE_VMAUTHD_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_VMAUTHD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_VNC_TRUE}" && test -z "${BUILD_MODULE_VNC_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_VNC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_WRAPPER_TRUE}" && test -z "${BUILD_MODULE_WRAPPER_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_WRAPPER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_WEB_FORM_TRUE}" && test -z "${BUILD_MODULE_WEB_FORM_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_WEB_FORM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/modsrc/Makefile") CONFIG_FILES="$CONFIG_FILES src/modsrc/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi medusa-2.1.1/AUTHORS0000644000175000001440000000146411723732127010770 00000000000000JoMo-Kun --------------------------------------- *Medusa core design/implementation *Modules: SMBNT, MS-SQL, SSH2, MySQL, VNC, Wrapper, CVS, NCP, PostgreSQL, SMTP/VRFY, SNMP, SVN, VmAuthd, HTTP (NTLM), PcAnywhere fizzgig --------------------------------------- *Networking code *Implementation of loadable module code *Modules: TELNET, HTTP pMonkey --------------------------------------- *Modules: FTP, IMAP, MySQL, REXEC, RLOGIN, RSH, SMTP-AUTH Foofus --------------------------------------- *Design of loadable modules Bokojan --------------------------------------- *Testing scripts Luciano Bello --------------------------------------- *Modules: WEB-FORM medusa-2.1.1/COPYING0000644000175000001440000004325411741166633010761 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. medusa-2.1.1/config.sub0000755000175000001440000007607311723732130011705 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-02-10' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # 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. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit 0;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mips64r5900 | mips64r5900el \ | mn10200 | mn10300 \ | msp430 \ | ns16k | ns32k \ | openrisc | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ | strongarm \ | tahoe | dvp | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mips64r5900-* | mips64r5900el-* \ | mmix-* \ | msp430-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mipsEE* | ee | ps2) basic_machine=mips64r5900el-scei case $os in -linux*) ;; *) os=-elf ;; esac ;; iop) basic_machine=mipsel-scei os=-irx ;; dvp) basic_machine=dvp-scei os=-elf ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; or32 | or32-*) basic_machine=or32-unknown os=-coff ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sh64) basic_machine=sh64-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* | -irx*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: medusa-2.1.1/install-sh0000755000175000001440000001425311723732130011716 00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "$0: no input file specified" >&2 exit 1 else : fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d "$dst" ]; then instcmd=: chmodcmd="" else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f "$src" ] || [ -d "$src" ] then : else echo "$0: $src does not exist" >&2 exit 1 fi if [ x"$dst" = x ] then echo "$0: no destination specified" >&2 exit 1 else : fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d "$dst" ] then dst=$dst/`basename "$src"` else : fi fi ## this sed command emulates the dirname command dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp='' while [ $# -ne 0 ] ; do pathcomp=$pathcomp$1 shift if [ ! -d "$pathcomp" ] ; then $mkdirprog "$pathcomp" else : fi pathcomp=$pathcomp/ done fi if [ x"$dir_arg" != x ] then $doit $instcmd "$dst" && if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename "$dst"` else : fi # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/#inst.$$# rmtmp=$dstdir/#rm.$$# # Trap to clean up temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && # Now remove or move aside any old file at destination location. We try this # two ways since rm can't unlink itself on some systems and the destination # file might be busy for other reasons. In this case, the final cleanup # might fail but the new file should still install successfully. { if [ -f "$dstdir/$dstfile" ] then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi && # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } medusa-2.1.1/README0000644000175000001440000000041011723732130010560 00000000000000======================================================= Medusa Parallel Network Login Auditor ======================================================= Copyright (C) 2012 Joe Mondloch JoMo-Kun / jmk@foofus.net See doc/medusa.html for information regarding Medusa medusa-2.1.1/config.h.in0000644000175000001440000000540611760000333011727 00000000000000/* config.h.in. Generated from configure.in by autoheader. */ /* Location of medusa module files */ #undef DEFAULT_MOD_PATH /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Found GnuTLS Library */ #undef HAVE_GNUTLS /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Found AFPFS-NG Library */ #undef HAVE_LIBAFPFS /* Define to 1 if you have the `c' library (-lc). */ #undef HAVE_LIBC /* Define to 1 if you have the `crypto' library (-lcrypto). */ #undef HAVE_LIBCRYPTO /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Found Libgcrypt Library */ #undef HAVE_LIBGCRYPT /* Found NCP Library */ #undef HAVE_LIBNCP /* Found PostgreSQL Library */ #undef HAVE_LIBPQ /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Found SSH2 Library */ #undef HAVE_LIBSSH2 /* Found OpenSSL Library */ #undef HAVE_LIBSSL /* Found SVN Library */ #undef HAVE_LIBSVN_CLIENT_1 /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasestr' function. */ #undef HAVE_STRCASESTR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vasprintf' function. */ #undef HAVE_VASPRINTF /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* The size of `long long', as computed by sizeof. */ #undef SIZEOF_LONG_LONG /* The size of `short', as computed by sizeof. */ #undef SIZEOF_SHORT /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION medusa-2.1.1/ChangeLog0000644000175000001440000002710211760001265011460 00000000000000================================================================ Version 2.1.1 ================================================================ Minor release updates: - GCC 4.7 compile issue ("-module" removed) - SMBNT: fix infinite loop issue when testing against OS X - SNMP: remove socket flushing that caused us to miss passwords - IMAP: less restrictive regex to better match OK responses - POP3: restart connection after each attempt to deal with shunning ================================================================ Version 2.1 ================================================================ Medusa Core Updates: - Combo format now accepts "host:user:lm hash:ntlm hash" - Autoconf updates and fixes - Removed PCRE library dependency (using stock glibc regex support) Module Updates: - Numerous bug-fixes across modules (e.g., SSH2 thread-safety) - Support for UltraVNC MS-Logon (local/domain Windows credentials) Additional Updates: - Third-party GUI released: http://wiki.taksmind.org/index.php?title=Medusa-gui ================================================================ Version 2.0 ================================================================ Medusa Core Updates: -Pool-based thread handling Previous version destroyed threads following the completion of a host or user test. The use of a thread pool should decrease the overall application overhead by limiting the frequency of thread destruction and creation. The original code ran into issues in several specific situations (e.g. testing over a thousand users with only a single password). Such cases resulted in a large number of threads being created and destroyed in short order, frequently resulting in an application crash. The thread pool should eliminate this particular problem. -Modules now request next credential set (username + password) Modules previously called getNextPass(), which returned a valid password until the password list for the user being tested was exhausted. At that point, the module exited and the login thread was destroyed. A new thread and module instance would be created for the next user to test. We now use getNextCredetialSet(), which returns a valid user and password. This allows the module to get the next user to test and decide whether the connection needs to be completely torn down or not. -Secondary user credential queue added for missed login tests. In certain situations we need to scale back the number of concurrent login threads targetting a specific service. For example, MSDE's workload governor limits the service to no more than 5 concurrent connections. If the user kicked-off 10 parallel login threads, 5 of those are going to fail and terminate. The challenge is that each of those threads was already assigned a credential set to test. The previous version simply printed the username and password combinations which were not tested and moved on. We now push these missed credentials into a host specific queue. Once the login threads have finished their normal checks, they move on to this queue and retry the previously missed credentials. In some cases, say it's the last thread that pushed something into the queue before exiting, we kick-off a clean-up thread to walk through any remaining items. -Host and User-level Resume Support for host and user-level resuming of a scan. When Medusa receives a SIGINT, it will calculate and display a "resume map". This map can then be supplied to the next run. For example, "medusa [OPTIONS PREVIOUSLY USED] -Z h6u1u2h8.". This map describes which hosts were completed and which systems had not been touched. If a host was partially completed, it describes which users had been tested for that specific system. It should be noted that password-level resuming is not supported. If a user's password list was only partially completed, testing of the user will be restarted on resume. Module Updates: FTP -Misc. fixes IMAP -Domain module option for BASIC/NTLM authentication types -Allow auth type to be specified -Misc. fixes (NTLM base64 length, restart HTTP connection after each request) IMAP -Domain module option for LOGIN/NTLM authentication types -Regex-based server response matching for better handling of slow targets -Misc. fixes (handle dropped connections, force TLSv1, base64 length) MSSQL -Auto SQL port identification via "SQL Ping" technique NCP -Misc. fixes (connection retry code) POP3 -Domain module option for NTLM authentication type -Regex-based server response matching for better handling of slow targets -Misc. fixes (base64 length) SMTP -Regex-based server response matching for better handling of slow targets SMTP-VRFY -Misc. fixes (don't include "@" if no domain specified) SSH -Detect and warn if being built on Debian/Ubuntu system (broken libssh2) VMAUTHD -Regex-based server response matching for better handling of slow targets Web-Form -Misc. fixes WRAPPER -Misc. fixes (fix handling of short usernames/passwords) ================================================================ Version 1.5 ================================================================ Medusa Core Updates: -Provides additional information about current account check (e.g. 172.22.110.58 (60 of 104, 51 complete)) -Support for simple resume by host. -Bug fix for "-e" option -Bug fix for displaying hostname vs. IP -Added function for printing a specified length of binary data in hex Module Updates: AFP -Added new module for Apple Filing Protocol from pmonkey HTTP -NTLM auth bug fix -Digest authentication support (MD5 and MD5-sess) IMAP -STARTTLS extension support -NTLM support MYSQL -Misc. bug fixes POP3 -STARTTLS extension support -Better handling of connections dropped by remote server -Support user-supplied domain names -LOGIN, PLAIN, and NTLM support SMBNT -Created framework for different authentication levels (e.g. LM, NTLM, etc). -Support for basic LM authentication to allow for case insensitive bruting -NTLMv2/LMv2 support (Vista bruting) -Fix for guest user check -Support for "DOMAIN\USER" and "DOMAIN\\USER" style names SMTP -Renamed SMTP-AUTH to SMTP -NTLM support SMTP-VRFY -Misc. bug fixes SSH -Honor number of user specified retries -Restart connection when server fails to respond with auth modes after several attempts TELNET -Basic AS/400 Telnet / TN5250 support -Log hosts supplying only a password prompt (non-AAA) VMAUTHD -Misc. bug fixes WEB-FORM -Misc. bug fixes for user-supplied FORM-DATA value Misc. Updates: -Added ZSH Functions file -Updated Medusa ebuild version and added new module dependencies. ================================================================ Version 1.4 ================================================================ Medusa Core Updates: -Major re-working of the autoconf setup. Modules can now be enabled/disabled individually. Also, modules for which the base dependencies are not satisfied are simply not built. In the past they were compiled, but left in a non-functional state. The default is to build all "stable" modules. -APR version detection -Misc bug fix in networking code -SSL socket rework. Fixes issue with concurrent mixed SSL and non-SSL connections (FTPS). Module Updates: FTP -Added support for explicit and implicit SFTP -Better handling of FTP banners HTTP -Now leaves user specified value intact within Host: header -Minor code cleanup IMAP -LOGIN AUTH support -Added TAG module parameter -No longer restarts connection after each attempt NNTP -Added module with AUTHINFO support POP3 -No longer restarts connection after each attempt MySQL -Misc bug fixes / error handling -Added MySQL pre-4.1 pass-the-hash support NCP -Misc bug fixes SMBNT -Misc bug fixes SMTP-AUTH -AUTH PLAIN support -AUTH LOGIN (e.g. Exchange) support SSH -Handles new libssh2 error messages -Libssh2 (0.18) should no longer cause Medusa to hang on SSHv1 hosts or when the target refuses to send its banner. -Added banner parameter verification (Luciano Bello) VNC -Misc bug fixes WEB-FORM -Added new module from Luciano Bello WRAPPER -Better handling of failed attempts within oracle.pl script ================================================================ Version 1.3 ================================================================ Medusa Core Updates: -Module listing fix for OpenBSD/AMD64 -Autoconf tweaks for NCP & SVN checks -Autoconf tweaks for Solaris/OpenBSD -Removed unnecessary IP address checks -Other minor bug fixes ================================================================ Version 1.2 ================================================================ Moved following modules to stable: NCP, VNC, PostgreSQL, SVN, CVS, VmAuthd, SNMP Medusa Core Updates: -Compile on x86_64, Mac OS X. -Minor bug fixes. -Modified license with OpenSSL GPL exemption. Module Updates: SMBNT -Added AS/400 target support. -Global "-e" option now works with module "PASS:HASH". FTP -Modified response parsing code to support AS/400 brute-forcing. REXEC -Modified response parsing code. Wrapper -Added oracle script. -Added SMB NULL session script. ================================================================ Version 1.1 ================================================================ Added following modules (unstable): CVS, NCP, PostgreSQL, SMTP/VRFY, SNMP, SVN, VmAuthd, VNC Moved following modules to stable: PcAnywhere, FTP, IMAP, RSH, REXEC, RLOGIN, and generic wrapper Medusa Core Updates: -Display module list sorted alphabetically -Compiles on OpenBSD -Added delayed receive functions which allow the modules to specify the timeout for both the initial socket read and the second "is any more data there?" check. -Modified SSL connect function. The function now takes an already existing socket and switches it over to SSL. This is needed for modules like VMAUTHD. -Major rework of network receive function. Original code was copied from Hydra and seemed to have some issues. Module Updates: HTTP -Added check for 301 error code (success) -NTLM authentication support IMAP -Minor code cleanup MySQL -Added support for testing accounts without password PcAnywhere -Added sleep to deal with servers freaking out when attempts arrive too quickly POP3 -Added AS/400 mode. Examines error codes to give us better information about account status. SMBNT -Added check to detect non-existent accounts when auditing an XP client Telnet -Moved receive functions to new delayed receive functions. This is slower, but we should actually be able to brute devices with long logon banners now. Wrapper -Added support for scripts to pass error messages back to Medusa. Misc. Updates: Rdesktop -Added better success/failure detection -Added support to detect various error messages -Added basic W2K support -Added basic OS detection Ebuilds -Updated libssh2 ebuild based on bugs.gentoo.org feedback. -Updated Medusa ebuild based on bugs.gentoo.org feedback. -Updated Medusa version and added new module dependencies. -Modified ncpfs ebuild for "install-dev" option. ================================================================ Version 1.0 ================================================================ Initial release Modules (stable): HTTP, MS-SQL, SMBNT, SSHv2, Telnet, POP3 and MySQL Modules (unstable): RSH, RLOGIN, REXEC, FTP, IMAP, PcAnywhere, and generic wrapper medusa-2.1.1/configure.in0000644000175000001440000010341211760000277012220 00000000000000AC_INIT AC_CONFIG_SRCDIR([src/medusa.c]) AM_CONFIG_HEADER(config.h) dnl Detect the canonical host and target build environment AC_CANONICAL_HOST AC_CANONICAL_TARGET AM_INIT_AUTOMAKE(medusa, 2.1.1) AC_LANG([C]) AC_PROG_CC AC_HEADER_STDC AC_CHECK_SIZEOF(int,cross) AC_CHECK_SIZEOF(long,cross) AC_CHECK_SIZEOF(long long,cross) AC_CHECK_SIZEOF(short,cross) CFLAGS="${CFLAGS=}" AC_MSG_CHECKING(whether to enable debugging) debug_default="yes" AC_ARG_ENABLE(debug, [ --enable-debug=[no/yes] turn on debugging (default=yes)],, enable_debug=$debug_default) if test "x$enable_debug" = "xyes"; then CPPFLAGS="$CPPFLAGS -g -DDEBUG" AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi AC_ARG_WITH(postgresql, AS_HELP_STRING([--with-postgresql=prefix],[Prefix for postgresql include directory (default = /usr)]), [postgresql_prefix="$withval"], [postgresql_prefix="/usr"]) AC_ARG_WITH(afpfsng, AS_HELP_STRING([--with-afpfsng=prefix],[Prefix for afpfs-ng include directory (default = /usr)]), [afpfsng_prefix="$withval"], [afpfsng_prefix="/usr"]) dnl FreeBSD was not looking in /usr/local... dnl AC_SEARCH_LIBS ? if test -d "/usr/local/lib" then LDFLAGS="$LDFLAGS -L/usr/local/lib" fi if test -d "/usr/local/ssl/lib" then LDFLAGS="$LDFLAGS -L/usr/local/ssl/lib" fi CPPFLAGS="$CPPFLAGS -fPIC" CPPFLAGS="$CPPFLAGS -I/usr/include -I/usr/local/include -I/usr/local/ssl/include \ -I${postgresql_prefix}/include/postgresql -I${postgresql_prefix}/include/pgsql -I${afpfsng_prefix}/include/afpfs-ng" AS_MESSAGE([checking for pthread support...]) AC_CHECK_LIB(pthread, main, [], [AC_MSG_ERROR([ *** Application requires pthread support *** ])]) AS_MESSAGE([checking for dlopen/dlclose...]) AC_CHECK_LIB(dl, dlclose, [], [AC_CHECK_LIB(c, dlclose, [], [AC_MSG_ERROR([ *** Application requires dlopen/dlclose (e.g. libdl) *** ])]) ] ) dnl MacPorts if test -d "/opt/local"; then CPPFLAGS="$CPPFLAGS -I/opt/local/include" LDFLAGS="$LDFLAGS -L/opt/local/lib" fi dnl Mac OS X doesn't have clock_gettime() AC_SEARCH_LIBS(clock_gettime, [rt]) AC_CHECK_FUNCS(clock_gettime, [], [AC_MSG_WARN([ No clock_gettime(), using gettimeofday() instead ])]) check_libssl="false" AS_MESSAGE([checking for OpenSSL Library and Header files...]) AC_CHECK_LIB(crypto, CRYPTO_lock, [], [AC_MSG_WARN([ *** LibCrypto may be required for *BSD ***])]) AC_CHECK_HEADER([openssl/ssl.h], [AC_CHECK_LIB(ssl, main, [AC_DEFINE(HAVE_LIBSSL, 1, [Found OpenSSL Library]) LIBS="$LIBS -lssl -lcrypto" check_libssl="true"], [AC_MSG_WARN([ *** OpenSSL library required for SSL support. *** Many of the Medusa modules depend on the OpenSSL library and header files. If multiple modules are unexpectedly disabled, this is likely the cause. Make sure to install libssl-dev, openssl-devel or whatever package your distribution uses to distribute these files. ])] )], [AC_MSG_WARN([ *** OpenSSL header files required for SSL support. *** Many of the Medusa modules depend on the OpenSSL library and header files. If multiple modules are unexpectedly disabled, this is likely the cause. Make sure to install libssl-dev, openssl-devel or whatever package your distribution uses to distribute these files. ])] ) AC_MSG_NOTICE([*** Checking module dependencies and enabling accordingly ***]) dnl ********** AFP Medusa Module Option Checks ********** check_module_afp="false" AS_MESSAGE([checking for AFPFS-NG Library and Header files...]) AC_CHECK_HEADER([afpfs-ng/afp_protocol.h], [AC_CHECK_LIB(afpclient, main, [AC_DEFINE(HAVE_LIBAFPFS, 1, [Found AFPFS-NG Library]) MODULE_LIBS="$MODULE_LIBS /usr/lib/libafpclient.so.0" check_module_afp="true"], [AC_MSG_WARN([ *** AFPFS-NG library required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. ])] )], [AC_MSG_WARN([ *** AFPFS-NG header files required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. ])] ) AC_MSG_CHECKING(whether to enable AFP module) AC_ARG_ENABLE(module-afp, [ --enable-module-afp=[no/yes] Enable AFP module (default=no)], [case "${enableval}" in yes) enable_module_afp=true ;; no) enable_module_afp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-afp]) ;; esac], [enable_module_afp=$check_module_afp]) AM_CONDITIONAL(BUILD_MODULE_AFP, test x"$enable_module_afp" = "xtrue") if test x"$enable_module_afp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** CVS Medusa Module Option Checks ********** AC_MSG_CHECKING(whether to enable CVS module) AC_ARG_ENABLE(module-cvs, [ --enable-module-cvs=[no/yes] Enable CVS module (default=yes)], [case "${enableval}" in yes) enable_module_cvs=true ;; no) enable_module_cvs=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-cvs]) ;; esac], [enable_module_cvs="true"]) AM_CONDITIONAL(BUILD_MODULE_CVS, test x"$enable_module_cvs" = "xtrue") if test x"$enable_module_cvs" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** FTP Medusa Module ********** AC_MSG_CHECKING(whether to enable FTP module) AC_ARG_ENABLE(module-ftp, [ --enable-module-ftp=[no/yes] Enable FTP module (default=yes)], [case "${enableval}" in yes) enable_module_ftp=true ;; no) enable_module_ftp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-ftp]) ;; esac], [enable_module_ftp="true"]) AM_CONDITIONAL(BUILD_MODULE_FTP, test x"$enable_module_ftp" = "xtrue") if test x"$enable_module_ftp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** HTTP Medusa Module ********** check_module_http=$check_libssl AC_MSG_CHECKING(whether to enable HTTP module) AC_ARG_ENABLE(module-http, [ --enable-module-http=[no/yes] Enable HTTP module (default=yes)], [case "${enableval}" in yes) enable_module_http=true ;; no) enable_module_http=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-http]) ;; esac], [enable_module_http=$check_module_http]) AM_CONDITIONAL(BUILD_MODULE_HTTP, test x"$enable_module_http" = "xtrue") if test x"$enable_module_http" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** IMAP Medusa Module ********** AC_MSG_CHECKING(whether to enable IMAP module) AC_ARG_ENABLE(module-imap, [ --enable-module-imap=[no/yes] Enable IMAP module (default=yes)], [case "${enableval}" in yes) enable_module_imap=true ;; no) enable_module_imap=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-imap]) ;; esac], [enable_module_imap="true"]) AM_CONDITIONAL(BUILD_MODULE_IMAP, test x"$enable_module_imap" = "xtrue") if test x"$enable_module_imap" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** MSSQL Medusa Module ********** check_module_mssql=$check_libssl AC_MSG_CHECKING(whether to enable MSSQL module) AC_ARG_ENABLE(module-mssql, [ --enable-module-mssql=[no/yes] Enable MSSQL module (default=yes)], [case "${enableval}" in yes) enable_module_mssql=true ;; no) enable_module_mssql=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-mssql]) ;; esac], [enable_module_mssql=$check_module_mssql]) AM_CONDITIONAL(BUILD_MODULE_MSSQL, test x"$enable_module_mssql" = "xtrue") if test x"$enable_module_mssql" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** MYSQL Medusa Module ********** AC_MSG_CHECKING(whether to enable MYSQL module) AC_ARG_ENABLE(module-mysql, [ --enable-module-mysql=[no/yes] Enable MYSQL module (default=yes)], [case "${enableval}" in yes) enable_module_mysql=true ;; no) enable_module_mysql=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-mysql]) ;; esac], [enable_module_mysql="true"]) AM_CONDITIONAL(BUILD_MODULE_MYSQL, test x"$enable_module_mysql" = "xtrue") if test x"$enable_module_mysql" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** NCP Medusa Module ********** check_module_ncp="false" AS_MESSAGE([checking for NCPFS Library and Header files...]) AC_CHECK_HEADER([ncp/nwcalls.h], [AC_CHECK_LIB(ncp, main, [AC_DEFINE(HAVE_LIBNCP, 1, [Found NCP Library]) MODULE_LIBS="$MODULE_LIBS -lncp" check_module_ncp="true"], [AC_MSG_WARN([ *** NCPFS library required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using "make install-dev" within the NCPFS source. The NCP module will NOT be built. ])] )], [AC_MSG_WARN([ *** NCPFS header files required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using "make install-dev" within the NCPFS source. The NCP module will NOT be built. ])] ) AC_MSG_CHECKING(whether to enable NCP module) AC_ARG_ENABLE(module-ncp, [ --enable-module-ncp=[no/yes] Enable NCP module (default=yes)], [case "${enableval}" in yes) enable_module_ncp=true ;; no) enable_module_ncp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-ncp]) ;; esac], [enable_module_ncp=$check_module_ncp]) AM_CONDITIONAL(BUILD_MODULE_NCP, test x"$enable_module_ncp" = "xtrue") if test x"$enable_module_ncp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** NNTP Medusa Module ********** AC_MSG_CHECKING(whether to enable NNTP module) AC_ARG_ENABLE(module-nntp, [ --enable-module-nntp=[no/yes] Enable NNTP module (default=yes)], [case "${enableval}" in yes) enable_module_nntp=true ;; no) enable_module_nntp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-nntp]) ;; esac], [enable_module_nntp="true"]) AM_CONDITIONAL(BUILD_MODULE_NNTP, test x"$enable_module_nntp" = "xtrue") if test x"$enable_module_nntp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** PCANYWHERE Medusa Module ********** AC_MSG_CHECKING(whether to enable PCANYWHERE module) AC_ARG_ENABLE(module-pcanywhere, [ --enable-module-pcanywhere=[no/yes] Enable PCANYWHERE module (default=yes)], [case "${enableval}" in yes) enable_module_pcanywhere=true ;; no) enable_module_pcanywhere=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-pcanywhere]) ;; esac], [enable_module_pcanywhere="true"]) AM_CONDITIONAL(BUILD_MODULE_PCANYWHERE, test x"$enable_module_pcanywhere" = "xtrue") if test x"$enable_module_pcanywhere" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** POP3 Medusa Module ********** AC_MSG_CHECKING(whether to enable POP3 module) AC_ARG_ENABLE(module-pop3, [ --enable-module-pop3=[no/yes] Enable POP3 module (default=yes)], [case "${enableval}" in yes) enable_module_pop3=true ;; no) enable_module_pop3=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-pop3]) ;; esac], [enable_module_pop3="true"]) AM_CONDITIONAL(BUILD_MODULE_POP3, test x"$enable_module_pop3" = "xtrue") if test x"$enable_module_pop3" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** POSTGRES Medusa Module ********** check_module_postgres="false" AS_MESSAGE([checking for PostgreSQL Library and Header files...]) AC_CHECK_HEADER([libpq-fe.h], [AC_CHECK_LIB(pq, main, [AC_DEFINE(HAVE_LIBPQ, 1, [Found PostgreSQL Library]) MODULE_LIBS="$MODULE_LIBS -lpq" check_module_postgres="true"], [AC_MSG_WARN([ *** LIBPQ library required for PostgreSQL module. *** The PostgreSQL package must be installed for the PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. ])] )], [AC_MSG_WARN([ *** LIBPQ header files required for PostgreSQL module. *** The PostgreSQL package must be installed for PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. ])] ) AC_MSG_CHECKING(whether to enable POSTGRES module) AC_ARG_ENABLE(module-postgres, [ --enable-module-postgres=[no/yes] Enable POSTGRES module (default=yes)], [case "${enableval}" in yes) enable_module_postgres=true ;; no) enable_module_postgres=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-postgres]) ;; esac], [enable_module_postgres=$check_module_postgres]) AM_CONDITIONAL(BUILD_MODULE_POSTGRES, test x"$enable_module_postgres" = "xtrue") if test x"$enable_module_postgres" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** REXEC Medusa Module ********** AC_MSG_CHECKING(whether to enable REXEC module) AC_ARG_ENABLE(module-rexec, [ --enable-module-rexec=[no/yes] Enable REXEC module (default=yes)], [case "${enableval}" in yes) enable_module_rexec=true ;; no) enable_module_rexec=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-rexec]) ;; esac], [enable_module_rexec="true"]) AM_CONDITIONAL(BUILD_MODULE_REXEC, test x"$enable_module_rexec" = "xtrue") if test x"$enable_module_rexec" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** RLOGIN Medusa Module ********** AC_MSG_CHECKING(whether to enable RLOGIN module) AC_ARG_ENABLE(module-rlogin, [ --enable-module-rlogin=[no/yes] Enable RLOGIN module (default=yes)], [case "${enableval}" in yes) enable_module_rlogin=true ;; no) enable_module_rlogin=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-rlogin]) ;; esac], [enable_module_rlogin="true"]) AM_CONDITIONAL(BUILD_MODULE_RLOGIN, test x"$enable_module_rlogin" = "xtrue") if test x"$enable_module_rlogin" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** RSH Medusa Module ********** AC_MSG_CHECKING(whether to enable RSH module) AC_ARG_ENABLE(module-rsh, [ --enable-module-rsh=[no/yes] Enable RSH module (default=yes)], [case "${enableval}" in yes) enable_module_rsh=true ;; no) enable_module_rsh=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-rsh]) ;; esac], [enable_module_rsh="true"]) AM_CONDITIONAL(BUILD_MODULE_RSH, test x"$enable_module_rsh" = "xtrue") if test x"$enable_module_rsh" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SMBNT Medusa Module ********** check_module_smbnt=$check_libssl AC_MSG_CHECKING(whether to enable SMBNT module) AC_ARG_ENABLE(module-smbnt, [ --enable-module-smbnt=[no/yes] Enable SMBNT module (default=yes)], [case "${enableval}" in yes) enable_module_smbnt=true ;; no) enable_module_smbnt=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-smbnt]) ;; esac], [enable_module_smbnt=$check_module_smbnt]) AM_CONDITIONAL(BUILD_MODULE_SMBNT, test x"$enable_module_smbnt" = "xtrue") if test x"$enable_module_smbnt" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SMTP Medusa Module ********** AC_MSG_CHECKING(whether to enable SMTP module) AC_ARG_ENABLE(module-smtp, [ --enable-module-smtp=[no/yes] Enable SMTP module (default=yes)], [case "${enableval}" in yes) enable_module_smtp=true ;; no) enable_module_smtp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-smtp]) ;; esac], [enable_module_smtp="true"]) AM_CONDITIONAL(BUILD_MODULE_SMTP, test x"$enable_module_smtp" = "xtrue") if test x"$enable_module_smtp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SMTP-VRFY Medusa Module ********** AC_MSG_CHECKING(whether to enable SMTP-VRFY module) AC_ARG_ENABLE(module-smtp-vrfy, [ --enable-module-smtp-vrfy=[no/yes] Enable SMTP-VRFY module (default=yes)], [case "${enableval}" in yes) enable_module_smtp_vrfy=true ;; no) enable_module_smtp_vrfy=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-smtp-vrfy]) ;; esac], [enable_module_smtp_vrfy="true"]) AM_CONDITIONAL(BUILD_MODULE_SMTP_VRFY, test x"$enable_module_smtp_vrfy" = "xtrue") if test x"$enable_module_smtp_vrfy" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SNMP Medusa Module ********** AC_MSG_CHECKING(whether to enable SNMP module) AC_ARG_ENABLE(module-snmp, [ --enable-module-snmp=[no/yes] Enable SNMP module (default=yes)], [case "${enableval}" in yes) enable_module_snmp=true ;; no) enable_module_snmp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-snmp]) ;; esac], [enable_module_snmp="true"]) AM_CONDITIONAL(BUILD_MODULE_SNMP, test x"$enable_module_snmp" = "xtrue") if test x"$enable_module_snmp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SSH Medusa Module ********** check_module_ssh="false" AS_MESSAGE([checking for Libssh2 Library files...]) AC_CHECK_LIB(ssh2, main, [AC_DEFINE(HAVE_LIBSSH2, 1, [Found SSH2 Library]) MODULE_LIBS="$MODULE_LIBS -lssh2" check_module_ssh="true"], [AC_MSG_WARN([ *** Libssh2 required for SSH2 module. *** Libssh2 (http://www.libssh2.org) is not the same as libssh (http://0xbadc0de.be). Make sure you have the correct library. The SSH2 module will NOT be built. ])] ) dnl Test whether libssh2 was built with libgcrypt if test x"$check_module_ssh" = "xtrue"; then check_libgcrypt="false" if test -f "/usr/lib/libssh2.so"; then LIBSSH2_PATH="/usr/lib/libssh2.so" elif test -f "/usr/local/lib/libssh2.so"; then LIBSSH2_PATH="/usr/local/lib/libssh2.so" elif test -f "/opt/local/lib/libssh2.dylib"; then LIBSSH2_PATH="/opt/local/lib/libssh2.dylib" elif test -f "/usr/local/lib/libssh2.dylib"; then LIBSSH2_PATH="/usr/local/lib/libssh2.dylib" else AC_MSG_WARN([ LIBSSH2 path not found. Assuming it was... ]) fi dnl Use otool on Mac OS X if test -f "`which ldd`"; then LDD="ldd" elif test -f "`which otool`"; then LDD="otool -L" else AC_MSG_WARN([ No ldd detected. Unable to test whether Libssh2 was compiled to use libgcrypt. Assuming it was... ]) check_libgcrypt="true" fi if test ! -z "`$LDD $LIBSSH2_PATH |grep libgcrypt`"; then AC_MSG_WARN([ Libssh2 compiled using libgcrypt. Checking additional dependencies. ]) check_libgcrypt="true" fi if test x"$check_libgcrypt" = "xtrue"; then AS_MESSAGE([checking for Libgrcypt Library files...]) AC_CHECK_LIB(gcrypt, gcry_control, [AC_DEFINE(HAVE_LIBGCRYPT, 1, [Found Libgcrypt Library]) LIBS="$LIBS -lgcrypt"], [AC_MSG_WARN([ *** Libgcrypt required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgcrypt11-dev). The SSH2 module will NOT be built. ]) check_module_ssh="false" ]) AS_MESSAGE([checking for GnuTLS Library files...]) AC_CHECK_LIB(gnutls, gnutls_handshake, [AC_DEFINE(HAVE_GNUTLS, 1, [Found GnuTLS Library]) LIBS="$LIBS -lgnutls"], [AC_MSG_WARN([ *** GnuTLS required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgnutls-dev). The SSH2 module will NOT be built. ]) check_module_ssh="false" ]) fi fi AC_MSG_CHECKING(whether to enable SSH module) AC_ARG_ENABLE(module-ssh, [ --enable-module-ssh=[no/yes] Enable SSH module (default=yes)], [case "${enableval}" in yes) enable_module_ssh=true ;; no) enable_module_ssh=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-ssh]) ;; esac], [enable_module_ssh=$check_module_ssh]) AM_CONDITIONAL(BUILD_MODULE_SSH, test x"$enable_module_ssh" = "xtrue") if test x"$enable_module_ssh" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SVN Medusa Module ********** check_module_svn="false" AS_MESSAGE([checking for Subversion Library and Header files...]) AC_PATH_PROG(APR_CONFIG, apr-1-config) if test -z "$APR_CONFIG"; then AC_PATH_PROG(APR_CONFIG, apr-config) if test -z "$APR_CONFIG"; then AC_MSG_WARN([ *** apr-config/apr-1-config not found and required for SVN module *** Make sure to install libapr1-dev or whatever package your distribution uses to distribute this file. ]) fi fi if test -n "$APR_CONFIG"; then if test x`$APR_CONFIG --cc` = "xcc"; then AC_MSG_WARN([ *** Apache (apr) was compiled using Sun C compiler and not GNU gcc. *** "$APR_CONFIG --cc" responded with "cc", which usually means that your build of Apache was compiled with Sun C compiler and not with gcc. This means that the version of libtool embedded within Apache installation is also configured for Sun C compiler and not gcc. The Sun C compiler setup is incompatible because the options to each compiler are different for building shared objects and libraries. Specifically, the Sun compiler supports the "-mt" flag, whereas gcc does not. In order to build the SVN Medusa module, rebuild $APR_CONFIG using gcc, or remove the "-mt" CPPFLAGS flag from the autogenerated Medusa configuration files. ]) else APR_INCLUDE_DIR=`$APR_CONFIG --includedir` AC_SUBST(APR_INCLUDE_DIR) CPPFLAGS="$CPPFLAGS `$APR_CONFIG --includes --cppflags`" AC_CHECK_HEADER([$APR_INCLUDE_DIR/apr_tables.h], [AC_CHECK_HEADER([subversion-1/svn_client.h], [AC_CHECK_LIB(svn_client-1, main, [AC_DEFINE(HAVE_LIBSVN_CLIENT_1, 1, [Found SVN Library]) MODULE_LIBS="$MODULE_LIBS -lsvn_client-1" check_module_svn="true"], [AC_MSG_WARN([ *** Subversion libsvn library required for SVN module. *** ])] )], [AC_MSG_WARN([ *** Subversion header files required for SVN module. (e.g., libsvn-dev) *** ])])], [AC_MSG_WARN([ *** APR header files required for SVN module. (e.g., libapr1-dev) *** ])] ) fi else check_module_svn="false" fi AC_MSG_CHECKING(whether to enable SVN module) AC_ARG_ENABLE(module-svn, [ --enable-module-svn=[no/yes] Enable SVN module (default=yes)], [case "${enableval}" in yes) enable_module_svn=true ;; no) enable_module_svn=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-svn]) ;; esac], [enable_module_svn=$check_module_svn]) AM_CONDITIONAL(BUILD_MODULE_SVN, test x"$enable_module_svn" = "xtrue") if test x"$enable_module_svn" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** TELNET Medusa Module ********** AC_MSG_CHECKING(whether to enable TELNET module) AC_ARG_ENABLE(module-telnet, [ --enable-module-telnet=[no/yes] Enable TELNET module (default=yes)], [case "${enableval}" in yes) enable_module_telnet=true ;; no) enable_module_telnet=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-telnet]) ;; esac], [enable_module_telnet="true"]) AM_CONDITIONAL(BUILD_MODULE_TELNET, test x"$enable_module_telnet" = "xtrue") if test x"$enable_module_telnet" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** VMAUTHD Medusa Module ********** AC_MSG_CHECKING(whether to enable VMAUTHD module) AC_ARG_ENABLE(module-vmauthd, [ --enable-module-vmauthd=[no/yes] Enable VMAUTHD module (default=yes)], [case "${enableval}" in yes) enable_module_vmauthd=true ;; no) enable_module_vmauthd=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-vmauthd]) ;; esac], [enable_module_vmauthd="true"]) AM_CONDITIONAL(BUILD_MODULE_VMAUTHD, test x"$enable_module_vmauthd" = "xtrue") if test x"$enable_module_vmauthd" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** VNC Medusa Module ********** check_module_vnc=$check_libssl AC_MSG_CHECKING(whether to enable VNC module) AC_ARG_ENABLE(module-vnc, [ --enable-module-vnc=[no/yes] Enable VNC module (default=yes)], [case "${enableval}" in yes) enable_module_vnc=true ;; no) enable_module_vnc=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-vnc]) ;; esac], [enable_module_vnc=$check_module_vnc]) AM_CONDITIONAL(BUILD_MODULE_VNC, test x"$enable_module_vnc" = "xtrue") if test x"$enable_module_vnc" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** WRAPPER Medusa Module ********** AC_MSG_CHECKING(whether to enable WRAPPER module) AC_ARG_ENABLE(module-wrapper, [ --enable-module-wrapper=[no/yes] Enable WRAPPER module (default=yes)], [case "${enableval}" in yes) enable_module_wrapper=true ;; no) enable_module_wrapper=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-wrapper]) ;; esac], [enable_module_wrapper="true"]) AM_CONDITIONAL(BUILD_MODULE_WRAPPER, test x"$enable_module_wrapper" = "xtrue") if test x"$enable_module_wrapper" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** Web Form Medusa Module ********** check_module_web_form=$check_libssl AC_MSG_CHECKING(whether to enable WEB-FORM module) AC_ARG_ENABLE(module-web-form, [ --enable-module-web-form=[no/yes] Enable WEB-FORM module (default=yes)], [case "${enableval}" in yes) enable_module_web_form=true ;; no) enable_module_web_form=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-web-form]) ;; esac], [enable_module_web_form=$check_module_web_form]) AM_CONDITIONAL(BUILD_MODULE_WEB_FORM, test x"$enable_module_web_form" = "xtrue") if test x"$enable_module_web_form" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi AC_MSG_NOTICE([]) AC_MSG_NOTICE([*******************************************************]) AC_MSG_NOTICE([ Medusa Module Build Summary]) AC_MSG_NOTICE([]) show_build_status() { if test "$1" = "true" ; then AC_MSG_NOTICE([$2 Enabled]) else AC_MSG_NOTICE([$2 ** Disabled **]) fi } show_build_status "${enable_module_afp}" " AFP " show_build_status "${enable_module_cvs}" " CVS " show_build_status "${enable_module_ftp}" " FTP " show_build_status "${enable_module_http}" " HTTP " show_build_status "${enable_module_imap}" " IMAP " show_build_status "${enable_module_mssql}" " MSSQL " show_build_status "${enable_module_mysql}" " MYSQL " show_build_status "${enable_module_ncp}" " NCP " show_build_status "${enable_module_nntp}" " NNTP " show_build_status "${enable_module_pcanywhere}" " PCANYWHERE " show_build_status "${enable_module_pop3}" " POP3 " show_build_status "${enable_module_postgres}" " POSTGRES " show_build_status "${enable_module_rexec}" " REXEC " show_build_status "${enable_module_rlogin}" " RLOGIN " show_build_status "${enable_module_rsh}" " RSH " show_build_status "${enable_module_smbnt}" " SMBNT " show_build_status "${enable_module_smtp}" " SMTP " show_build_status "${enable_module_smtp_vrfy}" " SMTP-VRFY " show_build_status "${enable_module_snmp}" " SNMP " show_build_status "${enable_module_ssh}" " SSH " show_build_status "${enable_module_svn}" " SVN " show_build_status "${enable_module_telnet}" " TELNET " show_build_status "${enable_module_vmauthd}" " VMAUTHD " show_build_status "${enable_module_vnc}" " VNC " show_build_status "${enable_module_wrapper}" " WRAPPER " show_build_status "${enable_module_web_form}" " WEB-FORM " AC_MSG_NOTICE([]) AC_MSG_NOTICE([ If a module is unexpectedly marked as disabled, check ]) AC_MSG_NOTICE([ above output and verify dependancies were satisfied. ]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([ It should also be noted that, by default, not all of ]) AC_MSG_NOTICE([ the modules are built. Incomplete modules or modules ]) AC_MSG_NOTICE([ which have not been sufficiently tested may be ]) AC_MSG_NOTICE([ disabled. To enable non-default modules, use the ]) AC_MSG_NOTICE([ "--enable-module-MODULE_NAME" configure option.]) AC_MSG_NOTICE([*******************************************************]) AC_MSG_NOTICE([]) AC_CHECK_FUNCS(strcasestr) AC_CHECK_FUNCS(asprintf) AC_CHECK_FUNCS(vasprintf) dnl -lm --> mysql/floor(), http/log() dnl -lrt --> clock_gettime() case "$target" in *linux*) LIBDL="-ldl -lrt -lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *freebsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *netbsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *openbsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="-g -Wl,-E" ;; *apple-darwin*) # Modules will segfault when executed (show usage works) if medusa core # is not linked to CoreFoundation (starting with 10.6). This is believed to # be due to libsvn linking to CoreFoundation and our modules linked via # "-lsvn_client-1". See http://www.openradar.me/7209349 for more info. LIBDL="-ldl -framework CoreFoundation" RDYNAMIC="" MODULE_LIBS="$MODULE_LIBS -bundle -flat_namespace -undefined suppress" EXTRA_LDFLAGS="" ;; *solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" LDFLAGS="$LDFLAGS -R/usr/local/lib -R/usr/local/ssl/lib -L/usr/local/ssl/lib" LIBDL="-ldl -lm -lrt -lnsl -lsocket" RDYNAMIC="-Rdynamic" EXTRA_LDFLAGS="" MODULE_LIBS="$MODULE_LIBS -G" ;; *cygwin*) CPPFLAGS="$CPPFLAGS -DCYGWIN" LIBDL="-ldl" RDYNAMIC="" MODULE_LIBS="$MODULE_LIBS -shared" ;; *) LIBDL="-ldl -lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; esac AC_SUBST([MODULE_LIBS]) LDFLAGS="$LDFLAGS $RDYNAMIC $EXTRA_LDFLAGS" LIBS="$LIBS $LIBDL" test "$prefix" = NONE && prefix=${ac_default_prefix} _default_mod_path="${prefix}/lib/medusa/modules" AC_ARG_WITH(default-mod-path, AS_HELP_STRING([--with-default-mod-path=path],[Location of medusa module files (default = /usr/local/lib/medusa/modules)]),[_default_mod_path="$withval"]) AC_DEFINE_UNQUOTED(DEFAULT_MOD_PATH, "$_default_mod_path", [Location of medusa module files]) AC_SUBST(DEFAULT_MOD_PATH) AC_CONFIG_FILES([Makefile src/Makefile src/modsrc/Makefile]) AC_OUTPUT medusa-2.1.1/doc/0000755000175000001440000000000011760001577010537 500000000000000medusa-2.1.1/doc/medusa-smtp-vrfy.html0000644000175000001440000000164311723732130014567 00000000000000 Foofus Networking Services - Medusa::SMTP-VRFY

Medusa Parallel Network Login Auditor :: SMTP-VRFY

JoMo-Kun / jmk "AT" foofus "DOT" net

The SMTP-VRFY module can be used to enumerate which accounts are valid on a mail server. The module sends the following:

EHLO some_name
VRFY account@domain

The module expects the accounts to be checked to be supplied via the user options (-u/-U/-C). The domain should be supplied as if it were a password. The value sent via the EHLO command can be set using the -m EHLO: module option. The default is to send MEDUSA.

This module was written while testing a single mis-configured SMTP SPAM filter. Other devices probably behave differently. Some tweaking of the module may be required.

Medusa Documentation
medusa-2.1.1/doc/medusa-snmp.html0000644000175000001440000000302511723732130013571 00000000000000 Foofus Networking Services - Medusa::SNMP

Medusa Parallel Network Login Auditor :: SNMP

JoMo-Kun / jmk "AT" foofus "DOT" net

The SNMP module tests community strings against the Simple Network Management Protocol (SNMP) service.

The module has several options: TIMEOUT, VERSION and ACCESS. The default values are 2 seconds, version 1 and READ access. It should be noted that when testing for WRITE capability, the module will read the current value of sysLocation and then write that same value back to the system.

Since SNMP is a UDP-based protocol, there is no handshaking between sending and receiving transport-layer entities. Due to this connectionless communication, about the only time we know a SNMP service exists, is if we send the correct community string and the server sends a response. All other queries result in no response whatsoever. The approach we use here is to initially just send all of our SNMP GET requests. After that completes, we wait TIMEOUT seconds for any responses. If we get any responses back, we examine them to see which community strings were successful. If ACCESS:WRITE was specified, we check for write access on each of the previously successful values. This techique should allow for quick brute forcing. However, one should take care with the TIMEOUT and SEND_DELAY values as to avoid causing issues with the target service or missing response data.

Medusa Documentation
medusa-2.1.1/doc/medusa-vnc.html0000644000175000001440000000213111723732130013377 00000000000000 Foofus Networking Services - Medusa::VNC

Medusa Parallel Network Login Auditor :: VNC

JoMo-Kun / jmk "AT" foofus "DOT" net

The VNC module tests accounts against the VNC service.

This module was developed using both RealVNC and UltraVNC, which support rudimentary anti-brute force functionality. RealVNC, for example, allows 5 failed attempts and then enforces a 10 second delay. For each subsequent attempt that delay is doubled. UltraVNC appears to allow 6 invalid attempts and then forces a 10 second delay between each following attempt. This module attempts to identify these situations and react appropriately by invoking sleep(). The user can set a sleep limit when brute forcing RealVNC using the MAXSLEEP parameter. Once this value has been reached, the module will exit.

This module supports password-less and password-only authentication as well as UltraVNC MS-Logon (local/domain Windows credentials) username/password credentials.

Medusa Documentation
medusa-2.1.1/doc/medusa-pcanywhere.html0000644000175000001440000000254711723732130014771 00000000000000 Foofus Networking Services - Medusa::PcAnywhere

Medusa Parallel Network Login Auditor :: PcAnywhere

JoMo-Kun / jmk "AT" foofus "DOT" net

The PcAnywhere module tests accounts against the Symantec PcAnywhere service.

NOTE: PcAnywhere allows only one connection at a time. Running multiple threads per target may not work well.

Module based on packet captures from Server Version 10.5.1 and Client 10.0.2.

PCA Authentication Methods:
   ADS (Active Directory Services) [1]
   FTP [2]
   HTTP [2]
   HTTPS [2]
   Microsoft LDAP [2]
   Netscape LDAP [2]
   Novell LDAP [2]
   NT [1]
   pcAnywhere [1]
   Windows [3]

[1] Verified working
[2] Untested
[3] Verified to work when PcAnywhere host authenticates against domain accounts.
Authentication fails for local accounts with both the module and the PcAnywhere
client. Not sure what's going on...


Medusa Documentation
medusa-2.1.1/doc/medusa-compare.html0000644000175000001440000002201011750530716014243 00000000000000 Foofus Networking Services - Medusa

Medusa Parallel Network Login Auditor :: Feature Comparison

JoMo-Kun / jmk "AT" foofus "DOT" net

Note: Information contained on this page for Hydra and Ncrack is based on each tool's own documentation. No confirmation of supported services has been performed.

Area Feature Medusa 2.1 Hydra 7.1 Ncrack 0.4ALPHA
* License GPL-2 GPL-3 GPL-2
Core Parallel Method pthread fork()
Service Design Modular Built-in
Speed (several comparisons are included below) ? ? ?
Generic Wrapper Module
AFP
CVS
FTP FTP
Explicit FTPS (AUTH TLS Mode as defined in RFC 4217)
Implicit FTPS (FTP over SSL (990/tcp)
HTTP Basic Auth
NTLM Auth (Windows Integrated)
Digest Authentication MD5, MD5-sess MD5
HTTP Proxy
ICQ
IMAP Method LOGIN Support
Method AUTH-PLAIN Support
Method AUTH-NTLM Support
SSL Support IMAPS, STARTTLS IMAPS, STARTTLS
LDAP
Microsoft SQL Port Auto-Detection
MS-SQL
MySQL Pre-4.1 Authentication
Pre-4.1 Hash Passing
4.1+ Authentication
NCP (NetWare) √ (ncpfs) √ (ncpfs)
NNTP √ (Original AUTHINFO) √ (Original AUTHINFO)
Oracle Database √ (via Wrapper script)
Listener
SID
PcAnywhere Supported Encryption Level None None
Supported Authenication Mode(s) Native PCA, ADS, NT, Windows Native PCA
PCNFS
POP3 Method AUTH-USER Support
Method AUTH-LOGIN Support
Method AUTH-PLAIN Support
Method AUTH-NTLM Support
SSL Support POP3S, STARTTLS POP3S POP3S, STARTTLS
PostgreSQL
RDP (Terminal Server √ (via Wrapper Script)
REXEC
RLOGIN .rhost Support
Password Support
RSH
SAPR3
SIP
SMB (Microsoft Windows/Samba) Authentication Modes clear-text, LMv1, NTLMv1, LMv2, NTLMv2 clear-text, LMv1, NTLMv1, LMv2, NTLMv2 Unknown
Hash Passing
SMTP Method AUTH-LOGIN Support
Method AUTH-PLAIN Support
Method AUTH-NTLM Support
SSL Support STARTTLS STARTTLS
VRFY
SNMP √ (significantly faster design) √ (overwrites sysName with "HYDRA")
SOCKS5
SSHv2 √ (libssh2) √ (libssh)
SVN
TeamSpeak
Telnet Generic Telnet
Cisco (AAA/non-AAA)
Cisco enable password
AS/400 (TN5250) Support
VNC Password-less/Password-only Support
Anti-Brute Force Slowdown Support
Username/Password Support
VmWare Authentication Daemon Non-SSL Authentication
SSL Authentication
Web Form Module

Speed comparison: password list of 20 entries (valid entry at #20)
FTP / Ubuntu 11.10 vsftp 2.3.2
        [1 task]    [4 tasks]    [16 tasks] 
Medusa  1:03.53     15.727         7.658     (e.g., -t 16)
Hydra     57.527    16.545         8.013     (e.g., -t 16)
Ncrack  1:00.01     24.017        15.009     (e.g., -g cl=16,CL=16)

Speed comparison: password list of 1003 entries (valid entry at #1000)
HTTP / Windows 2008 IIS 7.0
        [1 task]    [4 tasks]    [16 tasks] 
Medusa  1.390       0.803        0.626       (e.g., -v 4 -t 16)
Hydra   1.443       0.855        0.790       (e.g., -t 16)
Ncrack  3.108       3.016        3.013       (e.g., -g cl=16,CL=16)

Speed comparison: password list of 1003 entries (valid entry at #986)
SMB / Windows 2008 
        [1 task]    [4 tasks]    [16 tasks] 
Medusa  6.859       0.919        0.500       (e.g., -v 4 -t 16)
Hydra   8.216                                (doesn't handle parallel connections)
Ncrack                                       (failed to auth to test server) 

Speed comparison: password list of 10 entries (valid entry at #10)
SSH Ubuntu 11.10 OpenSSH 5.8p1
        [1 task]    [4 tasks]    [16 tasks] 
Medusa  38.039      11.943       8.067       (e.g., -v 4 -t 16)
Hydra   32.122      12.208       8.457       (e.g., -t 16)
Ncrack  30.023      27.012       24.013      (e.g., -g cl=16,CL=16)


Medusa Documentation
medusa-2.1.1/doc/medusa-postgres.html0000644000175000001440000000116711723732130014467 00000000000000 Foofus Networking Services - Medusa::PostgreSQL

Medusa Parallel Network Login Auditor :: PostgreSQL

JoMo-Kun / jmk "AT" foofus "DOT" net

The postgres module tests accounts against the PostgreSQL service.

This module requires the PostgreSQL library: libpq.

The module has a single option, DB. This allows the user to specify the target database name. If the option is not set, the default behaviour is to use template1.

Medusa Documentation
medusa-2.1.1/doc/medusa-imap.html0000644000175000001440000000101411723732130013536 00000000000000 Foofus Networking Services - Medusa::IMAP

Medusa Parallel Network Login Auditor :: IMAP

JoMo-Kun / jmk "AT" foofus "DOT" net

The IMAP module tests accounts against the IMAP service. This module supports both imap (143) and imaps (993). The IMAP module asks for the server's capabilities and then does either a LOGIN or an AUTHENTICATE PLAIN, depending on its response.

Medusa Documentation
medusa-2.1.1/doc/medusa-mysql.html0000644000175000001440000000146211723732130013764 00000000000000 Foofus Networking Services - Medusa::MySQL

Medusa Parallel Network Login Auditor :: MySQL

JoMo-Kun / jmk "AT" foofus "DOT" net

The MySQL module tests accounts against the MySQL service.

In addition to normal password brute force attempts, this module supports "pass-the-hash" abilities for older MySQL (pre-4.1) hashes. The older MySQL pre-4.1 authentication scheme is vulnerable to a pass-the-hash authentication attack. Utilizing the old-style hashes gathered from a MySQL database, a user can use Medusa to verify their validity on other servers. A modified MySQL client can also be use to connect to located services directly utilizing a valid hash.

Medusa Documentation
medusa-2.1.1/doc/medusa-http.html0000644000175000001440000000065411723732130013600 00000000000000 Foofus Networking Services - Medusa::HTTP

Medusa Parallel Network Login Auditor :: HTTP

JoMo-Kun / jmk "AT" foofus "DOT" net

The HTTP module tests accounts against HTTP/HTTPS services using BASIC-AUTH, integrated windows authentication (NTLM) and digest (MD5 and MD5-sess).

Medusa Documentation
medusa-2.1.1/doc/medusa-vmauthd.html0000644000175000001440000000066411723732130014272 00000000000000 Foofus Networking Services - Medusa::VMAUTHD

Medusa Parallel Network Login Auditor :: VMWAUTHD

JoMo-Kun / jmk "AT" foofus "DOT" net

The VMWAUTHD module tests accounts against the VMware Authentication Daemon. It supports both non-SSL and SSL encrypted installations of the service.

Medusa Documentation
medusa-2.1.1/doc/medusa-ssh.html0000644000175000001440000000527211723732130013417 00000000000000 Foofus Networking Services - Medusa::SSH

Medusa Parallel Network Login Auditor :: SSH

JoMo-Kun / jmk "AT" foofus "DOT" net

The SSH module tests accounts against SSH service using SSH version 2. The module currently supports brute-forcing SSH Keyboard-interactive and Password authentication modes.

This module requires libssh2 (www.libssh2.org). This is NOT the same as libssh (0xbadc0de.be). It should be noted that the libssh2 library, and therefor, the Medusa SSH module only supports brute-forcing servers which can talk SSH version 2. Libssh2 does not have support for v1 and it looks likely that it never will.

The module has a single option, BANNER. If it's not obvious, this allows you to set the client banner sent during an authentication test. The default value is "SSH-2.0-MEDUSA".

Some notes regarding libssh2... Using the stock libssh2 library, it is likely that the user will encounter hung module threads when running Medusa. This problem is due to libssh2's libssh2_session_startup() not always returning. The cause of this hang within libssh2, I believe, stems from the SSH servers being tested getting pissed and not sending back a banner. The default behavior for OpenSSH is to allow only 10 unauthenticated connections and ignore everything else. While we weren't always running 10 threads in our tests, our threads may have been hitting it faster than it could clean up the previous connections...

This issue has been dealt with in two ways:

  • libssh2 waits forever for the ssh server to respond with a banner. This causes our threads to wait forever, which kinda blows. I've added a patch to libssh2 in the /misc directory which causes it to count to 1000 and then stop waiting. This minor patch has been submitted to the libssh2 folks and a fix will hopefully be included in a future release.
  • We now loop around the libssh2_session_startup() call. This function will fail if libssh2 was unable to negotiate a SSH session. We give it 5 shots to pass and sleep a user configurable time between each. If we fail after 5 attempts, we display that this happened and identify the host/user/pass combination that was not tested.

** As of libssh2 0.18 (devel), this issue appears to be resolved. **

It should be noted that while you can run many threads of SSH, more is not always better. As you increase past 10, you will notice the module having to retry the startup() function.

Medusa Documentation
medusa-2.1.1/doc/medusa-svn.html0000644000175000001440000000131311723732130013420 00000000000000 Foofus Networking Services - Medusa::SVN

Medusa Parallel Network Login Auditor :: SVN

JoMo-Kun / jmk "AT" foofus "DOT" net

The SVN module tests accounts against the Subversion (SVN) service.

This module requires the svn_client-1 library to be installed. This should have been installed as part of Subversion.

The module has a single option, BRANCH. This allows the user to specify the target SVN URL. For example, svn://host/branch. If the option is not set, the default behaviour is to use trunk.

Medusa Documentation
medusa-2.1.1/doc/medusa-nntp.html0000644000175000001440000000055711723732130013602 00000000000000 Foofus Networking Services - Medusa::NNTP

Medusa Parallel Network Login Auditor :: NNTP

JoMo-Kun / jmk "AT" foofus "DOT" net

The NNTP module tests accounts against the Network News Transfer Protocol via AUTHINFO.

Medusa Documentation
medusa-2.1.1/doc/medusa.10000644000175000001440000001475011723732130012021 00000000000000.TH MEDUSA 1 .SH NAME MEDUSA \- Parallel Network Login Auditor .SH SYNOPSIS .B medusa [-h host|-H file] [-u username|-U file] [-p password|-P file] [-C file] -M module [OPTIONS] .SH DESCRIPTION .I Medusa is intended to be a speedy, massively parallel, modular, login brute-forcer. The goal is to support as many services which allow remote authentication as possible. The author considers following items to some of the key features of this application: *Thread-based parallel testing. Brute-force testing can be performed against multiple hosts, users or passwords concurrently. *Flexible user input. Target information (host/user/password) can be specified in a variety of ways. For example, each item can be either a single entry or a file containing multiple entries. Additionally, a combination file format allows the user to refine their target listing. *Modular design. Each service module exists as an independent .mod file. This means that no modifications are necessary to the core application in order to extend the supported list of services for brute-forcing. .SH OPTIONS .TP .B \-h [TARGET] Target hostname or IP address. .TP .B \-H [FILE] Reads target specifications from the file specified rather than from the command line. The file should contain a list separated by newlines. .TP .B \-u [TARGET] Target username. .TP .B \-U [FILE] Reads target usernames from the file specified rather than from the command line. The file should contain a list separated by newlines. .TP .B \-p [TARGET] Target password. .TP .B \-P [FILE] Reads target passwords from the file specified rather than from the command line. The file should contain a list separated by newlines. .TP .B \-C [FILE] File containing combo entries. Combo files are colon separated and in the following format: host:user:password. If any of the three fields are left empty, the respective information should be provided either as a single global value or as a list in a file. The following combinations are possible in the combo file: 1.) foo:bar:fud 2.) foo:bar: 3.) foo:: 4.) :bar:fud 5.) :bar: 6.) ::fud 7.) foo::fud Medusa also supports using PwDump files as a combo file. The format of these files should be user:id:lm:ntlm:::. We look for ':::' at the end of the first line to determine if the file contains PwDump output. .TP .B \-O [FILE] File to append log information to. Medusa will log all accounts credentials found to be valid or cause an unknown error. It will also log the start and stop times of an audit, along with the calling parameters. .TP .B \-e [n/s/ns] Additional password checks ([n] No Password, [s] Password = Username). If both options are being used, they should be specified together ("-e ns"). If only a single option is being called use either "-e n" or "-e s". .TP .B \-M [TEXT] Name of the module to execute (without the .mod extension). .TP .B \-m [TEXT] Parameter to pass to the module. This can be passed multiple times with a different parameter each time and they will all be sent to the module (i.e. -m Param1 -m Param2, etc.) .TP .B \-d Dump all known modules. .TP .B \-n [NUM] Use for non-default TCP port number. .TP .B \-s Enable SSL. .TP .B \-g [NUM] Give up after trying to connect for NUM seconds (default 3). .TP .B \-r [NUM] Sleep NUM seconds between retry attempts (default 3). .TP .B \-R [NUM] Attempt NUM retries before giving up. The total number of attempts will be NUM + 1. .TP .B \-c [NUM] Set the number of usec that are waited during a test of the established network socket. Some services (e.g. FTP, IMAP, POP3, and SMTP) may be configured to drop connections after an arbitrary number of failed logon attempts. We try to reuse the established connection to send authentication attempts until this disconnect occurs, at which point the connection is reestablished. To accomplish this, we check the socket to see if it's still alive before authenticating within select modules. The default is perform a 1 usec check. It may be necessary to specify much larger values. For example, a 1000 usec was needed against our test vsftp server to avoid issues with its built-in anti-bruteforce mechanisms. .TP .B \-t [NUM] Total number of logins to be tested concurrently. It should be noted that rougly t x T threads could be running at any one time. 381 appears to be the limit on my fairly boring Gentoo Linux host. .TP .B \-T [NUM] Total number of hosts to be tested concurrently. .TP .B \-L Parallelize logins using one username per thread. The default is to process the entire username before proceeding. .TP .B \-f Stop scanning host after first valid username/password found. .TP .B \-F Stop audit after first valid username/password found on any host. .TP .B \-b Suppress startup banner .TP .B \-q Display module's usage information. This should be used in conjunction with the "-M" option. For example, "medusa -M smbnt -q". .TP .B \-v [NUM] Verbose level [0 - 6 (more)]. All messages at or below the specified level will be displayed. The default level is 5. The following is the breakdown of the verbose levels: 0) EXIT APPLICATION 1) MESSAGE WITHOUT TAG 2) LOG MESSAGE WITHOUT TAG 3) IMPORTANT MESSAGE 4) ACCOUNT FOUND 5) ACCOUNT CHECK 6) GENERAL MESSAGE .TP .B \-w [NUM] Error debug level [0 - 10 (more)]. All messages at or below the specified level will be displayed. The default level is 5. The following is the breakdown of the error levels: 0) FATAL 1) ALERT 2) CRITICAL 3) ERROR 4) WARNING 5) NOTICE 6) INFO 7) DEBUG 8) DEBUG - AUDIT 9) DEBUG - SERVER 10) DEBUG - MODULE .TP .B \-V Display version .TP .B \-Z [TEXT] Allows basic resuming of a previous scan. The supplied parameter describes which hosts were completed, which were partially tested and which had not been started. When Medusa receives a SIGINT, it will calculate and display a "resume map". This map can then be supplied to the next run. For example, "medusa [OPTIONS PREVIOUSLY USED] -Z h6u1u2h8.". In this particular example, hosts 1-5 were completed, host 6 was partially done (user 1 was partially completed and user 2 and beyond had not been started), host 7 was completed and host 8 and beyond had not been started. Medusa will parse this map and skip hosts and users accordingly. It should be noted that only host and user-level, not password-level, resuming is supported. If a user had been previously started, but was not completed, it will be tested from the start of its respective password list. .SH AUTHOR JoMo-Kun fizzgig .SH BUGS Found a bug? Feel free to send in a patch. medusa-2.1.1/doc/medusa.html0000644000175000001440000004755411760001337012634 00000000000000 Foofus Networking Services - Medusa

Medusa Parallel Network Login Auditor

JoMo-Kun / jmk "AT" foofus "DOT" net

What?

Medusa is intended to be a speedy, massively parallel, modular, login brute-forcer. The goal is to support as many services which allow remote authentication as possible. The author considers following items as some of the key features of this application:

  • Thread-based parallel testing. Brute-force testing can be performed against multiple hosts, users or passwords concurrently.
  • Flexible user input. Target information (host/user/password) can be specified in a variety of ways. For example, each item can be either a single entry or a file containing multiple entries. Additionally, a combination file format allows the user to refine their target listing.
  • Modular design. Each service module exists as an independent .mod file. This means that no modifications are necessary to the core application in order to extend the supported list of services for brute-forcing.

Why?

Why create Medusa? Isn't this the same thing as THC-Hydra? Here are some of the reasons for this application:

  • Application stability. Maybe I'm just lame, but Hydra frequently crashed on me. I was no longer confident that Hydra was actually doing what it claimed to be. Rather than fix Hydra, I decided to create my own buggy application which could crash in new and exciting ways.
  • Code organization. A while back I added several features to Hydra (parallel host scanning, SMBNT module). Retro-fitting the parallel host code to Hydra was a serious pain. This was mainly due to my coding ignorance, but was probably also due to Hydra not being designed from the ground-up to support this. Medusa was designed from the start to support parallel testing of hosts, users and passwords.
  • Speed. Hydra accomplishes its parallel testing by forking off a new process for each host and instance of the service being tested. When testing many hosts/users at once this creates a large amount of overhead as user/password lists must be duplicated for each forked process. Medusa is pthread-based and does not unnecessarily duplicate information.
  • Education. I am not an experienced C programmer, nor do I consider myself an expert in multi-threaded programming. Writing this application was a training exercise for me. Hopefully, the results of it will be useful for others.

For a quick comparison of Medusa, Ncrack, and THC-Hydra see: medusa-compare.html

How?

How do I use this thing? Simply running "medusa" without any options will dump all the parameters it accepts along with their respective description. Here are several example uses:

  • Display all modules currently installed:
    % medusa -d
     
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks
    
      Available modules in "." :
      Available modules in "/usr/local/lib/medusa/modules" :
        + mssql.mod :
          Brute force module for M$-SQL sessions : version 0.1.0
        + http.mod :
          Brute force module for HTTP : version 0.1.1
        + ssh.mod :
          Brute force module for SSH v2 sessions : version 0.1.1
        + smbnt.mod :
          Brute force module for SMB/NTLMv1 sessions : version 0.1.1
        + telnet.mod :
          Brute force module for telnet sessions : version 0.1.4
    
  • Display specific options for a given module:
    % medusa -M smbnt -q 
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks
    
    smbnt.mod (0.1.1) JoMo-Kun :: Brute force module for SMB/NTLMv1 sessions
    
    Available module options:
      GROUP:? (DOMAIN, LOCAL*, BOTH)
        Option sets NetBIOS workgroup field.
        DOMAIN: Check credentials against this hosts primary domain controller via this host.
        LOCAL:  Check local account.
        BOTH:   Check both. This leaves the workgroup field set blank and then attempts to check
                the credentials against the host. If the account does not exist locally on the
                host being tested, that host then queries its domain controller.
      GROUP_OTHER:?
        Option allows manual setting of domain to check against. Use instead of GROUP.
      PASS:?  (PASSWORD*, HASH, MACHINE)
        PASSWORD: Use normal password.
        HASH:     Use a NTLM hash rather than a password.
        MACHINE:  Use the machine's NetBIOS name as the password.
      NETBIOS
        Force NetBIOS Mode (Disable Native Win2000 Mode). Win2000 mode is the default.
        Default mode is to test TCP/445 using Native Win2000. If this fails, module will
        fall back to TCP/139 using NetBIOS mode. To test only TCP/139, use the following:
        medusa -M smbnt -m NETBIOS -n 139
    
    (*) Default value
    Usage example: "-M smbnt -m GROUP:DOMAIN -m PASS:HASH"
    
  • The following command instructs Medusa to test all passwords listed in passwords.txt against a single user (administrator) on the host 192.168.0.20 via the SMB service. The "-e ns" instructs Medusa to additionally check if the administrator account has either a blank password or has its password set to match its username (administrator).
    
    % medusa -h 192.168.0.20 -u administrator -P passwords.txt -e ns -M smbnt
    
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks
    
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password:  (1/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: administrator (2/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: password (3/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: pass1 (4/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: pass2 (5/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: pass3 (6/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: pass4 (7/7)
    
  • The below command-line demonstrates how to execute some of the parallel features of Medusa. Here at least 20 hosts and 10 users are tested concurrently. The "-L" options instructs Medusa to parallelize by user. This means each of the 10 threads targeting a host checks a unique user.
    
    % medusa -H hosts.txt -U users.txt -P passwords.txt -T 20 -t 10 -L -F -M smbnt
    
  • Medusa allows host/username/password data to also be set using a "combo" file. The combo file can be specified using the "-C" option. The file should contain one entry per line and have the values colon separated in the format host:user:password. If any of the three fields are left empty, the respective information should be provided either as a global value or as a list in a file. Medusa will perform a basic parameter check based on the contents of the first line in the file.

    The following combinations are possible in the combo file:

    • host:username:password
    • host:username:
    • host::
    • :username:password
    • :username:
    • ::password
    • host::password

    The following example will check each entry in the file combo.txt
    % medusa -M smbnt -C combo.txt

    The combo.txt file:
    192.168.0.20:administrator:password
    192.168.0.20:testuser:pass
    192.168.0.30:administrator:blah
    192.168.0.40:user1:foopass

    The following example will check each entry in the file combo.txt against the targets listed in hosts.txt
    % medusa -M smbnt -C combo.txt -H hosts.txt

    The combo.txt file:
    :administrator:password
    :testuser:pass
    :administrator:blah
    :user1:foopass

    Medusa also supports using PwDump files as a combo file. The format of these files should be user:id:lm:ntlm:::. We look for ':::' at the end of the first line to determine if the file contains PwDump output.

  • Resume a Medusa scan. Medusa has the ability to resume a scan which was interrupted with a SIGINT signal (e.g. CTRL-C). For example:

    Test interrupted with SIGINT
    % ../medusa -M ssh -H host.txt -U users.txt -p password
    Medusa v2.0 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks

    ACCOUNT CHECK: [ssh] Host: 192.168.0.1 (1 of 11, 0 complete) User: foo (1 of 4, 0 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.1 (1 of 11, 0 complete) User: administrator (2 of 4, 1 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.1 (1 of 11, 0 complete) User: jmk (3 of 4, 2 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.1 (1 of 11, 0 complete) User: bar (4 of 4, 3 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.11 (2 of 11, 1 complete) User: foo (1 of 4, 0 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.11 (2 of 11, 1 complete) User: administrator (2 of 4, 1 complete) Password: password (1 of 1 complete)
    ALERT: Medusa received SIGINT - Sending notification to login threads that we are are aborting.
    ACCOUNT CHECK: [ssh] Host: 192.168.0.11 (2 of 11, 1 complete) User: jmk (3 of 4, 2 complete) Password: password (1 of 1 complete)
    ALERT: To resume scan, add the following to your original command: "-Z h2u3u4h3."

    Interrupted scan being resumed
    % ../medusa -M ssh -H host.txt -U users.txt -p password -Z h2u3u4h3.
    Medusa v2.0 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks

    ACCOUNT CHECK: [ssh] Host: 192.168.0.11 (2 of 11, 0 complete) User: jmk (3 of 4, 0 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.11 (2 of 11, 0 complete) User: bar (4 of 4, 1 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.15 (3 of 11, 1 complete) User: foo (1 of 4, 0 complete) Password: password (1 of 1 complete)

    The following is a brief discription of the resume map:

    h2u3u4h3.
    +--------- First host which was not 100% completed
      +------- First user for host which was not 100% completed
        +----- First user for host which was not started
          +--- First host which was not started
            +- Map ending mark
    

Module specific details:

Where?

medusa-2.1.1.tar.gz
Medusa-gui (Java-based GUI developed by tak and bigmoneyhat)

Install Instructions:

General

The majority of Medusa was written and tested on Linux/Gentoo-based systems. While it has been known to work on variety of operating systems, it is quite possible there may be issues that crop up only on non-Gentoo devices. Of course, there are issues that will probably also show up on Gentoo that have so far been missed...

Medusa should be fairly straight-forward to build: "./configure; make; make install". However, this may result in a somewhat limited installation. To take full advantage of all the brute-forcing goodness that Medusa has to offer, several dependencies must be satisfied. The following table lists out the modules which have additional dependencies. In order for the modules to function, the appropriate header files must be installed on the system when the modules themselves are compiled. Additional module specific information is included within the documentation for each module.

Dependency Homepage Module Notes
OpenSSL http://www.openssl.org HTTP, MSSQL, SMBNT, SSL-based connections
LibSSH2 http://www.libssh2.org SSH LibSSH2 patch provided to address timing issue. Issue appears to be addressed in 0.18.
NCPFS ftp://platan.vc.cvut.cz/pub/linux/ncpfs NCP Use "make install-dev" to install header files.
LibPQ http://www.postgresql.org PostgreSQL
Subversion http://subversion.tigris.org SVN
afpfs-ng http://alexthepuffin.googlepages.com/home AFP Header files may need to be manually installed. Autoconf currently assumes install base of /usr (e.g. /usr/include/afpfs-ng)

It should also be noted that, by default, not all of the modules are built. Incomplete modules or modules which have not been sufficiently tested may be disabled. The "configure" output should identify which modules it will attempt to build. To enable non-default modules, use the "--enable-module-MODULE_NAME" configure option.

Linux/Gentoo

At this time Medusa is not available within Portage. An ebuild for Medusa has been submitted to bugs.gentoo.org, but has not yet made its way into Portage. In the meantime, all of the ebuilds can be used via Portage Overlay. For example, Medusa can be installed via the Gentoo "pentoo" overlay located at trac.pentoo.ch. Additionally, the ebuilds have been included and can also be manually installed.

The following ebuilds have been included within this distribution:

  • /misc/net-analyzer/medusa-2.1.ebuild

Some basic Portage Overlay instructions:

  • Modify /etc/make.conf
    PORTDIR_OVERLAY="/some/directory/"
  • Create the following within the PORTDIR_OVERLAY directory:
    net-analyzer/medusa
  • Place each ebuild and any accompanying files in its respective PORTDIR_OVERLAY directory.
    cd into each directory and execute:
    ebuild name_of_ebuild.ebuild digest
  • Modify /etc/portage/package.keywords
    net-analyzer/medusa ~x86

Other Systems

Medusa has been built and basic tests performed on a variety of default system installations. The following tables includes some notes from these tests.

Operating System Distro/Version Notes
Linux BackTrack 5 (32-bit) Installed: libssl-dev, libncp-dev, libpq-dev, libssh2-1-dev, libgcrypt11-dev, libgnutls-dev, libsvn-dev, libapr1-dev
BackTrack 5R1 (32-bit) Installed: libssl-dev, libncp-dev, libpq-dev, libssh2-1-dev, libsvn-dev
CentOS 6.2 (64-bit) Installed: "Development Tools", openssl-devel, libssh2-devel, postgresql-devel, subversion-devel
Debian 5.0.3 Installed: build-essential, libpcre3-dev, libssl-dev, libncp, libncp-dev, libpq5, libpq-dev, libssh2-1, libssh2-1-dev, libsvn-dev
Fedora 12 Installed: pcre-devel, afpfs-ng-devel, ncpfs-devel, postgresql-devel, libssh2-devel, subversion-devel
openSUSE 11.2 Installed: patterns-openSUSE-devel_C_C++, pcre-devel, ncpfs-devel, libssh2-devel, postgresql-devel, subversion-devel
Slackware 13.0
Ubuntu 8.0.4
Ubuntu 9.10
Ubuntu 11.10 Installed: build-essential, libssl-dev, libncp, libncp-dev, libpq5, libpq-dev, libssh2-1, libssh2-1-dev, libgcrypt11-dev, libgnutls-dev, libsvn-dev
SunOS Solaris 11 x86 Installed: developer-gnu
BSD FreeBSD 7.2 Installed: afpfs-ng, ncpfs, libssh, postgresql, libpq, libsvn
FreeBSD 9.0-CURRENT (32-bit)
OpenBSD 5.0 (64-bit)
Mac OS X OS X 10.6 Installed: MacPorts
OS X 10.7 Installed: HomeBrew
Microsoft Windows Cygwin I have been unable to build the modules under Cygwin. If anyone can figure this out, I'll buy you a beer at the next DefCon.

Who?

This fine piece of buggy software was brought to you by the geeks at Foofus.net. JoMo-Kun was the chief goon and wrote the core of Medusa along with several of the modules. Foofus created the initial design for the loadable modules. Fizzgig provided the networking code, several modules, the loadable module implementation along with also fixing a bunch JoMo-Kun's crappy stuff. pMonkey was a crazy module coding fiend. Last, but certainly not least, Heidi provided the tool's name.

Huh?

If you have questions regarding this application, feel free to contact us. Either send me email directly or join our mailing list foofus-tools. If it breaks, please send a detailed bug report. Even better, send in a patch. I make no claims that this program will do what you want it to. I've been using it during our assessments for years now successfully. Hopefully, others will have similar luck. If you find Medusa useful and want to give something back, please submit new modules, code improvements or just buy any of the Foofus.net goons a beer at the next DefCon.

Joe

© Copyright 2012, Foofus Advanced Security Services
any time. any fucknut.
medusa-2.1.1/doc/medusa-rexec.html0000644000175000001440000000052511723732130013724 00000000000000 Foofus Networking Services - Medusa::REXEC

Medusa Parallel Network Login Auditor :: REXEC

JoMo-Kun / jmk "AT" foofus "DOT" net

The REXEC module tests accounts against the REXEC service.

Medusa Documentation
medusa-2.1.1/doc/medusa-afp.html0000644000175000001440000000141711723732130013365 00000000000000 Foofus Networking Services - Medusa::AFP

Medusa Parallel Network Login Auditor :: AFP

JoMo-Kun / jmk "AT" foofus "DOT" net

The AFP module tests accounts against the Apple Filing Protocol service.

This AFP module leverages the afpfs-ng FUSE-based client (http://alexthepuffin.googlepages.com/home). The current Medusa autoconf setup requires that the afpfs-ng header files be installed to /usr/include/afpfs-ng and the libary be located at /usr/lib/libafpclient.so.0. If this does not match your setup, modifications to the autoconf configuration will be necessary.

Medusa Documentation
medusa-2.1.1/doc/medusa-ftp.html0000644000175000001440000000070611723732130013410 00000000000000 Foofus Networking Services - Medusa::FTP

Medusa Parallel Network Login Auditor :: FTP

JoMo-Kun / jmk "AT" foofus "DOT" net

The FTP module tests accounts against the FTP and FTPS services. This includes both Explicit FTPS (AUTH TLS Mode as defined in RFC 4217) and Implicit (FTP over SSL (990/tcp)).

Medusa Documentation
medusa-2.1.1/doc/medusa-pop3.html0000644000175000001440000000243111723732130013475 00000000000000 Foofus Networking Services - Medusa::POP3

Medusa Parallel Network Login Auditor :: POP3

JoMo-Kun / jmk "AT" foofus "DOT" net

The POP3 module tests accounts against the POP3 service.

The module has a single option, MODE. If left unset, the default behavior is to check for either "+" or "-" in the server's response to see if the attempt was successful.

If the server being tested in an AS/400, the module should be executed using the option -m MODE:AS400. This will result in the -ERR message being returned to be parsed for addition information. This is based on information gathered from the following document: Enumeration_of_AS400_users_via_pop3.pdf

The module supports both POP3 (110/tcp) and POP3S (POP3 protocol over TLS/SSL) (995/tcp). In addition, it supports the POP3 STARTTLS extention, as defined in http://www.faqs.org/rfcs/rfc2595.html. Medusa will submit a "STLS" command to the target server. If a positive response is returned, a TLS session will be initiated.

Medusa Documentation
medusa-2.1.1/doc/medusa-smbnt.html0000644000175000001440000002335411723732130013746 00000000000000 Foofus Networking Services - Medusa::SMBNT

Medusa Parallel Network Login Auditor :: SMBNT

JoMo-Kun / jmk "AT" foofus "DOT" net

The SMBNT module tests accounts against the Microsoft netbios-ssn (TCP/139) and microsoft-ds (TCP/445) services. Besides testing normal passwords, this module allows Medusa to directly test NTLM hashes against a Windows host. This may be useful for an auditor who has aquired a sam._ or pwdump file and would like to quickly determine which are valid entries.

Several "-m 'METHOD:VALUE'" options can be used with this module. The following are valid methods: AUTH, GROUP, GROUP_OTHER, PASS and NETBIOS. The following values are useful for these methods:

Method Value Description
AUTH LM Force LMv1 authentication. Since LM hashes don't store character case information, this could potentially be used to improve our ability to identify more complex passwords. For example, if the user has a password of "paSsWoRD", the only way to determine that via NTLM is to submit a value of "paSsWoRD". With LM we can simply send "password". It may also be possible to modify Samba to only do LM, so that whole mixed-case password thing can be ignored.

Unfortunately, LM authentication is not without its problems. If a password attempt is reported as failed, it could mean one of at least three different things:

* The password is indeed wrong.
* No LM hash is stored for that account.
* The GPO Network Security: LAN Manager authentication level is set as one of the following:
- Send NTLMv2 response only\refuse LM (Level 4)
- Send NTLMv2 response only\refuse LM & NTLM (Level 5)

In both of the two later cases, the password may be correct, but we won't know it. I've found no remote and anonymous way of determining the LAN Manager authentication level. My assumption was that it'd be revealed during the protocol negotiation, but that doesn't seem to be the case.
NTLM* The module will send only a NTLMv1 response. This method is the most tested option and the current default. It should work in the majority of cases, with the notable exception of when the GPO Network Security: LAN Manager authentication level is set to "Send NTLMv2 response only\refuse LM & NTLM (Level 5)".
LMv2 This option leverages the LMv2 response algorithm. The LMv2 response is used to provide pass-through authentication compatibility with older servers. The response is based on the NTLM password hash and is exactly 24 bytes. It appears that this method works against the majority of Microsoft Windows operating systems (e.g. NT 4, 2000, 2003, XP, Vista and 2008). It will likely become the default method in future releases.
NTLMv2 This option enforces the use of the NTLMv2 response algorithm. Support for this algorithm was added with Microsoft Windows with NT 4.0 SP4. It should be noted that the method doesn't currently work with Microsoft Vista. While NTLMv2 authentication with Samba and Windows 2003 functions as expected, Vista systems respond with the oh-so-helpful "INVALID_PARAMETER" error code. LMv2 authentication is recommended in cases where LM and NTLM are refused.
GROUP LOCAL* Check local account.
DOMAIN Check credentials against this hosts primary domain controller via this host.
BOTH Check both. This leaves the workgroup field set blank and then attempts to check the credentials against the host. If the account does not exist locally on the host being tested, that host then queries its domain controller.
GROUP_OTHER [user specified] Configure arbitrary domain for host to authenticate against.
PASS PASSWORD* Use a normal password.
HASH Use a LM or NTLM hash rather than a password.
MACHINE Use the Machine's NetBIOS name as the password.
NETBIOS Force NetBIOS Mode (Disable Native Win2000 Mode)
  (*) Default value

The following examples demonstrate several uses of the SMBNT module:

  • The default behavior is to test NATIVE Win2000 mode via TCP/445. If this connection fails, NETBIOS mode is checked on TCP/139. The following shows how to force the module into NETBIOS module.
    
    % medusa -h 192.168.0.20 -u administrator -e ns -M smbnt -m NETBIOS -n 139 
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks
    
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password:  (1/2)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: administrator (2/2)
    
  • The following example shows how to force to module to set a domain value other than either "localhost" or the system's default domain. This can be useful when testing trust relationships between domains.
    
    % medusa -h 192.168.0.20 -u foo -p bar -M smbnt -m GROUP_OTHER:FOODOM
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks 
    
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: foo (1/1) Password: bar (1/1)
    
  • This example demonstrates one way that PwDump output could be used with Medusa. Each user and their respective NTLM hash within the pwdump.txt file will be tested against the hosts listed in hosts.txt.
    
    % medusa -H hosts.txt -C pwdump.txt -M smbnt -m PASS:HASH
    
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks
    
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/10) User: Administrator (1/3) Password: 92D887C8010492C2944E2DF489A880E4:7A2EDE4F51BC5A03984C6BA2C239CF63::: (1/1)
    ACCOUNT FOUND: [smbnt] Host: 192.168.0.20 User: Administrator Password: 92D887C8010492C2944E2DF489A880E4:7A2EDE4F51BC5A03984C6BA2C239CF63::: [SUCCESS]
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/10) User: bar (2/3) Password: 49D58563113416EBAAD3B435B51404EE:AA3AFE73B6E0C2D87B3A428BF696AE71::: (1/1)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/10) User: foo (3/3) Password: 92D887C8010492C2944E2DF489A880E4:7A2EDE4F51BC5A03984C6BA2C239CF63::: (1/1)
    ACCOUNT FOUND: [smbnt] Host: 192.168.0.20 User: foo Password: 92D887C8010492C2944E2DF489A880E4:7A2EDE4F51BC5A03984C6BA2C239CF63::: [SUCCESS]
    < snip >
    
    It should be noted that once a valid hash is located, it is often not necessary to "crack" the password in order to use it. Using a modified SAMBA client, the hash can just be "passed" directly. See this page for a SAMBA patch and several examples.

Be careful of mass domain account lockout with this module. For example, assume you are checking several accounts against many domain workstations. If you are using either the "GROUP:DOMAIN" or the "GROUP:BOTH" option and these accounts do not exist locally on the workstations, each workstation will in turn check their respective domain controller. This could cause a bunch of lockouts. Of course, it'd look like the workstations, not you, were doing it. ;)

FYI, this code is unable to test accounts on default XP hosts which are not part of a domain and do not have normal file sharing enabled. Default XP does not allow shares and returns STATUS_LOGON_FAILED for both valid and invalid credentials. XP with simple sharing enabled returns SUCCESS for both valid and invalid credentials. If anyone knows a way to test in these configurations...

The following is a basic speed test performed against several virtual machines. The test utilized a 5000 entry dictionary with the correct value at line 4998. The cell value reflects the observed average number of password attempts per second.

TARGET OS/AUTH LEVEL 2000 XP 2003 Vista 2008
LM 345.1 t/s 796.1 t/s 125.6 t/s 655 t/s* 379.3 t/s*
NTLM 357.1 t/s 821.0 t/s 140.6 t/s 546.2 t/s 373.2 t/s
LMv2 338.2 t/s 801.1 t/s 164.5 t/s 637.3 t/s 371.9 t/s
NTLMv2 364.1 t/s 812.2 t/s 165.4 t/s - -

* Did not find password in LM mode, since no LM hash is stored in default install of Vista/2008.
- Authentication failed with "INVALID_PARAMETER" response.

A potential timing-based attack was also observed during testing with 2008. It takes roughly 13 seconds to check 5000 passwords against a valid account. It takes only about 6 seconds to test the same number against a non-existant account.

Medusa Documentation
medusa-2.1.1/doc/medusa-web-form.html0000644000175000001440000000064511723732130014337 00000000000000 Foofus Networking Services - Medusa::Web-Form

Medusa Parallel Network Login Auditor :: Web-Form

JoMo-Kun / jmk "AT" foofus "DOT" net

Basic web form brute force module which handles GET/POST requests. Supports customizable submit parameters and server response text.

Medusa Documentation
medusa-2.1.1/doc/medusa-smtp.html0000644000175000001440000000055311723732130013602 00000000000000 Foofus Networking Services - Medusa::SMTP-AUTH

Medusa Parallel Network Login Auditor :: SMTP-AUTH

JoMo-Kun / jmk "AT" foofus "DOT" net

Brute force module for SMTP Authentication with TLS (STARTTLS extension).

Medusa Documentation
medusa-2.1.1/doc/medusa-ncp.html0000644000175000001440000000422611723732130013400 00000000000000 Foofus Networking Services - Medusa::NCP

Medusa Parallel Network Login Auditor :: NCP

JoMo-Kun / jmk "AT" foofus "DOT" net

The NCP module tests accounts against the NetWare NCP service. This module was developed using a NetWare 5.1 host as the target.

This module requires ncpfs. The ncpfs package must also be installed using the "install-dev" option. This installs both the ncpfs header files and the static libncp library. A modified Gentoo ebuild has been included in the /misc/net-fs/ncpfs directory which includes a USE flag for this option.

The module has a single option, CONTEXT. It should be noted that libncp does not by default automatically specific a user context. If it fails to resolve the name provided it appends the server's context to the username and attempts to resolve that value. It is advised that users specify a context for each account being tested. A global context can be specified using the CONTEXT option. A per-user context can be defined as part of the account name within a file containing usernames or the username passed via the command-line.

The following examples demonstrate several uses of the NCP module:

  • Specify a context for all accounts in users.txt:
    
    % medusa -h 192.168.0.20 -U users.txt -p bar -M ncp -m CONTEXT:.OU=administrators.O=foofus
    
    
  • Pass the full user context via the "-u" parameter:
    
    % medusa -h 192.168.0.20 -u username.OU=administrators.O=foofus -p bar -M ncp
    
    

Libncp, by default, also uses both the NDS and BIND authenticators. Unfortunately, the only error message returned to the module is that of the BIND authenticator. These messages are not as descriptive as NDS and only seem to report success or failure. In order to have more useful messages (account disabled/max logons exceeded/etc.), create a ~/.nwclient or /etc/ncpfs.conf file with the following text:

[Requester]
NetWare Protocol = NDS


Medusa Documentation
medusa-2.1.1/doc/medusa-wrapper.html0000644000175000001440000000271211723732130014276 00000000000000 Foofus Networking Services - Medusa::Wrapper

Medusa Parallel Network Login Auditor :: Wrapper

JoMo-Kun / jmk "AT" foofus "DOT" net

The purpose of the wrapper module is to allow the user to execute arbitrary scripts while taking advantage of Medusa managing hosts/users/passwords. Two sample scripts have been included in the wrapper directory.

This is a work in progress... The module currently uses fork() which isn't ideal. Not sure if I can kick off a thread and redirect STDIN/STDOUT for just that thread...

The initial goal for this module was to test RDP servers using rdesktop. A patch to rdesktop 1.4.1 has been included in the /misc/rdesktop directory. This extends the dictionary patch from cqure.net to work with the Medusa wrapper STDIN method. It should be noted that rdesktop doesn't appear to be able to use command-line passwords when connecting to Windows 2000 hosts. Windows 2003 and XP worked fine during testing.

The following example shows one way to use rdesktop with the wrapper module:

medusa -M wrapper -m TYPE:STDIN -m PROG:rdesktop -m ARGS:"-u %U -p - %H" -H hosts.txt -U users.txt -P passwords.txt

One possible method for hiding the graphical output from rdesktop:
% Xvfb :97 -ac -nolisten tcp &
% export DISPLAY=:97


Medusa Documentation
medusa-2.1.1/doc/medusa-telnet.html0000644000175000001440000000160411723732130014110 00000000000000 Foofus Networking Services - Medusa::TELNET

Medusa Parallel Network Login Auditor :: TELNET

JoMo-Kun / jmk "AT" foofus "DOT" net

The TELNET module tests accounts against the TELNET service. This module supports both telnet (23) and telnets (992).

The module currently has a single option, MODE. MODE can either be NORMAL (default) or AS400. The AS400 mode supports basic AS/400 tn5250 connections. This approach allows for more descriptive error messages than FTP when testing against an AS/400. However, POP3, if available on the AS/400, is still a better brute-force option.

The Telnet module will output to the log file hosts that were found to only have a password prompt. This may be useful when scanning for use, or lack of, AAA.

Medusa Documentation
medusa-2.1.1/doc/medusa-rlogin.html0000644000175000001440000000053111723732130014105 00000000000000 Foofus Networking Services - Medusa::RLOGIN

Medusa Parallel Network Login Auditor :: RLOGIN

JoMo-Kun / jmk "AT" foofus "DOT" net

The RLOGIN module tests accounts against the RLOGIN service.

Medusa Documentation
medusa-2.1.1/doc/medusa-rsh.html0000644000175000001440000000051511723732130013411 00000000000000 Foofus Networking Services - Medusa::RSH

Medusa Parallel Network Login Auditor :: RSH

JoMo-Kun / jmk "AT" foofus "DOT" net

The RSH module tests accounts against the RSH service.

Medusa Documentation
medusa-2.1.1/doc/medusa-cvs.html0000644000175000001440000000111311723732130013403 00000000000000 Foofus Networking Services - Medusa::CVS

Medusa Parallel Network Login Auditor :: CVS

JoMo-Kun / jmk "AT" foofus "DOT" net

The CVS module tests accounts against the CVS version control system via the pserver protocol.

The module has a single option, DIR. This allows the user to specify the target CVSROOT path. For example, :pserver:USER@HOST:/SOME_DIR. If the option is not set, the default behaviour is to use /root.

Medusa Documentation
medusa-2.1.1/doc/medusa-mssql.html0000644000175000001440000000165611723732130013763 00000000000000 Foofus Networking Services - Medusa::MSSQL

Medusa Parallel Network Login Auditor :: MSSQL

JoMo-Kun / jmk "AT" foofus "DOT" net

The MSSQL module tests accounts against Microsoft MS-SQL service.

It should be noted that MS-SQL Developer Edition and/or MSDE's concurrent workload governor limits you to no more than five concurrent connections to the server at any one time.

The MSSQL module will auto-detect the TCP ports used by the SQL server instances on the remote host. This is accomplished via a "SQL Ping" UDP request. If multiple instances are present on the host, only the first will be tested. Any additional instances will be reported and their respective TCP port will be noted. The auto-detection can be over-ridden by specifying a port via the Medusa "-n" option.

Medusa Documentation
medusa-2.1.1/NEWS0000644000175000001440000000000011723732130010372 00000000000000medusa-2.1.1/src/0000755000175000001440000000000011760001577010561 500000000000000medusa-2.1.1/src/medusa-thread-pool.h0000644000175000001440000000404611723732127014351 00000000000000/* * * Thread Pool Implementation * Based on Sun Microsystems, Inc. "Multithreaded Programming Guide" * http://docs.sun.com/app/docs/doc/816-5137/ggedn?a=view * * Declarations for the clients of a thread pool. */ #include typedef unsigned int uint_t; /* * The thr_pool_t type is opaque to the client. * It is created by thr_pool_create() and must be passed * unmodified to the remainder of the interfaces. */ typedef struct thr_pool thr_pool_t; /* * Create a thread pool. * min_threads: the minimum number of threads kept in the pool, * always available to perform work requests. * max_threads: the maximum number of threads that can be * in the pool, performing work requests. * linger: the number of seconds excess idle worker threads * (greater than min_threads) linger before exiting. * attr: attributes of all worker threads (can be NULL); * can be destroyed after calling thr_pool_create(). * On error, thr_pool_create() returns NULL with errno set to the error code. */ extern thr_pool_t *thr_pool_create(uint_t min_threads, uint_t max_threads, uint_t linger, pthread_attr_t *attr); /* * Enqueue a work request to the thread pool job queue. * If there are idle worker threads, awaken one to perform the job. * Else if the maximum number of workers has not been reached, * create a new worker thread to perform the job. * Else just return after adding the job to the queue; * an existing worker thread will perform the job when * it finishes the job it is currently performing. * * The job is performed as if a new detached thread were created for it: * pthread_create(NULL, attr, void *(*func)(void *), void *arg); * * On error, thr_pool_queue() returns -1 with errno set to the error code. */ extern int thr_pool_queue(thr_pool_t *pool, void *(*func)(void *), void *arg); /* * Wait for all queued jobs to complete. */ extern void thr_pool_wait(thr_pool_t *pool); /* * Cancel all queued jobs and destroy the pool. */ extern void thr_pool_destroy(thr_pool_t *pool); medusa-2.1.1/src/medusa-trace.h0000644000175000001440000000236311723732127013231 00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. See the * GNU General Public License for more details. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ #ifndef _MEDUSATRACE_H #define VB_EXIT 0 #define VB_NONE 1 #define VB_NONE_FILE 2 #define VB_IMPORTANT 3 #define VB_FOUND 4 #define VB_CHECK 5 #define VB_GENERAL 6 #define ERR_FATAL 0 #define ERR_ALERT 1 #define ERR_CRITICAL 2 #define ERR_ERROR 3 #define ERR_WARNING 4 #define ERR_NOTICE 5 #define ERR_INFO 6 #define ERR_DEBUG 7 #define ERR_DEBUG_AUDIT 8 #define ERR_DEBUG_SERVER 9 #define ERR_DEBUG_MODULE 10 #define _MEDUSATRACE_H #endif medusa-2.1.1/src/medusa.c0000644000175000001440000021425211723732127012132 00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. See the * GNU General Public License for more details. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * * Based on ideas from Hydra 3.1 by VanHauser [vh@thc.org] * Do only use for legal purposes. Illegal purposes cost $1 each. * */ #define VERSION_SVN "$Id: medusa.c 1666 2012-02-09 19:40:02Z jmk $" #include #include "medusa.h" #include "modsrc/module.h" char* szModuleName; char* szTempModuleParam; char* szModulePaths[3] = {"a", "b", "c"}; // will look at 3 different locations for modules if possible char** arrModuleParams; // the "argv" for the module int nModuleParamCount; // the "argc" for the module //int ctrlc = 0; sAudit *psAudit = NULL; void freeModuleParams() { int i; for (i = 0; i < nModuleParamCount; i++) { free(arrModuleParams[i]); } free(arrModuleParams); } /* Display appropriate usage information for application. */ void usage() { writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Syntax: %s [-h host|-H file] [-u username|-U file] [-p password|-P file] [-C file] -M module [OPT]", PROGRAM); writeVerbose(VB_NONE, " -h [TEXT] : Target hostname or IP address"); writeVerbose(VB_NONE, " -H [FILE] : File containing target hostnames or IP addresses"); writeVerbose(VB_NONE, " -u [TEXT] : Username to test"); writeVerbose(VB_NONE, " -U [FILE] : File containing usernames to test"); writeVerbose(VB_NONE, " -p [TEXT] : Password to test"); writeVerbose(VB_NONE, " -P [FILE] : File containing passwords to test"); writeVerbose(VB_NONE, " -C [FILE] : File containing combo entries. See README for more information."); writeVerbose(VB_NONE, " -O [FILE] : File to append log information to"); writeVerbose(VB_NONE, " -e [n/s/ns] : Additional password checks ([n] No Password, [s] Password = Username)"); writeVerbose(VB_NONE, " -M [TEXT] : Name of the module to execute (without the .mod extension)"); writeVerbose(VB_NONE, " -m [TEXT] : Parameter to pass to the module. This can be passed multiple times with a"); writeVerbose(VB_NONE, " different parameter each time and they will all be sent to the module (i.e."); writeVerbose(VB_NONE, " -m Param1 -m Param2, etc.)"); writeVerbose(VB_NONE, " -d : Dump all known modules"); writeVerbose(VB_NONE, " -n [NUM] : Use for non-default TCP port number"); writeVerbose(VB_NONE, " -s : Enable SSL"); writeVerbose(VB_NONE, " -g [NUM] : Give up after trying to connect for NUM seconds (default 3)"); writeVerbose(VB_NONE, " -r [NUM] : Sleep NUM seconds between retry attempts (default 3)"); writeVerbose(VB_NONE, " -R [NUM] : Attempt NUM retries before giving up. The total number of attempts will be NUM + 1."); writeVerbose(VB_NONE, " -c [NUM] : Time to wait in usec to verify socket is available (default 500 usec)."); writeVerbose(VB_NONE, " -t [NUM] : Total number of logins to be tested concurrently"); writeVerbose(VB_NONE, " -T [NUM] : Total number of hosts to be tested concurrently"); writeVerbose(VB_NONE, " -L : Parallelize logins using one username per thread. The default is to process "); writeVerbose(VB_NONE, " the entire username before proceeding."); writeVerbose(VB_NONE, " -f : Stop scanning host after first valid username/password found."); writeVerbose(VB_NONE, " -F : Stop audit after first valid username/password found on any host."); writeVerbose(VB_NONE, " -b : Suppress startup banner"); writeVerbose(VB_NONE, " -q : Display module's usage information"); writeVerbose(VB_NONE, " -v [NUM] : Verbose level [0 - 6 (more)]"); writeVerbose(VB_NONE, " -w [NUM] : Error debug level [0 - 10 (more)]"); writeVerbose(VB_NONE, " -V : Display version"); writeVerbose(VB_NONE, " -Z [TEXT] : Resume scan based on map of previous scan"); writeVerbose(VB_NONE, "\n"); return; } /* Read user options and check validity. */ int checkOptions(int argc, char **argv, sAudit *_psAudit) { int opt; extern char *optarg; extern int opterr; int ret = 0; int i = 0; int nIgnoreBanner = 0; /* initialize options */ _psAudit->iServerCnt = 1; _psAudit->iLoginCnt = 1; _psAudit->iParallelLoginFlag = PARALLEL_LOGINS_PASSWORD; _psAudit->iPortOverride = 0; /* Use default port */ _psAudit->iUseSSL = 0; /* No SSL */ _psAudit->iTimeout = DEFAULT_WAIT_TIME; /* Default wait of 3 seconds */ _psAudit->iRetryWait = WAIT_BETWEEN_CONNECT_RETRY; /* Default wait of 3 seconds */ _psAudit->iRetries = MAX_CONNECT_RETRY; /* Default of 2 retries (3 total attempts) */ _psAudit->iSocketWait = 500; /* Default wait of 500 usec */ _psAudit->iShowModuleHelp = 0; iVerboseLevel = 5; iErrorLevel = 5; for (i =0; i < argc; i++) { if (strstr(argv[i], "-b") != NULL) { nIgnoreBanner = 1; break; } } if (nIgnoreBanner == 0) writeVerbose(VB_NONE, "%s v%s [%s] (C) %s %s\n", PROGRAM, VERSION, WWW, AUTHOR, EMAIL); while ((opt = getopt(argc, argv, "h:H:u:U:p:P:C:O:e:M:m:g:r:R:c:t:T:n:bqdsLfFVv:w:Z:")) != EOF) { switch (opt) { case 'h': if (_psAudit->HostType) { writeError(ERR_ALERT, "Options 'h' and 'H' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pGlobalHost = malloc( strlen(optarg) + 1 ); memset(_psAudit->pGlobalHost, 0, strlen(optarg) + 1); strncpy(_psAudit->pGlobalHost, optarg, strlen(optarg)); _psAudit->HostType = L_SINGLE; } break; case 'H': if (_psAudit->HostType) { writeError(ERR_ALERT, "Options 'h' and 'H' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pOptHost = malloc( strlen(optarg) + 1 ); memset(_psAudit->pOptHost, 0, strlen(optarg) + 1); strncpy(_psAudit->pOptHost, optarg, strlen(optarg)); _psAudit->HostType = L_FILE; } break; case 'u': if (_psAudit->UserType) { writeError(ERR_ALERT, "Options 'u' and 'U' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pGlobalUser = malloc( strlen(optarg) + 1 ); memset(_psAudit->pGlobalUser, 0, strlen(optarg) + 1); strncpy(_psAudit->pGlobalUser, optarg, strlen(optarg)); _psAudit->UserType = L_SINGLE; _psAudit->iUserCnt = 1; } break; case 'U': if (_psAudit->UserType) { writeError(ERR_ALERT, "Options 'u' and 'U' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pOptUser = malloc( strlen(optarg) + 1 ); memset(_psAudit->pOptUser, 0, strlen(optarg) + 1); strncpy(_psAudit->pOptUser, optarg, strlen(optarg)); _psAudit->UserType = L_FILE; } break; case 'p': if (_psAudit->PassType) { writeError(ERR_ALERT, "Options 'p' and 'P' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pGlobalPass = malloc( strlen(optarg) + 2 ); memset(_psAudit->pGlobalPass, 0, strlen(optarg) + 2); strncpy(_psAudit->pGlobalPass, optarg, strlen(optarg)); _psAudit->PassType = L_SINGLE; _psAudit->iPassCnt = 1; } break; case 'P': if (_psAudit->PassType) { writeError(ERR_ALERT, "Options 'p' and 'P' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pOptPass = malloc( strlen(optarg) + 1 ); memset(_psAudit->pOptPass, 0, strlen(optarg) + 1); strncpy(_psAudit->pOptPass, optarg, strlen(optarg)); _psAudit->PassType = L_FILE; } break; case 'C': _psAudit->pOptCombo = malloc( strlen(optarg) + 1 ); memset(_psAudit->pOptCombo, 0, strlen(optarg) + 1); strncpy(_psAudit->pOptCombo, optarg, strlen(optarg)); break; case 'O': _psAudit->pOptOutput = malloc( strlen(optarg) + 1 ); memset(_psAudit->pOptOutput, 0, strlen(optarg) + 1); strncpy(_psAudit->pOptOutput, optarg, strlen(optarg)); break; case 'e': if (strcmp(optarg, "n") == 0) { _psAudit->iPasswordBlankFlag = TRUE; _psAudit->iPasswordUsernameFlag = FALSE; } else if (strcmp(optarg, "s") == 0) { _psAudit->iPasswordBlankFlag = FALSE; _psAudit->iPasswordUsernameFlag = TRUE; } else if ((strcmp(optarg, "ns") == 0) || (strcmp(optarg, "sn") == 0)) { _psAudit->iPasswordBlankFlag = TRUE; _psAudit->iPasswordUsernameFlag = TRUE; } else { writeError(ERR_ALERT, "Option 'e' requires value of n, s, or ns."); ret = EXIT_FAILURE; } break; case 's': _psAudit->iUseSSL = 1; break; case 'L': _psAudit->iParallelLoginFlag = PARALLEL_LOGINS_USER; break; case 'f': _psAudit->iFoundPairExitFlag = FOUND_PAIR_EXIT_HOST; break; case 'F': _psAudit->iFoundPairExitFlag = FOUND_PAIR_EXIT_AUDIT; break; case 't': _psAudit->iLoginCnt = atoi(optarg); break; case 'T': _psAudit->iServerCnt = atoi(optarg); break; case 'n': _psAudit->iPortOverride = atoi(optarg); break; case 'v': iVerboseLevel = atoi(optarg); break; case 'w': iErrorLevel = atoi(optarg); break; case 'V': writeVerbose(VB_EXIT, ""); // Terminate now break; case 'M': szModuleName = malloc(strlen(optarg) + 1); memset(szModuleName, 0, strlen(optarg) + 1); strncpy(szModuleName, optarg, strlen(optarg)); _psAudit->pModuleName = szModuleName; break; case 'm': nModuleParamCount++; szTempModuleParam = malloc(strlen(optarg) + 1); memset(szTempModuleParam, 0, strlen(optarg) + 1); strncpy(szTempModuleParam, optarg, strlen(optarg)); arrModuleParams = realloc(arrModuleParams, nModuleParamCount * sizeof(char*)); arrModuleParams[nModuleParamCount - 1] = szTempModuleParam; break; case 'd': listModules(szModulePaths, 1); // End the program after this executes by passing a 1 as the second param break; case 'b': // Do nothing - supression of the startup banner is handled before the switch statement break; case 'q': _psAudit->iShowModuleHelp = 1; break; case 'g': _psAudit->iTimeout = atoi(optarg); break; case 'r': _psAudit->iRetryWait = atoi(optarg); break; case 'R': _psAudit->iRetries = atoi(optarg); break; case 'c': _psAudit->iSocketWait = atoi(optarg); break; case 'Z': _psAudit->pOptResume = malloc( strlen(optarg) + 1 ); memset(_psAudit->pOptResume, 0, strlen(optarg) + 1); strncpy(_psAudit->pOptResume, optarg, strlen(optarg)); break; default: writeError(ERR_CRITICAL, "Unknown error processing command-line options."); ret = EXIT_FAILURE; } } if (argc <= 1) { ret = EXIT_FAILURE; } if (_psAudit->iShowModuleHelp) { ret = invokeModule(_psAudit->pModuleName, NULL, NULL, NULL); if (ret < 0) { writeError(ERR_CRITICAL, "invokeModule failed - see previous errors for an explanation"); } } else { if ( !((_psAudit->HostType) || (_psAudit->pOptCombo)) ) { writeError(ERR_ALERT, "Host information must be supplied."); ret = EXIT_FAILURE; } else if ( !((_psAudit->UserType) || (_psAudit->pOptCombo)) ) { writeError(ERR_ALERT, "User logon information must be supplied."); ret = EXIT_FAILURE; } else if ( !((_psAudit->PassType) || (_psAudit->pOptCombo) || (_psAudit->iPasswordBlankFlag) || ( _psAudit->iPasswordUsernameFlag)) ) { writeError(ERR_ALERT, "Password information must be supplied."); ret = EXIT_FAILURE; } } return ret; } int invokeModule(char* pModuleName, sLogin* pLogin, int argc, char* argv[]) { void *pLibrary; int iReturn; function_go pGo; function_showUsage pUsage; char* modPath; int nPathLength; int i; int nSuccess = 0; iReturn = -1; pLibrary = NULL; pGo = NULL; pUsage = NULL; if (NULL == pModuleName) { listModules(szModulePaths, 0); writeError(ERR_CRITICAL, "invokeModule called with no name"); return -1; } // Find the first available path to use for(i = 0; i < 3; i++) { if (szModulePaths[i] != NULL) { // Is the module available under here? writeError(ERR_DEBUG, "Trying module path of %s", szModulePaths[i]); nPathLength = strlen(szModulePaths[i]) + strlen(pModuleName) + strlen(MODULE_EXTENSION) + 2; // Going to add a slash too modPath = malloc(nPathLength); memset(modPath, 0, nPathLength); strncpy(modPath, szModulePaths[i], strlen(szModulePaths[i])); strncat(modPath, "/", 1); strncat(modPath, pModuleName, strlen(pModuleName)); strncat(modPath, MODULE_EXTENSION, strlen(MODULE_EXTENSION)); // Now try the load writeError(ERR_DEBUG, "Attempting to load %s", modPath); pLibrary = dlopen(modPath, RTLD_NOW); if (pLibrary == NULL) { continue; } else if (!pLogin) { pUsage = (function_showUsage)dlsym(pLibrary, "showUsage"); writeError(ERR_DEBUG, "Attempting to display usage information for module: %s", modPath); if (pUsage == NULL) { writeError(ERR_ALERT, "Couldn't get a pointer to \"showUsage\" for module %s [%s]", modPath, dlerror()); return -1; } else { nSuccess = 1; pUsage(); } dlclose(pLibrary); exit(EXIT_SUCCESS); // TEMP FIX } else { pGo = (function_go)dlsym(pLibrary, "go"); if (pGo == NULL) { writeError(ERR_ALERT, "Couldn't get a pointer to \"go\" for module %s [%s]", modPath, dlerror()); return -1; } else { nSuccess = 1; iReturn = pGo(pLogin, argc, argv); break; } dlclose(pLibrary); } } } if (!nSuccess) { writeVerbose(VB_IMPORTANT, "Couldn't load \"%s\" [%s]. Place the module in the medusa directory, set the MEDUSA_MODULE_NAME environment variable or run the configure script again using --with-default-mod-path=[path].", pModuleName, dlerror()); iReturn = -1; } return iReturn; } /* Read the contents of a user supplied file. Store contents in memory and provide a count of the total file lines processed. */ void loadFile(char *pFile, char **pFileContent, int *iFileCnt) { FILE *pfFile; size_t stFileSize = 0; char tmp[MAX_BUF]; char *ptr; *iFileCnt = 0; if ((pfFile = fopen(pFile, "r")) == NULL) { writeError(ERR_FATAL, "Failed to open file %s - %s", pFile, strerror( errno ) ); } else { /* get file stats */ while (! feof(pfFile) ) { if ( fgets(tmp, MAX_BUF, pfFile) != NULL ) { if (tmp[0] != '\0') { stFileSize += strlen(tmp) + 1; (*iFileCnt)++; } } } rewind(pfFile); *pFileContent = malloc(stFileSize + 1); /* extra end NULL */ if (pFileContent == NULL) { writeError(ERR_FATAL, "Failed to allocate memory for file %s.", pFile); } memset(*pFileContent, 0, stFileSize + 1); ptr = *pFileContent; /* load file into mem */ while (! feof(pfFile) ) { if (fgets(tmp, MAX_BUF, pfFile) != NULL) { /* ignore blank lines */ if ((tmp[0] == '\n') || (tmp[0] == '\r')) { (*iFileCnt)--; writeError(ERR_DEBUG, "Ignoring blank line in file: %s. Resetting total count: %d.", pFile, (*iFileCnt)); } else if (tmp[0] != '\0') { if (tmp[strlen(tmp) - 1] == '\n') tmp[strlen(tmp) - 1] = '\0'; if (tmp[strlen(tmp) - 1] == '\r') tmp[strlen(tmp) - 1] = '\0'; memcpy(ptr, tmp, strlen(tmp) + 1); ptr += strlen(tmp) + 1; } } } *ptr = '\0'; /* extra NULL to identify end of list */ } if((*iFileCnt) == 0) { writeError(ERR_FATAL, "Error loading user supplied file (%s) -- file may be empty.", pFile); } free(pFile); return; } /* Examine the first row of the combo file to determine information provided. Combo files are colon separated and in the following format: host:user:password. If any of the three fields are left empty, the respective information should be provided either as a single global value or as a list in a file. The following combinations are possible in the combo file: 1. foo:bar:fud 2. foo:bar: 3. foo:: 4. :bar:fud 5. :bar: 6. ::fud 7. foo::fud Medusa also supports using PwDump files as a combo file. The format of these files should be user:id:lm:ntlm. We look for ':::' at the end of the first line to determine if the file contains PwDump output. In addition, a LM/NTLM hash pair can be supplied in lieu of a password (e.g. host:user:lm:ntlm). */ int processComboFile(sAudit **_psAudit) { int ret = 0, iColonCount = 0; char *pComboTmp; writeError(ERR_DEBUG, "[processComboFile] Processing user supplied combo file."); pComboTmp = (*_psAudit)->pGlobalCombo; /* PwDump file check */ /* USERNAME:ID:LM HASH:NTLM HASH::: */ writeError(ERR_DEBUG, "[processComboFile] PwDump file check."); while (*pComboTmp != '\0') { if (strcmp(pComboTmp, ":::") == 0) { iColonCount += 3; pComboTmp += 3; } else if (*pComboTmp == ':') { iColonCount++; pComboTmp++; } else { pComboTmp++; } if ((iColonCount == 6) && (*pComboTmp == '\0')) { writeError(ERR_DEBUG, "[processComboFile] Combo format scan detected PwDump file."); if (((*_psAudit)->HostType != L_SINGLE) && ((*_psAudit)->HostType != L_FILE)) { writeError(ERR_FATAL, "Combo format used requires host information via (-h/-H)."); } if (((*_psAudit)->UserType != L_SINGLE) && ((*_psAudit)->UserType != L_FILE)) { (*_psAudit)->UserType = L_PWDUMP; } (*_psAudit)->PassType = L_PWDUMP; return ret; } } if ( ! ((iColonCount == 2) || (iColonCount == 3)) ) { writeError(ERR_DEBUG, "[processComboFile] Number of colons detected in first entry: %d", iColonCount); writeError(ERR_FATAL, "Invalid combo file format."); } pComboTmp = (*_psAudit)->pGlobalCombo; if (*pComboTmp == ':') { /* no host specified */ writeError(ERR_DEBUG, "[processComboFile] No host combo field specified."); if (((*_psAudit)->HostType != L_SINGLE) && ((*_psAudit)->HostType != L_FILE)) { writeError(ERR_FATAL, "Combo format used requires host information via (-h/-H)."); } } else { writeError(ERR_DEBUG, "[processComboFile] Host combo field specified."); (*_psAudit)->HostType = L_COMBO; while (*pComboTmp != ':') { if (pComboTmp == NULL) { writeError(ERR_FATAL, "Failed to process combo file. Incorrect format."); } pComboTmp++; } } pComboTmp++; if (*pComboTmp == ':') { /* no user specified */ writeError(ERR_DEBUG, "[processComboFile] No user combo field specified."); if (((*_psAudit)->UserType != L_SINGLE) && ((*_psAudit)->UserType != L_FILE)) { writeError(ERR_FATAL, "Combo format used requires user information via (-u/-U)."); } } else { writeError(ERR_DEBUG, "[processComboFile] User combo field specified."); (*_psAudit)->UserType = L_COMBO; while (*pComboTmp != ':') { if (pComboTmp == NULL) { writeError(ERR_FATAL, "Failed to process combo file. Incorrect format."); } pComboTmp++; } } pComboTmp++; if (*pComboTmp == '\0') { /* no password specified */ writeError(ERR_DEBUG, "[processComboFile] No password combo field specified."); if (((*_psAudit)->PassType != L_SINGLE) && ((*_psAudit)->PassType != L_FILE) && ((*_psAudit)->iPasswordBlankFlag == FALSE) && ((*_psAudit)->iPasswordUsernameFlag == FALSE)) { writeError(ERR_FATAL, "Combo format used requires password information via (-p/-P)."); } } else { writeError(ERR_DEBUG, "[processComboFile] Password combo field specified."); (*_psAudit)->PassType = L_COMBO; } return ret; } /* Return next user-specified host during audit data table building process. This host information may be a single global entry, from a file containing a list of hosts, or from a combo file. */ char* findNextHost(sAudit *_psAudit, char *_pHost) { if (_psAudit->pGlobalCombo) { writeError(ERR_DEBUG, "[findNextHost] Process global combo file."); /* advance to next entry in combo list */ if ((_psAudit->iUserListFlag == LIST_COMPLETE) && (_psAudit->iHostListFlag == LIST_COMPLETE)) { writeError(ERR_DEBUG, "[findNextHost] Advance to next entry in combo list."); /* skip host */ while (*_psAudit->pGlobalCombo != '\0') _psAudit->pGlobalCombo++; _psAudit->pGlobalCombo++; /* skip user */ while (*_psAudit->pGlobalCombo != '\0') _psAudit->pGlobalCombo++; _psAudit->pGlobalCombo++; /* skip pass */ while (*_psAudit->pGlobalCombo != '\0') _psAudit->pGlobalCombo++; _psAudit->pGlobalCombo++; if (*_psAudit->pGlobalCombo == '\0') { _psAudit->iAuditFlag = AUDIT_COMPLETE; } else { _psAudit->iAuditFlag = AUDIT_IN_PROGRESS; } } /* convert ':' to '\0' in combo entries */ if ((_psAudit->pComboEntryTmp == NULL) || ((_psAudit->iUserListFlag == LIST_COMPLETE) && (_psAudit->iHostListFlag == LIST_COMPLETE))) { writeError(ERR_DEBUG, "[findNextHost] Convert ':' to '\\0' in combo entries."); _psAudit->pComboEntryTmp = _psAudit->pGlobalCombo; if (*_psAudit->pComboEntryTmp != '\0') { /* host:user ==> host\0user */ while (*_psAudit->pComboEntryTmp != ':') _psAudit->pComboEntryTmp++; memset(_psAudit->pComboEntryTmp, 0, 1); /* user:pass ==> user\0pass */ while (*_psAudit->pComboEntryTmp != ':') _psAudit->pComboEntryTmp++; memset(_psAudit->pComboEntryTmp, 0, 1); } } _psAudit->pComboEntryTmp = _psAudit->pGlobalCombo; } else { if ((_psAudit->iUserListFlag == LIST_COMPLETE) && (_psAudit->iHostListFlag == LIST_COMPLETE)) { _psAudit->iAuditFlag = AUDIT_COMPLETE; } } _psAudit->iHostListFlag = LIST_COMPLETE; if (_psAudit->iAuditFlag == AUDIT_COMPLETE) { _pHost = NULL; } else if (_psAudit->HostType == L_COMBO) { if (*_psAudit->pGlobalCombo == '\0') { _pHost = NULL; } else { _pHost = _psAudit->pGlobalCombo; } } else if (_psAudit->HostType == L_FILE) { if (*_psAudit->pGlobalHost != '\0') { _pHost = _psAudit->pGlobalHost; /* advancing host list */ while (*_psAudit->pGlobalHost != '\0') _psAudit->pGlobalHost++; _psAudit->pGlobalHost++; if (*_psAudit->pGlobalHost != '\0') { _psAudit->iHostListFlag = LIST_IN_PROGRESS; } else { /* resetting host list */ _psAudit->pGlobalHost = _psAudit->pHostFile; } } } else if (_psAudit->HostType == L_SINGLE) { _pHost = _psAudit->pGlobalHost; _psAudit->iAuditFlag = AUDIT_COMPLETE; } else { writeError(ERR_FATAL, "[findNextHost] HostType not properly defined."); } return _pHost; } /* Return next user-specified user during audit data table building process. This host information may be a single global entry, from a file containing a list of users, or from a combo file. */ char* findNextUser(sAudit *_psAudit, char *_pUser) { char* pComboTmp; _psAudit->iUserListFlag = LIST_COMPLETE; if (_psAudit->UserType == L_COMBO) { /* advance to username */ if (_psAudit->pGlobalCombo) { pComboTmp = _psAudit->pComboEntryTmp; while (*pComboTmp != '\0') pComboTmp++; pComboTmp++; } if (_pUser != NULL) _pUser = NULL; else _pUser = pComboTmp; writeError(ERR_DEBUG, "[findNextUser] Combo User: %s", _pUser); } else if (_psAudit->UserType == L_PWDUMP) { if (_pUser != NULL) _pUser = NULL; else _pUser = _psAudit->pComboEntryTmp; writeError(ERR_DEBUG, "[findNextUser] PwDump User: %s", _pUser); } else if (_psAudit->UserType == L_FILE) { _pUser = _psAudit->pGlobalUser; if (*_psAudit->pGlobalUser != '\0') { /* advance user list pointer */ while (*_psAudit->pGlobalUser != '\0') _psAudit->pGlobalUser++; _psAudit->pGlobalUser++; _psAudit->iUserListFlag = LIST_IN_PROGRESS; } else { /* reset list */ _psAudit->pGlobalUser = _psAudit->pUserFile; _pUser = NULL; } writeError(ERR_DEBUG, "[findNextUser] L_FILE User: %s", _pUser); } else if (_psAudit->UserType == L_SINGLE) { if (_pUser != NULL) _pUser = NULL; else _pUser = _psAudit->pGlobalUser; } else { writeError(ERR_FATAL, "[findNextUser] UserType (%d) not properly defined.", _psAudit->UserType); } return _pUser; } /* Return next user-specified password during audit data table building process. This password information is only from the combo file. */ char* findLocalPass(sAudit *_psAudit) { char *pPass; char *pComboTmp; if ((_psAudit->PassType == L_COMBO) || (_psAudit->PassType == L_PWDUMP)) { /* advance to password */ if (_psAudit->pGlobalCombo) { pComboTmp = _psAudit->pComboEntryTmp; while (*pComboTmp != '\0') pComboTmp++; pComboTmp++; while (*pComboTmp != '\0') pComboTmp++; pComboTmp++; } pPass = pComboTmp; writeError(ERR_DEBUG, "[findLocalPass] pPass: %s", pPass); } else { pPass = NULL; } return pPass; } int loadLoginInfo(sAudit *_psAudit) { int res; sHost *psHost = NULL; sHost *psHostPrevTmp = NULL; char *pHost = NULL; sUser *psUser = NULL; char *pUser = NULL; sPass *psPass = NULL; char *pPass = NULL; /* initialize / reset */ _psAudit->iHostCnt = 0; _psAudit->iHostsDone = 0; while ((pHost = findNextHost(_psAudit, pHost))) { /* combo file: search list to see if host has already been added */ psHost = _psAudit->psHostRoot; while (psHost) { if ( strcmp(pHost,psHost->pHost) ) psHost = psHost->psHostNext; else break; } /* create new host table in list */ if (psHost == NULL) { _psAudit->iHostCnt++; psHost = malloc(sizeof(sHost)); memset(psHost, 0, sizeof(sHost)); /* set root pointer if this is the first host */ if (_psAudit->psHostRoot == NULL) { _psAudit->psHostRoot = psHost; psHostPrevTmp = _psAudit->psHostRoot; } else { psHostPrevTmp->psHostNext = psHost; psHostPrevTmp = psHost; } psHost->pHost = malloc( strlen(pHost) + 1 ); memset(psHost->pHost, 0, strlen(pHost) + 1); strncpy(psHost->pHost, pHost, strlen(pHost) + 1); psHost->iPortOverride = _psAudit->iPortOverride; psHost->iUseSSL = _psAudit->iUseSSL; psHost->iTimeout = _psAudit->iTimeout; psHost->iRetryWait = _psAudit->iRetryWait; psHost->iRetries = _psAudit->iRetries; psHost->iUserCnt = 0; psHost->iId = _psAudit->iHostCnt; } while ((pUser = findNextUser(_psAudit, pUser))) { /* combo file: search list to see if user has already been added */ psUser = psHost->psUser; while (psUser) { if ( strcmp(pUser,psUser->pUser) ) psUser = psUser->psUserNext; else break; } /* create new user table in list */ if (psUser == NULL) { psHost->iUserCnt++; psUser = malloc(sizeof(sUser)); memset(psUser, 0, sizeof(sUser)); if (psHost->psUserPrevTmp) { /* setting host next user pointer */ psHost->psUserPrevTmp->psUserNext = psUser; } else { /* setting host root user pointer */ psHost->psUser = psUser; } psHost->psUserPrevTmp = psUser; psUser->pUser = malloc( strlen(pUser) + 1 ); memset(psUser->pUser, 0, strlen(pUser) + 1); strncpy(psUser->pUser, pUser, strlen(pUser)); psUser->iPassCnt = _psAudit->iPassCnt; psUser->iPassStatus = PL_UNSET; psUser->iId = psHost->iUserCnt; psHost->iUserPassCnt += _psAudit->iPassCnt; if (_psAudit->iPasswordUsernameFlag) { psHost->iUserPassCnt++; psUser->iPassCnt++; } if (_psAudit->iPasswordBlankFlag) { psHost->iUserPassCnt++; psUser->iPassCnt++; } } pPass = findLocalPass(_psAudit); if (pPass) { psPass = malloc(sizeof(sPass)); memset(psPass, 0, sizeof(sPass)); psPass->pPass = malloc( strlen(pPass) + 1 ); memset(psPass->pPass, 0, strlen(pPass) + 1); strncpy(psPass->pPass, pPass, strlen(pPass)); psUser->iPassCnt++; psHost->iUserPassCnt++; if (psUser->psPassPrevTmp) { /* setting user next pass pointer */ psUser->psPassPrevTmp->psPassNext = psPass; } else { /* setting user root pass pointer */ psUser->psPass = psPass; psUser->psPassCurrent = psPass; } psUser->psPassPrevTmp = psPass; } } } return SUCCESS; } /* Grab the next password for a particular user */ char* getNextPass(sLogin *_psLogin) { sAudit *_psAudit = _psLogin->psServer->psAudit; sUser *_psUser = _psLogin->psUser; char *pPass = NULL; /* is this user's password list complete? */ if ((_psUser->iPassStatus != PL_DONE) && (_psUser->iPassStatus != PASS_AUDIT_COMPLETE)) { /* is this the user's first password request? */ if (_psUser->iPassStatus == PL_UNSET) _psUser->iPassStatus = PL_NULL; /* process blank password or password matching username */ if ((_psUser->iPassStatus == PL_NULL) || (_psUser->iPassStatus == PL_USERNAME)) { if ((_psUser->iPassStatus == PL_NULL) && (_psAudit->iPasswordBlankFlag)) { pPass = ""; _psUser->iPassStatus = PL_USERNAME; } else if (_psAudit->iPasswordUsernameFlag) { pPass = _psUser->pUser; _psUser->iPassStatus = PL_LOCAL; } else { _psUser->iPassStatus = PL_LOCAL; } } if (pPass == NULL ) { /* process local passwords - i.e. passwords specified within combo file for user */ if ((_psUser->iPassStatus == PL_LOCAL) && (_psUser->psPassCurrent)) { pPass = _psUser->psPassCurrent->pPass; _psUser->psPassCurrent = _psUser->psPassCurrent->psPassNext; } /* process global passwords - i.e. passwords specified via "-p" or "-P" options */ else if (_psAudit->pGlobalPass) { _psUser->iPassStatus = PL_GLOBAL; if (_psUser->pPass) { while (*_psUser->pPass != '\0') _psUser->pPass++; _psUser->pPass++; if (*_psUser->pPass != '\0') { pPass = _psUser->pPass; } else { /* password auditing of host is complete */ _psUser->iPassStatus = PL_DONE; _psLogin->psServer->psHost->iUsersDone++; } } else { _psUser->pPass = _psAudit->pGlobalPass; pPass = _psUser->pPass; } } else { /* password auditing of host is complete */ _psUser->iPassStatus = PL_DONE; _psLogin->psServer->psHost->iUsersDone++; } } } return pPass; } /* Generates the next credential set for login module to test. The module is responsible for allocating and releasing memory used for the credential set. */ int getNextNormalCredSet(sLogin *_psLogin, sCredentialSet *_psCredSet) { int nUserListChecked = FALSE; _psCredSet->iStatus = CREDENTIAL_SAME_USER; /* is this the first user for a login thread? */ if (_psLogin->psUser == NULL) { writeError(ERR_DEBUG, "[getNextNormalCred] Initial credential set request for login module."); _psLogin->psServer->psHost->iUserStatus = UL_NORMAL; _psCredSet->iStatus = CREDENTIAL_NEW_USER; /* multiple login threads of same user */ if (_psLogin->psServer->psAudit->iParallelLoginFlag == PARALLEL_LOGINS_PASSWORD) { if (_psLogin->psServer->psHost->psUserCurrent == NULL) _psLogin->psServer->psHost->psUserCurrent = _psLogin->psServer->psHost->psUser; _psLogin->psUser = _psLogin->psServer->psHost->psUserCurrent; if (_psLogin->psUser) writeError(ERR_DEBUG, "[getNextNormalCred] (PARALLEL_LOGINS_PASSWORD) setting user: %s", _psLogin->psUser->pUser); } /* multiple login threads of one unique user per thread */ else { /* only increment user pointer if this is not the first module */ if (_psLogin->psServer->psHost->psUserCurrent == NULL) { writeError(ERR_DEBUG, "[getNextNormalCred] Assigning initial user for host being tested."); _psLogin->psServer->psHost->psUserCurrent = _psLogin->psServer->psHost->psUser; _psLogin->psUser = _psLogin->psServer->psHost->psUserCurrent; //_psLogin->psServer->psHost->iUserStatus = UL_NORMAL; } else { writeError(ERR_DEBUG, "[getNextNormalCred] Assigning next available user for host being tested."); _psLogin->psUser = _psLogin->psServer->psHost->psUserCurrent->psUserNext; _psLogin->psServer->psHost->psUserCurrent = _psLogin->psUser; } if (_psLogin->psUser) writeError(ERR_DEBUG, "[getNextNormalCred] (PARALLEL_LOGINS_USER) setting NEW user: %s", _psLogin->psUser->pUser); } } /* find next available password - if password list is exhausted for user, move on to the next user */ while ((_psLogin->psUser) && ((_psCredSet->pPass = getNextPass(_psLogin)) == NULL)) { /* is password testing for user complete */ if ((_psLogin->psUser->iPassStatus == PL_DONE) || (_psLogin->psUser->iPassStatus == PASS_AUDIT_COMPLETE)) { writeError(ERR_INFO, "Login Module: %d - Current user password list is complete, selecting next user.", _psLogin->iId); if (_psLogin->psServer->psHost->psUserCurrent == NULL) { _psLogin->psUser = NULL; } else { _psLogin->psUser = _psLogin->psServer->psHost->psUserCurrent->psUserNext; _psLogin->psServer->psHost->psUserCurrent = _psLogin->psUser; } if (_psLogin->psUser == NULL) { /* end of list - check entire list for unfinished credentials */ if (nUserListChecked == FALSE) { writeError(ERR_INFO, "Login Module: %d - Current user password list is complete, rescanning userlist for unfinished credentials.", _psLogin->iId); _psLogin->psUser = _psLogin->psServer->psHost->psUser; _psLogin->psServer->psHost->psUserCurrent = _psLogin->psUser; nUserListChecked = TRUE; } else { writeError(ERR_INFO, "Login Module: %d - No more user accounts available for testing.", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; } } else { writeError(ERR_INFO, "Login Module: %d - Selecting next password for user: %s", _psLogin->iId, _psLogin->psUser->pUser); _psCredSet->iStatus = CREDENTIAL_NEW_USER; } } } if ((_psLogin->psUser == NULL) || (_psCredSet->pPass == NULL)) { //writeError(ERR_INFO, "Login Module: %d - No more available users/passwords, setting credential status to CREDENTIAL_DONE.", _psLogin->iId); writeError(ERR_INFO, "Login Module: %d - No more users/passwords available in the normal queue.", _psLogin->iId); //_psCredSet->iStatus = CREDENTIAL_DONE; _psLogin->psServer->psHost->iUserStatus = UL_MISSED; } _psCredSet->psUser = _psLogin->psUser; return SUCCESS; } /* In certain situations we need to scale back the number of concurrent login threads targetting a specific service. For example, MSDE's workload governor limits the service to no more than 5 concurrent connections. If the user kicked-off 10 parallel login threads, 5 of those are going to fail and terminate. The challenge is that each of those threads was already assigned a credential set to test. The addMissedCredSet() function creates a linked list of credentials which were not tested for a given host. This function retrieves the next credential set from that list for testing. */ int getNextMissedCredSet(sLogin *_psLogin, sCredentialSet *_psCredSet) { sCredentialSet *psCredSetMissed = NULL; writeError(ERR_DEBUG, "Retrieving the next available credential set from list of previously missed sets."); /* skip credential if user testing is complete (e.g. password found, account locked) */ psCredSetMissed = _psLogin->psServer->psCredentialSetMissedCurrent; while ((psCredSetMissed) && (psCredSetMissed->psUser->iPassStatus == PASS_AUDIT_COMPLETE)) { psCredSetMissed = _psLogin->psServer->psCredentialSetMissedCurrent->psCredentialSetNext; _psLogin->psServer->psCredentialSetMissedCurrent = psCredSetMissed; } /* located next credential set that was not previously tested */ if (psCredSetMissed) { _psCredSet->psUser = psCredSetMissed->psUser; _psCredSet->pPass = psCredSetMissed->pPass; _psLogin->psServer->psCredentialSetMissedCurrent = psCredSetMissed->psCredentialSetNext; if (_psLogin->psUser == _psCredSet->psUser) _psCredSet->iStatus = CREDENTIAL_SAME_USER; else _psCredSet->iStatus = CREDENTIAL_NEW_USER; _psLogin->psServer->iCredentialsMissed--; writeError(ERR_DEBUG, "Login Module: %d - Selected next credential set from list of previously missed sets (%s/%s).", _psLogin->iId, _psCredSet->psUser->pUser, _psCredSet->pPass); } else { writeError(ERR_INFO, "Login Module: %d - No additional missed users/passwords, setting credential status to CREDENTIAL_DONE.", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; _psLogin->psServer->psHost->iUserStatus = UL_DONE; } _psLogin->psUser = _psCredSet->psUser; return SUCCESS; } /* Function returns next available username and password to module for testing. The normal host's list of users and their respective passwords (local, global, etc) are tested first. If any credential sets were not successfully tested (module instance died for some reason) they re-checked after all normal tests are done. */ int getNextCredSet(sLogin *_psLogin, sCredentialSet *_psCredSet) { if (_psCredSet == NULL) writeError(ERR_FATAL, "getNextCredSet() called, but not supplied allocated memory for _psCredSet"); memset(_psCredSet, 0, sizeof(sCredentialSet)); pthread_mutex_lock(&_psLogin->psServer->ptmMutex); /* terminate all login threads */ if (_psLogin->psServer->psAudit->iStatus == AUDIT_ABORT) { writeError(ERR_INFO, "Audit aborting... notifying login module: %d", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; } /* valid credential set found -- exit host flag set */ else if ((_psLogin->psServer->iValidPairFound) && (_psLogin->psServer->psAudit->iFoundPairExitFlag == FOUND_PAIR_EXIT_HOST)) { writeError(ERR_INFO, "Exiting Login Module: %d [Stop Host Scan After Valid Pair Found Enabled]", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; } /* valid credential set found -- exit audit flag set */ else if ((_psLogin->psServer->psAudit->iValidPairFound) && (_psLogin->psServer->psAudit->iFoundPairExitFlag == FOUND_PAIR_EXIT_AUDIT)) { writeError(ERR_INFO, "Exiting Login Module: %d [Stop Audit Scans After Valid Pair Found Enabled]", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; } else { switch (_psLogin->psServer->psHost->iUserStatus) { case UL_UNSET: case UL_NORMAL: /* check for next available login to perform */ if (getNextNormalCredSet(_psLogin, _psCredSet) != SUCCESS) writeError(ERR_FATAL, "getNextNormalCredSet() function call failed."); /* the normal queue is exhausted - check the missed credentials queue */ if (_psLogin->psServer->psHost->iUserStatus == UL_MISSED) if (getNextMissedCredSet(_psLogin, _psCredSet) != SUCCESS) writeError(ERR_FATAL, "getNextMissedCredSet() function call failed."); break; case UL_MISSED: /* check for next available login missed during normal testing */ if (getNextMissedCredSet(_psLogin, _psCredSet) != SUCCESS) writeError(ERR_FATAL, "getNextMissedCredSet() function call failed."); break; case UL_DONE: writeError(ERR_INFO, "Login Module: %d - No additional users/passwords, setting credential status to CREDENTIAL_DONE.", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; break; default: writeError(ERR_DEBUG, "Login Module: %d - Entered undefined state (%d) within getNextCredSet()", _psLogin->iId, _psLogin->psServer->psHost->iUserStatus); break; } } pthread_mutex_unlock(&_psLogin->psServer->ptmMutex); return SUCCESS; } /* Process password result from login module */ int setPassResult(sLogin *_psLogin, char *_pPass) { pthread_mutex_lock(&_psLogin->psServer->ptmMutex); writeVerbose(VB_CHECK, "[%s] Host: %s (%d of %d, %d complete) User: %s (%d of %d, %d complete) Password: %s (%d of %d complete)", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psServer->psHost->iId, _psLogin->psServer->psAudit->iHostCnt, _psLogin->psServer->psAudit->iHostsDone, _psLogin->psUser->pUser, _psLogin->psUser->iId, _psLogin->psServer->psHost->iUserCnt, _psLogin->psServer->psHost->iUsersDone, _pPass, _psLogin->psUser->iLoginsDone + 1, _psLogin->psUser->iPassCnt ); _psLogin->iLoginsDone++; _psLogin->psUser->iLoginsDone++, _psLogin->psServer->iLoginsDone++; switch (_psLogin->iResult) { case LOGIN_RESULT_SUCCESS: if (_psLogin->pErrorMsg) { writeVerbose(VB_FOUND, "[%s] Host: %s User: %s Password: %s [SUCCESS (%s)]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _pPass, _psLogin->pErrorMsg); free(_psLogin->pErrorMsg); _psLogin->pErrorMsg = NULL; } else writeVerbose(VB_FOUND, "[%s] Host: %s User: %s Password: %s [SUCCESS]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _pPass); _psLogin->psServer->psAudit->iValidPairFound = TRUE; _psLogin->psServer->iValidPairFound = TRUE; _psLogin->psUser->iPassStatus = PASS_AUDIT_COMPLETE; _psLogin->psServer->psHost->iUsersDone++; break; case LOGIN_RESULT_FAIL: if (_psLogin->pErrorMsg) { writeError(ERR_INFO, "[%s] Host: %s User: %s [FAILED (%s)]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _psLogin->pErrorMsg); free(_psLogin->pErrorMsg); _psLogin->pErrorMsg = NULL; } else writeError(ERR_INFO, "[%s] Host: %s User: %s [FAILED]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser); break; case LOGIN_RESULT_ERROR: if (_psLogin->pErrorMsg) { writeVerbose(VB_FOUND, "[%s] Host: %s User: %s Password: %s [ERROR (%s)]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _pPass, _psLogin->pErrorMsg); free(_psLogin->pErrorMsg); _psLogin->pErrorMsg = NULL; } else writeVerbose(VB_FOUND, "[%s] Host: %s User: %s Password: %s [ERROR]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _pPass); _psLogin->psUser->iPassStatus = PASS_AUDIT_COMPLETE; _psLogin->psServer->psHost->iUsersDone++; break; default: writeError(ERR_INFO, "[%s] Host: %s User: %s [UNKNOWN %d]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _psLogin->iResult); break; } pthread_mutex_unlock(&_psLogin->psServer->ptmMutex); } /* In certain situations we need to scale back the number of concurrent login threads targetting a specific service. For example, MSDE's workload governor limits the service to no more than 5 concurrent connections. If the user kicked-off 10 parallel login threads, 5 of those are going to fail and terminate. The challenge is that each of those threads was already assigned a credential set to test. This function creates a list of those credentials so that they can be tested by the remaining threads at the end of their current run. */ int addMissedCredSet(sLogin *_psLogin, sCredentialSet *_psCredSet) { sCredentialSet *psCredSetMissed = NULL; pthread_mutex_lock(&_psLogin->psServer->ptmMutex); writeError(ERR_NOTICE, "[%s] Host: %s - Login thread (%d) prematurely ended. The current number of parallel login threads may exceed what this service can reasonably handle. The total number of threads for this host will be decreased.", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->iId ); if (_psLogin->psServer->iLoginCnt > 1) _psLogin->psServer->iLoginCnt--; writeError(ERR_NOTICE, "[%s] Host: %s User: %s Password: %s - The noted credentials have been added to the end of the queue for testing.", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psCredSet->psUser->pUser, _psCredSet->pPass ); /* build structure for missed credential set */ psCredSetMissed = malloc(sizeof(sCredentialSet)); memset(psCredSetMissed, 0, sizeof(sCredentialSet)); psCredSetMissed->psUser = _psCredSet->psUser; psCredSetMissed->pPass = malloc(strlen(_psCredSet->pPass) + 1); memset(psCredSetMissed->pPass, 0, strlen(_psCredSet->pPass) + 1); strncpy(psCredSetMissed->pPass, _psCredSet->pPass, strlen(_psCredSet->pPass)); /* append structure to host's list of missed credentials */ if (_psLogin->psServer->psCredentialSetMissed == NULL) /* first missed credential set */ { _psLogin->psServer->psCredentialSetMissed = psCredSetMissed; _psLogin->psServer->psCredentialSetMissedCurrent = psCredSetMissed; } else _psLogin->psServer->psCredentialSetMissedTail->psCredentialSetNext = psCredSetMissed; _psLogin->psServer->psCredentialSetMissedTail = psCredSetMissed; _psLogin->psServer->iCredentialsMissed++; pthread_mutex_unlock(&_psLogin->psServer->ptmMutex); } void* startModule(void* pParams) { int64_t nRet = 0; sModuleStart* modParams = (sModuleStart*)pParams; if (NULL == modParams) { writeError(ERR_FATAL, "Bad pointer passed to invokeModule"); nRet = -1; return (void*) nRet; } writeError(ERR_DEBUG, "startModule iId: %d pLogin: %X modParams->argv: %X modParams: %X", modParams->pLogin->iId, modParams->pLogin, modParams->argv, modParams); nRet = invokeModule(modParams->szModuleName, modParams->pLogin, modParams->argc, modParams->argv); if (nRet < 0) { writeVerbose(VB_EXIT, "invokeModule failed - see previous errors for an explanation"); nRet = -1; return (void*) nRet; } return (void*) nRet; // Success } /* Initiate and manage host-specific thread pool for logins. Each target host has a single thread for this purpose. The thread spawns multiple child threads which each initiate the selected module to perform the actual logons. */ void *startLoginThreadPool(void *arg) { sServer *_psServer = (sServer *)arg; thr_pool_t *login_pool = NULL; sLogin psLogin[_psServer->psAudit->iLoginCnt]; sModuleStart modParams[_psServer->psAudit->iLoginCnt]; int iLoginId = 0; int iLoginCnt = _psServer->psAudit->iLoginCnt; struct addrinfo hints, *res; int errcode; void *ptr; writeError(ERR_DEBUG_SERVER, "Server ID: %d Host: %s iUserPassCnt: %d iLoginCnt: %d", _psServer->iId, _psServer->psHost->pHost, _psServer->psHost->iUserPassCnt, iLoginCnt); /* create thread pool - min threads, max threads, linger time, attributes */ if (iLoginCnt > _psServer->psHost->iUserPassCnt) iLoginCnt = _psServer->psHost->iUserPassCnt; if ((login_pool = thr_pool_create(0, iLoginCnt, POOL_THREAD_LINGER, NULL)) == NULL) { writeError(ERR_FATAL, "Failed to create root login thread pool for host: %s", _psServer->psHost->pHost); } /* resolve host name */ _psServer->pHostIP = malloc(100); memset(_psServer->pHostIP, 0, 100); memset(&hints, 0, sizeof (hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags |= AI_CANONNAME; errcode = getaddrinfo(_psServer->psHost->pHost, NULL, &hints, &res); if (errcode != 0) { writeError(ERR_CRITICAL, "Failed to resolve hostname: %s - %s", _psServer->psHost->pHost, gai_strerror(errcode)); return; } if (res->ai_next != NULL) writeError(ERR_ERROR, "Hostname resolved to multiple addresses. Selecting first address for testing."); inet_ntop (res->ai_family, res->ai_addr->sa_data, _psServer->pHostIP, 100); switch (res->ai_family) { case AF_INET: ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; break; case AF_INET6: ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; break; } inet_ntop (res->ai_family, ptr, _psServer->pHostIP, 100); writeError(ERR_DEBUG_SERVER, "Set IPv%d address: %s (%s)",res->ai_family == PF_INET6 ? 6 : 4, _psServer->pHostIP, res->ai_canonname); freeaddrinfo(res); /* add login tasks to pool queue */ for (iLoginId = 0; iLoginId < iLoginCnt; iLoginId++) { writeError(ERR_DEBUG_SERVER, "Adding new login task (%d) to server queue (%d)", iLoginId, _psServer->iId); psLogin[iLoginId].iId = iLoginId; psLogin[iLoginId].psServer = _psServer; psLogin[iLoginId].iResult = LOGIN_RESULT_UNKNOWN; psLogin[iLoginId].pErrorMsg = NULL; psLogin[iLoginId].iLoginsDone = 0; psLogin[iLoginId].psUser = NULL; modParams[iLoginId].szModuleName = szModuleName; modParams[iLoginId].pLogin = &(psLogin[iLoginId]); //psLogin + (iLoginId * sizeof(sLogin)); modParams[iLoginId].argc = nModuleParamCount; modParams[iLoginId].argv = (char**)arrModuleParams; if ( thr_pool_queue(login_pool, startModule, (void *) &modParams[iLoginId]) < 0 ) { writeError(ERR_CRITICAL, "Failed to add module launch task to login thread pool for server queue: %d.", _psServer->iId); return; } } /* wait for login thread pool to finish */ writeError(ERR_DEBUG_SERVER, "waiting for server %d login pool to end", _psServer->iId); thr_pool_wait(login_pool); /* In certain situations we need to scale back the number of concurrent login threads targetting a specific service. For example, MSDE's workload governor limits the service to no more than 5 concurrent connections. If the user kicked-off 10 parallel login threads, 5 of those are going to fail and terminate. The challenge is that each of those threads was already assigned a credential set to test. When these threads failed, we pushed the missed credentials into a queue assigned to the target host. This queue may already have been taken care of by running threads when they finished their normal tasks. However, if the missed logons were pushed to the queue by exiting threads after the other threads had terminated, they are still sitting there. To deal with this problem, we kick off a single thread to run through these. */ iLoginId = 0; if ((_psServer->psAudit->iStatus != AUDIT_ABORT) && (_psServer->iCredentialsMissed > 0)) { writeError(ERR_DEBUG_SERVER, "Adding new clean-up login task to server queue (%d) for %d missed logins", _psServer->iId, _psServer->iCredentialsMissed); _psServer->psHost->iUserStatus = UL_MISSED; psLogin[iLoginId].iResult = LOGIN_RESULT_UNKNOWN; psLogin[iLoginId].pErrorMsg = NULL; psLogin[iLoginId].psUser = NULL; if ( thr_pool_queue(login_pool, startModule, (void *) &modParams[iLoginId]) < 0 ) { writeError(ERR_CRITICAL, "Failed to add module launch task to login thread pool for server queue: %d.", _psServer->iId); return; } /* wait for login thread pool to finish */ writeError(ERR_DEBUG_SERVER, "waiting for server %d login pool to end", _psServer->iId); thr_pool_wait(login_pool); } writeError(ERR_DEBUG_SERVER, "destroying server %d login pool", _psServer->iId); thr_pool_destroy(login_pool); /* track the number of hosts which have been completed */ pthread_mutex_lock(&_psServer->psAudit->ptmMutex); _psServer->psAudit->iHostsDone++; pthread_mutex_unlock(&_psServer->psAudit->ptmMutex); /* The logon modules for server have all terminated, however, the server's userlist is not marked as completed. This may be due to the module exiting prematurely (e.g. the service being tested became unavailable). We mark the host as UL_ERROR to avoid having it added to the resume list. */ if ((_psServer->psAudit->iStatus != AUDIT_ABORT) && ((_psServer->psHost->iUserStatus == UL_NORMAL) || (_psServer->psHost->iUserStatus == UL_MISSED))) { writeError(ERR_DEBUG_SERVER, "Server thread exiting and server's userlist testing was marked as in progress. Was this host prematurely aborted?"); _psServer->psHost->iUserStatus = UL_ERROR; } writeError(ERR_DEBUG_SERVER, "exiting server: %d", _psServer->iId); free(_psServer->pHostIP); return; } /* Initiate and manage thread pool for target systems. Each target host will have a single parent thread, which manages all childs login threads specific to that individual machine. */ int startServerThreadPool(sAudit *_psAudit) { sServer psServer[_psAudit->iHostCnt]; sHost *psHost; int iServerId; sUser *psUser; char *szResumeMap = NULL; char *szUserMap = NULL; int nAddHost; int nUserMapSize; int nFirstNewHostFound; int nFirstNewUserFound; char szTmp[11]; char szTmp1[11]; char szTmp2[11]; writeVerbose(VB_GENERAL, "Parallel Hosts: %d Parallel Logins: %d", _psAudit->iServerCnt, _psAudit->iLoginCnt); writeVerbose(VB_GENERAL, "Total Hosts: %d ", _psAudit->iHostCnt); if (_psAudit->iUserCnt == 0) writeVerbose(VB_GENERAL, "Total Users: [combo]"); else writeVerbose(VB_GENERAL, "Total Users: %d", _psAudit->iUserCnt); if (_psAudit->iPassCnt == 0) writeVerbose(VB_GENERAL, "Total Passwords: [combo]"); else writeVerbose(VB_GENERAL, "Total Passwords: %d", _psAudit->iPassCnt); /* create thread pool - min threads, max threads, linger time, attributes */ if (_psAudit->iServerCnt > _psAudit->iHostCnt) _psAudit->iServerCnt = _psAudit->iHostCnt; /* initialize global crypto (OpenSSL, Libgcrypt) variables */ init_crypto_locks(); if ((_psAudit->server_pool = thr_pool_create(0, _psAudit->iServerCnt, POOL_THREAD_LINGER, NULL)) == NULL) { writeError(ERR_ERROR, "Failed to create root server thread pool."); return FAILURE; } /* initialize servers */ memset(psServer, 0, sizeof(sServer) * _psAudit->iHostCnt); psHost = _psAudit->psHostRoot; nFirstNewHostFound = FALSE; /* add server tasks to pool queue (one task per host to be tested) */ for (iServerId = 0; iServerId < _psAudit->iHostCnt; iServerId++) { /* resume map was supplied by user - skip hosts and users which were previously completed */ nAddHost = TRUE; if (_psAudit->pOptResume) { memset(szTmp, 0, 11); memset(szTmp1, 0, 11); snprintf(szTmp, 10, "h%d.", psHost->iId); snprintf(szTmp1, 10, "h%du", psHost->iId); if (nFirstNewHostFound == TRUE) { writeError(ERR_DEBUG_SERVER, "[Host Resume] Adding host: %d (we've passed the point of the previous run)", psHost->iId); } else if (szResumeMap = strstr(_psAudit->pOptResume, szTmp1)) { writeError(ERR_DEBUG_SERVER, "[Host Resume] Adding host: %d (host was located in resume map)", psHost->iId); /* extract host's user resume map */ if (index(szResumeMap + 1, 0x68)) nUserMapSize = index(szResumeMap + 1, 0x68) - szResumeMap; /* calculate length of host resume map from start to the next "h" */ else if (index(szResumeMap + 1, 0x2e)) nUserMapSize = index(szResumeMap + 1, 0x2e) - szResumeMap; /* calculate length of host resume map from start to the terminating "." */ else nUserMapSize = strlen(szResumeMap); /* single, or last, host resume */ if (nUserMapSize < 4) writeError(ERR_FATAL, "Error extacting user resume map for host: %d", psHost->iId); szUserMap = malloc(nUserMapSize + 1); memset(szUserMap, 0, nUserMapSize + 1); strncpy(szUserMap, szResumeMap, nUserMapSize); writeError(ERR_DEBUG_SERVER, "[Host Resume] Host: %d - Processing host's user resume map: %s", psHost->iId, szUserMap); /* examine each user for the host and mark previously tested accounts as completed */ nFirstNewUserFound = FALSE; psUser = psHost->psUser; while (psUser) { memset(szTmp, 0, 11); memset(szTmp1, 0, 11); snprintf(szTmp, 10, "u%du", psUser->iId); snprintf(szTmp1, 10, "u%dh", psUser->iId); snprintf(szTmp2, 10, "u%d.", psUser->iId); if (nFirstNewUserFound == TRUE) { writeError(ERR_DEBUG_SERVER, "[User Resume] Adding user: %d (we've passed the point of the previous run)", psUser->iId); } else if (strstr(szResumeMap, szTmp)) { writeError(ERR_DEBUG_SERVER, "[User Resume] Adding user: %d (user was located in resume map)", psUser->iId); } else if ((strstr(szResumeMap, szTmp1)) || (strstr(szResumeMap, szTmp2))) { writeError(ERR_DEBUG_SERVER, "[User Resume] Adding user: %d (user was located in resume map and identified as first untouched account)", psUser->iId); nFirstNewUserFound = TRUE; } else { writeError(ERR_DEBUG_SERVER, "[User Resume] Skipping user: %d (user has already been tested)", psUser->iId); psUser->iPassStatus = PL_DONE; } psUser = psUser->psUserNext; } } else if (strstr(_psAudit->pOptResume, szTmp)) { writeError(ERR_DEBUG_SERVER, "[Host Resume] Adding host: %d (host was located in resume map and identified as first untouched system)", psHost->iId); nFirstNewHostFound = TRUE; } else { writeError(ERR_DEBUG_SERVER, "[Host Resume] Skipping host: %d (host has already been tested)", psHost->iId); nAddHost = FALSE; psHost->iUserStatus = UL_DONE; } } if (nAddHost) { writeError(ERR_DEBUG_AUDIT, "adding new server (%d) to queue", iServerId); if (pthread_mutex_init(&(psServer[iServerId].ptmMutex), NULL) != 0) writeError(ERR_FATAL, "Server (%d) mutex initialization failed - %s\n", iServerId, strerror( errno ) ); psServer[iServerId].psAudit = _psAudit; psServer[iServerId].iId = iServerId; psServer[iServerId].psHost = psHost; psServer[iServerId].iLoginCnt = _psAudit->iLoginCnt; psServer[iServerId].iLoginsDone = 0; psServer[iServerId].iCredentialsMissed = 0; //if ( thr_pool_queue(server_pool, startLoginThreadPool, (void *)psServer + iServerId * sizeof(sServer)) < 0 ) if ( thr_pool_queue(_psAudit->server_pool, startLoginThreadPool, (void *) &psServer[iServerId]) < 0 ) { writeError(ERR_ERROR, "Failed to add host task to server thread pool."); return FAILURE; } } psHost = psHost->psHostNext; } /* wait for thread pool to finish */ writeError(ERR_DEBUG_AUDIT, "waiting for server pool to end"); thr_pool_wait(_psAudit->server_pool); writeError(ERR_DEBUG_AUDIT, "destroying server pool"); thr_pool_destroy(_psAudit->server_pool); /* destroy and clean-up server objects */ for (iServerId = 0; iServerId < _psAudit->iHostCnt; iServerId++) { if (pthread_mutex_init(&(psServer[iServerId].ptmMutex), NULL) != 0) writeError(ERR_FATAL, "Server (%d) mutex destroy call failed - %s\n", iServerId, strerror( errno ) ); } kill_crypto_locks(); return SUCCESS; } /* Function called on SIGINT. We process the host and user tables and generate a map representing their current state. This map can then be supplied to Medusa to essentially resume the run. It should be noted, however, that users which were partially tested will be resumed from the start of their password list. */ void sigint_handler(int sig) { sHost *psHost; sUser *psUser; char szTmp[10+1]; // we can only resume h + 7 + . + \0, so 7 digits... 9,999,999 (should be enough) hosts char *szResumeMap = NULL; int nResumeMapSize = 0; int nItemByteSize = 0; struct sigaction sig_action; /* SIGINT is blocked by default within the handler. We explicitly unblock it here. This allows us to hit CTRL-C a second time and really quit the application without waiting for the threads to complete their work. */ sig_action.sa_flags = 0; sigemptyset(&sig_action.sa_mask); sigaddset(&sig_action.sa_mask, SIGINT); sig_action.sa_handler = SIG_DFL; sigaction(SIGINT, &sig_action, 0); sigprocmask(SIG_UNBLOCK, &sig_action.sa_mask, 0); /* notify threads that they should be exiting and then wait for them to finish */ writeError(ERR_ALERT, "Medusa received SIGINT - Sending notification to login threads that we are are aborting."); psAudit->iStatus = AUDIT_ABORT; writeError(ERR_INFO, "Waiting for login threads to terminate..."); thr_pool_wait(psAudit->server_pool); /* We note each partially finished host and the first new host for which testing has not started. We do the same for each partially completed host's user list. The number of partially completed hosts likely matches the number of parallel hosts being tested (T). The number of partially completed users for a given host likely matches the number of parallel logins being performed (t). This results in us reporting T(t + 1) + 1 items. Let's assume each item will require X bytes to report, which leads us to X(Tt + T + 1) bytes needed. Example: h6u1u2h7u3u4h8. +---------------- First host which was not 100% completed +-------------- First user for host which was not 100% completed +------------ First user for host which was not started +---- First host which was not started */ /* base our byte count on the largest number we may need to record - ex: h1236\0 */ if (psAudit->iHostCnt > psAudit->iUserCnt) nItemByteSize = 1 + (int)log10(psAudit->iHostCnt) + 1; else nItemByteSize = 1 + (int)log10(psAudit->iUserCnt) + 1; nResumeMapSize = nItemByteSize * (psAudit->iServerCnt * psAudit->iLoginCnt + psAudit->iServerCnt + 1) + 1; /* include terminating "." */ szResumeMap = malloc(nResumeMapSize + 1); memset(szResumeMap, 0, nResumeMapSize + 1); memset(szTmp, 0, 10 + 1); psHost = psAudit->psHostRoot; while ((psHost) && (psHost->iUserStatus != UL_UNSET)) { /* identify the hosts which are not 100% complete */ if ((psHost->iUserStatus != UL_DONE) && (psHost->iUserStatus != UL_ERROR)) { writeError(ERR_DEBUG, "Incomplete Host: %d", psHost->iId); memset(szTmp, 0, 10 + 1); snprintf(szTmp, 10, "h%d", psHost->iId); strncat(szResumeMap, szTmp, 10); /* identify the users which are not 100% complete for specific host */ psUser = psHost->psUser; while ((psUser) && (psUser->iPassStatus != PL_UNSET)) { if ((psUser->iPassStatus == PL_DONE) || (psUser->iPassStatus == PASS_AUDIT_COMPLETE)) writeError(ERR_DEBUG, "Complete User: %d", psUser->iId); else { writeError(ERR_DEBUG, "Incomplete User: %d", psUser->iId); memset(szTmp, 0, 10 + 1); snprintf(szTmp, 10, "u%d", psUser->iId); strncat(szResumeMap, szTmp, 10); } psUser = psUser->psUserNext; } /* identify the first untouched user */ if ((psUser) && (psUser->iPassStatus == PL_UNSET)) { writeError(ERR_DEBUG, "First New User: %d", psUser->iId); memset(szTmp, 0, 10 + 1); snprintf(szTmp, 10, "u%d", psUser->iId); strncat(szResumeMap, szTmp, 10); } } else { writeError(ERR_DEBUG, "Complete Host: %d", psHost->iId); } psHost = psHost->psHostNext; } /* identify the first untouched host */ if ((psHost) && (psHost->iUserStatus == UL_UNSET)) { writeError(ERR_DEBUG, "First New Host: %d", psHost->iId); memset(szTmp, 0, 10 + 1); snprintf(szTmp, 8, "h%d", psHost->iId); strncat(szResumeMap, szTmp, 8); } /* terminate resume map */ strncat(szResumeMap, ".", 1); writeError(ERR_ALERT, "To resume scan, add the following to your original command: \"-Z %s\"", szResumeMap); free(szResumeMap); exit(0); } int main(int argc, char **argv, char *envp[]) { struct sigaction sig_action; int iExitStatus; int i; struct tm *tm_ptr; time_t the_time; char time_buf[256]; /* set signal handling for SIGINT */ sig_action.sa_flags = 0; sigemptyset(&sig_action.sa_mask); sigaddset(&sig_action.sa_mask, SIGINT); sig_action.sa_handler = sigint_handler; sigaction(SIGINT, &sig_action, 0); /* initial module settings and parameters Don't worry if there are NULL or blank values here (they will be checked when loading the module) */ szModuleName = NULL; szModulePaths[0] = getenv("MEDUSA_MODULE_PATH"); szModulePaths[1] = "."; #ifdef DEFAULT_MOD_PATH szModulePaths[2] = DEFAULT_MOD_PATH; #else szModulePaths[2] = "/usr/lib/medusa/modules"; #endif szTempModuleParam = NULL; arrModuleParams = malloc(sizeof(char*)); memset(arrModuleParams, 0, sizeof(char*)); nModuleParamCount = 0; /* initialized audit structure */ psAudit = malloc(sizeof(sAudit)); memset(psAudit, 0, sizeof(sAudit)); if (pthread_mutex_init(&(psAudit->ptmMutex), NULL) != 0) writeError(ERR_FATAL, "Audit mutex initialization failed - %s\n", strerror( errno ) ); /* parse user-supplied parameters - populate module parameters */ if (checkOptions(argc, argv, psAudit)) { usage(); exit(EXIT_FAILURE); } for (i = 0; i < nModuleParamCount; i++) { writeVerbose(VB_GENERAL, "Module parameter: %s", arrModuleParams[i]); } if (szModuleName == NULL) { writeVerbose(VB_EXIT, "You must specify a module to execute using -M MODULE_NAME"); freeModuleParams(); exit(EXIT_FAILURE); } if (psAudit->HostType == L_FILE) { loadFile(psAudit->pOptHost, &psAudit->pHostFile, &psAudit->iHostCnt); psAudit->pGlobalHost = psAudit->pHostFile; } if (psAudit->UserType == L_FILE) { loadFile(psAudit->pOptUser, &psAudit->pUserFile, &psAudit->iUserCnt); psAudit->pGlobalUser = psAudit->pUserFile; } if (psAudit->PassType == L_FILE) { loadFile(psAudit->pOptPass, &psAudit->pPassFile, &psAudit->iPassCnt); psAudit->pGlobalPass = psAudit->pPassFile; } if (psAudit->pOptCombo != NULL) { loadFile(psAudit->pOptCombo, &psAudit->pComboFile, &psAudit->iComboCnt); psAudit->pGlobalCombo = psAudit->pComboFile; if (processComboFile(&psAudit)) { exit(iExitStatus); } } if ( loadLoginInfo(psAudit) == SUCCESS ) writeError(ERR_DEBUG, "Successfully loaded login information."); else writeError(ERR_FATAL, "Failed to load login information."); if (psAudit->pOptCombo != NULL) free(psAudit->pComboFile); if (psAudit->pHostFile != NULL) free(psAudit->pHostFile); if (psAudit->pUserFile != NULL) free(psAudit->pUserFile); if (psAudit->pOptOutput != NULL) { if ((pOutputFile = fopen(psAudit->pOptOutput, "a+")) == NULL) { writeError(ERR_FATAL, "Failed to open output file %s - %s", psAudit->pOptOutput, strerror( errno ) ); } else { if (pthread_mutex_init((&ptmFileMutex), NULL) != 0) writeError(ERR_FATAL, "File mutex initialization failed - %s\n", strerror( errno ) ); /* write start time and user options to log */ (void) time(&the_time); tm_ptr = localtime(&the_time); strftime(time_buf, 256, "%Y-%m-%d %H:%M:%S", tm_ptr); writeVerbose(VB_NONE_FILE, "# Medusa v.%s (%s)\n", VERSION, time_buf); writeVerbose(VB_NONE_FILE, "# "); for (i =0; i < argc; i++) { writeVerbose(VB_NONE_FILE, "%s ", argv[i]); } writeVerbose(VB_NONE_FILE, "\n"); } } /* launch actually password auditing threads */ if ( startServerThreadPool(psAudit) == SUCCESS ) { /* stop time */ (void) time(&the_time); tm_ptr = localtime(&the_time); strftime(time_buf, 256, "%Y-%m-%d %H:%M:%S", tm_ptr); writeVerbose(VB_NONE_FILE, "# Medusa has finished (%s).\n", time_buf); writeVerbose(VB_GENERAL, "Medusa has finished."); iExitStatus = EXIT_SUCCESS; } else { /* stop time */ (void) time(&the_time); tm_ptr = localtime(&the_time); strftime(time_buf, 256, "%Y-%m-%d %H:%M:%S", tm_ptr); writeVerbose(VB_NONE_FILE, "# Medusa failed (%s).\n", time_buf); writeError(ERR_CRITICAL, "Medusa failed."); iExitStatus = EXIT_FAILURE; } /* general memory clean-up */ if ((psAudit->pOptOutput != NULL) && (pthread_mutex_destroy(&ptmFileMutex) != 0)) writeError(ERR_FATAL, "File mutex destroy call failed - %s\n", strerror( errno ) ); if (pthread_mutex_destroy(&(psAudit->ptmMutex)) != 0) writeError(ERR_FATAL, "Audit mutex destroy call failed - %s\n", strerror( errno ) ); free(psAudit->pPassFile); free(psAudit); if (szModuleName != NULL) free(szModuleName); freeModuleParams(); exit(iExitStatus); } medusa-2.1.1/src/Makefile.am0000644000175000001440000000073411723732127012542 00000000000000bin_PROGRAMS = medusa medusa_SOURCES = listModules.c medusa.c medusa-thread-pool.c medusa-thread-ssl.c medusa-net.c medusa-trace.c medusa-utils.c # set the include path found by configure INCLUDES = -I$(top_srcdir)/src $(all_includes) # the library search path. #medusa_LDFLAGS = -rdynamic -ldl -lpthread -lssl noinst_HEADERS = medusa.h medusa-thread-pool.h medusa-thread-ssl.h medusa-net.h medusa-trace.h medusa-utils.h uthash.h #AM_CFLAGS = -DLIBOPENSSL SUBDIRS = modsrc medusa-2.1.1/src/medusa-utils.c0000644000175000001440000001660211723732127013267 00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. See the * GNU General Public License for more details. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ #include "medusa.h" #include "medusa-trace.h" #include "medusa-utils.h" /* Base64 Functions used from Wget (http://wget.sunsite.dk/) */ /* Encode the string STR of length LENGTH to base64 format and place it to B64STORE. The output will be \0-terminated, and must point to a writable buffer of at least 1+BASE64_LENGTH(length) bytes. It returns the length of the resulting base64 data, not counting the terminating zero. This implementation will not emit newlines after 76 characters of base64 data. */ int base64_encode(const char *str, int length, char *b64store) { /* Conversion table. */ static char tbl[64] = { 'A','B','C','D','E','F','G','H', 'I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X', 'Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n', 'o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3', '4','5','6','7','8','9','+','/' }; int i; const unsigned char *s = (const unsigned char *) str; char *p = b64store; /* Transform the 3x8 bits to 4x6 bits, as required by base64. */ for (i = 0; i < length; i += 3) { *p++ = tbl[s[0] >> 2]; *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)]; *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)]; *p++ = tbl[s[2] & 0x3f]; s += 3; } /* Pad the result if necessary... */ if (i == length + 1) *(p - 1) = '='; else if (i == length + 2) *(p - 1) = *(p - 2) = '='; /* ...and zero-terminate it. */ *p = '\0'; return p - b64store; } #define IS_ASCII(c) (((c) & 0x80) == 0) #define IS_BASE64(c) ((IS_ASCII (c) && base64_char_to_value[c] >= 0) || c == '=') /* Get next character from the string, except that non-base64 characters are ignored, as mandated by rfc2045. */ #define NEXT_BASE64_CHAR(c, p) do { \ c = *p++; \ } while (c != '\0' && !IS_BASE64 (c)) /* Decode data from BASE64 (assumed to be encoded as base64) into memory pointed to by TO. TO should be large enough to accomodate the decoded data, which is guaranteed to be less than strlen(base64). Since TO is assumed to contain binary data, it is not NUL-terminated. The function returns the length of the data written to TO. -1 is returned in case of error caused by malformed base64 input. */ int base64_decode (const char *base64, char *to) { /* Table of base64 values for first 128 characters. Note that this assumes ASCII (but so does Wget in other places). */ static short base64_char_to_value[128] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0- 9 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10- 19 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20- 29 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 30- 39 */ -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, /* 40- 49 */ 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, /* 50- 59 */ -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, /* 60- 69 */ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70- 79 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80- 89 */ 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, /* 90- 99 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */ 49, 50, 51, -1, -1, -1, -1, -1 /* 120-127 */ }; const char *p = base64; char *q = to; while (1) { unsigned char c; unsigned long value; /* Process first byte of a quadruplet. */ NEXT_BASE64_CHAR (c, p); if (!c) break; if (c == '=') return -1; /* illegal '=' while decoding base64 */ value = base64_char_to_value[c] << 18; /* Process scond byte of a quadruplet. */ NEXT_BASE64_CHAR (c, p); if (!c) return -1; /* premature EOF while decoding base64 */ if (c == '=') return -1; /* illegal `=' while decoding base64 */ value |= base64_char_to_value[c] << 12; *q++ = value >> 16; /* Process third byte of a quadruplet. */ NEXT_BASE64_CHAR (c, p); if (!c) return -1; /* premature EOF while decoding base64 */ if (c == '=') { NEXT_BASE64_CHAR (c, p); if (!c) return -1; /* premature EOF while decoding base64 */ if (c != '=') return -1; /* padding `=' expected but not found */ continue; } value |= base64_char_to_value[c] << 6; *q++ = 0xff & value >> 8; /* Process fourth byte of a quadruplet. */ NEXT_BASE64_CHAR (c, p); if (!c) return -1; /* premature EOF while decoding base64 */ if (c == '=') continue; value |= base64_char_to_value[c]; *q++ = 0xff & value; } return q - to; } /* Create the authentication header contents for the `Basic' scheme. This is done by encoding the string "USER:PASS" to base64 and prepending the string "Basic " in front of it. */ char *basic_authentication_encode(const char *user, const char *passwd) { char *t1, *t2; int len1 = strlen (user) + 1 + strlen (passwd); t1 = (char *)alloca (len1 + 1); sprintf (t1, "%s:%s", user, passwd); t2 = (char *)malloc (BASE64_LENGTH (len1) + 1); base64_encode (t1, len1, t2); return (t2); } /* End Wget Base64 Functions */ /* Solaris doesn't have a strcasestr */ #ifndef HAVE_STRCASESTR char *strcasestr(const char *a, const char *b) { size_t l; char f[3]; snprintf(f, sizeof(f), "%c%c", tolower(*b), toupper(*b)); for (l = strcspn(a, f); l != strlen(a); l += strcspn(a + l + 1, f) + 1) if (strncasecmp(a + l, b, strlen(b)) == 0) return((char *) a + l); return(NULL); } #endif /* Solaris (10x86, at least) does not appear to have asprintf/vasprintf functions Function code taken from ndoutils_sunos.c */ #ifndef HAVE_VASPRINTF #define CHUNKSIZE 512 int vasprintf(char **ret, const char *fmt, va_list ap) { int chunks; size_t buflen; char *buf; int len; chunks = ((strlen(fmt) + 1) / CHUNKSIZE) + 1; buflen = chunks * CHUNKSIZE; for (;;) { if ((buf = malloc(buflen)) == NULL) { *ret = NULL; return -1; } len = vsnprintf(buf, buflen, fmt, ap); if (len >= 0 && len < (buflen - 1)) { break; } free(buf); buflen = (++chunks) * CHUNKSIZE; /* * len >= 0 are required for vsnprintf implementation that * return -1 of buffer insufficient */ if (len >= 0 && len >= buflen) { buflen = len + 1; } } *ret = buf; return len; FILE *fp; *ret = NULL; } #endif #ifndef HAVE_ASPRINTF int asprintf(char **ret, const char *fmt, ...) { int len; va_list ap; va_start(ap, fmt); len = vasprintf(ret, fmt, ap); va_end(ap); return len; } #endif medusa-2.1.1/src/medusa-thread-pool.c0000644000175000001440000003023411723732127014342 00000000000000/* * * Thread Pool Implementation * Based on Sun Microsystems, Inc. "Multithreaded Programming Guide" * http://docs.sun.com/app/docs/doc/816-5137/ggedn?a=view * * See for interface declarations. */ #if !defined(_REENTRANT) #define _REENTRANT #endif //#include "medusa-thread-pool.h" #include "medusa.h" #include #include #include /* * FIFO queued job */ typedef struct job job_t; struct job { job_t *job_next; /* linked list of jobs */ void *(*job_func)(void *); /* function to call */ void *job_arg; /* its argument */ }; /* * List of active worker threads, linked through their stacks. */ typedef struct active active_t; struct active { active_t *active_next; /* linked list of threads */ pthread_t active_tid; /* active thread id */ }; /* * The thread pool, opaque to the clients. */ struct thr_pool { thr_pool_t *pool_forw; /* circular linked list */ thr_pool_t *pool_back; /* of all thread pools */ pthread_mutex_t pool_mutex; /* protects the pool data */ pthread_cond_t pool_busycv; /* synchronization in pool_queue */ pthread_cond_t pool_workcv; /* synchronization with workers */ pthread_cond_t pool_waitcv; /* synchronization in pool_wait() */ active_t *pool_active; /* list of threads performing work */ job_t *pool_head; /* head of FIFO job queue */ job_t *pool_tail; /* tail of FIFO job queue */ pthread_attr_t pool_attr; /* attributes of the workers */ int pool_flags; /* see below */ uint_t pool_linger; /* seconds before idle workers exit */ int pool_minimum; /* minimum number of worker threads */ int pool_maximum; /* maximum number of worker threads */ int pool_nthreads; /* current number of worker threads */ int pool_idle; /* number of idle workers */ }; /* pool_flags */ #define POOL_WAIT 0x01 /* waiting in thr_pool_wait() */ #define POOL_DESTROY 0x02 /* pool is being destroyed */ /* the list of all created and not yet destroyed thread pools */ static thr_pool_t *thr_pools = NULL; /* protects thr_pools */ static pthread_mutex_t thr_pool_lock = PTHREAD_MUTEX_INITIALIZER; /* set of all signals */ static sigset_t fillset; static void *worker_thread(void *); static int create_worker(thr_pool_t *pool) { sigset_t oset; int error; /* jmk - The original code passed NULL to pthread_create for thread ID. This appears to cause segfaults on Linux... */ pthread_t *ppthread; ppthread = malloc( sizeof(pthread_t) ); memset(ppthread, 0, sizeof(pthread_t)); (void) pthread_sigmask(SIG_SETMASK, &fillset, &oset); error = pthread_create(ppthread, &pool->pool_attr, worker_thread, pool); (void) pthread_sigmask(SIG_SETMASK, &oset, NULL); free(ppthread); return (error); } /* * Worker thread is terminating. Possible reasons: * - excess idle thread is terminating because there is no work. * - thread was cancelled (pool is being destroyed). * - the job function called pthread_exit(). * In the last case, create another worker thread * if necessary to keep the pool populated. */ static void worker_cleanup(thr_pool_t *pool) { --pool->pool_nthreads; if (pool->pool_flags & POOL_DESTROY) { if (pool->pool_nthreads == 0) (void) pthread_cond_broadcast(&pool->pool_busycv); } else if (pool->pool_head != NULL && pool->pool_nthreads < pool->pool_maximum && create_worker(pool) == 0) { pool->pool_nthreads++; } (void) pthread_mutex_unlock(&pool->pool_mutex); } static void notify_waiters(thr_pool_t *pool) { if (pool->pool_head == NULL && pool->pool_active == NULL) { pool->pool_flags &= ~POOL_WAIT; (void) pthread_cond_broadcast(&pool->pool_waitcv); } } /* * Called by a worker thread on return from a job. */ static void job_cleanup(thr_pool_t *pool) { pthread_t my_tid = pthread_self(); active_t *activep; active_t **activepp; (void) pthread_mutex_lock(&pool->pool_mutex); for (activepp = &pool->pool_active; (activep = *activepp) != NULL; activepp = &activep->active_next) { if (activep->active_tid == my_tid) { *activepp = activep->active_next; break; } } if (pool->pool_flags & POOL_WAIT) notify_waiters(pool); } static void * worker_thread(void *arg) { thr_pool_t *pool = (thr_pool_t *)arg; int timedout; job_t *job; void *(*func)(void *); active_t active; struct timespec ts; struct timeval tv; /* * This is the worker's main loop. It will only be left * if a timeout occurs or if the pool is being destroyed. */ (void) pthread_mutex_lock(&pool->pool_mutex); pthread_cleanup_push((void *)worker_cleanup, pool); active.active_tid = pthread_self(); for (;;) { /* * We don't know what this thread was doing during * its last job, so we reset its signal mask and * cancellation state back to the initial values. */ (void) pthread_sigmask(SIG_SETMASK, &fillset, NULL); (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); (void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); timedout = 0; pool->pool_idle++; if (pool->pool_flags & POOL_WAIT) notify_waiters(pool); while (pool->pool_head == NULL && !(pool->pool_flags & POOL_DESTROY)) { if (pool->pool_nthreads <= pool->pool_minimum) { (void) pthread_cond_wait(&pool->pool_workcv, &pool->pool_mutex); } else { #ifndef HAVE_CLOCK_GETTIME gettimeofday(&tv, NULL); ts.tv_sec = tv.tv_sec; ts.tv_nsec = tv.tv_usec * 1000; #else (void) clock_gettime(CLOCK_REALTIME, &ts); #endif ts.tv_sec += pool->pool_linger; if (pool->pool_linger == 0 || pthread_cond_timedwait(&pool->pool_workcv, &pool->pool_mutex, &ts) == ETIMEDOUT) { timedout = 1; break; } } } pool->pool_idle--; if (pool->pool_flags & POOL_DESTROY) break; if ((job = pool->pool_head) != NULL) { timedout = 0; func = job->job_func; arg = job->job_arg; pool->pool_head = job->job_next; if (job == pool->pool_tail) pool->pool_tail = NULL; active.active_next = pool->pool_active; pool->pool_active = &active; (void) pthread_mutex_unlock(&pool->pool_mutex); pthread_cleanup_push((void *)job_cleanup, pool); free(job); /* * Call the specified job function. */ (void) func(arg); /* * If the job function calls pthread_exit(), the thread * calls job_cleanup(pool) and worker_cleanup(pool); * the integrity of the pool is thereby maintained. */ pthread_cleanup_pop(1); /* job_cleanup(pool) */ } if (timedout && pool->pool_nthreads > pool->pool_minimum) { /* * We timed out and there is no work to be done * and the number of workers exceeds the minimum. * Exit now to reduce the size of the pool. */ break; } } pthread_cleanup_pop(1); /* worker_cleanup(pool) */ return (NULL); } static void clone_attributes(pthread_attr_t *new_attr, pthread_attr_t *old_attr) { struct sched_param param; void *addr; size_t size; int value; (void) pthread_attr_init(new_attr); if (old_attr != NULL) { (void) pthread_attr_getstack(old_attr, &addr, &size); /* don't allow a non-NULL thread stack address */ (void) pthread_attr_setstack(new_attr, NULL, size); (void) pthread_attr_getscope(old_attr, &value); (void) pthread_attr_setscope(new_attr, value); (void) pthread_attr_getinheritsched(old_attr, &value); (void) pthread_attr_setinheritsched(new_attr, value); (void) pthread_attr_getschedpolicy(old_attr, &value); (void) pthread_attr_setschedpolicy(new_attr, value); (void) pthread_attr_getschedparam(old_attr, ¶m); (void) pthread_attr_setschedparam(new_attr, ¶m); (void) pthread_attr_getguardsize(old_attr, &size); (void) pthread_attr_setguardsize(new_attr, size); } /* make all pool threads be detached threads */ (void) pthread_attr_setdetachstate(new_attr, PTHREAD_CREATE_DETACHED); } thr_pool_t * thr_pool_create(uint_t min_threads, uint_t max_threads, uint_t linger, pthread_attr_t *attr) { thr_pool_t *pool; (void) sigfillset(&fillset); if (min_threads > max_threads || max_threads < 1) { errno = EINVAL; return (NULL); } if ((pool = malloc(sizeof (*pool))) == NULL) { errno = ENOMEM; return (NULL); } (void) pthread_mutex_init(&pool->pool_mutex, NULL); (void) pthread_cond_init(&pool->pool_busycv, NULL); (void) pthread_cond_init(&pool->pool_workcv, NULL); (void) pthread_cond_init(&pool->pool_waitcv, NULL); pool->pool_active = NULL; pool->pool_head = NULL; pool->pool_tail = NULL; pool->pool_flags = 0; pool->pool_linger = linger; pool->pool_minimum = min_threads; pool->pool_maximum = max_threads; pool->pool_nthreads = 0; pool->pool_idle = 0; /* * We cannot just copy the attribute pointer. * We need to initialize a new pthread_attr_t structure using * the values from the caller-supplied attribute structure. * If the attribute pointer is NULL, we need to initialize * the new pthread_attr_t structure with default values. */ clone_attributes(&pool->pool_attr, attr); /* insert into the global list of all thread pools */ (void) pthread_mutex_lock(&thr_pool_lock); if (thr_pools == NULL) { pool->pool_forw = pool; pool->pool_back = pool; thr_pools = pool; } else { thr_pools->pool_back->pool_forw = pool; pool->pool_forw = thr_pools; pool->pool_back = thr_pools->pool_back; thr_pools->pool_back = pool; } (void) pthread_mutex_unlock(&thr_pool_lock); return (pool); } int thr_pool_queue(thr_pool_t *pool, void *(*func)(void *), void *arg) { job_t *job; if ((job = malloc(sizeof (*job))) == NULL) { errno = ENOMEM; return (-1); } job->job_next = NULL; job->job_func = func; job->job_arg = arg; (void) pthread_mutex_lock(&pool->pool_mutex); if (pool->pool_head == NULL) pool->pool_head = job; else pool->pool_tail->job_next = job; pool->pool_tail = job; if (pool->pool_idle > 0) (void) pthread_cond_signal(&pool->pool_workcv); else if (pool->pool_nthreads < pool->pool_maximum && create_worker(pool) == 0) pool->pool_nthreads++; (void) pthread_mutex_unlock(&pool->pool_mutex); return (0); } void thr_pool_wait(thr_pool_t *pool) { (void) pthread_mutex_lock(&pool->pool_mutex); pthread_cleanup_push((void *)pthread_mutex_unlock, &pool->pool_mutex); while (pool->pool_head != NULL || pool->pool_active != NULL) { pool->pool_flags |= POOL_WAIT; (void) pthread_cond_wait(&pool->pool_waitcv, &pool->pool_mutex); } pthread_cleanup_pop(1); /* pthread_mutex_unlock(&pool->pool_mutex); */ } void thr_pool_destroy(thr_pool_t *pool) { active_t *activep; job_t *job; (void) pthread_mutex_lock(&pool->pool_mutex); pthread_cleanup_push((void *)pthread_mutex_unlock, &pool->pool_mutex); /* mark the pool as being destroyed; wakeup idle workers */ pool->pool_flags |= POOL_DESTROY; (void) pthread_cond_broadcast(&pool->pool_workcv); /* cancel all active workers */ for (activep = pool->pool_active; activep != NULL; activep = activep->active_next) (void) pthread_cancel(activep->active_tid); /* wait for all active workers to finish */ while (pool->pool_active != NULL) { pool->pool_flags |= POOL_WAIT; (void) pthread_cond_wait(&pool->pool_waitcv, &pool->pool_mutex); } /* the last worker to terminate will wake us up */ while (pool->pool_nthreads != 0) (void) pthread_cond_wait(&pool->pool_busycv, &pool->pool_mutex); pthread_cleanup_pop(1); /* pthread_mutex_unlock(&pool->pool_mutex); */ /* * Unlink the pool from the global list of all pools. */ (void) pthread_mutex_lock(&thr_pool_lock); if (thr_pools == pool) thr_pools = pool->pool_forw; if (thr_pools == pool) thr_pools = NULL; else { pool->pool_back->pool_forw = pool->pool_forw; pool->pool_forw->pool_back = pool->pool_back; } (void) pthread_mutex_unlock(&thr_pool_lock); /* * There should be no pending jobs, but just in case... */ for (job = pool->pool_head; job != NULL; job = pool->pool_head) { pool->pool_head = job->job_next; free(job); } (void) pthread_attr_destroy(&pool->pool_attr); free(pool); } medusa-2.1.1/src/medusa-trace.c0000644000175000001440000001260211723732127013221 00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. See the * GNU General Public License for more details. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ #include #include #include #include #include "medusa.h" #include "medusa-trace.h" #include #include #include void writeVerbose(int iLevel, char *pMsg, ...) { va_list ap; char buf[512]; char bufOut[1024]; char temp[6]; unsigned char cTemp; int i = 0; if (pMsg == NULL) { fprintf(stderr, "CRITICAL: writeDebug() called with NULL message.\n"); } else if (iLevel <= iVerboseLevel) { va_start(ap, pMsg); memset(bufOut, 0, 1024); memset(buf, 0, 512); vsnprintf(buf, sizeof(buf) - 1, pMsg, ap); /* Convert specific non-printable characters to HEX Non-printable: < 32d or > 126d Ignore: \n, \r and TAB */ for (i = 0; i < sizeof(buf); i++) { memset(temp, 0, 6); cTemp = (unsigned char)buf[i]; if ((cTemp < 32 && cTemp > 0 && cTemp != 9 && cTemp != 10 && cTemp != 13) || cTemp > 126) { sprintf(temp, "[%02X]", cTemp); } else sprintf(temp, "%c", cTemp); strncat(bufOut, temp, 6); } switch (iLevel) { case VB_FOUND: fprintf(stdout, "ACCOUNT FOUND: %s\n", bufOut); if (pOutputFile != NULL) { pthread_mutex_lock(&ptmFileMutex); fprintf(pOutputFile, "ACCOUNT FOUND: %s\n", buf); fflush(pOutputFile); pthread_mutex_unlock(&ptmFileMutex); } va_end(ap); break; case VB_CHECK: fprintf(stdout, "ACCOUNT CHECK: %s\n", bufOut); va_end(ap); break; case VB_IMPORTANT: fprintf(stdout, "IMPORTANT: %s\n", bufOut); va_end(ap); break; case VB_GENERAL: fprintf(stdout, "GENERAL: %s\n", bufOut); va_end(ap); break; case VB_NONE: fprintf(stdout, "%s\n", bufOut); va_end(ap); break; case VB_NONE_FILE: if (pOutputFile != NULL) { pthread_mutex_lock(&ptmFileMutex); fprintf(pOutputFile, "%s", bufOut); fflush(pOutputFile); pthread_mutex_unlock(&ptmFileMutex); } va_end(ap); break; case VB_EXIT: fprintf(stdout, "%s\n", bufOut); va_end(ap); exit(EXIT_SUCCESS); break; default: fprintf(stdout, "UNKNOWN: %s\n", bufOut); va_end(ap); break; } } return; } void writeError(int iLevel, char *pMsg, ...) { va_list ap; char buf[4096]; char bufOut[16384]; char temp[6]; unsigned char cTemp; int i = 0; if (pMsg == NULL) { fprintf(stderr, "CRITICAL: writeError() called with NULL message.\n"); } else if (iLevel <= iErrorLevel) { va_start(ap, pMsg); memset(bufOut, 0, 16384); memset(buf, 0, 4096); vsnprintf(buf, sizeof(buf), pMsg, ap); // Convert any chars less than 32d or greater than 126d to hex for (i = 0; i < sizeof(buf); i++) { memset(temp, 0, 6); cTemp = (unsigned char)buf[i]; if ((cTemp < 32 && cTemp > 0) || cTemp > 126) { sprintf(temp, "[%02X]", cTemp); } else sprintf(temp, "%c", cTemp); strncat(bufOut, temp, 6); } switch (iLevel) { case ERR_FATAL: fprintf(stderr, "FATAL: %s\n", bufOut); va_end(ap); exit(EXIT_FAILURE); break; case ERR_ALERT: fprintf(stderr, "ALERT: "); break; case ERR_CRITICAL: fprintf(stderr, "CRITICAL: "); break; case ERR_ERROR: fprintf(stderr, "ERROR: "); break; case ERR_WARNING: fprintf(stderr, "WARNING: "); break; case ERR_NOTICE: fprintf(stderr, "NOTICE: "); break; case ERR_INFO: fprintf(stderr, "INFO: "); break; case ERR_DEBUG: fprintf(stderr, "DEBUG [%X]: ", (int)pthread_self()); break; case ERR_DEBUG_AUDIT: fprintf(stderr, "DEBUG AUDIT [%X]: ", (int)pthread_self()); break; case ERR_DEBUG_SERVER: fprintf(stderr, "DEBUG SERVER [%X]: ", (int)pthread_self()); break; case ERR_DEBUG_MODULE: fprintf(stderr, "DEBUG MODULE [%X]: ", (int)pthread_self()); break; default: fprintf(stdout, "UNKNOWN ERROR [%X]: ", (int)pthread_self()); break; } fprintf(stderr, "%s\n", bufOut); va_end(ap); } return; } void writeErrorBin(int iLevel, char *pMsg, char *pData, int iLength) { int i; if (iLevel <= iErrorLevel) { fprintf(stderr, "DATA: %s ", pMsg); for(i=0; i /* memcmp,strlen */ #include /* ptrdiff_t */ #include /* uint32_t etc */ #define UTHASH_VERSION 1.8 /* C++ requires extra stringent casting */ #if defined __cplusplus #define TYPEOF(x) (typeof(x)) #else #define TYPEOF(x) #endif #define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ #define uthash_malloc(sz) malloc(sz) /* malloc fcn */ #define uthash_free(ptr) free(ptr) /* free fcn */ #define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ #define uthash_expand_fyi(tbl) /* can be defined to log expands */ /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ #define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ /* calculate the element whose hash handle address is hhe */ #define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)hhp) - (tbl)->hho)) #define HASH_FIND(hh,head,keyptr,keylen,out) \ do { \ unsigned _hf_bkt,_hf_hashv; \ out=TYPEOF(out)NULL; \ if (head) { \ HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ keyptr,keylen,out); \ } \ } \ } while (0) #ifdef HASH_BLOOM #define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) #define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) #define HASH_BLOOM_MAKE(tbl) \ do { \ (tbl)->bloom_nbits = HASH_BLOOM; \ (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ } while (0); #define HASH_BLOOM_FREE(tbl) \ do { \ uthash_free((tbl)->bloom_bv); \ } while (0); #define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) #define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) #define HASH_BLOOM_ADD(tbl,hashv) \ HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) #define HASH_BLOOM_TEST(tbl,hashv) \ HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) #else #define HASH_BLOOM_MAKE(tbl) #define HASH_BLOOM_FREE(tbl) #define HASH_BLOOM_ADD(tbl,hashv) #define HASH_BLOOM_TEST(tbl,hashv) (1) #endif #define HASH_MAKE_TABLE(hh,head) \ do { \ (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ sizeof(UT_hash_table)); \ if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ (head)->hh.tbl->tail = &((head)->hh); \ (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl->buckets, 0, \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ HASH_BLOOM_MAKE((head)->hh.tbl); \ (head)->hh.tbl->signature = HASH_SIGNATURE; \ } while(0) #define HASH_ADD(hh,head,fieldname,keylen_in,add) \ HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add) #define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ do { \ unsigned _ha_bkt; \ (add)->hh.next = NULL; \ (add)->hh.key = (char*)keyptr; \ (add)->hh.keylen = keylen_in; \ if (!(head)) { \ head = (add); \ (head)->hh.prev = NULL; \ HASH_MAKE_TABLE(hh,head); \ } else { \ (head)->hh.tbl->tail->next = (add); \ (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ (head)->hh.tbl->tail = &((add)->hh); \ } \ (head)->hh.tbl->num_items++; \ (add)->hh.tbl = (head)->hh.tbl; \ HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ (add)->hh.hashv, _ha_bkt); \ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ HASH_FSCK(hh,head); \ } while(0) #define HASH_TO_BKT( hashv, num_bkts, bkt ) \ do { \ bkt = ((hashv) & ((num_bkts) - 1)); \ } while(0) /* delete "delptr" from the hash table. * "the usual" patch-up process for the app-order doubly-linked-list. * The use of _hd_hh_del below deserves special explanation. * These used to be expressed using (delptr) but that led to a bug * if someone used the same symbol for the head and deletee, like * HASH_DELETE(hh,users,users); * We want that to work, but by changing the head (users) below * we were forfeiting our ability to further refer to the deletee (users) * in the patch-up process. Solution: use scratch space in the table to * copy the deletee pointer, then the latter references are via that * scratch pointer rather than through the repointed (users) symbol. */ #define HASH_DELETE(hh,head,delptr) \ do { \ unsigned _hd_bkt; \ struct UT_hash_handle *_hd_hh_del; \ if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ uthash_free((head)->hh.tbl->buckets ); \ HASH_BLOOM_FREE((head)->hh.tbl); \ uthash_free((head)->hh.tbl); \ head = NULL; \ } else { \ _hd_hh_del = &((delptr)->hh); \ if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ (head)->hh.tbl->tail = \ (UT_hash_handle*)((char*)((delptr)->hh.prev) + \ (head)->hh.tbl->hho); \ } \ if ((delptr)->hh.prev) { \ ((UT_hash_handle*)((char*)((delptr)->hh.prev) + \ (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ } else { \ head = TYPEOF(head)((delptr)->hh.next); \ } \ if (_hd_hh_del->next) { \ ((UT_hash_handle*)((char*)_hd_hh_del->next + \ (head)->hh.tbl->hho))->prev = \ _hd_hh_del->prev; \ } \ HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ (head)->hh.tbl->num_items--; \ } \ HASH_FSCK(hh,head); \ } while (0) /* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ #define HASH_FIND_STR(head,findstr,out) \ HASH_FIND(hh,head,findstr,strlen(findstr),out) #define HASH_ADD_STR(head,strfield,add) \ HASH_ADD(hh,head,strfield,strlen(add->strfield),add) #define HASH_FIND_INT(head,findint,out) \ HASH_FIND(hh,head,findint,sizeof(int),out) #define HASH_ADD_INT(head,intfield,add) \ HASH_ADD(hh,head,intfield,sizeof(int),add) #define HASH_DEL(head,delptr) \ HASH_DELETE(hh,head,delptr) /* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. */ #ifdef HASH_DEBUG #define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) #define HASH_FSCK(hh,head) \ do { \ unsigned _bkt_i; \ unsigned _count, _bkt_count; \ char *_prev; \ struct UT_hash_handle *_thh; \ if (head) { \ _count = 0; \ for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ _bkt_count = 0; \ _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ _prev = NULL; \ while (_thh) { \ if (_prev != (char*)(_thh->hh_prev)) { \ HASH_OOPS("invalid hh_prev %p, actual %p\n", \ _thh->hh_prev, _prev ); \ } \ _bkt_count++; \ _prev = (char*)(_thh); \ _thh = _thh->hh_next; \ } \ _count += _bkt_count; \ if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ HASH_OOPS("invalid bucket count %d, actual %d\n", \ (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ } \ } \ if (_count != (head)->hh.tbl->num_items) { \ HASH_OOPS("invalid hh item count %d, actual %d\n", \ (head)->hh.tbl->num_items, _count ); \ } \ /* traverse hh in app order; check next/prev integrity, count */ \ _count = 0; \ _prev = NULL; \ _thh = &(head)->hh; \ while (_thh) { \ _count++; \ if (_prev !=(char*)(_thh->prev)) { \ HASH_OOPS("invalid prev %p, actual %p\n", \ _thh->prev, _prev ); \ } \ _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ (head)->hh.tbl->hho) : NULL ); \ } \ if (_count != (head)->hh.tbl->num_items) { \ HASH_OOPS("invalid app item count %d, actual %d\n", \ (head)->hh.tbl->num_items, _count ); \ } \ } \ } while (0) #else #define HASH_FSCK(hh,head) #endif /* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to * the descriptor to which this macro is defined for tuning the hash function. * The app can #include to get the prototype for write(2). */ #ifdef HASH_EMIT_KEYS #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ do { \ unsigned _klen = fieldlen; \ write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ write(HASH_EMIT_KEYS, keyptr, fieldlen); \ } while (0) #else #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) #endif /* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ #ifdef HASH_FUNCTION #define HASH_FCN HASH_FUNCTION #else #define HASH_FCN HASH_JEN #endif /* The Bernstein hash function, used in Perl prior to v5.6 */ #define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _hb_keylen=keylen; \ char *_hb_key=(char*)key; \ (hashv) = 0; \ while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ bkt = (hashv) & (num_bkts-1); \ } while (0) /* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ #define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _sx_i; \ char *_hs_key=(char*)key; \ hashv = 0; \ for(_sx_i=0; _sx_i < keylen; _sx_i++) \ hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ bkt = hashv & (num_bkts-1); \ } while (0) #define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _fn_i; \ char *_hf_key=(char*)key; \ hashv = 2166136261UL; \ for(_fn_i=0; _fn_i < keylen; _fn_i++) \ hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ bkt = hashv & (num_bkts-1); \ } while(0); #define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _ho_i; \ char *_ho_key=(char*)key; \ hashv = 0; \ for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ hashv += _ho_key[_ho_i]; \ hashv += (hashv << 10); \ hashv ^= (hashv >> 6); \ } \ hashv += (hashv << 3); \ hashv ^= (hashv >> 11); \ hashv += (hashv << 15); \ bkt = hashv & (num_bkts-1); \ } while(0) #define HASH_JEN_MIX(a,b,c) \ do { \ a -= b; a -= c; a ^= ( c >> 13 ); \ b -= c; b -= a; b ^= ( a << 8 ); \ c -= a; c -= b; c ^= ( b >> 13 ); \ a -= b; a -= c; a ^= ( c >> 12 ); \ b -= c; b -= a; b ^= ( a << 16 ); \ c -= a; c -= b; c ^= ( b >> 5 ); \ a -= b; a -= c; a ^= ( c >> 3 ); \ b -= c; b -= a; b ^= ( a << 10 ); \ c -= a; c -= b; c ^= ( b >> 15 ); \ } while (0) #define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _hj_i,_hj_j,_hj_k; \ char *_hj_key=(char*)key; \ hashv = 0xfeedbeef; \ _hj_i = _hj_j = 0x9e3779b9; \ _hj_k = keylen; \ while (_hj_k >= 12) { \ _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + ( (unsigned)_hj_key[2] << 16 ) \ + ( (unsigned)_hj_key[3] << 24 ) ); \ _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + ( (unsigned)_hj_key[6] << 16 ) \ + ( (unsigned)_hj_key[7] << 24 ) ); \ hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + ( (unsigned)_hj_key[10] << 16 ) \ + ( (unsigned)_hj_key[11] << 24 ) ); \ \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ \ _hj_key += 12; \ _hj_k -= 12; \ } \ hashv += keylen; \ switch ( _hj_k ) { \ case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ case 5: _hj_j += _hj_key[4]; \ case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ case 1: _hj_i += _hj_key[0]; \ } \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ bkt = hashv & (num_bkts-1); \ } while(0) /* The Paul Hsieh hash function */ #undef get16bits #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) #define get16bits(d) (*((const uint16_t *) (d))) #endif #if !defined (get16bits) #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ +(uint32_t)(((const uint8_t *)(d))[0]) ) #endif #define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ do { \ char *_sfh_key=(char*)key; \ uint32_t _sfh_tmp, _sfh_len = keylen; \ \ int _sfh_rem = _sfh_len & 3; \ _sfh_len >>= 2; \ hashv = 0xcafebabe; \ \ /* Main loop */ \ for (;_sfh_len > 0; _sfh_len--) { \ hashv += get16bits (_sfh_key); \ _sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \ hashv = (hashv << 16) ^ _sfh_tmp; \ _sfh_key += 2*sizeof (uint16_t); \ hashv += hashv >> 11; \ } \ \ /* Handle end cases */ \ switch (_sfh_rem) { \ case 3: hashv += get16bits (_sfh_key); \ hashv ^= hashv << 16; \ hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \ hashv += hashv >> 11; \ break; \ case 2: hashv += get16bits (_sfh_key); \ hashv ^= hashv << 11; \ hashv += hashv >> 17; \ break; \ case 1: hashv += *_sfh_key; \ hashv ^= hashv << 10; \ hashv += hashv >> 1; \ } \ \ /* Force "avalanching" of final 127 bits */ \ hashv ^= hashv << 3; \ hashv += hashv >> 5; \ hashv ^= hashv << 4; \ hashv += hashv >> 17; \ hashv ^= hashv << 25; \ hashv += hashv >> 6; \ bkt = hashv & (num_bkts-1); \ } while(0); #ifdef HASH_USING_NO_STRICT_ALIASING /* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads. * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. * So MurmurHash comes in two versions, the faster unaligned one and the slower * aligned one. We only use the faster one on CPU's where we know it's safe. * * Note the preprocessor built-in defines can be emitted using: * * gcc -m64 -dM -E - < /dev/null (on gcc) * cc -## a.c (where a.c is a simple test file) (Sun Studio) */ #if (defined(__i386__) || defined(__x86_64__)) #define HASH_MUR HASH_MUR_UNALIGNED #else #define HASH_MUR HASH_MUR_ALIGNED #endif /* Appleby's MurmurHash fast version for unaligned-tolerant archs like i386 */ #define HASH_MUR_UNALIGNED(key,keylen,num_bkts,hashv,bkt) \ do { \ const unsigned int _mur_m = 0x5bd1e995; \ const int _mur_r = 24; \ hashv = 0xcafebabe ^ keylen; \ char *_mur_key = (char *)key; \ uint32_t _mur_tmp, _mur_len = keylen; \ \ for (;_mur_len >= 4; _mur_len-=4) { \ _mur_tmp = *(uint32_t *)_mur_key; \ _mur_tmp *= _mur_m; \ _mur_tmp ^= _mur_tmp >> _mur_r; \ _mur_tmp *= _mur_m; \ hashv *= _mur_m; \ hashv ^= _mur_tmp; \ _mur_key += 4; \ } \ \ switch(_mur_len) \ { \ case 3: hashv ^= _mur_key[2] << 16; \ case 2: hashv ^= _mur_key[1] << 8; \ case 1: hashv ^= _mur_key[0]; \ hashv *= _mur_m; \ }; \ \ hashv ^= hashv >> 13; \ hashv *= _mur_m; \ hashv ^= hashv >> 15; \ \ bkt = hashv & (num_bkts-1); \ } while(0) /* Appleby's MurmurHash version for alignment-sensitive archs like Sparc */ #define HASH_MUR_ALIGNED(key,keylen,num_bkts,hashv,bkt) \ do { \ const unsigned int _mur_m = 0x5bd1e995; \ const int _mur_r = 24; \ hashv = 0xcafebabe ^ keylen; \ char *_mur_key = (char *)key; \ uint32_t _mur_len = keylen; \ int _mur_align = (int)_mur_key & 3; \ \ if (_mur_align && (_mur_len >= 4)) { \ unsigned _mur_t = 0, _mur_d = 0; \ switch(_mur_align) { \ case 1: _mur_t |= _mur_key[2] << 16; \ case 2: _mur_t |= _mur_key[1] << 8; \ case 3: _mur_t |= _mur_key[0]; \ } \ _mur_t <<= (8 * _mur_align); \ _mur_key += 4-_mur_align; \ _mur_len -= 4-_mur_align; \ int _mur_sl = 8 * (4-_mur_align); \ int _mur_sr = 8 * _mur_align; \ \ for (;_mur_len >= 4; _mur_len-=4) { \ _mur_d = *(unsigned *)_mur_key; \ _mur_t = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \ unsigned _mur_k = _mur_t; \ _mur_k *= _mur_m; \ _mur_k ^= _mur_k >> _mur_r; \ _mur_k *= _mur_m; \ hashv *= _mur_m; \ hashv ^= _mur_k; \ _mur_t = _mur_d; \ _mur_key += 4; \ } \ _mur_d = 0; \ if(_mur_len >= _mur_align) { \ switch(_mur_align) { \ case 3: _mur_d |= _mur_key[2] << 16; \ case 2: _mur_d |= _mur_key[1] << 8; \ case 1: _mur_d |= _mur_key[0]; \ } \ unsigned _mur_k = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \ _mur_k *= _mur_m; \ _mur_k ^= _mur_k >> _mur_r; \ _mur_k *= _mur_m; \ hashv *= _mur_m; \ hashv ^= _mur_k; \ _mur_k += _mur_align; \ _mur_len -= _mur_align; \ \ switch(_mur_len) \ { \ case 3: hashv ^= _mur_key[2] << 16; \ case 2: hashv ^= _mur_key[1] << 8; \ case 1: hashv ^= _mur_key[0]; \ hashv *= _mur_m; \ } \ } else { \ switch(_mur_len) \ { \ case 3: _mur_d ^= _mur_key[2] << 16; \ case 2: _mur_d ^= _mur_key[1] << 8; \ case 1: _mur_d ^= _mur_key[0]; \ case 0: hashv ^= (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \ hashv *= _mur_m; \ } \ } \ \ hashv ^= hashv >> 13; \ hashv *= _mur_m; \ hashv ^= hashv >> 15; \ } else { \ for (;_mur_len >= 4; _mur_len-=4) { \ unsigned _mur_k = *(unsigned*)_mur_key; \ _mur_k *= _mur_m; \ _mur_k ^= _mur_k >> _mur_r; \ _mur_k *= _mur_m; \ hashv *= _mur_m; \ hashv ^= _mur_k; \ _mur_key += 4; \ } \ switch(_mur_len) \ { \ case 3: hashv ^= _mur_key[2] << 16; \ case 2: hashv ^= _mur_key[1] << 8; \ case 1: hashv ^= _mur_key[0]; \ hashv *= _mur_m; \ } \ \ hashv ^= hashv >> 13; \ hashv *= _mur_m; \ hashv ^= hashv >> 15; \ } \ bkt = hashv & (num_bkts-1); \ } while(0) #endif /* HASH_USING_NO_STRICT_ALIASING */ /* key comparison function; return 0 if keys equal */ #define HASH_KEYCMP(a,b,len) memcmp(a,b,len) /* iterate over items in a known bucket to find desired item */ #define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ out = TYPEOF(out)((head.hh_head) ? ELMT_FROM_HH(tbl,head.hh_head) : NULL); \ while (out) { \ if (out->hh.keylen == keylen_in) { \ if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \ } \ out= TYPEOF(out)((out->hh.hh_next) ? \ ELMT_FROM_HH(tbl,out->hh.hh_next) : NULL); \ } /* add an item to a bucket */ #define HASH_ADD_TO_BKT(head,addhh) \ do { \ head.count++; \ (addhh)->hh_next = head.hh_head; \ (addhh)->hh_prev = NULL; \ if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ (head).hh_head=addhh; \ if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ && (addhh)->tbl->noexpand != 1) { \ HASH_EXPAND_BUCKETS((addhh)->tbl); \ } \ } while(0) /* remove an item from a given bucket */ #define HASH_DEL_IN_BKT(hh,head,hh_del) \ (head).count--; \ if ((head).hh_head == hh_del) { \ (head).hh_head = hh_del->hh_next; \ } \ if (hh_del->hh_prev) { \ hh_del->hh_prev->hh_next = hh_del->hh_next; \ } \ if (hh_del->hh_next) { \ hh_del->hh_next->hh_prev = hh_del->hh_prev; \ } /* Bucket expansion has the effect of doubling the number of buckets * and redistributing the items into the new buckets. Ideally the * items will distribute more or less evenly into the new buckets * (the extent to which this is true is a measure of the quality of * the hash function as it applies to the key domain). * * With the items distributed into more buckets, the chain length * (item count) in each bucket is reduced. Thus by expanding buckets * the hash keeps a bound on the chain length. This bounded chain * length is the essence of how a hash provides constant time lookup. * * The calculation of tbl->ideal_chain_maxlen below deserves some * explanation. First, keep in mind that we're calculating the ideal * maximum chain length based on the *new* (doubled) bucket count. * In fractions this is just n/b (n=number of items,b=new num buckets). * Since the ideal chain length is an integer, we want to calculate * ceil(n/b). We don't depend on floating point arithmetic in this * hash, so to calculate ceil(n/b) with integers we could write * * ceil(n/b) = (n/b) + ((n%b)?1:0) * * and in fact a previous version of this hash did just that. * But now we have improved things a bit by recognizing that b is * always a power of two. We keep its base 2 log handy (call it lb), * so now we can write this with a bit shift and logical AND: * * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) * */ #define HASH_EXPAND_BUCKETS(tbl) \ do { \ unsigned _he_bkt; \ unsigned _he_bkt_i; \ struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ memset(_he_new_buckets, 0, \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ tbl->ideal_chain_maxlen = \ (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ tbl->nonideal_items = 0; \ for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ { \ _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ while (_he_thh) { \ _he_hh_nxt = _he_thh->hh_next; \ HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ tbl->nonideal_items++; \ _he_newbkt->expand_mult = _he_newbkt->count / \ tbl->ideal_chain_maxlen; \ } \ _he_thh->hh_prev = NULL; \ _he_thh->hh_next = _he_newbkt->hh_head; \ if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ _he_thh; \ _he_newbkt->hh_head = _he_thh; \ _he_thh = _he_hh_nxt; \ } \ } \ tbl->num_buckets *= 2; \ tbl->log2_num_buckets++; \ uthash_free( tbl->buckets ); \ tbl->buckets = _he_new_buckets; \ tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ (tbl->ineff_expands+1) : 0; \ if (tbl->ineff_expands > 1) { \ tbl->noexpand=1; \ uthash_noexpand_fyi(tbl); \ } \ uthash_expand_fyi(tbl); \ } while(0) /* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ /* Note that HASH_SORT assumes the hash handle name to be hh. * HASH_SRT was added to allow the hash handle name to be passed in. */ #define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) #define HASH_SRT(hh,head,cmpfcn) \ do { \ unsigned _hs_i; \ unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ if (head) { \ _hs_insize = 1; \ _hs_looping = 1; \ _hs_list = &((head)->hh); \ while (_hs_looping) { \ _hs_p = _hs_list; \ _hs_list = NULL; \ _hs_tail = NULL; \ _hs_nmerges = 0; \ while (_hs_p) { \ _hs_nmerges++; \ _hs_q = _hs_p; \ _hs_psize = 0; \ for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ _hs_psize++; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ if (! (_hs_q) ) break; \ } \ _hs_qsize = _hs_insize; \ while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ if (_hs_psize == 0) { \ _hs_e = _hs_q; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_qsize--; \ } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ _hs_e = _hs_p; \ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ ((void*)((char*)(_hs_p->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_psize--; \ } else if (( \ cmpfcn(TYPEOF(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ TYPEOF(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ ) <= 0) { \ _hs_e = _hs_p; \ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ ((void*)((char*)(_hs_p->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_psize--; \ } else { \ _hs_e = _hs_q; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_qsize--; \ } \ if ( _hs_tail ) { \ _hs_tail->next = ((_hs_e) ? \ ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ } else { \ _hs_list = _hs_e; \ } \ _hs_e->prev = ((_hs_tail) ? \ ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ _hs_tail = _hs_e; \ } \ _hs_p = _hs_q; \ } \ _hs_tail->next = NULL; \ if ( _hs_nmerges <= 1 ) { \ _hs_looping=0; \ (head)->hh.tbl->tail = _hs_tail; \ (head) = TYPEOF(head)ELMT_FROM_HH((head)->hh.tbl, _hs_list); \ } \ _hs_insize *= 2; \ } \ HASH_FSCK(hh,head); \ } \ } while (0) /* This function selects items from one hash into another hash. * The end result is that the selected items have dual presence * in both hashes. There is no copy of the items made; rather * they are added into the new hash through a secondary hash * hash handle that must be present in the structure. */ #define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ do { \ unsigned _src_bkt, _dst_bkt; \ void *_last_elt=NULL, *_elt; \ UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ if (src) { \ for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ _src_hh; \ _src_hh = _src_hh->hh_next) { \ _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ if (cond(_elt)) { \ _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ _dst_hh->key = _src_hh->key; \ _dst_hh->keylen = _src_hh->keylen; \ _dst_hh->hashv = _src_hh->hashv; \ _dst_hh->prev = _last_elt; \ _dst_hh->next = NULL; \ if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ if (!dst) { \ dst = TYPEOF(dst)_elt; \ HASH_MAKE_TABLE(hh_dst,dst); \ } else { \ _dst_hh->tbl = (dst)->hh_dst.tbl; \ } \ HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ (dst)->hh_dst.tbl->num_items++; \ _last_elt = _elt; \ _last_elt_hh = _dst_hh; \ } \ } \ } \ } \ HASH_FSCK(hh_dst,dst); \ } while (0) #define HASH_CLEAR(hh,head) \ do { \ if (head) { \ uthash_free((head)->hh.tbl->buckets ); \ uthash_free((head)->hh.tbl); \ (head)=NULL; \ } \ } while(0) /* obtain a count of items in the hash */ #define HASH_COUNT(head) HASH_CNT(hh,head) #define HASH_CNT(hh,head) (head?(head->hh.tbl->num_items):0) typedef struct UT_hash_bucket { struct UT_hash_handle *hh_head; unsigned count; /* expand_mult is normally set to 0. In this situation, the max chain length * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If * the bucket's chain exceeds this length, bucket expansion is triggered). * However, setting expand_mult to a non-zero value delays bucket expansion * (that would be triggered by additions to this particular bucket) * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. * (The multiplier is simply expand_mult+1). The whole idea of this * multiplier is to reduce bucket expansions, since they are expensive, in * situations where we know that a particular bucket tends to be overused. * It is better to let its chain length grow to a longer yet-still-bounded * value, than to do an O(n) bucket expansion too often. */ unsigned expand_mult; } UT_hash_bucket; /* random signature used only to find hash tables in external analysis */ #define HASH_SIGNATURE 0xa0111fe1 #define HASH_BLOOM_SIGNATURE 0xb12220f2 typedef struct UT_hash_table { UT_hash_bucket *buckets; unsigned num_buckets, log2_num_buckets; unsigned num_items; struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ /* in an ideal situation (all buckets used equally), no bucket would have * more than ceil(#items/#buckets) items. that's the ideal chain length. */ unsigned ideal_chain_maxlen; /* nonideal_items is the number of items in the hash whose chain position * exceeds the ideal chain maxlen. these items pay the penalty for an uneven * hash distribution; reaching them in a chain traversal takes >ideal steps */ unsigned nonideal_items; /* ineffective expands occur when a bucket doubling was performed, but * afterward, more than half the items in the hash had nonideal chain * positions. If this happens on two consecutive expansions we inhibit any * further expansion, as it's not helping; this happens when the hash * function isn't a good fit for the key domain. When expansion is inhibited * the hash will still work, albeit no longer in constant time. */ unsigned ineff_expands, noexpand; uint32_t signature; /* used only to find hash tables in external analysis */ #ifdef HASH_BLOOM uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ uint8_t *bloom_bv; char bloom_nbits; #endif } UT_hash_table; typedef struct UT_hash_handle { struct UT_hash_table *tbl; void *prev; /* prev element in app order */ void *next; /* next element in app order */ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ struct UT_hash_handle *hh_next; /* next hh in bucket order */ void *key; /* ptr to enclosing struct's key */ unsigned keylen; /* enclosing struct's key len */ unsigned hashv; /* result of hash-fcn(key) */ } UT_hash_handle; #endif /* UTHASH_H */ medusa-2.1.1/src/medusa-thread-ssl.h0000644000175000001440000000046011723732127014175 00000000000000/* * * Functions to enable multi-threaded use of crypto libraries. * * OpenSSL -- http://www.openssl.org/docs/crypto/threads.html * Libgcrypt -- http://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html * */ extern void init_crypto_locks(void); extern void kill_crypto_locks(void); medusa-2.1.1/src/medusa-net.h0000644000175000001440000000560411723732127012722 00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. See the * GNU General Public License for more details. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ #ifndef _MEDUSA_NET_H #define _MEDUSA_NET_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "medusa.h" #define OPTION_SSL 1 #define MAX_CONNECT_RETRY 3 #define WAIT_BETWEEN_CONNECT_RETRY 3 #define DEFAULT_WAIT_TIME 3 // 3 second max wait on connects #define READ_WAIT_TIME 20 * 1000000 // Time to wait for a receive in microseconds typedef struct __sConnectParams { long nHost; int nPort; int nUseSSL; float nSSLVersion; int nProtocol; int nType; unsigned long nProxyStringIP; int nProxyStringPort; char* szProxyAuthentication; int nTimeout; int nRetries; int nRetryWait; int nSourcePort; } sConnectParams; extern int medusaConnect(sConnectParams* pParams); extern int medusaConnectSSL(sConnectParams* pParams); extern int medusaConnectSocketSSL(sConnectParams* pParams, int hSocket); extern int medusaConnectTCP(sConnectParams* pParams); extern int medusaConnectUDP(sConnectParams* pParams); extern int medusaDisconnect(int socket); extern int medusaDataReadyWritingTimed(int socket, time_t sec, time_t usec); extern int medusaDataReadyWriting(int socket); extern int medusaDataReadyTimed(int socket, time_t sec, time_t usec); extern int medusaDataReady(int socket); extern int medusaReceive(int socket, char *buf, int length); extern char* medusaReceiveRaw(int socket, int* nBufferSize); extern char* medusaReceiveRawDelay(int socket, int* nBufferSize, int nReceiveDelay1, int nReceiveDelay2); extern char* medusaReceiveLine(int socket, int* nBufferSize); extern char* medusaReceiveLineDelay(int socket, int* nBufferSize, int nReceiveDelay, int nReceiveDelay2); extern int medusaReceiveRegex(int hSocket, unsigned char **szBufReceive, int* nBufReceive, const char* regex); extern int medusaSend(int socket, char *buf, int size, int options); extern int makeToLower(char *buf); #endif medusa-2.1.1/src/medusa-utils.h0000644000175000001440000000235611723732127013275 00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. See the * GNU General Public License for more details. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ #ifndef _MEDUSA_UTILS_H #define _MEDUSA_UTILS_H /* How many bytes it will take to store LEN bytes in base64. */ #define BASE64_LENGTH(len) (4 * (((len) + 2) / 3)) extern int base64_encode(const char *str, int length, char *b64store); extern int base64_decode(const char *base64, char *to); extern char *basic_authentication_encode(const char *user, const char *passwd); /* solaris doesn't have a strcasestr */ #ifndef HAVE_STRCASESTR char *strcasestr(const char *, const char *); #endif #endif medusa-2.1.1/src/medusa.h0000644000175000001440000001706211723732127012137 00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. See the * GNU General Public License for more details. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ #ifndef _MEDUSA_H #define _MEDUSA_H #include #include #include #include #include #include #include #include #include #include #include #include "medusa-trace.h" #include "medusa-net.h" #include "medusa-thread-pool.h" #include "medusa-thread-ssl.h" #ifdef HAVE_CONFIG_H #include #endif #define PROGRAM "Medusa" #ifndef VERSION #define VERSION "1.0" #endif #define AUTHOR "JoMo-Kun / Foofus Networks" #define EMAIL "" #define WWW "http://www.foofus.net" #define SUCCESS 0 #define FAILURE -1 #define FALSE 0 #define TRUE 1 /* GLOBAL VARIABLES */ FILE *pOutputFile; pthread_mutex_t ptmFileMutex; int iVerboseLevel; // Global control over general message verbosity int iErrorLevel; // Global control over error debugging verbosity //#define MAX_BUF (16 * 1024) #define MAX_BUF 16384 /* Older Solaris doesn't seem to define INADDR_NONE */ #ifndef INADDR_NONE #define INADDR_NONE ((unsigned long) -1 #endif /* Cygwin doesn't seem to define INET_ADDRSTRLEN */ #ifndef INET_ADDRSTRLEN #define INET_ADDRSTRLEN 16 #endif // Number of seconds that idle threads can linger before exiting, when no tasks // come in. The idle threads can only exit if they are extra threads, above the // number of minimum threads. #define POOL_THREAD_LINGER 1 #define FREE(x) \ if (x != NULL) { \ free(x); \ x = NULL; \ } #define L_UNSET 0 #define L_SINGLE 1 #define L_FILE 2 #define L_COMBO 3 #define L_PWDUMP 4 typedef struct __sPass { struct __sPass *psPassNext; char *pPass; } sPass; /* Used in __sUser to define progress of an individual username audit */ #define PL_UNSET 0 #define PL_NULL 1 #define PL_USERNAME 2 #define PL_LOCAL 3 #define PL_GLOBAL 4 #define PL_DONE 5 #define PASS_AUDIT_COMPLETE 6 typedef struct __sUser { struct __sUser *psUserNext; char *pUser; struct __sPass *psPass; struct __sPass *psPassCurrent; struct __sPass *psPassPrevTmp; char *pPass; int iPassCnt; int iLoginsDone; int iPassStatus; int iId; } sUser; /* Used in __sHost to define progress of the audit of the host's users */ #define UL_UNSET 0 #define UL_NORMAL 1 #define UL_MISSED 2 #define UL_DONE 3 #define UL_ERROR 4 typedef struct __sHost { struct __sHost *psHostNext; char *pHost; int iUseSSL; // use SSL int iPortOverride; // use this port instead of the module's default port int iTimeout; // Number of seconds to wait before a connection times out int iRetryWait; // Number of seconds to wait between retries int iRetries; // Number of retries to attempt sUser *psUser; sUser *psUserCurrent; sUser *psUserPrevTmp; int iUserCnt; int iUserPassCnt; int iUsersDone; // number of users tested int iUserStatus; int iId; } sHost; /* Used in __sCredentialSet to relay information to module regarding user */ #define CREDENTIAL_SAME_USER 1 #define CREDENTIAL_NEW_USER 2 #define CREDENTIAL_DONE 3 typedef struct __sCredentialSet { struct __sCredentialSet *psCredentialSetNext; struct __sUser *psUser; char *pPass; int iStatus; } sCredentialSet; typedef struct __sServer { struct __sAudit *psAudit; struct __sHost *psHost; char *pHostIP; int iValidPairFound; int iId; int iLoginCnt; // total number of logins performed concurrently against specific server int iLoginsDone; // number of logins performed by all threads under this server sCredentialSet *psCredentialSetMissed; sCredentialSet *psCredentialSetMissedCurrent; sCredentialSet *psCredentialSetMissedTail; int iCredentialsMissed; pthread_mutex_t ptmMutex; } sServer; #define LOGIN_RESULT_UNKNOWN 1 #define LOGIN_RESULT_SUCCESS 2 #define LOGIN_RESULT_FAIL 3 #define LOGIN_RESULT_ERROR 4 typedef struct __sLogin { struct __sServer *psServer; struct __sUser *psUser; int iResult; char *pErrorMsg; int iId; int iLoginsDone; // number of logins performed by this thread } sLogin; #define AUDIT_IN_PROGRESS 0 #define AUDIT_COMPLETE 1 #define LIST_IN_PROGRESS 0 #define LIST_COMPLETE 1 #define FOUND_PAIR_EXIT_HOST 1 #define FOUND_PAIR_EXIT_AUDIT 2 #define PARALLEL_LOGINS_USER 1 #define PARALLEL_LOGINS_PASSWORD 2 #define AUDIT_ABORT 1 typedef struct __sAudit { char *pOptHost; // user specified host or host file char *pOptUser; // user specified username or username file char *pOptPass; // user specified password or password file char *pOptCombo; // user specified combo host/username/password file char *pOptOutput; // user specified output file char *pOptResume; // user specified resume command char *pModuleName; // current module name char *pGlobalHost; char *pGlobalUser; char *pGlobalPass; char *pGlobalCombo; char *pHostFile; char *pUserFile; char *pPassFile; char *pComboFile; int iHostCnt; // total number of hosts supplied for testing int iUserCnt; // total number of users supplied for testing int iPassCnt; // total number of passwords supplied for testing int iComboCnt; // total number of entries in combo file int iServerCnt; // total number of hosts scanned concurrently int iLoginCnt; // total number of logins performed concurrently int iHostsDone; // number of hosts tested int iPortOverride; // use this port instead of the module's default port int iUseSSL; // enable SSL int iTimeout; // Number of seconds to wait before a connection times out int iRetryWait; // Number of seconds to wait between retries int iRetries; // Number of retries to attempt int iSocketWait; // Number of usec to wait when module calls medusaCheckSocket function int HostType; int UserType; int PassType; int iShowModuleHelp; // Flag used to show individual module help char *pComboEntryTmp; // used to managed processing of user supplied files int iHostListFlag; int iUserListFlag; int iAuditFlag; /* Tracks loading of user supplied information */ int iPasswordBlankFlag; /* Submit a blank password for each user account */ int iPasswordUsernameFlag; /* Submit a password matching the username for each user account */ int iFoundPairExitFlag; /* When a valid login pair is found, end scan of host or of complete audit */ int iParallelLoginFlag; /* Parallel logins by user or password */ int iValidPairFound; int iStatus; /* Flag to indicate to threads that audit is aborting */ sHost *psHostRoot; thr_pool_t *server_pool; pthread_mutex_t ptmMutex; } sAudit; typedef struct __sModuleStart { char* szModuleName; sLogin* pLogin; int argc; char** argv; } sModuleStart; #define _MEDUSA_H #endif medusa-2.1.1/src/Makefile.in0000644000175000001440000005074711760000304012546 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = medusa$(EXEEXT) subdir = src DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_medusa_OBJECTS = listModules.$(OBJEXT) medusa.$(OBJEXT) \ medusa-thread-pool.$(OBJEXT) medusa-thread-ssl.$(OBJEXT) \ medusa-net.$(OBJEXT) medusa-trace.$(OBJEXT) \ medusa-utils.$(OBJEXT) medusa_OBJECTS = $(am_medusa_OBJECTS) medusa_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(medusa_SOURCES) DIST_SOURCES = $(medusa_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive HEADERS = $(noinst_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ APR_CONFIG = @APR_CONFIG@ APR_INCLUDE_DIR = @APR_INCLUDE_DIR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_MOD_PATH = @DEFAULT_MOD_PATH@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODULE_LIBS = @MODULE_LIBS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ medusa_SOURCES = listModules.c medusa.c medusa-thread-pool.c medusa-thread-ssl.c medusa-net.c medusa-trace.c medusa-utils.c # set the include path found by configure INCLUDES = -I$(top_srcdir)/src $(all_includes) # the library search path. #medusa_LDFLAGS = -rdynamic -ldl -lpthread -lssl noinst_HEADERS = medusa.h medusa-thread-pool.h medusa-thread-ssl.h medusa-net.h medusa-trace.h medusa-utils.h uthash.h #AM_CFLAGS = -DLIBOPENSSL SUBDIRS = modsrc all: all-recursive .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) medusa$(EXEEXT): $(medusa_OBJECTS) $(medusa_DEPENDENCIES) @rm -f medusa$(EXEEXT) $(LINK) $(medusa_OBJECTS) $(medusa_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/listModules.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medusa-net.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medusa-thread-pool.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medusa-thread-ssl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medusa-trace.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medusa-utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medusa.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-binPROGRAMS \ clean-generic ctags ctags-recursive distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: medusa-2.1.1/src/medusa-thread-ssl.c0000644000175000001440000000344011723732127014171 00000000000000/* * * Functions to enable multi-threaded use of crypto libraries. * * OpenSSL -- http://www.openssl.org/docs/crypto/threads.html * Libgcrypt -- http://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html * * This code is based on Curl 7.21.1 * * See for interface declarations. * */ #include "medusa.h" #ifdef HAVE_LIBSSL static pthread_mutex_t *lockarray; #include static void lock_callback(int mode, int type, char *file, int line) { (void)file; (void)line; if (mode & CRYPTO_LOCK) { pthread_mutex_lock(&(lockarray[type])); } else { pthread_mutex_unlock(&(lockarray[type])); } } static unsigned long thread_id(void) { unsigned long ret; ret=(unsigned long)pthread_self(); return(ret); } void init_locks_openssl(void) { int i; lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); for (i=0; i #include GCRY_THREAD_OPTION_PTHREAD_IMPL; void init_locks_gnutls(void) { gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); gnutls_global_init(); } #endif void init_crypto_locks(void) { #ifdef HAVE_LIBSSL init_locks_openssl(); #endif #ifdef HAVE_GNUTLS init_locks_gnutls(); #endif } void kill_crypto_locks(void) { #ifdef HAVE_LIBSSL kill_locks_openssl(); #endif } medusa-2.1.1/src/medusa-net.c0000644000175000001440000006441711750566000012717 00000000000000/*************************************************************************** * medusa-net.c * * Copyright (C) 2006 by fizzgig * * fizzgig@foofus.net * * * * Low level networking stuff used by all medusa modules. * * Based heavily on the original hydra networking code by * * VanHauser and the good folks at thc (vh@thc.org). * * * * * * CHANGE LOG * * 04/04/2005 -- Created by fizzgig (fizzgig@foofus.net) * * 04/12/2005 -- Final "alpha" implementation * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * 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. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * * This program is released under the GPL with the additional exemption * * that compiling, linking, and/or using OpenSSL is allowed. * * * ***************************************************************************/ #include "medusa.h" #include "medusa-trace.h" #include "medusa-net.h" #include "uthash.h" #include #include #ifdef HAVE_LIBSSL #include #include #endif #ifdef HAVE_LIBSSL /* Original code utilized global variables for SSL socket support. Unfortunately, this could potentially be an issue in cases where modules utilize both SSL and non-SSL within a session (e.g. FTPS). It's possible one thread could connect to a service in the clear while another requires SSL. The global variable obviously makes this impossible. Ideally, this data should be unique to thread and tracked there. However, I believe implementing this would require rewriting all send/receive calls. For now, we are utilizing a hash of socket id to SSL information structure for tracking which connections require SSL. */ struct SSLSOCKETINFO { int id; /* key --> socket id */ int nUseSSL; SSL *ssl; SSL_CTX *sslContext; UT_hash_handle hh; /* required for UThash */ }; struct SSLSOCKETINFO *psSSLSocketInfo = NULL; pthread_mutex_t ptmSSLMutex; #endif // Modules can call this function to set up the sConnectParams structure needed for connection functions. // It copies data from the login structure and overrides default values if the user specified command-line // parameters. The typical use of this function, then, is: // 1) Create a sConnectParams structure // 2) Zero all members of the structure // 3) Set individual members of the structure with default module values (like port) // 4) Call initConnectionParams void initConnectionParams(sLogin* pLogin, sConnectParams* pParams) { pParams->nHost = inet_addr(pLogin->psServer->pHostIP); if (pLogin->psServer->psHost->iPortOverride != 0) { // Override the port pParams->nPort = pLogin->psServer->psHost->iPortOverride; } pParams->nUseSSL = pLogin->psServer->psHost->iUseSSL; pParams->nTimeout = pLogin->psServer->psHost->iTimeout; pParams->nRetryWait = pLogin->psServer->psHost->iRetryWait; pParams->nRetries = pLogin->psServer->psHost->iRetries; if (pParams->nProtocol == 0) pParams->nProtocol = SOCK_STREAM; if (pParams->nType == 0) pParams->nType = 6; } int medusaConnectInternal(unsigned long nHost, int nPort, int nProtocol, int nType, int nWaitTime, int nRetries, int nRetryWait,unsigned long nProxyStringIP, int nProxyStringPort, char* szProxyAuthentication, int nSourcePort) { int s, ret = -1; int nFail = 0; struct sockaddr_in target, source; char *buf, *tmpptr = NULL; char out[16]; long flag; int nOpt, nSize; fd_set myset; struct timeval tv; int nUseProxy = nProxyStringIP > 0 ? 1 : 0; s = socket(PF_INET, nProtocol, nType); if (s >= 0) { /* Handle a source port request from a module */ if ( nSourcePort != 0 ) { int bind_ok=0; source.sin_family = PF_INET; source.sin_port = htons(nSourcePort); source.sin_addr.s_addr = INADDR_ANY; /* We will try to find a free port down to 512 */ while (!bind_ok && nSourcePort >= 512) { if (bind(s, (struct sockaddr *)&source, sizeof(source))==-1) { if (errno == EADDRINUSE) { writeError(ERR_DEBUG, "Port %d in use trying next lower port.", nSourcePort); nSourcePort--; source.sin_port = htons(nSourcePort); } else { if (errno == EACCES && (getuid() > 0)) { writeError(ERR_ERROR, "Source port for this service requires root privileges."); return FAILURE; } } } else bind_ok=1; } } /* End of source port fun */ if (nUseProxy > 0) { target.sin_port = htons(nProxyStringPort); memcpy(&target.sin_addr.s_addr, &nProxyStringIP, sizeof(unsigned long)); } else { target.sin_port = htons(nPort); memcpy(&target.sin_addr.s_addr, &nHost, sizeof(unsigned long)); } target.sin_family = AF_INET; // Set non-blocking if((flag = fcntl(s, F_GETFL, NULL)) < 0) { writeError(ERR_ERROR, "Error fcntl(..., F_GETFL) (%s)", strerror(errno)); return -1; } flag |= O_NONBLOCK; if(fcntl(s, F_SETFL, flag) < 0) { writeError(ERR_ERROR, "Error fcntl(..., F_SETFL) (%s)", strerror(errno)); return -1; } nFail = 0; ret = connect(s, (struct sockaddr*)&target, sizeof(struct sockaddr_in)); if (errno == EINPROGRESS) { do { if (nFail > 0 && nFail <= nRetries) { writeError(ERR_ERROR, "Thread %X: Host: %s Cannot connect [unreachable], retrying (%d of %d retries)", (int)pthread_self(), inet_ntop(AF_INET, &target.sin_addr, out, sizeof(out)), nFail, nRetries); sleep(nRetryWait); } else if (nFail > nRetries) return -1; tv.tv_sec = nWaitTime; tv.tv_usec = 0; FD_ZERO(&myset); FD_SET(s, &myset); ret = select(s + 1, NULL, &myset, NULL, &tv); if (ret < 0 && errno != EINTR) { writeError(ERR_ERROR, "Error connecting to host: %s", strerror(errno)); return -1; } else if (ret > 0) { nSize = sizeof(int); if (getsockopt(s, SOL_SOCKET, SO_ERROR, (void*)(&nOpt), &nSize) < 0) { writeError(ERR_ERROR, "Error in getsockopt() %s", strerror(errno)); return -1; } if (nOpt != 0) { // Socket is not valid - connection failed writeVerbose(VB_GENERAL, "Unable to connect (invalid socket): unreachable destination - %s", inet_ntop(AF_INET, &target.sin_addr, out, sizeof(out))); return -1; } // If we get here, the socket should be valid ret = 0; break; } else { nFail++; } } while (1); } if (ret != 0 || nFail > nRetries) { writeVerbose(VB_GENERAL, "Unable to connect: unreachable destination"); ret = -1; return ret; } // Set the socket to be blocking again if((flag = fcntl(s, F_GETFL, NULL)) < 0) { writeError(ERR_ERROR, "Error fcntl(..., F_GETFL) (%s)", strerror(errno)); return -1; } flag &= ~O_NONBLOCK; if(fcntl(s, F_SETFL, flag) < 0) { writeError(ERR_ERROR, "Error fcntl(..., F_SETFL) (%s)", strerror(errno)); return -1; } ret = s; writeError(ERR_DEBUG, "Connected (internal)"); if (nUseProxy > 0) { buf = malloc(4096); memset(buf, 0, 4096); memset(&target, 0, sizeof(struct sockaddr_in)); memcpy(&target.sin_addr.s_addr, &nHost, sizeof(unsigned long)); target.sin_family = AF_INET; if (szProxyAuthentication == NULL) snprintf(buf, 4095, "CONNECT %s:%d HTTP/1.0\r\n\r\n", inet_ntop(AF_INET, &target.sin_addr, out, sizeof(out)), nPort); else snprintf(buf, 4095, "CONNECT %s:%d HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n", inet_ntop(AF_INET, &target.sin_addr, out, sizeof(out)), nPort, szProxyAuthentication); send(s, buf, strlen(buf), 0); recv(s, buf, 4096, 0); if (strncmp("HTTP/", buf, strlen("HTTP/")) == 0 && (tmpptr = index(buf, ' ')) != NULL && *++tmpptr == '2') { writeError(ERR_DEBUG, "Connected (with proxy)"); } else { //writeError(ERR_DEBUG, "Unable to connect using SSL (Code: %c%c%c)", *tmpptr, *(tmpptr + 1), *(tmpptr + 2)); writeError(ERR_ERROR, "CONNECT call to proxy failed with code %c%c%c", *tmpptr, *(tmpptr + 1), *(tmpptr + 2)); close(s); ret = -1; free(buf); return ret; } free(buf); } nFail = 0; return ret; } return ret; } #ifdef HAVE_LIBSSL RSA *sslTempRSACallback(SSL * ssl, int export, int keylength) { /* "rsa" was previously global... do we ever need to return a previously generated value? */ RSA *rsa = NULL; if (rsa == NULL) rsa = RSA_generate_key(512, RSA_F4, NULL, NULL); return rsa; } int medusaConnectSSLInternal(sConnectParams* pParams, int hSocket) { int err; struct SSLSOCKETINFO *s; SSL *ssl = NULL; SSL_CTX *sslContext = NULL; pthread_mutex_lock(&ptmSSLMutex); SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); /* The SSL context can support SSLv2, SSLv3, or both. The default is to use whatever the server demands. The module can override this by setting nSSLVersion. */ /* Debian's OpenSSL has SSLv2 support disabled. */ #ifndef OPENSSL_NO_SSL2 if (pParams->nSSLVersion == 2) sslContext = SSL_CTX_new(SSLv2_client_method()); else #endif if (pParams->nSSLVersion == 3) sslContext = SSL_CTX_new(SSLv3_client_method()); else if (pParams->nSSLVersion == (float)3.1) sslContext = SSL_CTX_new(TLSv1_client_method()); else sslContext = SSL_CTX_new(SSLv23_client_method()); if (sslContext == NULL) { err = ERR_get_error(); writeError(ERR_ERROR, "SSL: Error allocating context: %s", ERR_error_string(err, NULL)); return -1; } // set the compatbility mode SSL_CTX_set_options(sslContext, SSL_OP_ALL); // we set the default verifiers and dont care for the results SSL_CTX_set_default_verify_paths(sslContext); SSL_CTX_set_tmp_rsa_callback(sslContext, sslTempRSACallback); SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL); if ((hSocket < 0) && ((hSocket = medusaConnect(pParams)) < 0)) return -1; if ((ssl = SSL_new(sslContext)) == NULL) { err = ERR_get_error(); writeError(ERR_ERROR, "Error preparing an SSL context: %s", ERR_error_string(err, NULL)); return -1; } SSL_set_fd(ssl, hSocket); if (SSL_connect(ssl) <= 0) { err = ERR_get_error(); writeError(ERR_ERROR, "Could not create an SSL session: %s", ERR_error_string(err, NULL)); return -1; } writeError(ERR_DEBUG, "SSL negotiated cipher: %s", SSL_get_cipher(ssl)); s = malloc(sizeof(struct SSLSOCKETINFO)); memset(s, 0, sizeof(struct SSLSOCKETINFO)); s->id = hSocket; s->nUseSSL = 1; s->ssl = ssl; s->sslContext = sslContext; HASH_ADD_INT( psSSLSocketInfo, id, s ); pthread_mutex_unlock(&ptmSSLMutex); return hSocket; } #endif int medusaReceiveInternal(int socket, char *buf, int length) { #ifdef HAVE_LIBSSL int err; int nRet; struct SSLSOCKETINFO *s; HASH_FIND_INT( psSSLSocketInfo, &socket, s ); if ((s != NULL) && (s->nUseSSL)) { do { nRet = SSL_read(s->ssl, buf, length); if (nRet <= 0) { err = SSL_get_error(s->ssl, nRet); switch(err) { case SSL_ERROR_ZERO_RETURN: writeError(ERR_DEBUG, "The TLS/SSL connection has been closed."); break; case SSL_ERROR_SSL: writeError(ERR_ERROR, "A failure in the SSL library occurred, usually a protocol error."); break; case SSL_ERROR_SYSCALL: writeError(ERR_DEBUG, "TLS/SSL I/O error occurered (%d - %s)", err, ERR_error_string(err, NULL)); break; default: writeError(ERR_ERROR, "Unknown TLS/SSL error occurred (%d - %s)", err, ERR_error_string(err, NULL)); } } } while (nRet == -1 && err == SSL_ERROR_SYSCALL && errno == EINTR); return nRet; } else #endif return recv(socket, buf, length, 0); } /* This is a more robust receive function that can optionally convert NULLS to spaces Callers should check the value of *nBufferSize on return - IT MAY HAVE BEEN CHANGED */ char* medusaReceiveDataInternal(int socket, int* nBufferSize, int nConvertNullsToSpaces, int nReceiveDelay1, int nReceiveDelay2) { /* When receiving UDP packets, we need to be mindful of packets exceeding our default buffer size. Since we configure our UDP socket as SOCK_DGRAM, any packets beyond the buffer size will be discarded following a recv() call. UDP messages, or datagrams, should have the entire message within a single packet. The actual maximum size of this packet is unknown, however, due to a number of variables (see reference below). For our purposes, we are going to use the value of 576. http://www.uic.rsu.ru/doc/inet/tcp_stevens/ip_inter.htm#3_2 Although it's possible to send a 65535-byte IP datagram, most link layers will fragment this. Furthermore, a host is not required to receive a datagram larger than 576 bytes. TCP divides the user's data into pieces, so this limit normally doesn't affect TCP. With UDP we'll encounter numerous applications in later chapters (RIP, TFTP, BOOTP, the DNS, and SNMP) that limit themselves to 512 bytes of user data, to stay below this 576-byte limit. Realistically, however, most implementations today (especially those that support the Network File System, NFS) allow for just over 8192-byte IP datagrams. */ const unsigned int BUFFER_SIZE = 576; char *szBufReceive, *szBufReceiveTmp; int nBufReceive = 0, nBufReceiveTmp = 0, BufReceiveIndex = 0; int bSocketStatus = 0; int nReceiveDelay1sec = 0, nReceiveDelay1usec = 0; int nReceiveDelay2sec = 0, nReceiveDelay2usec = 0; *nBufferSize = 0; szBufReceive = malloc(BUFFER_SIZE + 1); memset(szBufReceive, 0, BUFFER_SIZE + 1); nReceiveDelay1sec = nReceiveDelay1 / 1000000; nReceiveDelay1usec = nReceiveDelay1 % 1000000; nReceiveDelay2sec = nReceiveDelay2 / 1000000; nReceiveDelay2usec = nReceiveDelay2 % 1000000; bSocketStatus = medusaDataReadyTimed(socket, nReceiveDelay1sec, nReceiveDelay1usec); if (bSocketStatus > 0) { writeError(ERR_DEBUG, "Data receive: Data waiting."); nBufReceive = medusaReceive(socket, szBufReceive, BUFFER_SIZE); if (nBufReceive <= 0) { writeError(ERR_DEBUG, "Data receive: Socket indicated data present, but none found."); free(szBufReceive); return NULL; } } else if (bSocketStatus == 0) { writeError(ERR_DEBUG, "Data receive: No data."); free(szBufReceive); return NULL; } else { writeError(ERR_ERROR, "Data receive: Failed to read from network socket."); free(szBufReceive); return NULL; } /* check for any addition data which may have been sent */ while (medusaDataReadyTimed(socket, nReceiveDelay2sec, nReceiveDelay2usec) > 0) { szBufReceiveTmp = malloc(BUFFER_SIZE + 1); memset(szBufReceiveTmp, 0, BUFFER_SIZE + 1); nBufReceiveTmp = medusaReceive(socket, szBufReceiveTmp, BUFFER_SIZE); if (nBufReceiveTmp <= 0) { writeError(ERR_DEBUG, "Data receive: No additional data."); free(szBufReceiveTmp); break; } if (nBufReceive + nBufReceiveTmp > BUFFER_SIZE) { writeError(ERR_DEBUG, "Additional data received. Increasing receive buffer %d bytes to %d.", nBufReceiveTmp, nBufReceive + nBufReceiveTmp + 1); szBufReceive = realloc(szBufReceive, nBufReceive + nBufReceiveTmp + 1); } memcpy(szBufReceive + nBufReceive, szBufReceiveTmp, nBufReceiveTmp); nBufReceive += nBufReceiveTmp; nBufReceiveTmp = 0; free(szBufReceiveTmp); } szBufReceive[nBufReceive] = 0; /* explicit NULL termination */ /* convert NULLS to spaces */ if (nConvertNullsToSpaces != 0) for (BufReceiveIndex = 0; BufReceiveIndex < nBufReceive; BufReceiveIndex++) if (szBufReceive[BufReceiveIndex] == 0) szBufReceive[BufReceiveIndex] = 32; writeError(ERR_DEBUG, "Formatted data received (size %d): %s", nBufReceive, szBufReceive); *nBufferSize = nBufReceive; return szBufReceive; } int medusaSendInternal(int socket, char *buf, int size, int options) { #ifdef HAVE_LIBSSL struct SSLSOCKETINFO *s; HASH_FIND_INT( psSSLSocketInfo, &socket, s ); if ((s != NULL) && (s->nUseSSL)) { return SSL_write(s->ssl, buf, size); } else { #endif int nRet; char *bufReceive = NULL; int nReceiveBufferSize = 0; /* flush any extraneous data remaining on socket */ /* while (medusaDataReadyTimed(socket, 0, 1) > 0) { bufReceive = medusaReceiveRaw(socket, &nReceiveBufferSize); writeError(ERR_DEBUG, "Purging extraneous data on socket from previous request (size %d): %s", nReceiveBufferSize, bufReceive); if (bufReceive == NULL) { break; } } */ nRet = send(socket, buf, size, options); if (nRet < 0) { writeError(ERR_ERROR, "Error in send() %s", strerror(errno)); } return nRet; #ifdef HAVE_LIBSSL } #endif } // ------------------ public functions ------------------ // Variants of medusaConnectInternal int medusaConnect(sConnectParams* pParams) { medusaConnectInternal(pParams->nHost, pParams->nPort, pParams->nProtocol, pParams->nType, pParams->nTimeout, pParams->nRetries, pParams->nRetryWait, pParams->nProxyStringIP, pParams->nProxyStringPort, pParams->szProxyAuthentication, pParams->nSourcePort); } int medusaConnectSSL(sConnectParams* pParams) { #ifdef HAVE_LIBSSL int hSocket; hSocket = medusaConnectSSLInternal(pParams, -1); if (hSocket > 0) pParams->nUseSSL = 1; return hSocket; #else writeError(ERR_ERROR, "Trying to connect via SSL, but medusa was not compiled with OPENSSL support. Using non-SSL connection."); pParams->nUseSSL = 0; return (medusaConnect(pParams)); #endif } /* Requires medusaConnect() to already have been called and for the socket to passed as an argument. Used for protocols which switch from non-SSL to SSL mid-connection. */ int medusaConnectSocketSSL(sConnectParams* pParams, int hSocket) { #ifdef HAVE_LIBSSL if (hSocket > 0) { pParams->nUseSSL = 1; return (medusaConnectSSLInternal(pParams, hSocket)); } else { writeError(ERR_ERROR, "Invalid socket handle."); pParams->nUseSSL = 0; return FAILURE; } #else writeError(ERR_ERROR, "Trying to connect via SSL, but medusa was not compiled with OPENSSL support."); pParams->nUseSSL = 0; return FAILURE; #endif } int medusaConnectTCP(sConnectParams* pParams) { pParams->nProtocol = SOCK_STREAM; pParams->nType = 6; return (medusaConnect(pParams)); } int medusaConnectUDP(sConnectParams* pParams) { // Modify the sConnectParams structure to make certain UDP stuff is set pParams->nProtocol = SOCK_DGRAM; pParams->nType = 17; return (medusaConnect(pParams)); } int medusaDisconnect(int hSocket) { #ifdef HAVE_LIBSSL struct SSLSOCKETINFO *s; if (hSocket <= 0) return -1; pthread_mutex_lock(&ptmSSLMutex); /* Remove socket's SSL informational structure (if it exists) */ HASH_FIND_INT( psSSLSocketInfo, &hSocket, s ); if (s != NULL) { HASH_DEL( psSSLSocketInfo, s ); } close(hSocket); pthread_mutex_unlock(&ptmSSLMutex); writeError(ERR_DEBUG, "Disconnect successful"); return -1; #else close(hSocket); writeError(ERR_DEBUG, "Disconnect successful"); return -1; #endif } int medusaDataReadyWritingTimed(int socket, time_t sec, time_t usec) { fd_set fds; struct timeval tv; FD_ZERO(&fds); FD_SET(socket, &fds); tv.tv_sec = sec; tv.tv_usec = usec; return (select(socket + 1, &fds, NULL, NULL, &tv)); } int medusaDataReadyWriting(int socket) { return (medusaDataReadyWritingTimed(socket, 30, 0)); } int medusaDataReadyTimed(int socket, time_t sec, time_t usec) { fd_set fds; struct timeval tv; FD_ZERO(&fds); FD_SET(socket, &fds); tv.tv_sec = sec; tv.tv_usec = usec; return (select(socket + 1, &fds, NULL, NULL, &tv)); } int medusaDataReady(int socket) { return (medusaDataReadyTimed(socket, 0, 0)); } /* Check socket status. Return 1 if connection is still valid. */ int medusaCheckSocket(int socket, int usec) { writeError(ERR_DEBUG, "wait time: %d", usec); if (medusaDataReadyTimed(socket, 0, usec) == 0) return 1; else return 0; } int medusaReceive(int socket, char *buf, int length) { int ret; ret = medusaReceiveInternal(socket, buf, length); writeError(ERR_DEBUG, "Data received (%d): %s", ret, buf); return ret; } char* medusaReceiveRaw(int socket, int* nBufferSize) { return medusaReceiveDataInternal(socket, nBufferSize, 0, READ_WAIT_TIME, 0); } char* medusaReceiveRawDelay(int socket, int* nBufferSize, int nReceiveDelay1, int nReceiveDelay2) { return medusaReceiveDataInternal(socket, nBufferSize, 0, nReceiveDelay1, nReceiveDelay2); } char* medusaReceiveLine(int socket, int* nBufferSize) { return medusaReceiveDataInternal(socket, nBufferSize, 1, READ_WAIT_TIME, 0); } char* medusaReceiveLineDelay(int socket, int* nBufferSize, int nReceiveDelay1, int nReceiveDelay2) { return medusaReceiveDataInternal(socket, nBufferSize, 1, nReceiveDelay1, nReceiveDelay2); } /* Receive function which uses regular expressions to determine whether we read all the data we're intending to. The goal is to address the issue of varying network speeds of servers. We don't want to retrieve only the first few bytes of a response and then start responding before the remote end is finished. The function will recheck the socket 5 times before giving up finding a match. Each recheck uses a larger timeout value. */ int medusaReceiveRegex(int hSocket, unsigned char **szBufReceive, int* nBufReceive, const char* regex) { char *szBufReceiveTmp = NULL; int nBufReceiveTmp = 0; regex_t preg; int errcode = REG_NOMATCH; char errmsg[512]; const char *error = NULL; int erroffset = 0; int nAttempt = 1; const unsigned int BUFFER_SIZE = 576; writeError(ERR_DEBUG, "Regural expession: \"%s\"", regex); errcode = regcomp(&preg, regex, REG_EXTENDED|REG_ICASE|REG_NOSUB); if (errcode) { memset(errmsg, 0, 512); regerror(errcode, &preg, errmsg, 512); writeError(ERR_ERROR, "Regex compilation failed: %s", errmsg); return FAILURE; } *szBufReceive = medusaReceiveDataInternal(hSocket, nBufReceive, 0, READ_WAIT_TIME, 0); if (*szBufReceive == NULL) return FAILURE; do { errcode = regexec(&preg, *szBufReceive, 0, 0, 0); if (errcode == REG_NOMATCH) { writeError(ERR_DEBUG, "Failed to match regex. Checking for additional data."); /* there more be more data waiting for us... */ if (medusaDataReadyTimed(hSocket, 0, 20000 * nAttempt) > 0) { szBufReceiveTmp = malloc(BUFFER_SIZE + 1); memset(szBufReceiveTmp, 0, BUFFER_SIZE + 1); nBufReceiveTmp = medusaReceive(hSocket, szBufReceiveTmp, BUFFER_SIZE); if (nBufReceiveTmp <= 0) { writeError(ERR_DEBUG, "Data receive: No additional data."); free(szBufReceiveTmp); break; } if (*nBufReceive + nBufReceiveTmp > BUFFER_SIZE) { writeError(ERR_DEBUG, "Additional data received. Increasing receive buffer %d bytes to %d.", nBufReceiveTmp, *nBufReceive + nBufReceiveTmp + 1); *szBufReceive = realloc(*szBufReceive, *nBufReceive + nBufReceiveTmp + 1); } memcpy(*szBufReceive + *nBufReceive, szBufReceiveTmp, nBufReceiveTmp); *nBufReceive += nBufReceiveTmp; nBufReceiveTmp = 0; free(szBufReceiveTmp); } else { /* no additional data found... let's check it a few times */ writeError(ERR_DEBUG, "No additional data found (attempt %d/5)", nAttempt); nAttempt++; } } else { regfree(&preg); writeError(ERR_DEBUG, "Successfully matched regex."); return SUCCESS; } } while (nAttempt <= 5); regfree(&preg); writeError(ERR_ERROR, "Failed to match regex pattern within server's response."); return FAILURE; } int medusaSend(int socket, char *buf, int size, int options) { char debugbuf[size + 1]; int k; memset(debugbuf, 0, size + 1); for (k = 0; k < size; k++) if (buf[k] == 0) debugbuf[k] = 32; else debugbuf[k] = buf[k]; writeError(ERR_DEBUG, "Data sent: %s", debugbuf); return (medusaSendInternal(socket, buf, size, options)); } int makeToLower(char *buf) { if (buf == NULL) return 1; while (buf[0] != 0) { buf[0] = tolower(buf[0]); buf++; } return 1; } medusa-2.1.1/src/listModules.c0000644000175000001440000001163511723732127013160 00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. See the * GNU General Public License for more details. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ /* ** listModules.c ** ** prints out a list of local modules, along with their ** brief descriptions. If no other directory is specified, ** (i.e., pszDir is NULL), we assume "." ** ** CHANGE LOG ** 02-17-2004 - Created by Foofus ** 02-18-2004 - Works with test module (Foofus). ** */ #include #include #include #include #include #include "modsrc/module.h" void listModules(char* arrPaths[], int nTerminateNow) { // If nTerminateNow > 0, the application will exit immediately struct dirent **pdeEntry; char *pszTarget; int iLength; void *pLibrary; int (*pSummary)(char**); char *pszUsage; char *pszLibName; char *pszDir; int i, j, k; /* Initialize variables */ pszTarget = NULL; iLength = 0; pLibrary = NULL; pSummary = NULL; pszUsage = NULL; pszLibName = NULL; /* Say hello */ for(i = 0; i < 3; i++) { /* Format the directory name */ pszDir = arrPaths[i]; if (pszDir == NULL) { continue; } else { iLength = strlen( pszDir ) + 1; pszTarget = (char*)malloc( iLength ); memset( pszTarget, 0, iLength ); strncpy( pszTarget, pszDir, strlen(pszDir) ); iLength = 0; } /* (was a directory specified?) */ writeVerbose(VB_NONE, " Available modules in \"%s\" :", pszTarget); /* Open the directory */ if ((k = scandir( pszTarget, &pdeEntry, 0, alphasort )) < 0) { if (nTerminateNow > 0) writeVerbose(VB_EXIT, "\tCouldn't open directory \"%s\"", pszTarget); else writeVerbose(VB_NONE, "\tCouldn't open directory \"%s\"", pszTarget); } else { /* For each file, is it a module? */ j = -1; while (++j < k) { iLength = strlen( pdeEntry[j]->d_name ); if (iLength > 4) { /* Check the file suffix */ if (strcmp( (char*)(pdeEntry[j]->d_name + strlen( pdeEntry[j]->d_name ) - 4), MODULE_EXTENSION ) == 0) { /* Build the complete filename */ iLength = strlen( pdeEntry[j]->d_name ) + strlen( pszTarget ) + 2; pszLibName = (char*)malloc( iLength ); memset( pszLibName, 0, iLength ); strncpy( pszLibName, pszTarget, strlen(pszTarget) ); strncat( pszLibName, "/", 1 ); strncat( pszLibName, pdeEntry[j]->d_name, strlen(pdeEntry[j]->d_name) ); /* Load this as a shared library */ pLibrary = dlopen( pszLibName, RTLD_NOW ); if (pLibrary == NULL) { writeVerbose(VB_NONE, " + %s : Couldn't load \"%s\" [%s]", pdeEntry[j]->d_name, pszLibName, dlerror()); } else { /* Get a pointer to the summary usage function */ pSummary = (int(*)(char**))dlsym( pLibrary, "summaryUsage" ); if (pSummary == NULL) { writeVerbose(VB_NONE, " + %s : Invalid module %s [no export of summaryUsage() : %s]", pdeEntry[j]->d_name, pszLibName, dlerror()); } else { pszUsage = NULL; pSummary((char**)&pszUsage); writeVerbose(VB_NONE, " + %s : %s", pdeEntry[j]->d_name, pszUsage); free( pszUsage ); } /* (could we get a pointer to the function?) */ /* Let go of the library */ dlclose( pLibrary ); } /* (could we load the library?) */ /* Don't need the library name any more */ free( pszLibName ); } /* (did the file have the proper extension?) */ } /* (is the name long enough to bother considering?) */ /* free finished entry */ free(pdeEntry[j]); } /* (while) */ writeVerbose(VB_NONE, ""); } /* (could we open the directory?) */ /* All done. */ free( pszTarget ); } if (nTerminateNow > 0) writeVerbose(VB_EXIT, ""); } /* (listModules) */ medusa-2.1.1/src/modsrc/0000755000175000001440000000000011760001577012050 500000000000000medusa-2.1.1/src/modsrc/smtp.c0000644000175000001440000007056711723732127013137 00000000000000/* ** SMTP Authentication Daemon Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** Copyright (C) 2008 JoMo-Kun ** JoMo-Kun ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #include "ntlm.h" #define MODULE_NAME "smtp.mod" #define MODULE_AUTHOR "pmonkey@foofus.net" #define MODULE_SUMMARY_USAGE "Brute force module for SMTP Authentication with TLS" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: smtp.c 1583 2011-07-11 18:51:19Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_SMTP 25 #define PORT_SMTPS 465 #define RECEIVE_DELAY_1 20 * 1000000 #define RECEIVE_DELAY_2 0.5 * 1000000 #define AUTH_UNKNOWN 0 #define AUTH_PLAIN 1 #define AUTH_LOGIN 2 #define AUTH_NTLM 3 typedef struct __MODULE_DATA { char *szEHLO; int nAuthType; char* szDomain; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initConnection(_MODULE_DATA *_psSessionData, int hSocket, sConnectParams *params); int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " EHLO:? [optional] "); writeVerbose(VB_NONE, " Specify the EHLO greeting."); writeVerbose(VB_NONE, " AUTH:? (Authentication Type (PLAIN/LOGIN/NTLM). Default: automatic)"); writeVerbose(VB_NONE, " Module will query service for accepted methods via an \"AUTH\" request."); writeVerbose(VB_NONE, " PLAIN, LOGIN, and NTLM authentication methods are supported."); writeVerbose(VB_NONE, " DOMAIN:? [optional]"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "The DOMAIN option should supply the specified domain appropriately,"); writeVerbose(VB_NONE, "regardless of authentication type. The domain can also be supplied "); writeVerbose(VB_NONE, "via the username field, but the format appears to differ by auth type."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: "); writeVerbose(VB_NONE, " \"medusa -M smtp -m AUTH:NTLM -U accounts.txt -p password\""); writeVerbose(VB_NONE, " \"medusa -M smtp -m EHLO:world -U accounts.txt -p password\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr = NULL, *pOpt = NULL, *pOptTmp = NULL; _MODULE_DATA *psSessionData = NULL; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inAuthType = AUTH_PLAIN; else if (strcmp(pOpt, "LOGIN") == 0) psSessionData->nAuthType = AUTH_LOGIN; else if (strcmp(pOpt, "NTLM") == 0) psSessionData->nAuthType = AUTH_NTLM; else writeError(ERR_WARNING, "Invalid value for method AUTH."); } else if (strcmp(pOpt, "DOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDomain = malloc(strlen(pOpt) + 1); memset(psSessionData->szDomain, 0, strlen(pOpt) + 1); strncpy((char *) psSessionData->szDomain, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else if (strcmp(pOpt, "EHLO") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szEHLO = malloc(strlen(pOpt)); strncpy((char *) psSessionData->szEHLO, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method EHLO requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_SMTPS; else params.nPort = PORT_SMTP; initConnectionParams(psLogin, ¶ms); /* set EHLO, if not specified by user */ if (_psSessionData->szEHLO == NULL) { _psSessionData->szEHLO = malloc(5); memset(_psSessionData->szEHLO, 0, 5); sprintf(_psSessionData->szEHLO, "gerg"); } while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (initConnection(_psSessionData, hSocket, ¶ms) == FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) ) { nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nState = MSTATE_NEW; if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int initConnection(_MODULE_DATA *_psSessionData, int hSocket, sConnectParams *params) { int iRet; unsigned char *bufSend = NULL; unsigned char *bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; /* Retrieve SMTP banner */ writeError(ERR_DEBUG_MODULE, "[%s] Retrieving SMTP banner.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^220 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] failed: Server did not respond with '220'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* Send greeting to SMTP server */ writeError(ERR_DEBUG_MODULE, "[%s] Sending SMTP EHLO greeting.", MODULE_NAME); nSendBufferSize = 5 + strlen(_psSessionData->szEHLO) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "EHLO %s\r\n", _psSessionData->szEHLO); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^250 .*\r\n|^250-.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with '250'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* If server supports STARTTLS and we are not already within a SSL connection, let's use it. */ if ((params->nUseSSL == 0) && (strstr(bufReceive, "STARTTLS") != NULL)) { FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] Initiating STARTTLS session.", MODULE_NAME); bufSend = malloc(10 + 1); memset(bufSend, 0, 10 + 1); sprintf(bufSend, "STARTTLS\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^220 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with '220'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { FREE(bufReceive); params->nSSLVersion = 3.1; /* Force the use of TLSv1 */ if (medusaConnectSocketSSL(params, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish SSLv3 connection.", MODULE_NAME); return FAILURE; } /* Resend EHLO greeting as the AUTH types may have changed. */ writeError(ERR_DEBUG_MODULE, "[%s] Sending SMTP EHLO greeting.", MODULE_NAME); nSendBufferSize = 5 + strlen(_psSessionData->szEHLO) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "EHLO %s\r\n", _psSessionData->szEHLO); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^250 .*\r\n|^250-.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with '250'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } } } /* Process SMTP supported authentication types */ if (_psSessionData->nAuthType != AUTH_UNKNOWN) { writeError(ERR_DEBUG_MODULE, "[%s] Ignoring server requested AUTH type and using user-specified value.", MODULE_NAME); } else if ((strstr(bufReceive,"AUTH=LOGIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Detected authentication type: LOGIN"); _psSessionData->nAuthType = AUTH_LOGIN; } else if ((strstr(bufReceive,"AUTH=PLAIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Detected authentication type: PLAIN"); _psSessionData->nAuthType = AUTH_PLAIN; } else if ((strstr(bufReceive,"AUTH ") != NULL)) { if ((strstr(bufReceive,"LOGIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Detected authentication type: LOGIN"); _psSessionData->nAuthType = AUTH_LOGIN; } else if ((strstr(bufReceive,"PLAIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Detected authentication type: PLAIN"); _psSessionData->nAuthType = AUTH_PLAIN; } else if ((strstr(bufReceive,"NTLM") != NULL)) { writeError(ERR_DEBUG_MODULE, "Detected authentication type: NTLM"); _psSessionData->nAuthType = AUTH_NTLM; } } else { writeError(ERR_ERROR, "%s failed: Server did not respond that it supported LOGIN, PLAIN or NTLM as an authentication type. Use the AUTH module option to force the use of an authentication type.", MODULE_NAME); return FAILURE; } FREE(bufReceive); return SUCCESS; } /* http://www.technoids.org/saslmech.html C: AUTH PLAIN S: 334 C: AHdlbGRvbgB3M2xkMG4= S: 235 2.0.0 OK Authenticated */ int sendAuthPLAIN(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufReceive = NULL; unsigned char* bufSend = NULL; unsigned char* szTmpBuf = NULL; unsigned char* szTmpBuf64 = NULL; int nSendBufferSize = 0; int nReceiveBufferSize = 0; int nRet = SUCCESS; writeError(ERR_DEBUG_MODULE, "[%s] Initiating PLAIN Authentication Attempt.", MODULE_NAME); /* --- Send initial AUTH PLAIN command --- */ bufSend = malloc(12 + 1); memset(bufSend, 0, 12 + 1); sprintf(bufSend, "AUTH PLAIN\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); /* Server should respond with a 334 response code */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^334 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] SMTP server did not respond with \"334 \" to AUTH PLAIN request.", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* Send logon credentials: B64(USERNAME\0USERNAME\0PASSWORD) */ nSendBufferSize = strlen(szLogin) + 1 + strlen(szLogin) + 1 + strlen(szPassword); szTmpBuf = malloc(nSendBufferSize + 1); memset(szTmpBuf, 0, nSendBufferSize + 1); strncpy(szTmpBuf, szLogin, strlen(szLogin)); strncpy(szTmpBuf + strlen(szLogin) + 1, szLogin, strlen(szLogin)); strncpy(szTmpBuf + strlen(szLogin) + 1 + strlen(szLogin) + 1, szPassword, strlen(szPassword)); szTmpBuf64 = malloc((2 * nSendBufferSize + 2) + 1); memset(szTmpBuf64, 0, (2 * nSendBufferSize + 2) + 1); base64_encode(szTmpBuf, nSendBufferSize, szTmpBuf64); FREE(szTmpBuf); bufSend = malloc(strlen(szTmpBuf64) + 2 + 1); memset(bufSend, 0, strlen(szTmpBuf64) + 2 + 1); sprintf(bufSend, "%s\r\n", szTmpBuf64); FREE(szTmpBuf64); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); return SUCCESS; } /* http://www.technoids.org/saslmech.html C: AUTH LOGIN S: 334 VXNlcm5hbWU6 (Username:) C: d2VsZG9u (weldon) S: 334 UGFzc3dvcmQ6 (Password:) C: dzNsZDBu (w3ld0n) S: 235 2.0.0 OK Authenticated */ int sendAuthLOGIN(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufReceive = NULL; unsigned char* bufSend = NULL; unsigned char* szPrompt = NULL; unsigned char* szTmpBuf = NULL; unsigned char* szTmpBuf2 = NULL; unsigned char* szLoginDomain = NULL; int nSendBufferSize = 0; int nReceiveBufferSize = 0; int nRet = SUCCESS; writeError(ERR_DEBUG_MODULE, "[%s] Initiating LOGIN Authentication Attempt.", MODULE_NAME); /* --- Send initial AUTH LOGIN command --- */ bufSend = malloc(12 + 1); memset(bufSend, 0, 12 + 1); sprintf(bufSend, "AUTH LOGIN\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); /* Server should respond with a base64-encoded username prompt */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^334 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] SMTP server did not respond with \"334 \" to AUTH LOGIN request.", MODULE_NAME); FREE(bufReceive); return FAILURE; } if (((szTmpBuf = (char*)strstr(bufReceive, "334 ")) == NULL) || ((szTmpBuf2 = (char*)index(szTmpBuf, '\r')) == NULL)) { writeError(ERR_ERROR, "[%s] SMTP server sent unexpected response to AUTH LOGIN request.", MODULE_NAME); return FAILURE; } szTmpBuf2[0] = '\0'; szTmpBuf += 4; szPrompt = malloc(strlen(szTmpBuf) + 1); memset(szPrompt, 0, strlen(szTmpBuf) + 1); base64_decode(szTmpBuf, szPrompt); FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] SMTP server sent the following prompt: %s", MODULE_NAME, szPrompt); FREE(szPrompt); /* --- Send username --- */ /* Base64 encoded value can be up to 2x+2 original text. Leave additional space for "\r\n" and NULL */ if (_psSessionData->szDomain) { /* DOMAIN\USERNAME */ szLoginDomain = malloc(strlen(_psSessionData->szDomain) + 1 + strlen(szLogin) + 1); memset(szLoginDomain, 0, strlen(_psSessionData->szDomain) + 1 + strlen(szLogin) + 1); sprintf(szLoginDomain, "%s\\%s", _psSessionData->szDomain, szLogin); } else szLoginDomain = szLogin; writeError(ERR_DEBUG_MODULE, "[%s] Sending authenticate login value: %s %s", MODULE_NAME, szLoginDomain, szPassword); bufSend = malloc((2 * strlen(szLoginDomain) + 2) + 2 + 1); memset(bufSend, 0, (2 * strlen(szLoginDomain) + 2) + 2 + 1); base64_encode(szLoginDomain, strlen(szLoginDomain), bufSend); strncat(bufSend, "\r\n", 2); if (_psSessionData->szDomain) FREE(szLoginDomain); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } /* Server should respond with a base64-encoded password prompt */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^334 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] SMTP server did not respond with \"334 \" to AUTH LOGIN request.", MODULE_NAME); FREE(bufReceive); return FAILURE; } if (((szTmpBuf = (char*)strstr(bufReceive, "334 ")) == NULL) || ((szTmpBuf2 = (char*)index(szTmpBuf, '\r')) == NULL)) { writeError(ERR_ERROR, "[%s] SMTP server sent unexpected response to AUTH LOGIN request.", MODULE_NAME); return FAILURE; } szTmpBuf2[0] = '\0'; szTmpBuf += 4; szPrompt = malloc(strlen(szTmpBuf) + 1); memset(szPrompt, 0, strlen(szTmpBuf) + 1); base64_decode(szTmpBuf, szPrompt); FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] SMTP server sent the following prompt: %s", MODULE_NAME, szPrompt); FREE(szPrompt); /* --- Send password --- */ /* Base64 encoded value can be up to 2x+2 original text. Leave additional space for "\r\n" and NULL */ bufSend = malloc((2 * strlen(szPassword) + 2) + 2 + 1); memset(bufSend, 0, (2 * strlen(szPassword) + 2) + 2 + 1); base64_encode(szPassword, strlen(szPassword), bufSend); strncat(bufSend, "\r\n", 2); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } return SUCCESS; } /* http://davenport.sourceforge.net/ntlm.html#ntlmSmtpAuthentication */ int sendAuthNTLM(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; tSmbNtlmAuthRequest sTmpReq; tSmbNtlmAuthChallenge sTmpChall; tSmbNtlmAuthResponse sTmpResp; unsigned char* szTmpBuf = NULL; unsigned char* szTmpBuf64 = NULL; writeError(ERR_DEBUG_MODULE, "[%s] Initiating NTLM Authentication Attempt.", MODULE_NAME); /* --- Send Base-64 encoded Type-1 message --- */ buildAuthRequest(&sTmpReq, 0, NULL, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpReq) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpReq) + 2); base64_encode((char *)&sTmpReq, SmbLength(&sTmpReq), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] Sending initial challenge (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(szTmpBuf64) + 2; bufSend = malloc(10 + nSendBufferSize + 1); memset(bufSend, 0, 10 + nSendBufferSize + 1); sprintf(bufSend, "AUTH NTLM %s\r\n", szTmpBuf64); FREE(szTmpBuf64); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); /* Server should respond with a Base-64 encoded Type-2 challenge message. The challenge response format is "334", followed by a space, followed by the challenge message. */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^334 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Server did not send valid Type-2 challenge response.", MODULE_NAME); FREE(bufReceive); return FAILURE; } szTmpBuf = ((char*)index(bufReceive, '\r')); szTmpBuf[0] = '\0'; writeError(ERR_DEBUG_MODULE, "[%s] NTLM Challenge (B64 Encoded): %s", MODULE_NAME, bufReceive + 4); base64_decode(bufReceive + 4, (char *)&sTmpChall); FREE(bufReceive); /* --- Calculate and send Base-64 encoded Type 3 response --- */ buildAuthResponse(&sTmpChall, &sTmpResp, 0, szLogin, szPassword, _psSessionData->szDomain, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpResp) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpResp) + 2); base64_encode((char *)&sTmpResp, SmbLength(&sTmpResp), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] NTLM Response (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(szTmpBuf64) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "%s\r\n", szTmpBuf64); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szTmpBuf64); FREE(bufSend); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { int nRet = FAILURE; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; switch(_psSessionData->nAuthType) { case AUTH_PLAIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending PLAIN Authentication.", MODULE_NAME); nRet = sendAuthPLAIN(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_LOGIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending LOGIN Authentication.", MODULE_NAME); nRet = sendAuthLOGIN(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_NTLM: writeError(ERR_DEBUG_MODULE, "[%s] Sending NTLM Authentication.", MODULE_NAME); nRet = sendAuthNTLM(hSocket, _psSessionData, szLogin, szPassword); break; default: break; } if (nRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Unknown SMTP server response: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } if (strstr(bufReceive,"235 ") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_EXITING; } /* 435 Unable to authenticate at present: Authentication Failure */ else if (strstr(bufReceive,"435 ") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed (435).", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; } /* GroupWise - 501 Authentication failed! */ else if (strstr(bufReceive,"501 ") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed (501).", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; } else if (strstr(bufReceive,"535 ") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed (535).", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; } else { writeError(ERR_ERROR, "[%s] Unknown SMTP server response: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(nRet); } medusa-2.1.1/src/modsrc/svn.c0000644000175000001440000003360611723732127012753 00000000000000/* ** Subversion Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ** Subversion (1.2.3):/tools/examples/minimal_client.c ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "svn.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for Subversion sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: svn.c 1632 2011-12-01 22:08:14Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define LIBSVN_WARNING "No usable LIBSVN. Module disabled." #ifdef HAVE_LIBSVN_CLIENT_1 #include "subversion-1/svn_client.h" #include "subversion-1/svn_pools.h" #include "subversion-1/svn_config.h" #define PORT_SVN 3690 typedef struct __SVN_DATA { char *szURL; char *szBranch; } _SVN_DATA; /* Tells us whether we are to continue processing or not */ enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; /* Forward declarations */ int tryLogin(int hSocket, sLogin** login, _SVN_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _SVN_DATA *_psSessionData); /* Tell medusa how many parameters this module allows */ int getParamNumber() { return 0; // we don't need no stinking parameters } /* Displays information about the module and how it must be used */ void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " BRANCH:? "); writeVerbose(VB_NONE, " Sets URL branch to authenticate against. For example, svn://host/branch."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M svn -m BRANCH:test_project\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _SVN_DATA *psSessionData; psSessionData = malloc(sizeof(_SVN_DATA)); memset(psSessionData, 0, sizeof(_SVN_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszBranch = malloc(strlen(pOpt) + 1); memset(psSessionData->szBranch, 0, strlen(pOpt) + 1); strncpy((char *)psSessionData->szBranch, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method BRANCH requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _SVN_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); params.nPort = PORT_SVN; initConnectionParams(psLogin, ¶ms); /* set URL - branch, if not specified by user */ if (_psSessionData->szBranch == NULL) { //_psSessionData->szBranch = malloc(6); //memset(_psSessionData->szBranch, 0, 6); //sprintf(_psSessionData->szBranch, "trunk"); _psSessionData->szBranch = malloc(2); memset(_psSessionData->szBranch, 0, 2); sprintf(_psSessionData->szBranch, "/"); } _psSessionData->szURL = malloc(strlen(psLogin->psServer->pHostIP) + log(params.nPort) + strlen(_psSessionData->szBranch) + 10); memset(_psSessionData->szURL, 0, strlen(psLogin->psServer->pHostIP) + log(params.nPort) + strlen(_psSessionData->szBranch) + 10); sprintf(_psSessionData->szURL, "svn://%s:%d/%s", psLogin->psServer->pHostIP, params.nPort, _psSessionData->szBranch); writeError(ERR_DEBUG_MODULE, "[%s] Set URL: %s", MODULE_NAME, _psSessionData->szURL); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: /* simply check if server exists */ if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* close the connection since libsvn does its own thing */ medusaDisconnect(hSocket); hSocket = -1; writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(0, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(_psSessionData->szURL); FREE(_psSessionData->szBranch); FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ static svn_error_t * svn_prompt_callback (svn_auth_cred_simple_t **cred, void *baton, const char *realm, const char *username, svn_boolean_t may_save, apr_pool_t *pool) { svn_auth_cred_simple_t *ret = apr_pcalloc (pool, sizeof (*ret)); *cred = ret; return SVN_NO_ERROR; } int tryLogin(int hSocket, sLogin** psLogin, _SVN_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet; apr_pool_t *pool; svn_error_t *err; svn_opt_revision_t revision; apr_hash_t *dirents; svn_client_ctx_t *ctx; /* Initialize the application. Send all error messages to 'stderr'. */ if (svn_cmdline_init ("MEDUSA", stderr) != EXIT_SUCCESS) { writeError(ERR_ERROR, "[%s] LIBSVN svn_cmdline_init() Function Failed.", MODULE_NAME); return(FAILURE); } /* Create top-level memory pool. -- must this be thread-safe??? */ pool = svn_pool_create (NULL); /* Initialize and allocate the client_ctx object. */ if ((err = svn_client_create_context (&ctx, pool))) { writeError(ERR_ERROR, "[%s] LIBSVN svn_client_create_context() Function Failed.", MODULE_NAME); //svn_handle_error2 (err, stderr, FALSE, "MEDUSA: "); return(FAILURE); } svn_auth_provider_object_t *provider; apr_array_header_t *providers = apr_array_make (pool, 1, sizeof (svn_auth_provider_object_t *)); /* Set callback to not retry authentication */ //svn_client_get_simple_prompt_provider(&provider, svn_prompt_callback, NULL, 0, pool); svn_auth_get_simple_prompt_provider(&provider, svn_prompt_callback, NULL, 0, pool); APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider; //svn_auth_get_username_prompt_provider(&provider, svn_ame_prompt_callback, NULL, 0, pool); //APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider; /* Register the auth-providers into the context's auth_baton. */ svn_auth_open (&ctx->auth_baton, providers, pool); /* Set logon credentials using the auth_baton's run-time parameter hash */ svn_auth_set_parameter(ctx->auth_baton, SVN_AUTH_PARAM_DEFAULT_USERNAME, szLogin); svn_auth_set_parameter(ctx->auth_baton, SVN_AUTH_PARAM_DEFAULT_PASSWORD, szPassword); /* Set revision to be the HEAD revision. */ revision.kind = svn_opt_revision_head; /* Main call into libsvn_client does all the work. */ err = svn_client_ls (&dirents, _psSessionData->szURL, &revision, FALSE, ctx, pool); //err = svn_client_list2(_psSessionData->szURL, &revision, &revision, svn_depth_empty, SVN_DIRENT_ALL, FALSE, NULL, &ctx->auth_baton, ctx, pool); if ((err !=NULL) && err->apr_err == 170001) { if (strstr(err->message, "Username not found")) { writeError(ERR_ERROR, "[%s] The following SVN user does not appear to exist: %s", MODULE_NAME, szLogin); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else if (strstr(err->message, "Password incorrect")) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { writeError(ERR_DEBUG_MODULE, "[%s] Access refused. Unknown error: %s", MODULE_NAME, err->message); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } } else if (err != NULL) { writeError(ERR_ERROR, "[%s] Authentication Error (%d): %s.", MODULE_NAME, err->apr_err, err->message); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } setPassResult((*psLogin), szPassword); svn_pool_clear(pool); svn_pool_destroy(pool); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(LIBSVN_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, LIBSVN_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is LIBSVN installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is LIBSVN installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif medusa-2.1.1/src/modsrc/rlogin.c0000644000175000001440000002304711723732127013435 00000000000000/* ** RLOGIN Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "rlogin.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for RLOGIN sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: rlogin.c 1301 2010-02-09 22:54:18Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define BUF_SIZE 300 #define PORT_RLOGIN 513 // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins); } return SUCCESS; } int initModule(sLogin* psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) writeError(ERR_DEBUG_MODULE, "[%s] module asked for RLOGIN/SSL. Don't know if such a thing exists...\n"); else params.nPort = PORT_RLOGIN; params.nSourcePort = 1023; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int tryLogin(int hSocket, sLogin** psLogin, char* szLogin, char* szPassword) { char ipaddr_str[INET_ADDRSTRLEN]; int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* send username */ memset(bufSend, 0, sizeof(bufSend)); bufSend[0]=0x00; strncpy(bufSend+1, szLogin, strlen(szLogin)); bufSend[strlen(szLogin)+1]=0x00; strncpy(bufSend+2+strlen(szLogin), szLogin, strlen(szLogin)); bufSend[strlen(szLogin)+1+strlen(szLogin)+1]=0x00; strncpy(bufSend+1+strlen(szLogin)+1+strlen(szLogin)+1, "xterm", 5); bufSend[strlen(szLogin)+1+strlen(szLogin)+1+7]=0x00; if (medusaSend(hSocket, bufSend, strlen(szLogin)+1+strlen(szLogin)+1+7 , 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive,"Incorrect") != NULL) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed here.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else if (strstr(bufReceive,"Password") != NULL) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt asked for password.", MODULE_NAME); sprintf(bufSend,"%s\r",szPassword); if (medusaSend(hSocket, bufSend, strlen(bufSend) , 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive,"incorrect") != NULL) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed here.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { /* We can't tell for sure but it wasn't a failure or a password prompt */ writeError(ERR_DEBUG_MODULE, "%s : Login attempt succeeded via password send.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } } else { /* We can't tell for sure but it wasn't a failure or a password prompt */ writeError(ERR_INFO, "%s : Login attempt succeeded via .rhosts", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } medusa-2.1.1/src/modsrc/imap.c0000644000175000001440000007270311757213533013076 00000000000000/* ** IMAP Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2006 pMonkey ** pMonkey ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Helpful item besides reading lots of RFC's ** http://www.kolab.org/pipermail/kolab-commits/2005q1/001959.html ** ** Modifications: (JoMo-Kun) ** Support for LOGIN command ** Optional module parameters ** */ #include #include #include #include #include #include "module.h" #include "ntlm.h" #define MODULE_NAME "imap.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for IMAP sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: imap.c 1723 2012-05-23 16:59:07Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define BUF_SIZE 300 #define PORT_IMAP 143 #define PORT_IMAPS 993 #define RECEIVE_DELAY_1 20 * 1000000 #define RECEIVE_DELAY_2 0.5 * 1000000 #define AUTH_UNKNOWN 0 #define AUTH_LOGIN 1 #define AUTH_PLAIN 2 #define AUTH_NTLM 3 typedef struct __MODULE_DATA { char *szTag; int nAuthType; char* szDomain; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initConnection(_MODULE_DATA *_psSessionData, int hSocket, sConnectParams *params); int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, char* szLogin, char* szPassword); int initModule(_MODULE_DATA* _psSessionData, sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " TAG:? (Default: gerg)"); writeVerbose(VB_NONE, " AUTH:? (Authentication Type (LOGIN/PLAIN/NTLM). Default: automatic)"); writeVerbose(VB_NONE, " DOMAIN:? [optional]"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M imap -m TAG:A0001 -m AUTH:PLAIN"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "The DOMAIN option should supply the specified domain appropriately,"); writeVerbose(VB_NONE, "regardless of authentication type. The domain can also be supplied "); writeVerbose(VB_NONE, "via the username field, but the format appears to differ by auth type."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Example 1: NTLM authentication with DOMAIN option"); writeVerbose(VB_NONE, " \"medusa -M imap -m AUTH:NTLM -m DOMAIN:FOODOM -h host -u foo -p bar\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Example 2: NTLM authentication with domain via username"); writeVerbose(VB_NONE, " \"medusa -M imap -m AUTH:NTLM -h host -u foo@domain -p bar\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "* If no domain is specified when using NTLM authentication, the server"); writeVerbose(VB_NONE, "supplied value will be used."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Example 3: LOGIN authentication with domain via username"); writeVerbose(VB_NONE, " \"medusa -M imap -m AUTH:LOGIN -h host -u 'domain\\\\foo' -p bar\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !(0 <= argc <= 2) ) { // Show usage information writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module.", MODULE_NAME); return FAILURE; } else { // Parameters are good - make module go now writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszTag = malloc(strlen(pOpt) + 1); memset(psSessionData->szTag, 0, strlen(pOpt) + 1); strncpy(psSessionData->szTag, pOpt, strlen(pOpt) + 1); } else writeError(ERR_WARNING, "Method TAG requires value to be set."); } else if (strcmp(pOpt, "AUTH") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method AUTH requires value to be set."); else if (strcmp(pOpt, "LOGIN") == 0) psSessionData->nAuthType = AUTH_LOGIN; else if (strcmp(pOpt, "PLAIN") == 0) psSessionData->nAuthType = AUTH_PLAIN; else if (strcmp(pOpt, "NTLM") == 0) psSessionData->nAuthType = AUTH_NTLM; else writeError(ERR_WARNING, "Invalid value for method AUTH."); } else if (strcmp(pOpt, "DOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDomain = malloc(strlen(pOpt) + 1); memset(psSessionData->szDomain, 0, strlen(pOpt) + 1); strncpy((char *) psSessionData->szDomain, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } free(pOptTmp); } initModule(psSessionData, logins); } FREE(psSessionData); return SUCCESS; } int initModule(_MODULE_DATA *_psSessionData, sLogin* psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; unsigned char bufSend[BUF_SIZE]; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_IMAPS; else params.nPort = PORT_IMAP; initConnectionParams(psLogin, ¶ms); /* set TAG, if not specified by user */ if (_psSessionData->szTag == NULL) { _psSessionData->szTag = malloc(5); memset(_psSessionData->szTag, 0, 5); sprintf(_psSessionData->szTag, "gerg"); } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); /* Reset SSL flag if set (e.g., SSL connection had been reset by anti-bruteforce mechanism) */ params.nUseSSL = 0; if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (initConnection(_psSessionData, hSocket, ¶ms) == FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: /* The IMAP service may be configured to drop connections after an arbitrary number of failed logon attempts. We will reuse the established connection to send authentication attempts until that disconnect happens. At that point the connection should be reestablished. */ if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) ) { nState = tryLogin(hSocket, _psSessionData, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nState = MSTATE_NEW; if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int initConnection(_MODULE_DATA *_psSessionData, int hSocket, sConnectParams *params) { unsigned char *bufSend = NULL; unsigned char *bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; /* Retrieve IMAP server banner */ if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^\\* OK .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed to retrieve IMAP server banner. Exiting...", MODULE_NAME); return FAILURE; } else if ((strstr(bufReceive,"* OK ") != NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] Received IMAP server banner: %s", MODULE_NAME, bufReceive); FREE(bufReceive); } else if ((strstr(bufReceive,"* BYE Connection refused") != NULL)) { writeError(ERR_ERROR, "[%s] IMAP server refused connection. Is SSL required?", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { writeError(ERR_ERROR, "[%s] Failed to retrieve IMAP server banner.", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* Request IMAP server capabilities */ writeError(ERR_DEBUG_MODULE, "[%s] Sending IMAP CAPABILITIES request.", MODULE_NAME); nSendBufferSize = strlen(_psSessionData->szTag) + 13; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "%s CAPABILITY\r\n", _psSessionData->szTag); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "OK .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: No OK message received for CAPABILITY request.", MODULE_NAME); return FAILURE; } /* If server supports STARTTLS and we are not already within a SSL connection, let's use it. */ if ((params->nUseSSL == 0) && (strstr(bufReceive, "STARTTLS") != NULL)) { FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] Initiating STARTTLS session.", MODULE_NAME); bufSend = malloc(strlen(_psSessionData->szTag) + 11 + 1); memset(bufSend, 0, strlen(_psSessionData->szTag) + 11 + 1); sprintf(bufSend, "%s STARTTLS\r\n", _psSessionData->szTag); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "OK .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: No OK message received for STARTTLS request.", MODULE_NAME); return FAILURE; } /* OK Begin TLS negotiation now. */ else { FREE(bufReceive); params->nSSLVersion = 3.1; /* Force the use of TLSv1 */ if (medusaConnectSocketSSL(params, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish TLSv1 connection.", MODULE_NAME); return FAILURE; } /* Resend CAPABILITY request as the AUTH types may have changed. */ writeError(ERR_DEBUG_MODULE, "[%s] Sending IMAP CAPABILITIES request.", MODULE_NAME); nSendBufferSize = strlen(_psSessionData->szTag) + 13; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "%s CAPABILITY\r\n", _psSessionData->szTag); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "OK .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: No OK message received for CAPABILITY request.", MODULE_NAME); return FAILURE; } } } /* Process IMAP supported authentication types */ if (_psSessionData->nAuthType != AUTH_UNKNOWN) { writeError(ERR_DEBUG_MODULE, "[%s] Ignoring server requested AUTH type and using user-specified value.", MODULE_NAME); } else if ((strstr(bufReceive,"AUTH=LOGIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: LOGIN"); _psSessionData->nAuthType = AUTH_LOGIN; } else if ((strstr(bufReceive,"AUTH=PLAIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: PLAIN"); _psSessionData->nAuthType = AUTH_PLAIN; } else if ((strstr(bufReceive,"AUTH=NTLM") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: NTLM"); _psSessionData->nAuthType = AUTH_NTLM; } else { writeError(ERR_ERROR, "[%s] Failed: Server did not respond that it supported any of the authentication types we handle (PLAIN, LOGIN, NTLM). Use the AUTH module option to force the use of an authentication type.", MODULE_NAME); return FAILURE; } FREE(bufReceive); return SUCCESS; } /* A0001 LOGIN username password */ int sendAuthLogin(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* szEncodedAuth = NULL; int nSendBufferSize = 0; int nRet = SUCCESS; nSendBufferSize = strlen(_psSessionData->szTag) + 7 + strlen(szLogin) + 1 + strlen(szPassword) + 4 + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); if (_psSessionData->szDomain) { writeError(ERR_DEBUG_MODULE, "[%s] Sending authenticate login value: %s\\\\%s %s", MODULE_NAME, _psSessionData->szDomain, szLogin, szPassword); sprintf(bufSend, "%s LOGIN \"%s\\\\%s\" \"%s\"\r\n", _psSessionData->szTag, _psSessionData->szDomain, szLogin, szPassword); } else { writeError(ERR_DEBUG_MODULE, "[%s] Sending authenticate login value: %s %s", MODULE_NAME, szLogin, szPassword); sprintf(bufSend, "%s LOGIN \"%s\" \"%s\"\r\n", _psSessionData->szTag, szLogin, szPassword); } if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); nRet = FAILURE; } FREE(bufSend); return(nRet); } /* A0001 AUTHENTICATE PLAIN credentials(base64) */ int sendAuthPlain(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; unsigned char* szTmp = NULL; unsigned char* szEncodedAuth = NULL; int nSendBufferSize = 0; int nReceiveBufferSize = 0; /* Send initial AUTHENTICATE PLAIN command */ nSendBufferSize = strlen(_psSessionData->szTag) + 21; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "%s AUTHENTICATE PLAIN\r\n", _psSessionData->szTag); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] IMAP server did not respond with \"+\" to AUTHENTICATE PLAIN request.", MODULE_NAME); writeError(ERR_ERROR, "[%s] IMAP server sent the following response: %s", MODULE_NAME, bufReceive); return FAILURE; } /* Build a null separated string of szLogin \0 szLogin \0 szPassword */ nSendBufferSize = strlen(szLogin) + 1 + strlen(szLogin) + 1 + strlen(szPassword); szTmp = malloc(nSendBufferSize + 1); memset(szTmp, 0, nSendBufferSize + 1); /* username\0username\0password */ memcpy(szTmp, szLogin, strlen(szLogin)); memcpy(szTmp + strlen(szLogin) + 1, szLogin, strlen(szLogin)); memcpy(szTmp + strlen(szLogin) + 1 + strlen(szLogin) + 1, szPassword, strlen(szPassword)); szEncodedAuth = malloc(2 * nSendBufferSize + 1); memset(szEncodedAuth, 0, 2 * nSendBufferSize + 1); base64_encode(szTmp, nSendBufferSize, szEncodedAuth); FREE(szTmp); writeError(ERR_DEBUG_MODULE, "[%s] Sending authenticate plain value: %s", MODULE_NAME, szEncodedAuth); nSendBufferSize = strlen(szEncodedAuth) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "%s\r\n", szEncodedAuth); FREE(szEncodedAuth); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); return SUCCESS; } /* A0001 AUTHENTICATE NTLM NTLM IMAP Authentication Based on: http://curl.haxx.se/rfc/ntlm.html#ntlmImapAuthentication http://src.opensolaris.org/source/xref/sfw/usr/src/cmd/fetchmail/fetchmail-6.3.8/README.NTLM */ int sendAuthNTLM(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nSendBufferSize = 0; int nReceiveBufferSize = 0; tSmbNtlmAuthRequest sTmpReq; tSmbNtlmAuthChallenge sTmpChall; tSmbNtlmAuthResponse sTmpResp; unsigned char* szTmpBuf = NULL; unsigned char* szTmpBuf64 = NULL; /* --- Send initial AUTHENTICATE NTLM command --- */ nSendBufferSize = strlen(_psSessionData->szTag) + 21; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "%s AUTHENTICATE NTLM\r\n", _psSessionData->szTag); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); /* Server should respond with an empty challenge, consisting simply of a "+" */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] IMAP server did not respond with \"+\" to AUTHENTICATE NTLM request.", MODULE_NAME); writeError(ERR_ERROR, "[%s] IMAP server sent the following response: %s", MODULE_NAME, bufReceive); return FAILURE; } FREE(bufReceive); /* --- Send Base-64 encoded Type-1 message --- */ buildAuthRequest(&sTmpReq, 0, NULL, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpReq) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpReq) + 2); base64_encode((char *)&sTmpReq, SmbLength(&sTmpReq), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] Sending initial challenge (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(szTmpBuf64) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "%s\r\n", szTmpBuf64); FREE(szTmpBuf64); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); /* Server should respond with a Base-64 encoded Type-2 challenge message. The challenge response format is specified by RFC 1730 ("+", followed by a space, followed by the challenge message). */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+ .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Server did not send valid Type-2 challenge response.", MODULE_NAME); return FAILURE; } szTmpBuf = ((char*)index(bufReceive, '\r')); szTmpBuf[0] = '\0'; writeError(ERR_DEBUG_MODULE, "[%s] NTLM Challenge (B64 Encoded): %s", MODULE_NAME, bufReceive + 2); base64_decode(bufReceive + 2, (char *)&sTmpChall); FREE(bufReceive); /* --- Calculate and send Base-64 encoded Type 3 response --- */ buildAuthResponse(&sTmpChall, &sTmpResp, 0, szLogin, szPassword, _psSessionData->szDomain, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpResp) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpResp) + 2); base64_encode((char *)&sTmpResp, SmbLength(&sTmpResp), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] NTLM Response (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(szTmpBuf64) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "%s\r\n", szTmpBuf64); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szTmpBuf64); FREE(bufSend); /* Server should validate the response and indicate the result of authentication. e.g. 0001 OK AUTHENTICATE NTLM completed. */ return SUCCESS; } int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** psLogin, char* szLogin, char* szPassword) { int nRet; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; switch(_psSessionData->nAuthType) { case AUTH_LOGIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending LOGIN Authentication.", MODULE_NAME); nRet = sendAuthLogin(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_PLAIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending PLAIN Authentication.", MODULE_NAME); nRet = sendAuthPlain(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_NTLM: writeError(ERR_DEBUG_MODULE, "[%s] Sending NTLM Authentication.", MODULE_NAME); nRet = sendAuthNTLM(hSocket, _psSessionData, szLogin, szPassword); break; default: break; } if (nRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } /* Exchange 2003 Server Response Messages NO Logon failure: unknown user name or bad password. NO The specified authentication package is not supported. NO Clear text passwords have been disabled for this protocol. NO Cleartext login on this server requires the use of transport level security (SSL/TLS) */ writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, ".*\r\n") == FAILURE) || (bufReceive == NULL)) { /* The IMAP service may be configured to drop connections after an arbitrary number of failed logon attempts. We will reuse the established connection to send authentication attempts until that disconnect happens. A default install of Debian (6.0.3 Squeeze) and the Courier Mail Server (0.65) was found to drop connections immediately after the 8th failed attempt. */ if ( medusaCheckSocket(hSocket, (*psLogin)->psServer->psAudit->iSocketWait) ) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; return FAILURE; } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_NEW; } } else if (strstr(bufReceive,"OK") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_EXITING; } else if (strstr(bufReceive,"NO Clear text passwords have been disabled for this protocol.") != NULL) { writeError(ERR_ERROR, "[%s] Server reports that clear-text passwords have been disabled.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr(bufReceive,"NO Cleartext login on this server requires the use of transport level security (SSL/TLS)") != NULL) { writeError(ERR_ERROR, "[%s] Server reports that clear-text passwords are only allowed over SSL/TLS.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr(bufReceive,"NO The specified authentication package is not supported.") != NULL) { writeError(ERR_ERROR, "[%s] Server reports that the specified authentication package is not supported.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr(bufReceive,"NO") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; /* Exchange 2010 can include disconnect in message -- NO AUTHENTICATE failed.[0D][0A]* BYE Connection is closed. */ if (strstr(bufReceive,"* BYE ") != NULL) { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nRet = MSTATE_NEW; } } else if (strstr(bufReceive,"BAD") != NULL) { writeError(ERR_ERROR, "[%s] IMAP server responded that the command was unknown or the arguments were invalid.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else { writeError(ERR_ERROR, "[%s] Unknown IMAP server response: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(nRet); } medusa-2.1.1/src/modsrc/ncp.c0000644000175000001440000004100311723732127012713 00000000000000/* ** NCP Password/HASH Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ncpfs/nwauth ** ftp://platan.vc.cvut.cz/pub/linux/ncpfs/ ** ** Username format: BLAH.OU=Servers.O=foofus // found in current context.\nTrying server context */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "ncp.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for NCP sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: ncp.c 1680 2012-02-29 19:12:33Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define LIBNCP_WARNING "No usable LIBNCP. Module disabled." #ifdef HAVE_LIBNCP #include typedef struct __NCP_DATA { struct ncp_conn_spec spec; struct ncp_conn *conn; char *context; } _NCP_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _NCP_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _NCP_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " CONTEXT:? "); writeVerbose(VB_NONE, " Sets user context information."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "It should be noted that libncp does not by default automatically specific a user context."); writeVerbose(VB_NONE, "If it fails to resolve the name provided it appends the server's context to the username and attempts"); writeVerbose(VB_NONE, "to resolve that value. It is advised that users specify a context for each account being tested."); writeVerbose(VB_NONE, "A global context can be specified using the CONTEXT option. A per-user context can be defined"); writeVerbose(VB_NONE, "as part of the account name within a file containing usernames or the username passed via the "); writeVerbose(VB_NONE, "command-line."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M ncp -m CONTEXT:.OU=administrators.O=foofus -u username\""); writeVerbose(VB_NONE, " Usage example: \"-M ncp -u username.OU=administrators.O=foofus\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Libncp, by default, also uses both the NDS and BIND authenticators. Unfortunately, the only"); writeVerbose(VB_NONE, "error message returned to the module is that of the BIND authenticator. These messages are not"); writeVerbose(VB_NONE, "as descriptive as NDS and only seem to report success or failure. In order to have more useful"); writeVerbose(VB_NONE, "messages (account disabled/max logons exceeded/etc.), create a ~/.nwclient or /etc/ncpfs.conf"); writeVerbose(VB_NONE, "file with the following text:"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " [Requester]"); writeVerbose(VB_NONE, " NetWare Protocol = NDS"); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _NCP_DATA *psSessionData; psSessionData = malloc(sizeof(_NCP_DATA)); memset(psSessionData, 0, sizeof(_NCP_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; icontext = malloc(strlen(pOpt)); strncpy((char *)psSessionData->context, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method CONTEXT requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); FREE(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _NCP_DATA *_psSessionData) { enum MODULE_STATE nState = MSTATE_NEW; char *szUserContext = NULL; long NCPErrorCode; sCredentialSet *psCredSet = NULL; int i = 0; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: FREE(szUserContext); if (_psSessionData->context != NULL) { szUserContext = malloc(strlen(psCredSet->psUser->pUser) + strlen(_psSessionData->context) + 1); memset(szUserContext, 0, strlen(psCredSet->psUser->pUser) + strlen(_psSessionData->context) + 1); strncpy(szUserContext, psCredSet->psUser->pUser, strlen(psCredSet->psUser->pUser)); strncpy(szUserContext + strlen(psCredSet->psUser->pUser), _psSessionData->context, strlen(_psSessionData->context)); } else szUserContext = psCredSet->psUser->pUser; writeError(ERR_DEBUG_MODULE, "[%s] Set user context: %s", MODULE_NAME, szUserContext); NCPErrorCode = ncp_find_conn_spec3(psLogin->psServer->pHostIP, szUserContext, "", 1, 1 ? ~0U : getuid(), 0, &_psSessionData->spec); if (NCPErrorCode) { writeError(ERR_ERROR, "[%s] Failed to find an appropriate connection: %d.", MODULE_NAME, NCPErrorCode); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* Initiate NCP session connection - retry if necessary */ writeError(ERR_DEBUG_MODULE, "Attempting to establish connection with NCP server."); for (i = 1; i <= psLogin->psServer->psHost->iRetries + 1; i++) { NCPErrorCode = NWCCOpenConnByName(NULL, _psSessionData->spec.server, NWCC_NAME_FORMAT_BIND, NWCC_OPEN_NEW_CONN, NWCC_RESERVED, &_psSessionData->conn); if (NCPErrorCode) { writeError(ERR_ERROR, "[%s] Failed establishing NCP session (%d/%d): Error Code: %d Host: %s User: %s Pass: %s", MODULE_NAME, i, psLogin->psServer->psHost->iRetries + 1, NCPErrorCode, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); if (i == psLogin->psServer->psHost->iRetries + 1) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(0, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: ncp_close(_psSessionData->conn); nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module (%d) state %d host: %s", MODULE_NAME, psLogin->iId, nState, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } if (_psSessionData->context != NULL) if (szUserContext != NULL) FREE(szUserContext); FREE(psCredSet); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _NCP_DATA* _psSessionData, char* szLogin, char* szPassword) { int i, iRet; short int NCPErrorCode = 0; char *pErrorMsg = NULL; char ErrorCode[12]; int object_type = NCP_BINDERY_USER; char *szTemp = NULL; short int ncpErrorCode[] = { 0xFFFF, /* UNKNOWN_ERROR_CODE */ 0x0000, /* STATUS_SUCCESS */ 0xFD63, /* STATUS_LOGON_FAILURE */ 0xFDA7, /* SPECIFIED_BINARY_OBJECT_DOES_NOT_EXIST */ /* include/ncp/ncplib.h */ 0x8998, /* NWE_VOL_INVALID */ 0x899B, /* NWE_DIRHANDLE_INVALID */ 0x89C5, /* NWE_LOGIN_LOCKOUT */ 0x89D3, /* NWE_Q_NO_RIGHTS */ 0x89D5, /* NWE_Q_NO_JOB */ //0x89D6, /* NWE_Q_NO_JOB_RIGHTS */ 0x89D6, /* NWE_PASSWORD_UNENCRYPTED */ 0x89D7, /* NWE_PASSWORD_NOT_UNIQUE */ 0x89D8, /* NWE_PASSWORD_TOO_SHORT */ 0x89D9, /* NWE_LOGIN_MAX_EXCEEDED */ 0x89DA, /* NWE_LOGIN_UNAUTHORIZED_TIME */ 0x89DB, /* NWE_LOGIN_UNAUTHORIZED_STATION */ 0x89DC, /* NWE_ACCT_DISABLED */ 0x89DE, /* NWE_PASSWORD_INVALID */ 0x89DF, /* NWE_PASSWORD_EXPIRED */ 0x89E9, /* NWE_BIND_MEMBER_ALREADY_EXISTS */ 0x89FB, /* NWE_NCP_NOT_SUPPORTED */ 0x89FC, /* NWE_SERVER_UNKNOWN */ 0x89FD, /* NWE_CONN_NUM_INVALID */ 0x89FF, /* NWE_SERVER_FAILURE */ }; char *ncpErrorMsg[] = { "UNKNOWN_ERROR_CODE", "STATUS_SUCCESS", "STATUS_LOGON_FAILURE", "SPECIFIED_BINARY_OBJECT_DOES_NOT_EXIST", "NWE_VOL_INVALID", "NWE_DIRHANDLE_INVALID", "NWE_LOGIN_LOCKOUT", "NWE_Q_NO_RIGHTS", "NWE_Q_NO_JOB", //"NWE_Q_NO_JOB_RIGHTS", "NWE_PASSWORD_UNENCRYPTED", "NWE_PASSWORD_NOT_UNIQUE", "NWE_PASSWORD_TOO_SHORT", "NWE_LOGIN_MAX_EXCEEDED", "NWE_LOGIN_UNAUTHORIZED_TIME", "NWE_LOGIN_UNAUTHORIZED_STATION", "NWE_ACCT_DISABLED", "NWE_PASSWORD_INVALID", "NWE_PASSWORD_EXPIRED", "NWE_BIND_MEMBER_ALREADY_EXISTS", "NWE_NCP_NOT_SUPPORTED", "NWE_SERVER_UNKNOWN", "NWE_CONN_NUM_INVALID", "NWE_SERVER_FAILURE" }; memset(&ErrorCode, 0, 12); // NCP_BINDERY_NAME_LEN 48 // NCPFS_MAX_CFG_USERNAME 256 // NetWare 5 case insensitive??? size_t l = strlen(szPassword); if (l >= sizeof(_psSessionData->spec.password)) { ncp_close(_psSessionData->conn); writeError(ERR_ERROR, "[%s] Password too long. Max length 48 characters.", MODULE_NAME); iRet = MSTATE_EXITING; return(iRet); } memset(_psSessionData->spec.password, 0, sizeof(_psSessionData->spec.password)); memcpy(_psSessionData->spec.password, szPassword, l); /* Upper-case password */ szTemp = _psSessionData->spec.password; while(*szTemp != '\0') { *szTemp = toupper((unsigned char) *szTemp); szTemp++; } NCPErrorCode = ncp_login_conn(_psSessionData->conn, _psSessionData->spec.user, object_type, _psSessionData->spec.password); /* Locate appropriate NCP code message */ pErrorMsg = ncpErrorMsg[0]; /* UNKNOWN_ERROR_CODE */ for (i = 0; i < sizeof(ncpErrorCode)/2; i++) { if (NCPErrorCode == ncpErrorCode[i]) { pErrorMsg = ncpErrorMsg[i]; break; } } switch (NCPErrorCode & 0x0000FFFF) { case 0x0000: /* Success */ (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; break; case 0x89F0: /* Incorrect password - BIND Authenticator */ case 0x89FF: /* Incorrect password - NWE_SERVER_FAILURE */ case 0xFD63: /* Incorrect password - NDS Authenticator */ writeError(ERR_DEBUG_MODULE, "[%s] Incorrect password. Error code: %X", MODULE_NAME, NCPErrorCode); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; break; default: writeError(ERR_DEBUG_MODULE, "[%s] Failed to open connection. Error code: %X", MODULE_NAME, NCPErrorCode); sprintf(ErrorCode, "0x%8.8X:", NCPErrorCode); (*psLogin)->pErrorMsg = malloc( strlen(ErrorCode) + strlen(pErrorMsg) + 1); memset((*psLogin)->pErrorMsg, 0, strlen(ErrorCode) + strlen(pErrorMsg) + 1); strncpy((*psLogin)->pErrorMsg, ErrorCode, strlen(ErrorCode)); strncat((*psLogin)->pErrorMsg, pErrorMsg, strlen(pErrorMsg)); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; break; } setPassResult((*psLogin), szPassword); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(LIBNCP_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, LIBNCP_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Are the ncpfs headers and static library installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Are the ncpfs headers and static library installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif medusa-2.1.1/src/modsrc/rsh.c0000644000175000001440000002153211723732127012734 00000000000000/* ** RSH Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "rsh.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for RSH sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: rsh.c 1301 2010-02-09 22:54:18Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define BUF_SIZE 300 #define PORT_RSH 514 // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Rsh is a service where you either have .rhosts/hosts.equiv access\nfrom the source host or you don't. Passwords really don't matter.\nSo the best way to use this module is with a single dummy password and a\nlist of users you suspect may have .rhosts/hosts.equiv allows for your source.\nGood luck."); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins); } return SUCCESS; } int initModule(sLogin* psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) writeError(ERR_DEBUG_MODULE, "[%s] module asked for SSL but don't even know if such a thing exists\n"); else params.nPort = PORT_RSH; params.nSourcePort = 1023; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int tryLogin(int hSocket, sLogin** psLogin, char* szLogin, char* szPassword) { char ipaddr_str[INET_ADDRSTRLEN]; int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* Rsh could care less what the password is */ szPassword=szLogin; /* send username */ memset(bufSend, 0, sizeof(bufSend)); bufSend[0]=0x00; strncpy(bufSend+1, szLogin, strlen(szLogin)); bufSend[strlen(szLogin)+1]=0x00; strncpy(bufSend+2+strlen(szLogin), szPassword, strlen(szPassword)); bufSend[strlen(szLogin)+1+strlen(szPassword)+1]=0x00; strncpy(bufSend+1+strlen(szLogin)+1+strlen(szPassword)+1, "id", 3); bufSend[strlen(szLogin)+1+strlen(szPassword)+1+3]=0x00; if (medusaSend(hSocket, bufSend, strlen(szLogin)+1+strlen(szPassword)+1+4 , 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; /* this is the port that the client should listen to for stderr. We should really check this but we're going to skip */ bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data. Which ends rsh test.", MODULE_NAME); return FAILURE; } bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data. Exiting...", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive,"uid") != NULL) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } medusa-2.1.1/src/modsrc/postgres.c0000644000175000001440000002512011723732127014003 00000000000000/* ** PostgreSQL Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "postgres.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for PostgreSQL sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: postgres.c 1301 2010-02-09 22:54:18Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define LIBPQ_WARNING "No usable LIBPQ. Module disabled." #ifdef HAVE_LIBPQ #include "libpq-fe.h" #define PORT_POSTGRESQL 5432 typedef struct __POSTGRESQL_DATA { char *szDB; } _POSTGRESQL_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _POSTGRESQL_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _POSTGRESQL_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " DB:? "); writeVerbose(VB_NONE, " Sets target database name."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M postgres -m DB:some_db\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _POSTGRESQL_DATA *psSessionData; psSessionData = malloc(sizeof(_POSTGRESQL_DATA)); memset(psSessionData, 0, sizeof(_POSTGRESQL_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszDB = malloc(strlen(pOpt) + 1); memset(psSessionData->szDB, 0, strlen(pOpt) + 1); strncpy((char *)psSessionData->szDB, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method DB requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _POSTGRESQL_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); params.nPort = PORT_POSTGRESQL; initConnectionParams(psLogin, ¶ms); /* set database name, if not specified by user */ if (_psSessionData->szDB == NULL) { _psSessionData->szDB = malloc(10); memset(_psSessionData->szDB, 0, 10); sprintf(_psSessionData->szDB, "template1"); } writeError(ERR_DEBUG_MODULE, "[%s] Set database name: %s", MODULE_NAME, _psSessionData->szDB); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int tryLogin(int hSocket, sLogin** psLogin, _POSTGRESQL_DATA* _psSessionData, char* szLogin, char* szPassword) { char *szConnectionString; int iRet; szConnectionString = malloc(strlen((*psLogin)->psServer->pHostIP) + strlen(szLogin) + strlen(szPassword) + strlen(_psSessionData->szDB) + 47); memset(szConnectionString, 0, strlen((*psLogin)->psServer->pHostIP) + strlen(szLogin) + strlen(szPassword) + strlen(_psSessionData->szDB) + 47); sprintf(szConnectionString, "host = '%s' dbname = '%s' user = '%s' password = '%s' ", (*psLogin)->psServer->pHostIP, _psSessionData->szDB, szLogin, szPassword); if (PQstatus(PQconnectdb(szConnectionString)) == CONNECTION_OK) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } setPassResult((*psLogin), szPassword); free(szConnectionString); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(LIBPQ_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, LIBPQ_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is LIBPQ installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is LIBPQ installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif medusa-2.1.1/src/modsrc/Makefile.am0000644000175000001440000000775311750565732014047 00000000000000 modulesdir = $(libdir)/medusa/modules EXTRA_PROGRAMS = afp.mod cvs.mod ftp.mod http.mod imap.mod mssql.mod mysql.mod ncp.mod nntp.mod pcanywhere.mod \ pop3.mod postgres.mod rexec.mod rlogin.mod rsh.mod smbnt.mod smtp.mod smtp-vrfy.mod \ snmp.mod ssh.mod svn.mod telnet.mod vmauthd.mod vnc.mod web-form.mod wrapper.mod modules_PROGRAMS = if BUILD_MODULE_AFP modules_PROGRAMS += afp.mod endif if BUILD_MODULE_CVS modules_PROGRAMS += cvs.mod endif if BUILD_MODULE_FTP modules_PROGRAMS += ftp.mod endif if BUILD_MODULE_HTTP modules_PROGRAMS += http.mod endif if BUILD_MODULE_IMAP modules_PROGRAMS += imap.mod endif if BUILD_MODULE_MSSQL modules_PROGRAMS += mssql.mod endif if BUILD_MODULE_MYSQL modules_PROGRAMS += mysql.mod endif if BUILD_MODULE_NCP modules_PROGRAMS += ncp.mod endif if BUILD_MODULE_NNTP modules_PROGRAMS += nntp.mod endif if BUILD_MODULE_PCANYWHERE modules_PROGRAMS += pcanywhere.mod endif if BUILD_MODULE_POP3 modules_PROGRAMS += pop3.mod endif if BUILD_MODULE_POSTGRES modules_PROGRAMS += postgres.mod endif if BUILD_MODULE_REXEC modules_PROGRAMS += rexec.mod endif if BUILD_MODULE_RLOGIN modules_PROGRAMS += rlogin.mod endif if BUILD_MODULE_RSH modules_PROGRAMS += rsh.mod endif if BUILD_MODULE_SMBNT modules_PROGRAMS += smbnt.mod endif if BUILD_MODULE_SMTP modules_PROGRAMS += smtp.mod endif if BUILD_MODULE_SMTP_VRFY modules_PROGRAMS += smtp-vrfy.mod endif if BUILD_MODULE_SNMP modules_PROGRAMS += snmp.mod endif if BUILD_MODULE_SSH modules_PROGRAMS += ssh.mod endif if BUILD_MODULE_SVN modules_PROGRAMS += svn.mod endif if BUILD_MODULE_TELNET modules_PROGRAMS += telnet.mod endif if BUILD_MODULE_VMAUTHD modules_PROGRAMS += vmauthd.mod endif if BUILD_MODULE_VNC modules_PROGRAMS += vnc.mod endif if BUILD_MODULE_WEB_FORM modules_PROGRAMS += web-form.mod endif if BUILD_MODULE_WRAPPER modules_PROGRAMS += wrapper.mod endif afp_mod_SOURCES = afp.c ../medusa-trace.c cvs_mod_SOURCES = cvs.c ../medusa-trace.c ftp_mod_SOURCES = ftp.c ../medusa-trace.c http_mod_SOURCES = http.c ntlm.c http-digest.c ../medusa-trace.c imap_mod_SOURCES = imap.c ntlm.c ../medusa-trace.c mssql_mod_SOURCES = mssql.c ../medusa-trace.c mysql_mod_SOURCES = mysql.c ../medusa-trace.c sha1.c ncp_mod_SOURCES = ncp.c ../medusa-trace.c nntp_mod_SOURCES = nntp.c ../medusa-trace.c pcanywhere_mod_SOURCES = pcanywhere.c ../medusa-trace.c pop3_mod_SOURCES = pop3.c ntlm.c ../medusa-trace.c postgres_mod_SOURCES = postgres.c ../medusa-trace.c rexec_mod_SOURCES = rexec.c ../medusa-trace.c rlogin_mod_SOURCES = rlogin.c ../medusa-trace.c rsh_mod_SOURCES = rsh.c ../medusa-trace.c smbnt_mod_SOURCES = smbnt.c hmacmd5.c ../medusa-trace.c smtp_mod_SOURCES = smtp.c ntlm.c ../medusa-trace.c smtp_vrfy_mod_SOURCES = smtp-vrfy.c ../medusa-trace.c snmp_mod_SOURCES = snmp.c ../medusa-trace.c ssh_mod_SOURCES = ssh.c ../medusa-trace.c svn_mod_SOURCES = svn.c ../medusa-trace.c telnet_mod_SOURCES = telnet.c ../medusa-trace.c vmauthd_mod_SOURCES = vmauthd.c ../medusa-trace.c vnc_mod_SOURCES = vnc.c d3des.c ../medusa-trace.c web_form_mod_SOURCES = web-form.c ../medusa-trace.c wrapper_mod_SOURCES = wrapper.c ../medusa-trace.c INCLUDES = -I$(top_srcdir)/src $(all_includes) afp_mod_LDFLAGS = -fPIC cvs_mod_LDFLAGS = -fPIC ftp_mod_LDFLAGS = -fPIC http_mod_LDFLAGS = -fPIC imap_mod_LDFLAGS = -fPIC mssql_mod_LDFLAGS = -fPIC mysql_mod_LDFLAGS = -fPIC ncp_mod_LDFLAGS = -fPIC nntp_mod_LDFLAGS = -fPIC pcanywhere_mod_LDFLAGS = -fPIC pop3_mod_LDFLAGS = -fPIC postgres_mod_LDFLAGS = -fPIC rexec_mod_LDFLAGS = -fPIC rlogin_mod_LDFLAGS = -fPIC rsh_mod_LDFLAGS = -fPIC smbnt_mod_LDFLAGS = -fPIC smtp_mod_LDFLAGS = -fPIC smtp_vrfy_mod_LDFLAGS = -fPIC snmp_mod_LDFLAGS = -fPIC ssh_mod_LDFLAGS = -fPIC svn_mod_LDFLAGS = -fPIC telnet_mod_LDFLAGS = -fPIC vmauthd_mod_LDFLAGS = -fPIC vnc_mod_LDFLAGS = -fPIC web_form_mod_LDFLAGS = -fPIC wrapper_mod_LDFLAGS = -fPIC LDADD = @MODULE_LIBS@ noinst_HEADERS = module.h d3des.h sha1.h hmacmd5.h http-digest.h ntlm.h EXTRA_DIST = wrapper/*.pl medusa-2.1.1/src/modsrc/telnet.c0000644000175000001440000007602411723732127013441 00000000000000/*************************************************************************** * telnet.c * * Copyright (C) 2009 by fizzgig * * fizzgig@foofus.net * * * * Implementation of a telnet brute force module for * * medusa. Module concept by the one-and-only Foofus. * * Protocol stuff based on the original hydra telnet code by * * VanHauser and the good folks at thc (vh@thc.org) * * * * * * CHANGE LOG * * 04/05/2005 - Created by fizzgig (fizzgig@foofus.net) * * All other changes are in the Subversion comments * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2, * * as published by the Free Software Foundation * * * * 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. See the * * GNU General Public License for more details. * * * * http://www.gnu.org/licenses/gpl.txt * * * * This program is released under the GPL with the additional exemption * * that compiling, linking, and/or using OpenSSL is allowed. * * * * Tested on so far: * * Jetdirect cards (woo!) * * HP switches using basic auth * * Cisco switches using vty auth * * * * Support for hosts w/o username prompt added by pMonkey/JoMo-Kun * * * ***************************************************************************/ #include #include #include #include #include #include #include "module.h" #define MODULE_NAME "telnet.mod" #define MODULE_AUTHOR "fizzgig " #define MODULE_SUMMARY_USAGE "Brute force module for telnet sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: telnet.c 1580 2011-07-07 21:31:21Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define PORT_TELNET 23 #define PORT_TELNETS 992 #define PROMPT_UNKNOWN 0 #define PROMPT_LOGIN_PASSWORD 1 #define PROMPT_PASSWORD 2 #define RECEIVE_DELAY_1 20 * 1000000 #define RECEIVE_DELAY_2 0.5 * 1000000 #define MODE_NORMAL 0 #define MODE_AS400 1 typedef struct __MODULE_DATA { int nMode; } _MODULE_DATA; const unsigned int BUFFER_SIZE = 300; const char* KNOWN_PROMPTS = ">#$%/?"; // Each character represents a known telnet prompt - feel free to add a new one if desired const int KNOWN_PWD_SIZE = 4; // Make sure to keep this in sync with the size of the array below!! const char* KNOWN_PWD_PROMPTS[] = { "assword", "asscode", "ennwort", "ASSWORD" }; // Complete/partial lines that indicate a password request const int KNOWN_LOGIN_SIZE = 3; // Make sure to keep this in sync with the size of the array below!! const char* KNOWN_LOGIN_PROMPTS[] = { "login:", "sername:", "User" }; // Complete/partial lines that request a user name // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword, int nFoundPrompt); int tryLoginAS400(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA* _psSessionData); int processIAClogout(int hSocket, _MODULE_DATA* _psSessionData); void processIAC(int hSocket, _MODULE_DATA* _psSessionData, char** buffer, int* nBufferSize); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " MODE:? (NORMAL, AS400) [optional]"); writeVerbose(VB_NONE, " Sets the mode for error detection."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M telnet -m MODE:AS400 -U accounts.txt -p password\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inMode = MODE_AS400; else writeError(ERR_WARNING, "Invalid value for method MODE."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* _psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; char* bufReceive; int nReceiveBufferSize = 0, nFoundPrompt = PROMPT_UNKNOWN; int i = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, _psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (_psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = _psLogin->psServer->psAudit->iPortOverride; else if (_psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_TELNETS; else params.nPort = PORT_TELNET; initConnectionParams(_psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (_psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket <= 0) { writeError(ERR_ERROR, "[%s] Failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(_psLogin, psCredSet->pPass); return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); // Examine the first line returned nReceiveBufferSize = 0; bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) return FAILURE; bufReceive[nReceiveBufferSize] = 0; // Make certain buffer is null-terminated if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] null response was unexpected from a telnet server (is one running?)", MODULE_NAME); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(_psLogin, psCredSet->pPass); return FAILURE; } // Telnet protocol negotiation do { nFoundPrompt = PROMPT_UNKNOWN; processIAC(hSocket, _psSessionData, &bufReceive, &nReceiveBufferSize); if (bufReceive != NULL && bufReceive[0] != 0 && (unsigned char)bufReceive[0] != IAC) makeToLower(bufReceive); if (bufReceive != NULL) { writeError(ERR_DEBUG_MODULE, "Looking for login prompts"); if (_psSessionData->nMode == MODE_AS400) { if (strcasestr(bufReceive, (char *)"Sign On") != '\0') { writeError(ERR_INFO, "[%s] Detected AS/400 Sign On Screen.", MODULE_NAME); nFoundPrompt = PROMPT_LOGIN_PASSWORD; FREE(bufReceive); if (medusaDataReadyTimed(hSocket, 0, 20000) > 0) { // More data waiting bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive != NULL) bufReceive[nReceiveBufferSize] = 0; // Make certain buffer is null-terminated } break; } /* Sign On System . . . . . : TSTDBS16 Subsystem . . . . : QINTER Display . . . . . : QPADEV0001 */ } else { // Look for known login prompts for (i = 0; i < KNOWN_LOGIN_SIZE; i++) { if (strcasestr(bufReceive, KNOWN_LOGIN_PROMPTS[i]) != '\0') { // Do we have a prompt? writeError(ERR_DEBUG_MODULE, "Found login prompt..."); nFoundPrompt = PROMPT_LOGIN_PASSWORD; break; } } /* Some systems do not provide a login prompt and go right to password */ for (i = 0; i < KNOWN_PWD_SIZE; i++) { if (strcasestr(bufReceive, KNOWN_PWD_PROMPTS[i]) != '\0') { // Do we have a prompt? writeError(ERR_DEBUG_MODULE, "Found a password prompt already..."); nFoundPrompt = PROMPT_PASSWORD; if (_psLogin->psServer->iLoginsDone < 1 && _psLogin->iId == 0) writeVerbose(VB_NONE_FILE, "Password Prompt Only: %s\n", _psLogin->psServer->pHostIP); break; } } if (nFoundPrompt == PROMPT_UNKNOWN) { FREE(bufReceive); if (medusaDataReadyTimed(hSocket, 0, 20000) > 0) { // More data waiting bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive != NULL) bufReceive[nReceiveBufferSize] = 0; // Make certain buffer is null-terminated } } } } } while (bufReceive != NULL && (unsigned char)bufReceive[0] == IAC && nFoundPrompt == PROMPT_UNKNOWN); FREE(bufReceive); if (nFoundPrompt == PROMPT_UNKNOWN) { writeError(ERR_ERROR, "[%s] Failed to identify logon prompt.", MODULE_NAME); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(_psLogin, psCredSet->pPass); return FAILURE; } else nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: if (_psSessionData->nMode == MODE_AS400) nState = tryLoginAS400(hSocket, &_psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); else nState = tryLogin(hSocket, &_psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass, nFoundPrompt); if (_psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (processIAClogout(hSocket, _psSessionData) == FAILURE) { writeError(ERR_ERROR, "[%s] Failed to close existing Telnet session.", MODULE_NAME); } medusaDisconnect(hSocket); hSocket = -1; /* Cisco devices appear to keep sessions open for a brief time after we terminate the connection. They also seem to ignore "IAC DO LOGOUT" commands. Adding a sleep() hack here, to give them some time to clean-up. */ sleep(3); if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module (%d) state %d host: %s", MODULE_NAME, _psLogin->iId, nState, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; } } FREE(psCredSet); return SUCCESS; } int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword, int nFoundPrompt) { // This function should return MSTATE_RUNNING to continue or MSTATE_EXITING to terminate the module char bufSend[BUFFER_SIZE]; char* bufReceive; int nSendBufferSize = 0, nReceiveBufferSize = 0; int nContinue = 0, i = 0; // Check the socket and such if (hSocket <= 0) { writeError(ERR_ERROR, "%s failed: socket was invalid", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; // No good socket } if (nFoundPrompt == PROMPT_LOGIN_PASSWORD) { // Set up the send buffer memset(bufSend, 0, BUFFER_SIZE); sprintf(bufSend, "%s\r", szLogin); nSendBufferSize = strlen(bufSend) + 1; // Count the null terminator if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } do { // Look for a return bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) { // Found a prompt - telnet appears to be alive, keep going writeError(ERR_ERROR, "%s: Telnet did not respond to the sending of the user name '%s' in a timely fashion - is it down or refusing connections?", MODULE_NAME, szLogin); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } bufReceive[nReceiveBufferSize] = 0; // Make certain buffer is null-terminated // Do we have a prompt? if (strcspn(bufReceive, KNOWN_PROMPTS) != strlen(bufReceive)) { (*login)->iResult = LOGIN_RESULT_SUCCESS; setPassResult(*login, szPassword); free(bufReceive); return MSTATE_EXITING; } makeToLower(bufReceive); // Are we at a known password prompt? for (i = 0; i < KNOWN_PWD_SIZE; i++) { if (strcasestr(bufReceive, KNOWN_PWD_PROMPTS[i]) != '\0') { nContinue = 1; break; } } // Look for known login prompts if (nContinue == 0) { for (i = 0; i < KNOWN_LOGIN_SIZE; i++) { if (strcasestr(bufReceive, KNOWN_LOGIN_PROMPTS[i]) != '\0') { free(bufReceive); (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_RUNNING; } } } free(bufReceive); } while(nContinue == 0); } else if (nFoundPrompt == PROMPT_PASSWORD) { writeError(ERR_DEBUG_MODULE, "[%s] we are skipping a username", MODULE_NAME); } else { writeError(ERR_ERROR, "[%s] No login prompt detected.", MODULE_NAME); return FAILURE; } // Send the password memset(bufSend, 0, BUFFER_SIZE); sprintf(bufSend, "%s\r", szPassword); nSendBufferSize = strlen(bufSend) + 1; // Count the null terminator if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } // Look for a return bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) { writeError(ERR_ERROR, "timeout waiting for response from server after sending password"); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } bufReceive[nReceiveBufferSize] = 0; // Make certain buffer is null-terminated // It's possible that some telnet servers (like Microsoft's) may send some more IAC commands at this point // Take care of zem! processIAC(hSocket, _psSessionData, &bufReceive, &nReceiveBufferSize); if (bufReceive == NULL) bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); // Do we have a prompt? while (bufReceive != NULL) { /* check for known failures */ if (strstr(bufReceive, "Authentication failed")) { writeError(ERR_DEBUG_MODULE, "Server responded with Cisco \"Authentication failed.\" message."); (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } if (strstr(bufReceive, "Login invalid")) { writeError(ERR_DEBUG_MODULE, "Server responded with Cisco \"Login invalid\" message."); (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } else if (strcspn(bufReceive, KNOWN_PROMPTS) != strlen(bufReceive)) { // Found a prompt - telnet appears to be alive free(bufReceive); (*login)->iResult = LOGIN_RESULT_SUCCESS; setPassResult(*login, szPassword); return MSTATE_EXITING; } else { if (nFoundPrompt == PROMPT_LOGIN_PASSWORD) { // If we have a login prompt, we have failed for (i = 0; i < KNOWN_LOGIN_SIZE; i++) { if (strcasestr(bufReceive, KNOWN_LOGIN_PROMPTS[i]) != '\0') { free(bufReceive); writeError(ERR_DEBUG_MODULE, "unsuccessful login - user '%s' with a password of '%s'", szLogin, szPassword); (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } } } else { // We are operating on a non-login telnet setup for (i = 0; i < KNOWN_PWD_SIZE; i++) { if (strcasestr(bufReceive, KNOWN_PWD_PROMPTS[i]) != '\0') { free(bufReceive); writeError(ERR_DEBUG_MODULE, "unsuccessful login with a password of '%s'", szPassword); (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } } } } free(bufReceive); bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); } (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } int tryLoginAS400(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { char bufSend[BUFFER_SIZE]; char* bufReceive; int nSendBufferSize = 0, nReceiveBufferSize = 0; int iRet = FAILURE; char szUser[10 + 1]; char szPass[128 + 1]; char szErrorMsg[100]; if (hSocket <= 0) { writeError(ERR_ERROR, "%s failed: socket was invalid", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } /* Send username and password */ /* USERNAME \t (0x09) PASSWORD \r (0x0D) \0 (0x00) */ /* Password Policy Information http://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/rzakz/rzakzqpwdlvl.htm Short passwords: The AS/400 "short" passwords are 0-10 characters in length. They allow the following characters: A-Z 0-9 $ @ # _ Long passwords: The AS/400 "long" passwords are 0-128 characters in length. Upper and lower case passwords consisting of any characters are allowed. Usernames appear to be limited to 10 characters in length and use upper-case. ** This has not been fully verified. ** http://download.oracle.com/docs/html/B10256_01/ch2.htm IBM DB2/400 V4R5 object names can be up to 10 alphanumeric characters in length, beginning with a letter or a national character. */ memset(bufSend, 0, BUFFER_SIZE); memset(szUser, 0, 10 + 1); memset(szPass, 0, 128 + 1); strncpy(szUser, szLogin, 10); strncpy(szPass, szPassword, 128); sprintf(bufSend, "%s\t%s\r", szUser, szPass); nSendBufferSize = strlen(bufSend) + 1; if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } /* Process server response */ bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] Timeout waiting for response from server after sending password", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } if (strstr(bufReceive, "CPF1120") != NULL) { sprintf(szErrorMsg, "CPF1120 - User %s does not exist.", szUser); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = malloc( strlen(szErrorMsg) + 1 ); memset((*psLogin)->pErrorMsg, 0, strlen(szErrorMsg) + 1 ); strncpy((*psLogin)->pErrorMsg, szErrorMsg, strlen(szErrorMsg)); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else if (strstr(bufReceive, "CPF1116") != NULL) { strcpy(szErrorMsg, "CPF1116 - Next not valid sign-on attempt varies off device."); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = malloc( strlen(szErrorMsg) + 1 ); memset((*psLogin)->pErrorMsg, 0, strlen(szErrorMsg) + 1 ); strncpy((*psLogin)->pErrorMsg, szErrorMsg, strlen(szErrorMsg)); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else if (strstr(bufReceive, "CPF1392") != NULL) { strcpy(szErrorMsg, "CPF1392 - Next not valid sign-on disables user profile."); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = malloc( strlen(szErrorMsg) + 1 ); memset((*psLogin)->pErrorMsg, 0, strlen(szErrorMsg) + 1 ); strncpy((*psLogin)->pErrorMsg, szErrorMsg, strlen(szErrorMsg)); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } /* http://archive.midrange.com/midrange-l/200507/msg01092.html Cause . . . . . : User profile &1 has reached the maximum number of sign-on attempts and has been disabled, or the STATUS parameter has been changed to *DISABLED on the Create User Profile (CRTUSRPRF) or Change User Profile (CHGUSRPRF) command. Recovery . . . : To enable the user profile, have the security officer change the STATUS parameter to *ENABLED on the Change User Profile (CHGUSRPRF) command. */ else if (strstr(bufReceive, "CPF1394") != NULL) { sprintf(szErrorMsg, "CPF1394 - User profile %s cannot sign on.", szUser); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = malloc( strlen(szErrorMsg) + 1 ); memset((*psLogin)->pErrorMsg, 0, strlen(szErrorMsg) + 1 ); strncpy((*psLogin)->pErrorMsg, szErrorMsg, strlen(szErrorMsg)); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else if (strstr(bufReceive, "CPF1118") != NULL) { sprintf(szErrorMsg, "CPF1118 - No password associated with user %s.", szUser); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = malloc( strlen(szErrorMsg) + 1 ); memset((*psLogin)->pErrorMsg, 0, strlen(szErrorMsg) + 1 ); strncpy((*psLogin)->pErrorMsg, szErrorMsg, strlen(szErrorMsg)); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else if (strstr(bufReceive, "CPF1109") != NULL) { strcpy(szErrorMsg, "CPF1109 - Not authorized to subsystem."); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = malloc( strlen(szErrorMsg) + 1 ); memset((*psLogin)->pErrorMsg, 0, strlen(szErrorMsg) + 1 ); strncpy((*psLogin)->pErrorMsg, szErrorMsg, strlen(szErrorMsg)); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else if (strstr(bufReceive, "CPF1110") != NULL) { strcpy(szErrorMsg, "CPF1110 - Not authorized to work station."); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = malloc( strlen(szErrorMsg) + 1 ); memset((*psLogin)->pErrorMsg, 0, strlen(szErrorMsg) + 1 ); strncpy((*psLogin)->pErrorMsg, szErrorMsg, strlen(szErrorMsg)); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else if (strstr(bufReceive, "CPF1107") != NULL) { writeError(ERR_INFO, "[%s] CPF1107 - Password not correct for user profile.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } setPassResult((*psLogin), szPass); return iRet; } /* The sender of this command REQUESTS that the receiver forcibly log off the user process at the receiver's end, or confirms that the receiver has its permission to do so. */ int processIAClogout(int hSocket, _MODULE_DATA* _psSessionData) { unsigned char bufSend[] = { 0xFF, 0xFD, 0x12 }; /* IAC DO LOGOUT */ char* bufReceive = NULL; int nReceiveBufferSize = 0; writeError(ERR_DEBUG_MODULE, "[%s] Sending IAC DO LOGOUT command.", MODULE_NAME); if (medusaSend(hSocket, bufSend, 3, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } /* Receive any remaining IAC commands */ /* bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) return FAILURE; processIAC(hSocket, _psSessionData, &bufReceive, &nReceiveBufferSize); */ return SUCCESS; } void processIAC(int hSocket, _MODULE_DATA* _psSessionData, char** buffer, int* nReceiveBufferSize) { unsigned char* bufTemp = (unsigned char*)*buffer; /* We're not that friendly. Refuse to do anything asked of us. */ while (*bufTemp == IAC) /* IAC (0xFF) */ { writeError(ERR_DEBUG_MODULE, "Handling IAC Command..."); if ((bufTemp[1] == 0xfc || bufTemp[1] == 0xfe) && bufTemp[2] == 0x22) { writeError(ERR_DEBUG_MODULE, "TELNETD peer does not like linemode"); } if (bufTemp[1] == WILL) /* WILL (0xFB), WONT (0xFC) */ { /* AS/400 devices appear to request and require "Echo" and "Suppress Go Ahead" */ if (_psSessionData->nMode == MODE_AS400) if ((bufTemp[2] == TELOPT_ECHO) || (bufTemp[2] == TELOPT_SGA)) bufTemp[1] = DO; else bufTemp[1] = DONT; else bufTemp[1] = DONT; medusaSend(hSocket, bufTemp, 3, 0); } else if (bufTemp[1] == DO) /* DO (0xFD), DONT (0xFE) */ { bufTemp[1] = WONT; medusaSend(hSocket, bufTemp, 3, 0); } bufTemp += 3; /* Process three bytes at a time */ } if (*bufTemp == 0) { writeError(ERR_DEBUG_MODULE, "Getting more data"); free(*buffer); *nReceiveBufferSize = 0; *buffer = medusaReceiveLineDelay(hSocket, nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (*buffer != NULL) (*buffer)[*nReceiveBufferSize] = 0; // Make certain buffer is null-terminated else { // No data *buffer = NULL; return; } writeError(ERR_DEBUG_MODULE, "Next pass buffer: %s", *buffer); if ((unsigned char)*buffer[0] == IAC) { writeError(ERR_DEBUG_MODULE, "More commands waiting..."); } } } medusa-2.1.1/src/modsrc/ntlm.c0000644000175000001440000011056211723732127013114 00000000000000/* ** NTLM Authentication Protocol Support Functions ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Functions for processing Type-1, Type-2 and Type-3 messages used during ** NTLM authentication. The following document is an excellent resource ** on this topic: ** ** http://davenport.sourceforge.net/ntlm.html ** ** The ntlm.h/.c files combine content from multiple sources into a single ** convenient location. It is based on code contributed to the Hydra ** project by ilo@reversing.org along with analysis of the Fetchmail and ** Samba source. */ #include #include #include #include #include #include #include "ntlm.h" /* Byte order macros */ #ifndef _BYTEORDER_H #define _BYTEORDER_H /* This file implements macros for machine independent short and int manipulation Here is a description of this file that I emailed to the samba list once: > I am confused about the way that byteorder.h works in Samba. I have > looked at it, and I would have thought that you might make a distinction > between LE and BE machines, but you only seem to distinguish between 386 > and all other architectures. > > Can you give me a clue? sure. The distinction between 386 and other architectures is only there as an optimisation. You can take it out completely and it will make no difference. The routines (macros) in byteorder.h are totally byteorder independent. The 386 optimsation just takes advantage of the fact that the x86 processors don't care about alignment, so we don't have to align ints on int boundaries etc. If there are other processors out there that aren't alignment sensitive then you could also define CAREFUL_ALIGNMENT=0 on those processors as well. Ok, now to the macros themselves. I'll take a simple example, say we want to extract a 2 byte integer from a SMB packet and put it into a type called uint16 that is in the local machines byte order, and you want to do it with only the assumption that uint16 is _at_least_ 16 bits long (this last condition is very important for architectures that don't have any int types that are 2 bytes long) You do this: #define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) #define PVAL(buf,pos) ((unsigned)CVAL(buf,pos)) #define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) then to extract a uint16 value at offset 25 in a buffer you do this: char *buffer = foo_bar(); uint16 xx = SVAL(buffer,25); We are using the byteoder independence of the ANSI C bitshifts to do the work. A good optimising compiler should turn this into efficient code, especially if it happens to have the right byteorder :-) I know these macros can be made a bit tidier by removing some of the casts, but you need to look at byteorder.h as a whole to see the reasoning behind them. byteorder.h defines the following macros: SVAL(buf,pos) - extract a 2 byte SMB value IVAL(buf,pos) - extract a 4 byte SMB value SVALS(buf,pos) signed version of SVAL() IVALS(buf,pos) signed version of IVAL() SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer SSVALS(buf,pos,val) - signed version of SSVAL() SIVALS(buf,pos,val) - signed version of SIVAL() RSVAL(buf,pos) - like SVAL() but for NMB byte ordering RSVALS(buf,pos) - like SVALS() but for NMB byte ordering RIVAL(buf,pos) - like IVAL() but for NMB byte ordering RIVALS(buf,pos) - like IVALS() but for NMB byte ordering RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering RSIVALS(buf,pos,val) - like SIVALS() but for NMB ordering it also defines lots of intermediate macros, just ignore those :-) */ /* some switch macros that do both store and read to and from SMB buffers */ #define RW_PCVAL(read,inbuf,outbuf,len) \ { if (read) { PCVAL (inbuf,0,outbuf,len); } \ else { PSCVAL(inbuf,0,outbuf,len); } } #define RW_PIVAL(read,big_endian,inbuf,outbuf,len) \ { if (read) { if (big_endian) { RPIVAL(inbuf,0,outbuf,len); } else { PIVAL(inbuf,0,outbuf,len); } } \ else { if (big_endian) { RPSIVAL(inbuf,0,outbuf,len); } else { PSIVAL(inbuf,0,outbuf,len); } } } #define RW_PSVAL(read,big_endian,inbuf,outbuf,len) \ { if (read) { if (big_endian) { RPSVAL(inbuf,0,outbuf,len); } else { PSVAL(inbuf,0,outbuf,len); } } \ else { if (big_endian) { RPSSVAL(inbuf,0,outbuf,len); } else { PSSVAL(inbuf,0,outbuf,len); } } } #define RW_CVAL(read, inbuf, outbuf, offset) \ { if (read) { (outbuf) = CVAL (inbuf,offset); } \ else { SCVAL(inbuf,offset,outbuf); } } #define RW_IVAL(read, big_endian, inbuf, outbuf, offset) \ { if (read) { (outbuf) = ((big_endian) ? RIVAL(inbuf,offset) : IVAL (inbuf,offset)); } \ else { if (big_endian) { RSIVAL(inbuf,offset,outbuf); } else { SIVAL(inbuf,offset,outbuf); } } } #define RW_SVAL(read, big_endian, inbuf, outbuf, offset) \ { if (read) { (outbuf) = ((big_endian) ? RSVAL(inbuf,offset) : SVAL (inbuf,offset)); } \ else { if (big_endian) { RSSVAL(inbuf,offset,outbuf); } else { SSVAL(inbuf,offset,outbuf); } } } #undef CAREFUL_ALIGNMENT /* we know that the 386 can handle misalignment and has the "right" byteorder */ #ifdef __i386__ #define CAREFUL_ALIGNMENT 0 #endif #ifndef CAREFUL_ALIGNMENT #define CAREFUL_ALIGNMENT 1 #endif #define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) #define PVAL(buf,pos) ((unsigned)CVAL(buf,pos)) #define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val)) #if CAREFUL_ALIGNMENT #define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) #define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16) #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) #define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16)) #define SVALS(buf,pos) ((int16)SVAL(buf,pos)) #define IVALS(buf,pos) ((int32)IVAL(buf,pos)) #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val))) #define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val))) #define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val))) #define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val))) #else /* CAREFUL_ALIGNMENT */ /* this handles things for architectures like the 386 that can handle alignment errors */ /* WARNING: This section is dependent on the length of int16 and int32 being correct */ /* get single value from an SMB buffer */ #define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos))) #define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos))) #define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos))) #define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos))) /* store single value in an SMB buffer */ #define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val)) #define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val)) #define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val)) #define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val)) #endif /* CAREFUL_ALIGNMENT */ /* macros for reading / writing arrays */ #define SMBMACRO(macro,buf,pos,val,len,size) \ { int l; for (l = 0; l < (len); l++) (val)[l] = macro((buf), (pos) + (size)*l); } #define SSMBMACRO(macro,buf,pos,val,len,size) \ { int l; for (l = 0; l < (len); l++) macro((buf), (pos) + (size)*l, (val)[l]); } /* reads multiple data from an SMB buffer */ #define PCVAL(buf,pos,val,len) SMBMACRO(CVAL,buf,pos,val,len,1) #define PSVAL(buf,pos,val,len) SMBMACRO(SVAL,buf,pos,val,len,2) #define PIVAL(buf,pos,val,len) SMBMACRO(IVAL,buf,pos,val,len,4) #define PCVALS(buf,pos,val,len) SMBMACRO(CVALS,buf,pos,val,len,1) #define PSVALS(buf,pos,val,len) SMBMACRO(SVALS,buf,pos,val,len,2) #define PIVALS(buf,pos,val,len) SMBMACRO(IVALS,buf,pos,val,len,4) /* stores multiple data in an SMB buffer */ #define PSCVAL(buf,pos,val,len) SSMBMACRO(SCVAL,buf,pos,val,len,1) #define PSSVAL(buf,pos,val,len) SSMBMACRO(SSVAL,buf,pos,val,len,2) #define PSIVAL(buf,pos,val,len) SSMBMACRO(SIVAL,buf,pos,val,len,4) #define PSCVALS(buf,pos,val,len) SSMBMACRO(SCVALS,buf,pos,val,len,1) #define PSSVALS(buf,pos,val,len) SSMBMACRO(SSVALS,buf,pos,val,len,2) #define PSIVALS(buf,pos,val,len) SSMBMACRO(SIVALS,buf,pos,val,len,4) /* now the reverse routines - these are used in nmb packets (mostly) */ #define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) #define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16))) #define RSVAL(buf,pos) SREV(SVAL(buf,pos)) #define RSVALS(buf,pos) SREV(SVALS(buf,pos)) #define RIVAL(buf,pos) IREV(IVAL(buf,pos)) #define RIVALS(buf,pos) IREV(IVALS(buf,pos)) #define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val)) #define RSSVALS(buf,pos,val) SSVALS(buf,pos,SREV(val)) #define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val)) #define RSIVALS(buf,pos,val) SIVALS(buf,pos,IREV(val)) /* reads multiple data from an SMB buffer (big-endian) */ #define RPSVAL(buf,pos,val,len) SMBMACRO(RSVAL,buf,pos,val,len,2) #define RPIVAL(buf,pos,val,len) SMBMACRO(RIVAL,buf,pos,val,len,4) #define RPSVALS(buf,pos,val,len) SMBMACRO(RSVALS,buf,pos,val,len,2) #define RPIVALS(buf,pos,val,len) SMBMACRO(RIVALS,buf,pos,val,len,4) /* stores multiple data in an SMB buffer (big-endian) */ #define RPSSVAL(buf,pos,val,len) SSMBMACRO(RSSVAL,buf,pos,val,len,2) #define RPSIVAL(buf,pos,val,len) SSMBMACRO(RSIVAL,buf,pos,val,len,4) #define RPSSVALS(buf,pos,val,len) SSMBMACRO(RSSVALS,buf,pos,val,len,2) #define RPSIVALS(buf,pos,val,len) SSMBMACRO(RSIVALS,buf,pos,val,len,4) #define DBG_RW_PCVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \ { RW_PCVAL(read,inbuf,outbuf,len) \ DEBUG(5,("%s%04x %s: ", \ tab_depth(depth), base,string)); \ if (charmode) print_asc(5, (unsigned char*)(outbuf), (len)); else \ { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (outbuf)[idx])); } } \ DEBUG(5,("\n")); } #define DBG_RW_PSVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \ { RW_PSVAL(read,big_endian,inbuf,outbuf,len) \ DEBUG(5,("%s%04x %s: ", \ tab_depth(depth), base,string)); \ if (charmode) print_asc(5, (unsigned char*)(outbuf), 2*(len)); else \ { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (outbuf)[idx])); } } \ DEBUG(5,("\n")); } #define DBG_RW_PIVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \ { RW_PIVAL(read,big_endian,inbuf,outbuf,len) \ DEBUG(5,("%s%04x %s: ", \ tab_depth(depth), base,string)); \ if (charmode) print_asc(5, (unsigned char*)(outbuf), 4*(len)); else \ { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (outbuf)[idx])); } } \ DEBUG(5,("\n")); } #define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \ { RW_CVAL(read,inbuf,outbuf,0) \ DEBUG(5,("%s%04x %s: %02x\n", \ tab_depth(depth), base, string, outbuf)); } #define DBG_RW_SVAL(string,depth,base,read,big_endian,inbuf,outbuf) \ { RW_SVAL(read,big_endian,inbuf,outbuf,0) \ DEBUG(5,("%s%04x %s: %04x\n", \ tab_depth(depth), base, string, outbuf)); } #define DBG_RW_IVAL(string,depth,base,read,big_endian,inbuf,outbuf) \ { RW_IVAL(read,big_endian,inbuf,outbuf,0) \ DEBUG(5,("%s%04x %s: %08x\n", \ tab_depth(depth), base, string, outbuf)); } #endif /* _BYTEORDER_H */ /* Samba MD4 implementation */ /* NOTE: This code makes no attempt to be fast! It assumes that a int is at least 32 bits long */ static uint32 A, B, C, D; static uint32 F(uint32 X, uint32 Y, uint32 Z) { return (X&Y) | ((~X)&Z); } static uint32 G(uint32 X, uint32 Y, uint32 Z) { return (X&Y) | (X&Z) | (Y&Z); } static uint32 H(uint32 X, uint32 Y, uint32 Z) { return X^Y^Z; } static uint32 lshift(uint32 x, int s) { x &= 0xFFFFFFFF; return ((x<>(32-s)); } #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) #define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s) #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s) /* this applies md4 to 64 byte chunks */ static void mdfour64(uint32 *M) { int j; uint32 AA, BB, CC, DD; uint32 X[16]; for (j=0;j<16;j++) X[j] = M[j]; AA = A; BB = B; CC = C; DD = D; ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7); ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19); ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7); ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19); ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7); ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19); ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7); ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19); ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5); ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13); ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5); ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13); ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5); ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13); ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5); ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13); ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9); ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15); ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9); ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15); ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9); ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15); ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9); ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15); A += AA; B += BB; C += CC; D += DD; A &= 0xFFFFFFFF; B &= 0xFFFFFFFF; C &= 0xFFFFFFFF; D &= 0xFFFFFFFF; for (j=0;j<16;j++) X[j] = 0; } static void copy64(uint32 *M, unsigned char *in) { int i; for (i=0;i<16;i++) M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) | (in[i*4+1]<<8) | (in[i*4+0]<<0); } static void copy4(unsigned char *out,uint32 x) { out[0] = x&0xFF; out[1] = (x>>8)&0xFF; out[2] = (x>>16)&0xFF; out[3] = (x>>24)&0xFF; } /* produce a md4 message digest from data of length n bytes */ void mdfour(unsigned char *out, unsigned char *in, int n) { unsigned char buf[128]; uint32 M[16]; uint32 b = n * 8; int i; A = 0x67452301; B = 0xefcdab89; C = 0x98badcfe; D = 0x10325476; while (n > 64) { copy64(M, in); mdfour64(M); in += 64; n -= 64; } for (i=0;i<128;i++) buf[i] = 0; memcpy(buf, in, n); buf[n] = 0x80; if (n <= 55) { copy4(buf+56, b); copy64(M, buf); mdfour64(M); } else { copy4(buf+120, b); copy64(M, buf); mdfour64(M); copy64(M, buf+64); mdfour64(M); } for (i=0;i<128;i++) buf[i] = 0; copy64(M, buf); copy4(out, A); copy4(out+4, B); copy4(out+8, C); copy4(out+12, D); A = B = C = D = 0; } /* Samba DES implementation */ #define uchar unsigned char #define int16 signed short typedef int BOOL; #define False 0 #define True 1 static uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; static uchar perm2[48] = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}; static uchar perm4[48] = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; static uchar perm5[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25}; static uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25}; static uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; static uchar sbox[8][4][16] = { {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; static void permute(char *out, char *in, uchar *p, int n) { int i; for (i=0;i>1; key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); key[7] = str[6]&0x7F; for (i=0;i<8;i++) { key[i] = (key[i]<<1); } } static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) { int i; char outb[64]; char inb[64]; char keyb[64]; unsigned char key2[8]; str_to_key(key, key2); for (i=0;i<64;i++) { inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; outb[i] = 0; } dohash(outb, inb, keyb, forw); for (i=0;i<8;i++) { out[i] = 0; } for (i=0;i<64;i++) { if (outb[i]) out[i/8] |= (1<<(7-(i%8))); } } void E_P16(unsigned char *p14,unsigned char *p16) { unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; smbhash(p16, sp8, p14, 1); smbhash(p16+8, sp8, p14+7, 1); } void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) { smbhash(p24, c8, p21, 1); smbhash(p24+8, c8, p21+7, 1); smbhash(p24+16, c8, p21+14, 1); } void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) { smbhash(out, in, p14, 0); smbhash(out+8, in+8, p14+7, 0); } void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out) { smbhash(out, in, p14, 1); smbhash(out+8, in+8, p14+7, 1); } void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key) { unsigned char buf[8]; smbhash(buf, in, key, 1); smbhash(out, buf, key+9, 1); } void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) { unsigned char buf[8]; static unsigned char key2[8]; smbhash(buf, in, key, 1); key2[0] = key[7]; smbhash(out, buf, key2, 1); } void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw) { static unsigned char key2[8]; smbhash(out, in, key, forw); key2[0] = key[7]; smbhash(out + 8, in + 8, key2, forw); } void SamOEMhash( unsigned char *data, unsigned char *key, int val) { unsigned char s_box[256]; unsigned char index_i = 0; unsigned char index_j = 0; unsigned char j = 0; int ind; for (ind = 0; ind < 256; ind++) { s_box[ind] = (unsigned char)ind; } for( ind = 0; ind < 256; ind++) { unsigned char tc; j += (s_box[ind] + key[ind%16]); tc = s_box[ind]; s_box[ind] = s_box[j]; s_box[j] = tc; } for( ind = 0; ind < (val ? 516 : 16); ind++) { unsigned char tc; unsigned char t; index_i++; index_j += s_box[index_i]; tc = s_box[index_i]; s_box[index_i] = s_box[index_j]; s_box[index_j] = tc; t = s_box[index_i] + s_box[index_j]; data[ind] = data[ind] ^ s_box[t]; } } /* Samba encryption implementation*/ /**************************************************************************** Like strncpy but always null terminates. Make sure there is room! The variable n should always be one less than the available size. ****************************************************************************/ char *StrnCpy(char *dest,const char *src, size_t n) { char *d = dest; if (!dest) return(NULL); if (!src) { *dest = 0; return(dest); } while (n-- && (*d++ = *src++)) ; *d = 0; return(dest); } size_t skip_multibyte_char(char c) { return 0; } /******************************************************************* safe string copy into a known length string. maxlength does not include the terminating zero. ********************************************************************/ #undef DEBUG #define DEBUG(level, s) do { printf s; } while (0) char *safe_strcpy(char *dest,const char *src, size_t maxlength) { size_t len; if (!dest) { DEBUG(0,("ERROR: NULL dest in safe_strcpy\n")); return NULL; } if (!src) { *dest = 0; return dest; } len = strlen(src); if (len > maxlength) { DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n", (int)(len-maxlength), src)); len = maxlength; } memcpy(dest, src, len); dest[len] = 0; return dest; } void strupper(char *s) { while (*s) { size_t skip = skip_multibyte_char( *s ); if( skip != 0 ) s += skip; else { if (islower(*s)) *s = toupper(*s); s++; } } } extern void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); /* This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 */ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) { uchar p14[15], p21[21]; memset(p21,'\0',21); memset(p14,'\0',14); StrnCpy((char *)p14,(char *)passwd,14); strupper((char *)p14); E_P16(p14, p21); SMBOWFencrypt(p21, c8, p24); #ifdef DEBUG_PASSWORD DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); dump_data(100, (char *)p21, 16); dump_data(100, (char *)c8, 8); dump_data(100, (char *)p24, 24); #endif } /* Routines for Windows NT MD4 Hash functions. */ static int _my_wcslen(int16 *str) { int len = 0; while(*str++ != 0) len++; return len; } /* * Convert a string into an NT UNICODE string. * Note that regardless of processor type * this must be in intel (little-endian) * format. */ static int _my_mbstowcs(int16 *dst, uchar *src, int len) { int i; int16 val; for(i = 0; i < len; i++) { val = *src; SSVAL(dst,0,val); dst++; src++; if(val == 0) break; } return i; } /* * Creates the MD4 Hash of the users password in NT UNICODE. */ void E_md4hash(uchar *passwd, uchar *p16) { int len; int16 wpwd[129]; /* Password cannot be longer than 128 characters */ len = strlen((char *)passwd); if(len > 128) len = 128; /* Password must be converted to NT unicode */ _my_mbstowcs(wpwd, passwd, len); wpwd[len] = 0; /* Ensure string is null terminated */ /* Calculate length in bytes */ len = _my_wcslen(wpwd) * sizeof(int16); mdfour(p16, (unsigned char *)wpwd, len); } /* Does both the NT and LM owfs of a user's password */ void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) { char passwd[130]; memset(passwd,'\0',130); safe_strcpy( passwd, pwd, sizeof(passwd)-1); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); E_md4hash((uchar *)passwd, nt_p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); dump_data(120, passwd, strlen(passwd)); dump_data(100, (char *)nt_p16, 16); #endif /* Mangle the passwords into Lanman format */ passwd[14] = '\0'; strupper(passwd); /* Calculate the SMB (lanman) hash functions of the password */ memset(p16, '\0', 16); E_P16((uchar *) passwd, (uchar *)p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); dump_data(120, passwd, strlen(passwd)); dump_data(100, (char *)p16, 16); #endif /* clear out local copy of user's password (just being paranoid). */ memset(passwd, '\0', sizeof(passwd)); } /* Does the des encryption from the NT or LM MD4 hash. */ void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) { uchar p21[21]; memset(p21,'\0',21); memcpy(p21, passwd, 16); E_P24(p21, c8, p24); } /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) { uchar p21[21]; memset(p21,'\0',21); memcpy(p21, passwd, 8); memset(p21 + 8, 0xbd, 8); E_P24(p21, ntlmchalresp, p24); #ifdef DEBUG_PASSWORD DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n")); dump_data(100, (char *)p21, 21); dump_data(100, (char *)ntlmchalresp, 8); dump_data(100, (char *)p24, 24); #endif } /* Does the NT MD4 hash then des encryption. */ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) { uchar p21[21]; memset(p21,'\0',21); E_md4hash(passwd, p21); SMBOWFencrypt(p21, c8, p24); #ifdef DEBUG_PASSWORD DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); dump_data(100, (char *)p21, 16); dump_data(100, (char *)c8, 8); dump_data(100, (char *)p24, 24); #endif } /* libtnlm copyrigth was left here, anyway the interface was slightly modified */ /* included libntlm-3.2.9 (c) even if this code is based in 2.1 version*/ /* Libntlm AUTHORS -- information about the authors Copyright (C) 2002, 2003, 2004 Simon Josefsson See the end for copying conditions. Grant Edwards Original author of libntlm Andrew Tridgell Wrote functions borrowed from SMB. Simon Josefsson Build environment, maintainer. Frediano Ziglio Contributed LGPL versions of some of the GPL'd Samba files. */ /* The [IS]VAL macros are to take care of byte order for non-Intel * Machines -- I think this file is OK, but it hasn't been tested. * The other files (the ones stolen from Samba) should be OK. * I am not crazy about these macros -- they seem to have gotten * a bit complex. A new scheme for handling string/buffer fields * in the structures probably needs to be designed */ #define AddBytes(ptr, header, buf, count) \ { \ if (buf && count) \ { \ SSVAL(&ptr->header.len,0,count); \ SSVAL(&ptr->header.maxlen,0,count); \ SIVAL(&ptr->header.offset,0,((ptr->buffer - ((uint8*)ptr)) + ptr->bufIndex)); \ memcpy(ptr->buffer+ptr->bufIndex, buf, count); \ ptr->bufIndex += count; \ } \ else \ { \ ptr->header.len = \ ptr->header.maxlen = 0; \ SIVAL(&ptr->header.offset,0,ptr->bufIndex); \ } \ } #define AddString(ptr, header, string) \ { \ char *p = string; \ int len = 0; \ if (p) len = strlen(p); \ AddBytes(ptr, header, ((unsigned char*)p), len); \ } #define AddUnicodeString(ptr, header, string) \ { \ char *p = string; \ unsigned char *b = NULL; \ int len = 0; \ if (p) \ { \ len = strlen(p); \ b = strToUnicode(p); \ } \ AddBytes(ptr, header, b, len*2); \ } #define GetUnicodeString(structPtr, header) \ unicodeToString(((char*)structPtr) + IVAL(&structPtr->header.offset,0) , SVAL(&structPtr->header.len,0)/2) #define GetString(structPtr, header) \ toString((((char *)structPtr) + IVAL(&structPtr->header.offset,0)), SVAL(&structPtr->header.len,0)) #define DumpBuffer(fp, structPtr, header) \ dumpRaw(fp,((unsigned char*)structPtr)+IVAL(&structPtr->header.offset,0),SVAL(&structPtr->header.len,0)) static void dumpRaw(FILE *fp, unsigned char *buf, size_t len) { int i; for (i=0; i<(signed int)len; ++i) fprintf(fp,"%02x ",buf[i]); fprintf(fp,"\n"); } static char *unicodeToString(char *p, size_t len) { int i; static char buf[1024]; assert(len+1 < sizeof buf); for (i=0; i<(signed int)len; ++i) { buf[i] = *p & 0x7f; p += 2; } buf[i] = '\0'; return buf; } static unsigned char *strToUnicode(char *p) { static unsigned char buf[1024]; size_t l = strlen(p); int i = 0; assert(l*2 < sizeof buf); while (l--) { buf[i++] = *p++; buf[i++] = 0; } return buf; } static unsigned char *toString(char *p, size_t len) { static unsigned char buf[1024]; assert(len+1 < sizeof buf); memcpy(buf,p,len); buf[len] = 0; return buf; } /* Generate a Type-1 NTLM message */ void buildAuthRequest(tSmbNtlmAuthRequest *request, long flags, char *host, char *domain) { char *h = NULL; char *p = NULL; if (host == NULL) host = ""; if (domain == NULL) domain = ""; h = strdup(host); p = strchr(h,'@'); if (p) { if (!domain) domain = p+1; *p = '\0'; } if (flags ==0) flags = 0x0000b207; /* Lowest security options to avoid negotiation */ request->bufIndex = 0; memcpy(request->ident,"NTLMSSP\0\0\0",8); SIVAL(&request->msgType,0,1); SIVAL(&request->flags,0,flags); assert(strlen(host) < 128); AddString(request,host,h); assert(strlen(domain) < 128); AddString(request,domain,domain); free(h); } /* Process Type-2 message and generate Type-3 NTLM response*/ void buildAuthResponse(tSmbNtlmAuthChallenge *challenge, tSmbNtlmAuthResponse *response, long flags, char *user, char *password, char *domainname, char *host) { uint8 lmRespData[24]; uint8 ntRespData[24]; char *u = strdup(user); char *p = strchr(u,'@'); char *w = NULL; char *d = strdup(GetUnicodeString(challenge,uDomain)); char *domain = d; if (domainname != NULL) domain = domainname; if (host == NULL) host = ""; w = strdup(host); if (p) { domain = p+1; *p = '\0'; } SMBencrypt((unsigned char*)password, challenge->challengeData, lmRespData); SMBNTencrypt((unsigned char*)password, challenge->challengeData, ntRespData); response->bufIndex = 0; memcpy(response->ident,"NTLMSSP\0\0\0",8); SIVAL(&response->msgType,0,3); AddBytes(response,lmResponse,lmRespData,24); AddBytes(response,ntResponse,ntRespData,24); assert(strlen(domain) < 128); AddUnicodeString(response,uDomain,domain); assert(strlen(u) < 128); AddUnicodeString(response,uUser,u); assert(strlen(w) < 128); AddUnicodeString(response,uWks,w); AddString(response,sessionKey,NULL); if (flags != 0) challenge->flags = flags; /* Overide flags! */ response->flags = challenge->flags; if(d) free(d); if(u) free(u); } /* Debugging functions */ void dumpAuthRequest(tSmbNtlmAuthRequest *request) { fprintf(stderr, "NTLM Request:\n"); fprintf(stderr, " Ident = %s\n", request->ident); fprintf(stderr, " mType = %d\n", IVAL(&request->msgType,0)); fprintf(stderr, " Flags = %08x\n", IVAL(&request->flags,0)); fprintf(stderr, " Host = %s\n", GetString(request,host)); fprintf(stderr, " Domain = %s\n", GetString(request,domain)); } void dumpAuthChallenge(tSmbNtlmAuthChallenge *challenge) { fprintf(stderr, "NTLM Challenge:\n"); fprintf(stderr, " Ident = %s\n", challenge->ident); fprintf(stderr, " mType = %d\n", IVAL(&challenge->msgType,0)); fprintf(stderr, " Domain = %s\n", GetUnicodeString(challenge,uDomain)); fprintf(stderr, " Flags = %08x\n", IVAL(&challenge->flags,0)); fprintf(stderr, " Challenge = "); dumpRaw(stderr, challenge->challengeData,8); fprintf(stderr, " Uncomplete!! parse optional parameters\n"); } void dumpAuthResponse(tSmbNtlmAuthResponse *response) { fprintf(stderr, "NTLM Response:\n"); fprintf(stderr, " Ident = %s\n", response->ident); fprintf(stderr, " mType = %d\n", IVAL(&response->msgType,0)); fprintf(stderr, " LmResp = "); DumpBuffer(stderr, response,lmResponse); fprintf(stderr, " NTResp = "); DumpBuffer(stderr, response,ntResponse); fprintf(stderr, " Domain = %s\n", GetUnicodeString(response,uDomain)); fprintf(stderr, " User = %s\n", GetUnicodeString(response,uUser)); fprintf(stderr, " Wks = %s\n", GetUnicodeString(response,uWks)); fprintf(stderr, " sKey = "); DumpBuffer(stderr, response,sessionKey); fprintf(stderr, " Flags = %08x\n", IVAL(&response->flags,0)); } medusa-2.1.1/src/modsrc/sha1.c0000644000175000001440000002403511741166633013000 00000000000000/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* Original Source from: http://www.faqs.org/rfcs/rfc3174.html DESCRIPTION This file implements the Secure Hashing Algorithm 1 as defined in FIPS PUB 180-1 published April 17, 1995. The SHA-1, produces a 160-bit message digest for a given data stream. It should take about 2**n steps to find a message with the same digest as a given message and 2**(n/2) to find any two messages with the same digest, when n is the digest size in bits. Therefore, this algorithm can serve as a means of providing a "fingerprint" for a message. PORTABILITY ISSUES SHA-1 is defined in terms of 32-bit "words". This code uses (included via "sha1.h" to define 32 and 8 bit unsigned integer types. If your C compiler does not support 32 bit unsigned integers, this code is not appropriate. CAVEATS SHA-1 is designed to work with messages less than 2^64 bits long. Although SHA-1 allows a message digest to be generated for messages of any number of bits less than 2^64, this implementation only works with messages with a length that is a multiple of the size of an 8-bit character. CHANGES 2002 by Peter Zaitsev to - fit to new prototypes according to MySQL standard - Some optimizations - All checking is now done in debug only mode - More comments */ typedef unsigned char uint8; typedef unsigned char uchar; typedef unsigned long long int ulonglong; typedef unsigned int uint32; typedef short int16; typedef signed char int8; #include "sha1.h" /* Define the SHA1 circular left shift macro */ #define SHA1CircularShift(bits,word) \ (((word) << (bits)) | ((word) >> (32-(bits)))) /* Local Function Prototyptes */ static void SHA1PadMessage(SHA1_CONTEXT*); static void SHA1ProcessMessageBlock(SHA1_CONTEXT*); /* Initialize SHA1Context SYNOPSIS sha1_reset() context [in/out] The context to reset. DESCRIPTION This function will initialize the SHA1Context in preparation for computing a new SHA1 message digest. RETURN SHA_SUCCESS ok != SHA_SUCCESS sha Error Code. */ const uint32 sha_const_key[5]= { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; int sha1_reset(SHA1_CONTEXT *context) { #ifndef DBUG_OFF if (!context) return SHA_NULL; #endif context->Length = 0; context->Message_Block_Index = 0; context->Intermediate_Hash[0] = sha_const_key[0]; context->Intermediate_Hash[1] = sha_const_key[1]; context->Intermediate_Hash[2] = sha_const_key[2]; context->Intermediate_Hash[3] = sha_const_key[3]; context->Intermediate_Hash[4] = sha_const_key[4]; context->Computed = 0; context->Corrupted = 0; return SHA_SUCCESS; } /* Return the 160-bit message digest into the array provided by the caller SYNOPSIS sha1_result() context [in/out] The context to use to calculate the SHA-1 hash. Message_Digest: [out] Where the digest is returned. DESCRIPTION NOTE: The first octet of hash is stored in the 0th element, the last octet of hash in the 19th element. RETURN SHA_SUCCESS ok != SHA_SUCCESS sha Error Code. */ int sha1_result(SHA1_CONTEXT *context, uint8 Message_Digest[SHA1_HASH_SIZE]) { int i; #ifndef DBUG_OFF if (!context || !Message_Digest) return SHA_NULL; if (context->Corrupted) return context->Corrupted; #endif if (!context->Computed) { SHA1PadMessage(context); /* message may be sensitive, clear it out */ bzero((char*) context->Message_Block,64); context->Length = 0; /* and clear length */ context->Computed = 1; } for (i = 0; i < SHA1_HASH_SIZE; i++) Message_Digest[i] = (int8)((context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ))); return SHA_SUCCESS; } /* Accepts an array of octets as the next portion of the message. SYNOPSIS sha1_input() context [in/out] The SHA context to update message_array An array of characters representing the next portion of the message. length The length of the message in message_array RETURN SHA_SUCCESS ok != SHA_SUCCESS sha Error Code. */ int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array, unsigned length) { if (!length) return SHA_SUCCESS; #ifndef DBUG_OFF /* We assume client konows what it is doing in non-debug mode */ if (!context || !message_array) return SHA_NULL; if (context->Computed) return (context->Corrupted= SHA_STATE_ERROR); if (context->Corrupted) return context->Corrupted; #endif while (length--) { context->Message_Block[context->Message_Block_Index++]= (*message_array & 0xFF); context->Length += 8; /* Length is in bits */ #ifndef DBUG_OFF /* Then we're not debugging we assume we never will get message longer 2^64 bits. */ if (context->Length == 0) return (context->Corrupted= 1); /* Message is too long */ #endif if (context->Message_Block_Index == 64) { SHA1ProcessMessageBlock(context); } message_array++; } return SHA_SUCCESS; } /* Process the next 512 bits of the message stored in the Message_Block array. SYNOPSIS SHA1ProcessMessageBlock() DESCRIPTION Many of the variable names in this code, especially the single character names, were used because those were the names used in the publication. */ /* Constants defined in SHA-1 */ static const uint32 K[]= { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 }; static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context) { int t; /* Loop counter */ uint32 temp; /* Temporary word value */ uint32 W[80]; /* Word sequence */ uint32 A, B, C, D, E; /* Word buffers */ int index; /* Initialize the first 16 words in the array W */ for (t = 0; t < 16; t++) { index=t*4; W[t] = context->Message_Block[index] << 24; W[t] |= context->Message_Block[index + 1] << 16; W[t] |= context->Message_Block[index + 2] << 8; W[t] |= context->Message_Block[index + 3]; } for (t = 16; t < 80; t++) { W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); } A = context->Intermediate_Hash[0]; B = context->Intermediate_Hash[1]; C = context->Intermediate_Hash[2]; D = context->Intermediate_Hash[3]; E = context->Intermediate_Hash[4]; for (t = 0; t < 20; t++) { temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } for (t = 20; t < 40; t++) { temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } for (t = 40; t < 60; t++) { temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]); E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } for (t = 60; t < 80; t++) { temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } context->Intermediate_Hash[0] += A; context->Intermediate_Hash[1] += B; context->Intermediate_Hash[2] += C; context->Intermediate_Hash[3] += D; context->Intermediate_Hash[4] += E; context->Message_Block_Index = 0; } /* Pad message SYNOPSIS SHA1PadMessage() context: [in/out] The context to pad DESCRIPTION According to the standard, the message must be padded to an even 512 bits. The first padding bit must be a '1'. The last 64 bits represent the length of the original message. All bits in between should be 0. This function will pad the message according to those rules by filling the Message_Block array accordingly. It will also call the ProcessMessageBlock function provided appropriately. When it returns, it can be assumed that the message digest has been computed. */ static void SHA1PadMessage(SHA1_CONTEXT *context) { /* Check to see if the current message block is too small to hold the initial padding bits and length. If so, we will pad the block, process it, and then continue padding into a second block. */ int i=context->Message_Block_Index; if (i > 55) { context->Message_Block[i++] = 0x80; bzero((char*) &context->Message_Block[i], sizeof(context->Message_Block[0])*(64-i)); context->Message_Block_Index=64; /* This function sets context->Message_Block_Index to zero */ SHA1ProcessMessageBlock(context); bzero((char*) &context->Message_Block[0], sizeof(context->Message_Block[0])*56); context->Message_Block_Index=56; } else { context->Message_Block[i++] = 0x80; bzero((char*) &context->Message_Block[i], sizeof(context->Message_Block[0])*(56-i)); context->Message_Block_Index=56; } /* Store the message length as the last 8 octets */ context->Message_Block[56] = (int8) (context->Length >> 56); context->Message_Block[57] = (int8) (context->Length >> 48); context->Message_Block[58] = (int8) (context->Length >> 40); context->Message_Block[59] = (int8) (context->Length >> 32); context->Message_Block[60] = (int8) (context->Length >> 24); context->Message_Block[61] = (int8) (context->Length >> 16); context->Message_Block[62] = (int8) (context->Length >> 8); context->Message_Block[63] = (int8) (context->Length); SHA1ProcessMessageBlock(context); } medusa-2.1.1/src/modsrc/vnc.c0000644000175000001440000011036511757213661012735 00000000000000/* ** VNC Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2011 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ** VNCrack [FX/Phenolite] ** RealVNC (VNC Server 4 -- FREE) ** UltraVNC 1.0.9.6.1 ** ** Supports: password-less VNC, password-only VNC and UltraVNC MS-Logon */ #include #include #include #include #include #include "module.h" #include "d3des.h" #define MODULE_NAME "vnc.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for VNC sessions" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: vnc.c 1725 2012-05-23 17:00:33Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define OPENSSL_WARNING "No usable OPENSSL. Module disabled." #ifdef HAVE_LIBSSL #include #define PORT_VNC 5900 #define CHALLENGE_SIZE 16 #define SESSION_SUCCESS 1 #define SESSION_FAILURE 2 #define SESSION_SUCCESS_NO_AUTH 3 #define SESSION_MAX_AUTH_REALVNC 4 #define SESSION_MAX_AUTH_ULTRAVNC 5 #define AUTH_VNC 1 #define AUTH_UVNC_MSLOGIN 2 typedef struct __VNC_DATA { int nMaxAuthSleep; int nAuthType; char* szChallenge; char* szDomain; } _VNC_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _VNC_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _VNC_DATA *_psSessionData); int vncSessionSetup(int hSocket, _VNC_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " MAXSLEEP:?"); writeVerbose(VB_NONE, " Sets the maximum allowed sleep time when the VNC RealVNC anti-brute force delay"); writeVerbose(VB_NONE, " is encountered. This value is in seconds and, if left unset, defaults to 60."); writeVerbose(VB_NONE, " DOMAIN:?"); writeVerbose(VB_NONE, " Sets the domain value when authenticating against UltraVNC's MS-Logon feature."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Some versions of VNC have built-in anti-brute force functionality. RealVNC, for example,"); writeVerbose(VB_NONE, "allows 5 failed attempts and then enforces a 10 second delay. For each subsequent"); writeVerbose(VB_NONE, "attempt that delay is doubled. UltraVNC appears to allow 6 invalid attempts and then forces"); writeVerbose(VB_NONE, "a 10 second delay between each following attempt. This module attempts to identify these"); writeVerbose(VB_NONE, "situations and react appropriately by invoking sleep(). The user can set a sleep limit when"); writeVerbose(VB_NONE, "brute forcing RealVNC using the MAXSLEEP parameter. Once this value has been reached, the"); writeVerbose(VB_NONE, "module will exit."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "It should be noted that this module currently supports password-less and password-only VNC"); writeVerbose(VB_NONE, "servers. In addition, it supports UltraVNC's MS-Logon feature that can be used to provide"); writeVerbose(VB_NONE, "pass-through authentication against local and domain Windows accounts. In the case of basic"); writeVerbose(VB_NONE, "password-only VNC, provide any arbitrary username value."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M vnc -m MAXSLEEP:120 -m DOMAIN:FOOFUSDOM\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _VNC_DATA *psSessionData; psSessionData = malloc(sizeof(_VNC_DATA)); memset(psSessionData, 0, sizeof(_VNC_DATA)); psSessionData->nMaxAuthSleep = 60; if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inMaxAuthSleep = atoi(pOpt); else writeError(ERR_WARNING, "Method MAXSLEEP requires value to be set."); } else if (strcmp(pOpt, "DOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDomain = malloc(strlen(pOpt) + 1); memset(psSessionData->szDomain, 0, strlen(pOpt) + 1); strncpy((char *) psSessionData->szDomain, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _VNC_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; int iRet; unsigned char zChallenge[16]; sConnectParams params; int nAngrySleep = 10; int bAuthAllowed = FALSE; sCredentialSet *psCredSet = NULL; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_VNC; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: while (!bAuthAllowed) { if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); iRet = vncSessionSetup(hSocket, _psSessionData); switch( iRet ) { case SESSION_SUCCESS: writeError(ERR_DEBUG_MODULE, "VNC Session Initialized."); bAuthAllowed = TRUE; nState = MSTATE_RUNNING; break; case SESSION_SUCCESS_NO_AUTH: writeError(ERR_DEBUG_MODULE, "VNC Server Does Not Require Authentication."); psLogin->iResult = LOGIN_RESULT_SUCCESS; setPassResult(psLogin, "[NO AUTH REQUIRED]"); bAuthAllowed = TRUE; nState = MSTATE_EXITING; break; case SESSION_MAX_AUTH_REALVNC: writeError(ERR_ALERT, "[%s] Host %s reported too many security failures. Sleeping %d seconds before next attempt.", MODULE_NAME, psLogin->psServer->pHostIP, nAngrySleep); if (nAngrySleep > _psSessionData->nMaxAuthSleep) { writeError(ERR_ERROR, "[%s] Host %s exceeded maximum allowed sleep. Terminating connection.", MODULE_NAME, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; bAuthAllowed = TRUE; nState = MSTATE_EXITING; } else { sleep(nAngrySleep + 1); nAngrySleep = 2 * nAngrySleep; } break; case SESSION_MAX_AUTH_ULTRAVNC: writeError(ERR_ALERT, "[%s] Host %s has rejected the connection. Sleeping 10 seconds before next attempt.", MODULE_NAME, psLogin->psServer->pHostIP); if (nAngrySleep > _psSessionData->nMaxAuthSleep) { writeError(ERR_ERROR, "[%s] Host %s exceeded maximum allowed sleep. Terminating connection.", MODULE_NAME, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; bAuthAllowed = TRUE; nState = MSTATE_EXITING; } else { sleep(10 + 1); nAngrySleep = nAngrySleep + 10; } break; default: writeError(ERR_DEBUG_MODULE, "VNC Session Setup Failed."); psLogin->iResult = LOGIN_RESULT_UNKNOWN; bAuthAllowed = TRUE; nState = MSTATE_EXITING; break; } } bAuthAllowed = FALSE; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* VNC Specific Functions */ /* ** Encrypt CHALLENGE_SIZE bytes in memory using a password. ** Ripped from vncauth.c */ void vncEncryptBytes(unsigned char *bytes, char *passwd) { unsigned char key[8]; int i; /* key is simply password padded with nulls */ for (i = 0; i < 8; i++) { if (i < strlen(passwd)) { key[i] = passwd[i]; } else { key[i] = 0; } } deskey(key, EN0); for (i = 0; i < CHALLENGE_SIZE; i += 8) { des(bytes + i, bytes + i); } } void vncEncryptPasswdMs( unsigned char *encryptedPasswd, char *passwd ) { unsigned char key[8]; unsigned int i; /* pad password with nulls */ for (i = 0; i < 32; i++) { if (i < strlen(passwd)) { encryptedPasswd[i] = passwd[i]; } else { encryptedPasswd[i] = 0; } } /* Do encryption in-place - this way we overwrite our copy of the plaintext password */ deskey(key, EN0); des(encryptedPasswd, encryptedPasswd); } /* [UltraVNC/rfb/dh.cpp] */ uint64_t bytesToInt64(const char* const bytes) { uint64_t result = 0; int i; for (i = 0; i < 8; i++) { result <<= 8; result += (unsigned char) bytes[i]; } return result; } int int64ToBytes(const uint64_t integer, char* const bytes) { int i; for (i = 0; i < 8; i++) { bytes[i] = (unsigned char) (integer >> (8 * (7 - i))); } return SUCCESS; } /* [UltraVNC/vncviewer/vncauth.c] */ void vncEncryptBytes2(unsigned char *where, const int length, unsigned char *key) { int i, j; deskey(key, EN0); for (i = 0; i< 8; i++) where[i] ^= key[i]; des(where, where); for (i = 8; i < length; i += 8) { for (j = 0; j < 8; j++) where[i + j] ^= where[i + j - 8]; des(where + i, where + i); } } int vncSessionSetup(int hSocket, _VNC_DATA* _psSessionData) { char ProtocolVersion[13]; int iServerProtocolVersion; char* bufReceive; int nReceiveBufferSize = 0; int i = 0; int nSecurityTypes = 0; unsigned char* szSecurityTypes = NULL; memset(ProtocolVersion, 0, 13); /* --- VNC Protocol Handshake --- */ /* Retreive server VNC protocol version */ nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return SESSION_FAILURE; writeError(ERR_DEBUG_MODULE, "VNC Server Protocol Version: %s", bufReceive); /* The following message is triggered by 5 failed authentication attempts, at which ** point a 10 second lockout is applied before the next attempt is permitted. Each ** subsequent failed attempt causes the timeout to be doubled. ** ** RealVNC: Too many security failures ** WinVNC (<=3.3.3r2): Too many authentication failures */ if ((strncmp(bufReceive + 20, "Too many security failures", 26) == 0) || (strncmp(bufReceive + 20, "Too many authentication failures", 32) == 0)) { writeError(ERR_DEBUG_MODULE, "[%s] Host reported too many security failures.", MODULE_NAME); return SESSION_MAX_AUTH_REALVNC; } /* 3.3, 3.7 and 3.8 are the only published protocol versions (RFB Protocol v3.8 11/26/2010) */ else if (strncmp(bufReceive, "RFB 003.003", 11) == 0) { memcpy(ProtocolVersion, "RFB 003.003\n", 12); iServerProtocolVersion = 3; } else if (strncmp(bufReceive, "RFB 003.007", 11) == 0) { memcpy(ProtocolVersion, "RFB 003.007\n", 12); iServerProtocolVersion = 7; } else if (strncmp(bufReceive, "RFB 003.008", 11) == 0) { memcpy(ProtocolVersion, "RFB 003.008\n", 12); iServerProtocolVersion = 8; } /* RealVNC - VNC Server Enterprise Edition E4.6.3 (r66752) */ else if (strncmp(bufReceive, "RFB 004.001", 11) == 0) { memcpy(ProtocolVersion, "RFB 004.001\n", 12); iServerProtocolVersion = 8; } else { writeError(ERR_DEBUG_MODULE, "[%s] Unknown session setup response: %s. Setting client response to version 3.3.", MODULE_NAME, bufReceive); memcpy(ProtocolVersion, "RFB 003.003\n", 12); iServerProtocolVersion = 3; } /* Send client VNC protocol version */ writeError(ERR_DEBUG_MODULE, "VNC Client Protocol Version: %s", ProtocolVersion); if (medusaSend(hSocket, ProtocolVersion, 12, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } /* Some VNC servers seem to get upset if we go too fast. Sleeping 1/2 second seems to help. */ usleep(0.5 * 1000000); /* --- VNC Security Type Handshake --- */ /* Retreive VNC protocol authentication scheme response */ nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if ((bufReceive == NULL) || (nReceiveBufferSize == 0)) { writeError(ERR_ERROR, "No security type response received from server."); return SESSION_FAILURE; } /* RFB Protocol 3.3 - Security Type ** ** Server: U32 [security type] ** ** if the security types is 0, response is followed by: ** Server: U32 [reason-length] ** U8 array [reason for connection failure] */ else if (iServerProtocolVersion == 3) { writeErrorBin(ERR_DEBUG_MODULE, "Supported Security Types (version 3.3): ", bufReceive, nReceiveBufferSize); switch (bufReceive[3]) { case 0x00: /* connection failure */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Failed."); if (nReceiveBufferSize > 16) writeError(ERR_DEBUG_MODULE, "VNC Session Setup Failure Message: %s", bufReceive + 8); /* Server is probably in anti-brute force mode (UltraVNC) */ if ((nReceiveBufferSize == 42) && (strncmp(bufReceive + 8, "Your connection has been rejected.", 34) == 0)) return SESSION_MAX_AUTH_ULTRAVNC; else return SESSION_FAILURE; break; case 0x01: /* no authentication required */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Successful - No Authentication Required."); return SESSION_SUCCESS_NO_AUTH; break; case 0x02: /* authentication required -- set authentication challenge */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Successful."); if (nReceiveBufferSize == 20) { _psSessionData->szChallenge = malloc(17); memset(_psSessionData->szChallenge, 0, 17); memcpy(_psSessionData->szChallenge, bufReceive + 4, 16); writeError(ERR_DEBUG_MODULE, "VNC authentication challenge: %s", _psSessionData->szChallenge); _psSessionData->nAuthType = AUTH_VNC; return SESSION_SUCCESS; } else { writeError(ERR_ERROR, "[%s] Unknown session challenge. Possible unsupported authentication type.", MODULE_NAME); return SESSION_FAILURE; } break; case 0xfffffffa: /* UltaVNC MS-Logon */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC MS-Logon."); if (nReceiveBufferSize == 28) { _psSessionData->szChallenge = malloc(25); memset(_psSessionData->szChallenge, 0, 25); memcpy(_psSessionData->szChallenge, bufReceive + 4, 24); writeErrorBin(ERR_DEBUG_MODULE, "VNC authentication challenge: ", bufReceive + 4, 24); _psSessionData->nAuthType = AUTH_UVNC_MSLOGIN; return SESSION_SUCCESS; } else { writeError(ERR_ERROR, "[%s] Unknown session challenge. Possible unsupported authentication type.", MODULE_NAME); return SESSION_FAILURE; } break; default: /* unknown response */ writeError(ERR_ERROR, "[%s] VNC Session Setup - Unknown Response (3.3): %d", MODULE_NAME, bufReceive[3]); return SESSION_FAILURE; break; } } /* RFB Protocol 3.7, 3.8 - Security Type ** ** Server: U8 [number of security types] ** U8 array [security type] ** ** If the number of security types is 0, response is followed by: ** Server: U32 [reason-length] ** U8 array [reason for connection failure] */ else if ((iServerProtocolVersion == 7) || (iServerProtocolVersion == 8)) { writeErrorBin(ERR_DEBUG_MODULE, "Supported Security Types (> version 3.7): ", bufReceive, nReceiveBufferSize); /* connection failure */ if (bufReceive[0] == 0) { writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Failed."); //memcpy(nReasonLength + sizeof(int), bufReceive + 1, 4); if (nReceiveBufferSize > 8) writeError(ERR_DEBUG_MODULE, "VNC Session Setup Failure Message: %s", bufReceive + 5); /* Server is probably in anti-brute force mode (UltraVNC) */ if (strncmp(bufReceive + 5, "Your connection has been rejected.", 34) == 0) return SESSION_MAX_AUTH_ULTRAVNC; else return SESSION_FAILURE; } /* verify response length */ else if (nReceiveBufferSize == 1 + (int)bufReceive[0]) { nSecurityTypes = (int)bufReceive[0]; szSecurityTypes = malloc(nSecurityTypes + 1); memset(szSecurityTypes, 0, nSecurityTypes + 1); memcpy(szSecurityTypes, bufReceive + 1, nSecurityTypes); for (i = 0; i <= nSecurityTypes; i++) { writeError(ERR_DEBUG_MODULE, "Processing server security type: %d (%d/%d). We will select the first supported type encountered.", szSecurityTypes[i], i + 1, nSecurityTypes); switch (szSecurityTypes[i]) { case 0x01: /* no authentication required */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Password-only VNC - No Authentication Required"); if (medusaSend(hSocket, &szSecurityTypes[i], 1, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; else if (bufReceive[3] == 0) return SESSION_SUCCESS_NO_AUTH; else return FAILURE; break; case 0x02: /* authentication required -- set authentication challenge */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Password-only VNC"); if (medusaSend(hSocket, &szSecurityTypes[i], 1, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (nReceiveBufferSize == 16) { _psSessionData->szChallenge = malloc(17); memset(_psSessionData->szChallenge, 0, 17); memcpy(_psSessionData->szChallenge, bufReceive, 16); writeError(ERR_DEBUG_MODULE, "VNC authentication challenge: %s", _psSessionData->szChallenge); _psSessionData->nAuthType = AUTH_VNC; return SESSION_SUCCESS; } else { writeError(ERR_ERROR, "[%s] Unknown session challenge. Possible unsupported authentication type.", MODULE_NAME); return SESSION_FAILURE; } break; case 0x05: /* 5: RealVNC RA2 */ case 0x06: /* 6: RealVNC RA2ne */ case 0x81: /* 129: UNIX Logon Authentication */ case 0x82: /* 130: External Authentication */ writeError(ERR_ERROR, "VNC Session Setup - RealVNC (Type %d). RealVNC native authentication mode is NOT currently supported.", szSecurityTypes[i]); break; case 0x11: /* 17: UltraVNC */ /* http://www.uvnc.com/features/authentication.html */ /* [rfb/rfbproto.h] rfbUltraVNC 0x17 - after rfbUltraVNC, auth repeats via rfbVncAuthContinue rfbUltraVNC_SCPrompt 0x68 rfbUltraVNC_SessionSelect 0x69 rfbUltraVNC_MsLogonIAuth 0x70 rfbUltraVNC_MsLogonIIAuth 0x71 rfbUltraVNC_SecureVNCPluginAuth 0x72 */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC"); /* 0x11 UltraVNC contains multiple sub-types. If we respond with 0x11, the server should send us a list. For example, 0xffffffff 0x0171 (UltraVNC MS-Logon II). This appears to be sent sometimes as a single packet, sometimes as two. It seems that any sub-types we would enumerate here, however, were also listed in the initial supported security type response. As such, let's just skip this type and move on to the next in the list. If this assumption turns out to be incorrect, we should continue the security type negotiation here. */ break; case 0x70: /* 17: UltraVNC MS-Logon I */ case 0x71: /* 17: UltraVNC MS-Logon II */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC (Type %d)", szSecurityTypes[i]); if (medusaSend(hSocket, &szSecurityTypes[i], 1, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (nReceiveBufferSize == 24) { writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC MS-Logon II - Process authentication challenge"); _psSessionData->szChallenge = malloc(25); memset(_psSessionData->szChallenge, 0, 25); memcpy(_psSessionData->szChallenge, bufReceive, 24); writeErrorBin(ERR_DEBUG_MODULE, "VNC authentication challenge: ", _psSessionData->szChallenge, 24); _psSessionData->nAuthType = AUTH_UVNC_MSLOGIN; return SESSION_SUCCESS; } break; default: /* unknown response - skip and see if we find a supported type */ writeError(ERR_ERROR, "[%s] VNC Session Setup - Unknown Response (3.7/3.8): %d", MODULE_NAME, szSecurityTypes[i]); break; } } } else { writeError(ERR_ERROR, "[%s] VNC Session Setup - Unknown Response", MODULE_NAME); return SESSION_FAILURE; } } FREE(szSecurityTypes); return SESSION_FAILURE; } int sendAuthVNC(int hSocket, _VNC_DATA* _psSessionData, char* szPassword) { writeError(ERR_DEBUG_MODULE, "[%s] VNC authentication challenge: %s", MODULE_NAME, _psSessionData->szChallenge); vncEncryptBytes(_psSessionData->szChallenge, szPassword); writeError(ERR_DEBUG_MODULE, "[%s] VNC authentication response: %s", MODULE_NAME, _psSessionData->szChallenge); if (medusaSend(hSocket, _psSessionData->szChallenge, 16, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } return SUCCESS; } /* Based on ClientConnection::AuthMsLogonII() [UltraVNC/vncviewer/ClientConnection.cpp] MS Logon authentication supports "domain\user", "user" and "user@domain" logins */ int sendAuthMSLogin(int hSocket, _VNC_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char ms_user[256], ms_passwd[64]; unsigned char key[8]; int i = 0; int client_priv = 31337; /* arbitrary value -- client would typically randomly generate */ uint64_t g, p, resp, pub; char client_pub[8]; BIGNUM* server_pub; DH *dh_struct; int dh_error; unsigned char *dh_secret; char *bufSend = NULL; writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - UltraVNC Microsoft Logon", MODULE_NAME); /* parse server challenge -- g, p (mod) and server public key */ g = bytesToInt64(_psSessionData->szChallenge); p = bytesToInt64(_psSessionData->szChallenge + 8); resp = bytesToInt64(_psSessionData->szChallenge + 16); writeError(ERR_DEBUG_MODULE, "[%s] Server DH values: g: %d p/mod: %d public key: %d", MODULE_NAME, g, p, resp); /* create and populate DH structure */ dh_struct = DH_new(); dh_struct->g = BN_new(); BN_set_word(dh_struct->g, g); dh_struct->p = BN_new(); BN_set_word(dh_struct->p, p); dh_struct->priv_key = BN_new(); BN_set_word(dh_struct->priv_key, client_priv); if (DH_generate_key(dh_struct) == 0) writeError(ERR_ERROR, "[%s] Failed to generate key", MODULE_NAME); writeError(ERR_DEBUG_MODULE, "[%s] Client DH private key: %s public key: %s", MODULE_NAME, BN_bn2hex(dh_struct->priv_key), BN_bn2hex(dh_struct->pub_key)); DH_check(dh_struct, &dh_error); if (dh_error & DH_CHECK_P_NOT_SAFE_PRIME) writeError(ERR_DEBUG_MODULE, "[%s] Failed to create DH structure: DH_CHECK_P_NOT_SAFE_PRIME", MODULE_NAME); if (dh_error & DH_NOT_SUITABLE_GENERATOR) writeError(ERR_DEBUG_MODULE, "[%s] Failed to create DH structure: DH_NOT_SUITABLE_GENERATOR", MODULE_NAME); if (dh_error & DH_UNABLE_TO_CHECK_GENERATOR) writeError(ERR_DEBUG_MODULE, "[%s] Failed to create DH structure: DH_UNABLE_TO_CHECK_GENERATOR", MODULE_NAME); /* convert client public key into proper format for sending */ int64ToBytes(BN_get_word(dh_struct->pub_key), client_pub); /* generate shared secret using private DH key and server's public key */ server_pub = BN_new(); BN_set_word(server_pub, resp); dh_secret = malloc( DH_size(dh_struct) ); DH_compute_key(dh_secret, server_pub, dh_struct); /* OpenSSLs DH implementation is compliant with the SSL/TLS requirements that skip leading zeroes on the output. We need our key to be exactly 8 bytes long, so let's prepend it with the necessary number of zeros. */ memset(key, 0, 8); if (DH_size(dh_struct) < 8) for (i=0; i < DH_size(dh_struct); i++) key[8 - DH_size(dh_struct) + i] = dh_secret[i]; DH_free(dh_struct); writeErrorBin(ERR_DEBUG_MODULE, "Shared secret key: ", key, 8); memset(ms_user, 0, 256); memset(ms_passwd, 0, 64); if ((_psSessionData->szDomain) && (strlen(_psSessionData->szDomain) + 1 + strlen(szLogin) < 256)) { strncpy(ms_user, _psSessionData->szDomain, strlen(_psSessionData->szDomain)); strncat(ms_user, "\\", 1); strncat(ms_user, szLogin, strlen(szLogin)); } else strncpy(ms_user, szLogin, 256); strncpy(ms_passwd, szPassword, 64); writeError(ERR_DEBUG_MODULE, "Username: %s Password: %s", ms_user, ms_passwd); writeErrorBin(ERR_DEBUG_MODULE, "Username: ", ms_user, 256); writeErrorBin(ERR_DEBUG_MODULE, "Password: ", ms_passwd, 64); vncEncryptBytes2((unsigned char*) &ms_user, sizeof(ms_user), key); vncEncryptBytes2((unsigned char*) &ms_passwd, sizeof(ms_passwd), key); writeErrorBin(ERR_DEBUG_MODULE, "Encrypted username: ", ms_user, 256); writeErrorBin(ERR_DEBUG_MODULE, "Encrypted password: ", ms_passwd, 64); /* send client public key, encrypted username, and encrypted password */ bufSend = malloc(8 + sizeof(ms_user) + sizeof(ms_passwd) + 1); memset(bufSend, 0, 8 + sizeof(ms_user) + sizeof(ms_passwd) + 1); /* For extra fun, set client_pub to a value of 0x80000000 or greater. No more server... memset(client_pub, 0x0000000080, 5); */ memcpy(bufSend, client_pub, 8); memcpy(bufSend + 8, ms_user, sizeof(ms_user)); memcpy(bufSend + 8 + sizeof(ms_user), ms_passwd, sizeof(ms_passwd)); if (medusaSend(hSocket, bufSend, 8 + sizeof(ms_user) + sizeof(ms_passwd), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } return SUCCESS; } int sendExit(int hSocket) { char szExit[] = { 0x00, 0x00, 0x00, 0x00, 0x05, 0x1D, 0x03, 0x20 }; writeError(ERR_DEBUG_MODULE, "[%s] Send VNC connection termination command.", MODULE_NAME); if (medusaSend(hSocket, szExit, 8, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _VNC_DATA* _psSessionData, char* szLogin, char* szPassword) { char* bufReceive; int nReceiveBufferSize = 0; int iRet; /* perform authentication */ switch(_psSessionData->nAuthType) { case AUTH_VNC: sendAuthVNC(hSocket, _psSessionData, szPassword); break; case AUTH_UVNC_MSLOGIN: sendAuthMSLogin(hSocket, _psSessionData, szLogin, szPassword); break; default: writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - blah", MODULE_NAME); break; } writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Waiting for authentication result", MODULE_NAME); nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; else if (nReceiveBufferSize == 0) { /* Some VNC servers (e.g. TightVNC 2.0 Beta) simply drop the connection on a bad password */ writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Failed (no response from server)", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else if (nReceiveBufferSize >= 4) { switch (bufReceive[3]) { case 0x00: writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Success", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; // TODO: Is this only for UltraVNC? sendExit(hSocket); break; case 0x01: if ((nReceiveBufferSize > 8) && (strstr(bufReceive + 8, "Connection rejected by user") != NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Success (User rejected connection)", MODULE_NAME); (*psLogin)->pErrorMsg = malloc( 40 + 1 ); memset((*psLogin)->pErrorMsg, 0, 40 + 1 ); sprintf((*psLogin)->pErrorMsg, "User rejected connection request."); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Failed", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } break; default: writeError(ERR_ERROR, "[%s] VNC Authentication - Unknown Response: %d", MODULE_NAME, bufReceive[3]); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; break; } } else { writeError(ERR_ERROR, "[%s] VNC Authentication - Unknown Response", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } setPassResult((*psLogin), szPassword); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif medusa-2.1.1/src/modsrc/pcanywhere.c0000644000175000001440000005145511723732127014314 00000000000000/* ** PcAnywhere Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** pcaEncrypt() based on code from: ** Hydra 5.0 [David Maciejak ] ** ** Based on packet captures from: ** Server Version 10.5.1 ** Client 10.0.2 ** ** PCA Authentication Methods: ** ADS (Active Directory Services) [1] ** FTP [2] ** HTTP [2] ** HTTPS [2] ** Microsoft LDAP [2] ** Netscape LDAP [2] ** Novell LDAP [2] ** NT [1] ** pcAnywhere [1] ** Windows [3] ** ** [1] Verified working ** [2] Untested ** [3] Verified to work when PcAnywhere host authenticates against domain accounts. ** Authentication fails for local accounts with both the module and the PcAnywhere ** client. Not sure what's going on... ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "pcanywhere.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for PcAnywhere sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: pcanywhere.c 1301 2010-02-09 22:54:18Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define PORT_PCA 5631 #define BUF_SIZE 300 typedef struct __PCA_DATA { unsigned char domain[17]; } _PCA_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _PCA_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _PCA_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "NOTE: PcAnywhere allows only one connection at a time. Running multiple threads per target"); writeVerbose(VB_NONE, " may not work well."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " DOMAIN:?"); writeVerbose(VB_NONE, " Option allows manual setting of domain to check against when host uses NT authentication."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M pcanywhere -m DOMAIN:FOODOM\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _PCA_DATA *psSessionData; psSessionData = malloc(sizeof(_PCA_DATA)); memset(psSessionData, 0, sizeof(_PCA_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; idomain, pOpt, 16); memset(psSessionData->domain + strlen(psSessionData->domain) + 1, 0x5C, 1); // '\' } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } FREE(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _PCA_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; int nFirstPass = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_PCA; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); /* When not running in debug mode, we are failing to get the initial prompt from the server on connections after our initial attempt. Using the following sleep seems to fix the issue. Not sure if there is a disconnect command or something that we could send the server to make this a non-issue. */ if (nFirstPass != 0) sleep(1); nFirstPass = 1; if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ /* encrypt/decrypt: Symantec 31337 Crypto */ void pcaEncrypt(char *plaintext, char *ciphertext, int key, int offset) { int i; writeError(ERR_DEBUG_MODULE, "pcaEncrypt [plaintext]: %s", plaintext); if (strlen(plaintext) > 0) { ciphertext[0] = plaintext[0] ^ key; for (i = 1; i < strlen(plaintext); i++) ciphertext[i] = ciphertext[i-1] ^ plaintext[i] ^ (i - offset); } writeError(ERR_DEBUG_MODULE, "pcaEncrypt [ciphertext]: %s", ciphertext); } int pcaUserAuth(int hSocket, char* szDomain, char* szLogin, char* szPassword) { int iRet; unsigned char* szTmp; unsigned char bufSend[MAX_BUF]; int nSendBufferSize = 0; unsigned char bufSend1[] = { 0x6f, 0x62, 0x01, 0x02, 0x00, 0x00, 0x00 }; int nSendBufferSize1 = 7; unsigned char* bufReceive; int nReceiveBufferSize = 0; char clogin[128]=""; char cpass[128]=""; /* retrieve logon prompt */ // SEND: 6f 62 01 02 00 00 00 // RECV: 00 7d 08 // RECV: 00 7c 08 20 0d 0a 45 6e 74 65 72 20 6c 6f 67 69 6e 20 6e 61 6d 65 3a 20 writeError(ERR_DEBUG_MODULE, "%s: Retrieving login prompt.", MODULE_NAME); if (medusaSend(hSocket, bufSend1, nSendBufferSize1, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } /* When not running in debug mode, we are failing to get the login prompt from the server. Using the following sleep seems to fix the issue. This is probably just hiding some bug in the module code... */ sleep(1); nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive + 6, "Enter login name:")) { writeError(ERR_INFO, "%s: Host sent native PcAnywhere authentication prompt.", MODULE_NAME); pcaEncrypt(szLogin, clogin, 0xAB, 1); pcaEncrypt(szPassword, cpass, 0xAB, 1); memset(bufSend, 0, BUF_SIZE); bufSend[0] = 0x06; bufSend[1] = strlen(clogin); strncpy(bufSend + 2, clogin, BUF_SIZE - 3); nSendBufferSize = strlen(clogin) + 2; } else if (strstr(bufReceive + 6, "Enter user name:")) { writeError(ERR_INFO, "%s: Host sent NT authentication prompt.", MODULE_NAME); if (strlen(szDomain) > 0) { // FOODOM\administrator //0000001C 06 . //0000001D 14 ed a2 ec aa e6 af f6 91 f2 97 f7 93 f1 8e f7 ........ ........ //0000002D 8b e5 81 ff 9f ..... szTmp = malloc(strlen(szDomain) + 1 + strlen(szLogin) + 1); memset(szTmp, 0, strlen(szDomain) + 1 + strlen(szLogin) + 1); strncpy(szTmp, szDomain, strlen(szDomain)); memset(szTmp + strlen(szDomain), '\\', 1); strncpy(szTmp + strlen(szDomain) + 1, szLogin, strlen(szLogin)); pcaEncrypt(szTmp, clogin, 0xAB, 1); writeError(ERR_DEBUG_MODULE, "%s: Setting domain\\user value: %s", MODULE_NAME, szTmp); FREE(szTmp); memset(bufSend, 0, BUF_SIZE); bufSend[0] = 0x06; bufSend[1] = strlen(clogin); strncpy(bufSend + 2, clogin, BUF_SIZE - 3); nSendBufferSize = strlen(clogin) + 2; } else { pcaEncrypt(szLogin, clogin, 0xF7, 0); memset(bufSend, 0, BUF_SIZE); bufSend[0] = 0x06; bufSend[1] = strlen(clogin) + 1; bufSend[2] = 0xf7; strncpy(bufSend + 3, clogin, BUF_SIZE - 4); nSendBufferSize = strlen(clogin) + 3; } pcaEncrypt(szPassword, cpass, 0xAB, 1); } else if (bufReceive + 6) { writeError(ERR_ERROR, "%s: Server responded with unknown login prompt: %s", MODULE_NAME, bufReceive + 6); FREE(bufReceive); return FAILURE; } else { writeError(ERR_ERROR, "%s: Server failed to respond with login prompt.", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); /* send username */ writeError(ERR_DEBUG_MODULE, "%s: Sending username.", MODULE_NAME); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } /* retrieve password prompt */ // RECV: 00 3a 08 20 0d 0a 45 6e 74 65 72 20 70 61 73 73 77 6f 72 64 3a 20 // SEND: 2 + strlen(login) bytes nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive + 6, "Enter password:")) { writeError(ERR_DEBUG_MODULE, "%s: Retrieved \"Enter password:\"", MODULE_NAME); } else { writeError(ERR_ERROR, "%s: Server did not send: \"Enter password:\"", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); /* send encrypted password */ memset(bufSend, 0, BUF_SIZE); bufSend[0] = 0x06; bufSend[1] = strlen(cpass); strncpy(bufSend + 2, cpass, BUF_SIZE - 3); nSendBufferSize = strlen(cpass) + 2; writeError(ERR_DEBUG_MODULE, "%s: Sending password.", MODULE_NAME); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } } int pcaNegCrypt(int hSocket) { unsigned char bufSend[] = { 0x6f, 0x61, 0x00, 0x09, 0x00, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; int nSendBufferSize = 14; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* Testing encryption level. Only the default is currently supported. */ // SEND: 6f 61 00 09 00 fe 00 00 ff ff 00 00 00 00 // RECV: 1b 62 00 02 00 00 00 writeError(ERR_DEBUG_MODULE, "%s: Checking encryption level.", MODULE_NAME); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive + 28, "Host is denying connection")) { writeError(ERR_ERROR, "%s: PcAnywhere host denied connection. Host requires encryption which is currently not supported.", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); return SUCCESS; } int pcaSessionInit(hSocket) { unsigned char bufSend1[] = { 0x00, 0x00, 0x00, 0x00 }; int nSendBufferSize1 = 4; unsigned char bufSend2[] = { 0x6f, 0x06, 0xff }; int nSendBufferSize2 = 3; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* Initial connection. Retrieve PCA banner */ // SEND: 00 00 00 00 // RECV: 50 6c 65 61 73 65 20 70 72 65 73 73 20 3c 45 6e 74 65 72 3e 2e 2e 2e 0d 0a writeError(ERR_DEBUG_MODULE, "%s: Retrieving RCA banner.", MODULE_NAME); if (medusaSend(hSocket, bufSend1, nSendBufferSize1, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { /* can we not perform more than a single thread per host? */ writeError(ERR_ERROR, "%s: Failed to retrieve host banner. Is someone currently connected via PcAnywhere?", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive + 11, "Please press ...")) { writeError(ERR_DEBUG_MODULE, "%s: Retrieved \"Please press ...\"", MODULE_NAME); } else { writeError(ERR_ERROR, "%s: Server did not send: \"Please press ...\"", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); /* Unknown negotiation */ // SEND: 6f 06 ff // RECV: 78 02 1b 61 01 09 00 ff 00 00 ff 00 00 00 00 00 writeError(ERR_DEBUG_MODULE, "%s: Sending unknown packet.", MODULE_NAME); if (medusaSend(hSocket, bufSend2, nSendBufferSize2, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } FREE(bufReceive); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _PCA_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nSendBufferSize = 0; int nReceiveBufferSize = 0; writeError(ERR_DEBUG_MODULE, "%s: Initializing PcAnywhere connection.", MODULE_NAME); iRet = pcaSessionInit(hSocket); if (iRet == FAILURE) { writeError(ERR_ERROR, "%s: Failed to initialize PcAnywhere connection.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; return FAILURE; } writeError(ERR_DEBUG_MODULE, "%s: Negotiating encryption level.", MODULE_NAME); iRet = pcaNegCrypt(hSocket); if (iRet == FAILURE) { writeError(ERR_ERROR, "%s: Failed to negotiate encryption level.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; return FAILURE; } /* check if authentication was successful */ // RECV: (success) // XX XX 1b 49 00 50 6a 6d 6b 00 00 00 00 00 00 00 .M.I.Pjmk....... // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ // 00 00 00 00 0f 00 00 00 00 00 00 00 58 50 43 4c ............XPCL // 49 45 4e 54 30 31 00 00 00 00 00 00 00 00 00 00 IENT01.......... // 00 00 00 00 00 00 00 00 00 00 00 00 05 00 36 83 ..............6. // 33 0a 00 00 00 00 14 3...... // RECV: (failure) // XX XX 0d 0a 00 7b 08 49 6e 76 61 6c 69 64 20 6c .....{.Invalid l // 6f 67 69 6e 2e 20 50 6c 65 61 73 65 20 74 72 79 ogin. Please try // 20 61 67 61 69 6e 2e again. writeError(ERR_DEBUG_MODULE, "%s: Attempting PcAnywhere user authentication.", MODULE_NAME); iRet = pcaUserAuth(hSocket, _psSessionData->domain, szLogin, szPassword); if (iRet == FAILURE) { writeError(ERR_ERROR, "%s: Failed to send authentication information to PcAnywhere host.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; return FAILURE; } else if (strstr(bufReceive + 5, "Invalid login") || strstr(bufReceive + 6, "Enter password")) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); writeError(ERR_INFO, "%s : Machine name: %s Current logged on user: %s.", MODULE_NAME, bufReceive + 42, bufReceive + 4); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } medusa-2.1.1/src/modsrc/vmauthd.c0000644000175000001440000002537111723732127013615 00000000000000/* ** VMware Authentication Daemon Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ** Hydra 5.2 [van Hauser / David Maciejak ] ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "vmauthd.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for the VMware Authentication Daemon" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: vmauthd.c 1374 2010-05-21 18:35:01Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_VMAUTHD 902 typedef struct __VMAUTHD_DATA { } _VMAUTHD_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initConnection(int hSocket, sConnectParams *params); int tryLogin(int hSocket, sLogin** login, _VMAUTHD_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _VMAUTHD_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "The VMware Authentication Daemon listens on TCP port 902 and may or may not"); writeVerbose(VB_NONE, "require a SSL-encrypted connection. This module connects to the service using"); writeVerbose(VB_NONE, "non-SSL and will automatically switch to SSL if required."); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _VMAUTHD_DATA *psSessionData; psSessionData = malloc(sizeof(_VMAUTHD_DATA)); memset(psSessionData, 0, sizeof(_VMAUTHD_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _VMAUTHD_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_VMAUTHD; params.nSSLVersion = 3; /* VMware Authentication Daemon requires SSLv3 */ initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (initConnection(hSocket, ¶ms) == FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module specific functions */ /* 220 VMware Authentication Daemon Version 1.00 220 VMware Authentication Daemon Version 1.10: SSL Required */ int initConnection(int hSocket, sConnectParams *params) { int iRet; unsigned char* bufReceive = NULL; int nReceiveBufferSize; nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^220 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Incorrect VMware authentication protocol or service shutdown: %s.", MODULE_NAME, bufReceive); FREE(bufReceive); return FAILURE; } if (strstr(bufReceive, "SSL Required")) { writeError(ERR_INFO, "[%s] SSL Required for VMware authentication. Proceeding using SSL.", MODULE_NAME); if (medusaConnectSocketSSL(params, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish SSLv3 connection.", MODULE_NAME); FREE(bufReceive); return FAILURE; } } FREE(bufReceive); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _VMAUTHD_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet; unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; bufSend = malloc(strlen(szLogin) + 7 + 1); memset(bufSend, 0, strlen(szLogin) + 7 + 1); sprintf(bufSend, "USER %s\r\n", szLogin); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); /* 331 Password required for USERNAME.[0D][0A] */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^331 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] VMware authentication protocol error or service shutdown: %s.\n", MODULE_NAME, bufReceive); FREE(bufReceive); return FAILURE; } FREE(bufReceive); bufSend = malloc(strlen(szPassword) + 7 + 1); memset(bufSend, 0, strlen(szPassword) + 7 + 1); sprintf(bufSend, "PASS %s\r\n", szPassword); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] VMware authentication protocol error or service shutdown: %s.\n", MODULE_NAME, bufReceive); FREE(bufReceive); return FAILURE; } /* 230 User USERNAME logged in.[0D][0A] */ if (strncmp(bufReceive, "230 ", 4) == 0) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } /* 530 Login incorrect.[0D][0A] */ else if (strncmp(bufReceive, "530 ", 4) == 0) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { writeError(ERR_ERROR, "[%s] Unknown error occurred during authentication: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } medusa-2.1.1/src/modsrc/hmacmd5.h0000644000175000001440000000204011741166633013457 00000000000000/* Unix SMB/CIFS implementation. Interface header: Scheduler service Copyright (C) Luke Kenneth Casson Leighton 1996-1999 Copyright (C) Andrew Tridgell 1992-1999 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef _HMAC_MD5_H typedef struct { MD5_CTX ctx; unsigned char k_ipad[65]; unsigned char k_opad[65]; } HMACMD5Context; #endif /* _HMAC_MD5_H */ medusa-2.1.1/src/modsrc/mysql.c0000644000175000001440000006751611723732127013321 00000000000000/* ** MySQL Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** MySQL 4.1 authentication support added by: pmonkey ** ** MySQL <4.1 Pass Hash Support: jmk ** ** This module supports MySQL protocol 10. ** ** The older MySQL pre-4.1 authentication scheme is vulnerable to a pass-the- ** hash authentication attack. Utilizing the old-style hashes gathered from a ** MySQL database, a user can use Medusa to verify their validity on other ** servers. A modified MySQL client can also be use to connect to located ** services directly utilizing a valid hash. ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "mysql.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for MySQL sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: mysql.c 1578 2011-07-07 19:31:43Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define BUF_SIZE 300 #define PORT_MYSQL 3306 #define PROTO_UNKNOWN 0 #define PROTO_OLD 1 #define PROTO_NEW 2 #define PASSWORD 1 #define HASH 2 typedef struct __MYSQL_DATA { int protoFlag; int hashFlag; } _MYSQL_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _MYSQL_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MYSQL_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " PASS:? (PASSWORD*, HASH)"); writeVerbose(VB_NONE, " PASSWORD: Use normal password."); writeVerbose(VB_NONE, " HASH: Use a hash rather than a password. (non-SHA1 hashes only)"); writeVerbose(VB_NONE, "\n(*) Default value"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage examples:"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "1: Normal boring check..."); writeVerbose(VB_NONE, " medusa -M mysql -h somehost -u someuser -p somepassword"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "2: Using an old-style MySQL hash..."); writeVerbose(VB_NONE, " medusa -M mysql -h somehost -U users.txt -p 39b52a209cf03d62 -m PASS:HASH"); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr = NULL, *pOpt = NULL, *pOptTmp = NULL; _MYSQL_DATA *psSessionData; psSessionData = malloc(sizeof(_MYSQL_DATA)); memset(psSessionData, 0, sizeof(_MYSQL_DATA)); psSessionData->protoFlag = PROTO_NEW; if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); psSessionData->hashFlag = PASSWORD; for (i=0; ihashFlag = PASSWORD; else if (strcmp(pOpt, "HASH") == 0) psSessionData->hashFlag = HASH; else writeError(ERR_WARNING, "Invalid value for method PASS."); } free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MYSQL_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_MYSQL; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int MySQLSessionQuit(int hSocket) { char com_quit_packet[5] = { 0x01, 0x00, 0x00, 0x00, 0x01 }; if (medusaSend(hSocket, com_quit_packet, 5, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } return SUCCESS; } /* Code used verbatim from: MySQL 3.21 [mysql_com.h / password.c] */ struct rand_struct { unsigned long seed1, seed2, max_value; double max_value_dbl; }; void randominit(struct rand_struct *rand_st, unsigned long seed1, unsigned long seed2) { /* for mysql 3.21.# */ rand_st->max_value = 0x3FFFFFFFL; rand_st->max_value_dbl = (double) rand_st->max_value; rand_st->seed1 = seed1 % rand_st->max_value; rand_st->seed2 = seed2 % rand_st->max_value; } double rnd(struct rand_struct *rand_st) { rand_st->seed1 = (rand_st->seed1 * 3 + rand_st->seed2) % rand_st->max_value; rand_st->seed2 = (rand_st->seed1 + rand_st->seed2 + 33) % rand_st->max_value; return (((double) rand_st->seed1) / rand_st->max_value_dbl); } /* Code used verbatim from: MySQL 4.1 [password.c] */ #define PVERSION41_CHAR '*' typedef unsigned char uint8; typedef unsigned char uchar; typedef unsigned long long int ulonglong; typedef unsigned int uint32; typedef short int16; typedef unsigned long ulong; #include "sha1.h" #define SCRAMBLE_LENGTH 20 #define SCRAMBLE_LENGTH_323 8 #define char_val(X) (X >= '0' && X <= '9' ? X-'0' :\ X >= 'A' && X <= 'Z' ? X-'A'+10 :\ X >= 'a' && X <= 'z' ? X-'a'+10 :\ '\177') void hash_password(ulong *result, const char *password, uint password_len) { register ulong nr=1345345333L, add=7, nr2=0x12345671L; ulong tmp; const char *password_end= password + password_len; for (; password < password_end; password++) { if (*password == ' ' || *password == '\t') continue; /* skip space in password */ tmp= (ulong) (uchar) *password; nr^= (((nr & 63)+add)*tmp)+ (nr << 8); nr2+=(nr2 << 8) ^ nr; add+=tmp; } result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */; result[1]=nr2 & (((ulong) 1L << 31) -1L); } void octet2hex(char *to, const uint8 *str, unsigned int len) { char _dig_vec_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const uint8 *str_end= str + len; for (; str != str_end; ++str) { *to++= _dig_vec_upper[(*str & 0xF0) >> 4]; *to++= _dig_vec_upper[*str & 0x0F]; } *to= '\0'; } void hex2octet(uint8 *to, const char *str, uint len) { const char *str_end= str + len; while (str < str_end) { register char tmp= char_val(*str++); *to++= (tmp << 4) | char_val(*str++); } } static void my_crypt(char *to, const uchar *s1, const uchar *s2, uint len) { const uint8 *s1_end= s1 + len; while (s1 < s1_end) *to++= *s1++ ^ *s2++; } double my_rnd(struct rand_struct *rand_st) { rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value; rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value; return (((double) rand_st->seed1)/rand_st->max_value_dbl); } void scramble_323(char *to, _MYSQL_DATA *_psSessionData, const char *message, const char *password) { struct rand_struct rand_st; ulong hash_pass[2], hash_message[2]; if (password && password[0]) { char extra, *to_start=to; const char *message_end= message + SCRAMBLE_LENGTH_323; /* Idea borrowed from "The Database Hacker's Handbook: Defending Database Servers" */ if (_psSessionData->hashFlag == HASH) { if (strlen(password) != 16) writeError(ERR_ERROR, "[%s] Invalid Hash Type (Old Style Hash Required)", MODULE_NAME); sscanf(password, "%08lx%08lx", &hash_pass[0], &hash_pass[1]); } else hash_password(hash_pass, password, strlen(password)); hash_password(hash_message, message, SCRAMBLE_LENGTH_323); randominit(&rand_st, hash_pass[0] ^ hash_message[0], hash_pass[1] ^ hash_message[1]); for (; message < message_end; message++) *to++= (char) (floor(my_rnd(&rand_st)*31)+64); extra=(char) (floor(my_rnd(&rand_st)*31)); while (to_start != to) *(to_start++)^=extra; } *to= 0; } void scramble(char *to, _MYSQL_DATA *_psSessionData, const char *message, const char *password) { SHA1_CONTEXT sha1_context; uint8 hash_stage1[SHA1_HASH_SIZE]; uint8 hash_stage2[SHA1_HASH_SIZE]; sha1_reset(&sha1_context); /* Stock pass-the-hash Attacks do not appear feasible. However, if another conversation is intercepted and the SHA1 hash (hash_stage2) is known, hash_stage1 could probably be derived. A new reply could then be generated based on that information. Of course, if we already have this sort of network access, what are we messing with this for? */ if (_psSessionData->hashFlag == HASH) if ( (strncmp(password, "*", 1) == 0) && (strlen(password) == 2 * SHA1_HASH_SIZE + 1) ) writeError(ERR_ERROR, "[%s] MySQL 4.1 and above use a SHA1-based authentication scheme which does not appear to be susceptible to pass-the-hash style attacks.", MODULE_NAME); /* stage 1: hash password */ sha1_input(&sha1_context, (uint8 *) password, strlen(password)); sha1_result(&sha1_context, hash_stage1); /* stage 2: hash stage 1; note that hash_stage2 is stored in the database */ sha1_reset(&sha1_context); sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE); sha1_result(&sha1_context, hash_stage2); /* create crypt string as sha1(message, hash_stage2) */; sha1_reset(&sha1_context); sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); /* xor allows 'from' and 'to' overlap: lets take advantage of it */ sha1_result(&sha1_context, (uint8 *) to); my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH); } /* End of MySQL copy and paste items */ int MySQLPrepareAuthOld(_MYSQL_DATA *_psSessionData, char* szLogin, char* szPassword, char* szSessionSalt, unsigned char** szResponse, unsigned long* iResponseLength) { unsigned char* response; /* usernames limited to 16 characters - http://dev.mysql.com/doc/refman/5.1/en/user-names.html */ int login_len = strlen(szLogin) > 16 ? 16 : strlen(szLogin); int response_len = 4 /* header */ + 2 /* client flags */ + 3 /* max packet len */ + login_len /* username length */ + 1 /* NULL terminate username */ + 8; /* scrambled password len */ response = (unsigned char *) malloc(response_len + 1); memset(response, 0, response_len + 1); response[0] = response_len - 4; /* packet length */ response[1] = 0x00; response[2] = 0x00; response[3] = 0x01; /* packet number */ response[4] = 0x85; /* client flag */ response[5] = 0x24; response[6] = 0x00; /* max packet */ response[7] = 0x00; response[8] = 0x00; strncpy(response + 9, szLogin, login_len); response[9 + login_len] = '\0'; /* null terminate login */ if ( strcmp(szPassword, "") != 0) /* password set */ scramble_323((char *) &response[9 + login_len + 1], _psSessionData, szSessionSalt, szPassword); *(iResponseLength) = response_len; *szResponse = response; return SUCCESS; } /* Protocol 10 is used by MySQL 3.22 and later. However, MySQL 4.1 introduced a new password algorithm. In some cases, MySQL 4.1 and later systems will contain accounts which are still configured with password hashes generated using the older algorithm. When we authenticate to a 4.1 server and this is the case, the server is nice enough to tell us and allow us to reauthenticate. This function generates the appropriate response for this particular case. */ int MySQLPrepareAuthNewOld(_MYSQL_DATA *_psSessionData, char* szLogin, char* szPassword, char* szSessionSalt, unsigned char** szResponse, unsigned long* iResponseLength) { unsigned char* response; /* usernames limited to 16 characters - http://dev.mysql.com/doc/refman/5.1/en/user-names.html */ int login_len = strlen(szLogin) > 16 ? 16 : strlen(szLogin); int response_len = 4 + /* header */ 1 + 8; /* scrambled password length */ response = (unsigned char *) malloc(response_len + 1); memset(response, 0, response_len + 1); response[0] = response_len - 4; /* packet length */ response[3] = 0x03; /* packet number */ scramble_323((char *) &response[4], _psSessionData, szSessionSalt, szPassword); *(iResponseLength) = response_len; *szResponse = response; return SUCCESS; } /* http://www.redferni.uklinux.net/mysql/MySQL-Protocol.html */ int MySQLPrepareAuth(_MYSQL_DATA *_psSessionData, char* szLogin, char* szPassword, char* szSessionSalt, unsigned char** szResponse, unsigned long* iResponseLength) { unsigned char* response; /* usernames limited to 16 characters - http://dev.mysql.com/doc/refman/5.1/en/user-names.html */ int login_len = strlen(szLogin) > 16 ? 16 : strlen(szLogin); int response_len = 4 /* header */ + 4 /* client flags */ + 4 /* max packet len */ + 1 /* charset */ + 23 /* future expansion */ + login_len /* username */ + 1 /* NULL termination */ + 1; /* password length */ if ( strcmp(szPassword, "") != 0 ) /* password set */ response_len += 20; response = (unsigned char *) malloc(response_len + 1); memset(response, 0, response_len + 1); response[0] = response_len - 4; /* packet body length - exclude header */ response[1] = 0x00; response[2] = 0x00; response[3] = 0x01; /* packet number */ //response[4] = 0x85; /* client flag */ response[4] = 0x05; /* client flag */ //response[5] = 0x24; response[5] = 0xa6; response[6] = 0x03; response[7] = 0x00; response[8] = 0x00; /* max packet */ response[9] = 0x00; response[10] = 0x00; response[11] = 0x01; response[12] = 0x21; /* charset utf8 */ strncpy(response + 36, szLogin, login_len); /* NULL terminated username */ if ( strcmp(szPassword, "") == 0 ) /* no password set */ { response[36 + login_len + 1] = 0x00; } else { response[36 + login_len + 1] = 0x14; /* set length of scrambled password - 0x14 (20) */ /* generate SHA password hash */ scramble((char *) &response[36 + login_len + 1 + 1], _psSessionData, szSessionSalt, szPassword); } *(iResponseLength) = response_len; *szResponse = response; return SUCCESS; } int MySQLSessionInit(int hSocket, unsigned char** szSessionSalt) { unsigned char* bufReceive; unsigned char* szServerVersion; int nReceiveBufferSize = 0; int newerauth = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } /* check protocol version */ if (bufReceive[4] == 0xff) { if (strstr(bufReceive + 7, "is not allowed to connect to this MySQL server")) { writeError(ERR_WARNING, "%s: Server responded that host is not allowed to connect to MySQL service.", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { writeError(ERR_ERROR, "%s: Failed to retrieve server version: %s", MODULE_NAME, bufReceive + 7); FREE(bufReceive); return FAILURE; } } if (bufReceive[4] < 10) { writeError(ERR_ERROR, "%s: Server responded requesting protocol version (%d). Version 10 support required.", MODULE_NAME, bufReceive[4]); FREE(bufReceive); return FAILURE; } else if (bufReceive[4] > 10) { writeError(ERR_WARNING, "%s: Server responded requesting protocol version (%d). Support for versions >10 is unknown.", MODULE_NAME, bufReceive[4]); } /* check server version */ szServerVersion = bufReceive + 5; if (!(strstr(szServerVersion, "3.") || strstr(szServerVersion, "4.") || strstr(szServerVersion, "5.") )) { writeError(ERR_ERROR, "%s: Server responded requesting version (%d). Only versions 3.x, 4.x, and 5.x are currently supported.", MODULE_NAME, szServerVersion); FREE(bufReceive); return FAILURE; } if ((strstr(szServerVersion, "4.1") || strstr(szServerVersion, "5.") )) { newerauth=1; writeError(ERR_DEBUG_MODULE, "%s: Server version %s is using newer auth method.", MODULE_NAME, szServerVersion); } if (newerauth) { /* retrieve session salt for newer auth */ *szSessionSalt = malloc(22); memset(*szSessionSalt, 0, 22); memcpy(*szSessionSalt, bufReceive + strlen(szServerVersion) + 10, 9); memcpy(*szSessionSalt+8 , bufReceive + strlen(szServerVersion) + 37 , 12); if (strlen(*szSessionSalt) != 20) { writeError(ERR_ERROR, "%s: Failed to retrieve valid session salt.", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "%s: Retrieved session salt: %s", MODULE_NAME, *szSessionSalt); } } else { /* use the older salt code */ *szSessionSalt = malloc(10); memset(*szSessionSalt, 0, 10); memcpy(*szSessionSalt, bufReceive + strlen(szServerVersion) + 10, 9); if (strlen(*szSessionSalt) != 8) { writeError(ERR_ERROR, "%s: Failed to retrieve valid session salt.", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "%s: Retrieved session salt: %s.", MODULE_NAME, *szSessionSalt); } } FREE(bufReceive); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _MYSQL_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet, iReturnCode; unsigned char* bufReceive = NULL; unsigned char* szSessionSalt = NULL; unsigned char* szResponse = NULL; unsigned long iResponseLength = 0; int nReceiveBufferSize = 0; /* initialize MySQL connection */ iRet = MySQLSessionInit(hSocket, &szSessionSalt); if (iRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed to initialize MySQL connection (%s).", MODULE_NAME, (*psLogin)->psServer->pHostIP); (*psLogin)->iResult = LOGIN_RESULT_ERROR; return MSTATE_EXITING; } /* prepare client authentication packet */ if (strlen(szSessionSalt) == 8 || _psSessionData->protoFlag == PROTO_OLD) { if (_psSessionData->protoFlag == PROTO_OLD) { writeError(ERR_DEBUG_MODULE, "[%s] Using older style authentication based on previous server response.", MODULE_NAME); } iRet = MySQLPrepareAuthOld(_psSessionData, szLogin, szPassword, szSessionSalt, &szResponse, &iResponseLength); if (iRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed to create client authentication packet.", MODULE_NAME); return FAILURE; } } else { iRet = MySQLPrepareAuth(_psSessionData, szLogin, szPassword, szSessionSalt, &szResponse, &iResponseLength); if (iRet == FAILURE) { writeError(ERR_ERROR, "%s: Failed to create client authentication packet.", MODULE_NAME); return FAILURE; } } /* send authentication attempt */ if (medusaSend(hSocket, szResponse, iResponseLength, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); FREE(szResponse); return FAILURE; } FREE(szResponse); /* process authentication response */ nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } if (bufReceive[4] == 0x00) { (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iReturnCode = MSTATE_EXITING; } else if (bufReceive[4] == 0xFF) { (*psLogin)->iResult = LOGIN_RESULT_FAIL; if (bufReceive[5] == 0xe3 && bufReceive[6] == 0x04) { writeError(ERR_ERROR, "[%s] failed: MYSQL VERSION IS NEWER\n", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iReturnCode = MSTATE_EXITING; } else iReturnCode = MSTATE_NEW; } else if (bufReceive[4] == 0xFE) { /* Protocol 10 is used by MySQL 3.22 and later. However, MySQL 4.1 introduced a new password algorithm. In some cases, MySQL 4.1 and later systems will contain accounts which are still configured with password hashes generated using the older algorithm. When we authenticate to a 4.1 server and this is the case, the server is nice enough to tell us and allow us to reauthenticate. */ writeError(ERR_DEBUG_MODULE, "[%s] Server requested older authentication type. It is likely the remote account exists and has an older style password hash.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; /* Attempt authentication again using old-style password hash and existing connection */ _psSessionData->protoFlag = PROTO_OLD; iRet = MySQLPrepareAuthNewOld(_psSessionData, szLogin, szPassword, szSessionSalt, &szResponse, &iResponseLength); if (iRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed to create client authentication packet.", MODULE_NAME); return FAILURE; } /* send authentication attempt */ if (medusaSend(hSocket, szResponse, iResponseLength, 0) < 0) { writeError(ERR_ERROR, "[%s] medusaSend was not successful", MODULE_NAME); FREE(szResponse); return FAILURE; } FREE(szResponse); /* process authentication response */ FREE(bufReceive); nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } if (bufReceive[4] == 0x00) { (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iReturnCode = MSTATE_EXITING; } else if (bufReceive[4] == 0xFF) { (*psLogin)->iResult = LOGIN_RESULT_FAIL; if (bufReceive[5] == 0xe3 && bufReceive[6] == 0x04) { writeError(ERR_ERROR, "%s failed: MYSQL VERSION IS NEWER\n", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iReturnCode = MSTATE_EXITING; } else iReturnCode = MSTATE_NEW; } /* End of the weird downshift resend case */ } else { writeError(ERR_ERROR, "%s: Unknown response code received from server: %X", MODULE_NAME, bufReceive[4]); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iReturnCode = MSTATE_EXITING; } /* close MySQL connection */ iRet = MySQLSessionQuit(hSocket); if (iRet == FAILURE) { writeError(ERR_ERROR, "%s: Failed to terminate MySQL connection.", MODULE_NAME); return FAILURE; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iReturnCode); } medusa-2.1.1/src/modsrc/web-form.c0000644000175000001440000006152511723732127013664 00000000000000/*************************************************************************** * web-form.c * * Copyright (C) 2007 by Luciano Bello * * luciano@debian.org.ar * * * * Implementation of a web form brute force module for * * medusa. Module concept by the one-and-only Foofus. * * Protocol stuff based on the original medusa http code by * * fizzgig (fizzgig@foofus.net). * * * * * * CHANGE LOG * * 08/10/2007 - Created by Luciano Bello (luciano@debian.org) * * 08/24/2007 - Minor modification by JoMo-Kun * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2, * * as published by the Free Software Foundation * * * * 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. See the * * GNU General Public License for more details. * * * * http://www.gnu.org/licenses/gpl.txt * * * * This program is released under the GPL with the additional exemption * * that compiling, linking, and/or using OpenSSL is allowed. * * * ***************************************************************************/ #include "module.h" #define MODULE_NAME "web-form.mod" #define MODULE_AUTHOR "Luciano Bello " #define MODULE_SUMMARY_USAGE "Brute force module for web forms" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: web-form.c 1634 2011-12-02 19:55:09Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define OPENSSL_WARNING "No usable OPENSSL. Module disabled." #ifdef HAVE_LIBSSL #define HTTP_PORT 80 #define HTTPS_PORT 443 #define FORM_UNKNOWN 0 #define FORM_GET 1 #define FORM_POST 2 typedef struct __MODULE_DATA { char *szDir; char *szHostHeader; char *szUserAgent; int nFormType; char *szDenySignal; char *szFormData; char *szFormRest; char *szFormUser; char *szFormPass; char *szCustomHeader; int nCustomHeaders; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, int nPort, char* szLogin, char* szPassword); int initModule(_MODULE_DATA* _psSessionData, sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " USER-AGENT:? User-agent value. Default: \"I'm not Mozilla, I'm Ming Mong\"."); writeVerbose(VB_NONE, " FORM:? Target form to request. Default: \"/\""); writeVerbose(VB_NONE, " DENY-SIGNAL:? Authentication failure message. Attempt flagged as successful if text is not present in"); writeVerbose(VB_NONE, " server response. Default: \"Login incorrect\""); writeVerbose(VB_NONE, " CUSTOM-HEADER:? Custom HTTP header."); writeVerbose(VB_NONE, " More headers can be defined by using this option several times."); writeVerbose(VB_NONE, " FORM-DATA:?"); writeVerbose(VB_NONE, " Methods and fields to send to web service. Valid methods are GET and POST. The actual form"); writeVerbose(VB_NONE, " data to be submitted should also be defined here. Specifically, the fields: username and"); writeVerbose(VB_NONE, " password. The username field must be the first, followed by the password field."); writeVerbose(VB_NONE, " Default: \"post?username=&password=\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M web-form -m USER-AGENT:\"g3rg3 gerg\" -m FORM:\"webmail/index.php\" -m DENY-SIGNAL:\"deny!\""); writeVerbose(VB_NONE, " -m FORM-DATA:\"post?user=&pass=&submit=True\" -m CUSTOM-HEADER:\"Cookie: name=value\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !( 0 <= argc <= 2) ) { // Show usage information writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module.", MODULE_NAME); return FAILURE; } else { // Parameters are good - make module go now writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszDir = malloc(strlen(pOpt) + 1); memset(psSessionData->szDir, 0, strlen(pOpt) + 1); strncpy(psSessionData->szDir, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method FORM requires value to be set."); } else if (strcmp(pOpt, "DENY-SIGNAL") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDenySignal= malloc(strlen(pOpt) + 1); memset(psSessionData->szDenySignal, 0, strlen(pOpt) + 1); strncpy(psSessionData->szDenySignal, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method DENY-SIGNAL requires value to be set."); } else if (strcmp(pOpt, "FORM-DATA") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szFormData = malloc(strlen(pOpt) + 1); memset(psSessionData->szFormData, 0, strlen(pOpt) + 1); strncpy(psSessionData->szFormData, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method FORM-DATA requires value to be set."); } else if (strcmp(pOpt, "USER-AGENT") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szUserAgent = malloc(strlen(pOpt) + 1); memset(psSessionData->szUserAgent, 0, strlen(pOpt) + 1); strncpy(psSessionData->szUserAgent, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method USER-AGENT requires value to be set."); } else if (strcmp(pOpt, "CUSTOM-HEADER") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { if ( psSessionData->nCustomHeaders == 0 ) { psSessionData->szCustomHeader = malloc(strlen(pOpt) + 1); memset(psSessionData->szCustomHeader, 0, strlen(pOpt) + 3); strncpy(psSessionData->szCustomHeader, pOpt, strlen(pOpt)); strncpy(psSessionData->szCustomHeader + strlen(pOpt), "\r\n", 2); psSessionData->nCustomHeaders = 1; } else { int oldSize = strlen(psSessionData->szCustomHeader); psSessionData->szCustomHeader = realloc(psSessionData->szCustomHeader, oldSize + strlen(pOpt) + 3); memset(psSessionData->szCustomHeader + oldSize, 0, strlen(pOpt) + 3); strncpy(psSessionData->szCustomHeader + oldSize, pOpt, strlen(pOpt)); strncpy(psSessionData->szCustomHeader + oldSize + strlen(pOpt), "\r\n", 2); psSessionData->nCustomHeaders += 1; } } else writeError(ERR_WARNING, "Method CUSTOM-HEADER requires value to be set."); } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } free(pOptTmp); } initModule(psSessionData, logins); } FREE(psSessionData); return SUCCESS; } int initModule(_MODULE_DATA *_psSessionData, sLogin* _psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; char *pStrtokSavePtr = NULL; char *pTemp; int nBufLength = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, _psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (_psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = _psLogin->psServer->psAudit->iPortOverride; else if (_psLogin->psServer->psHost->iUseSSL > 0) params.nPort = HTTPS_PORT; else params.nPort = HTTP_PORT; initConnectionParams(_psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (_psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(_psLogin, psCredSet->pPass); return FAILURE; } /* Set request parameters */ if (!_psSessionData->szDir) { _psSessionData->szDir = malloc(1); memset(_psSessionData->szDir, 0, 1); sprintf(_psSessionData->szDir, "/"); } if (!_psSessionData->szHostHeader) { nBufLength = strlen(_psLogin->psServer->psHost->pHost) + 1 + log(params.nPort) + 1; _psSessionData->szHostHeader = malloc(nBufLength + 1); memset(_psSessionData->szHostHeader, 0, nBufLength + 1); sprintf(_psSessionData->szHostHeader, "%s:%d", _psLogin->psServer->psHost->pHost, params.nPort); } if (!_psSessionData->szFormData) { _psSessionData->szFormRest = malloc(1); memset(_psSessionData->szFormRest, 0, 1); _psSessionData->szFormUser = malloc(10); memset(_psSessionData->szFormUser, 0, 10); sprintf(_psSessionData->szFormUser, "username="); _psSessionData->szFormPass = malloc(10); memset(_psSessionData->szFormPass, 0, 10); sprintf(_psSessionData->szFormPass, "password="); _psSessionData->nFormType = FORM_POST; } else { /* Only set user-supplied form data on first pass */ if (_psSessionData->szFormUser == NULL) { pTemp = strtok_r(_psSessionData->szFormData, "?", &pStrtokSavePtr); writeError(ERR_DEBUG_MODULE, "[%s] User-supplied Form Action Method: %s", MODULE_NAME, pTemp); if(strncasecmp(pTemp, "POST", 4) == 0) _psSessionData->nFormType=FORM_POST; else if(strncasecmp(pTemp, "GET", 3) == 0) _psSessionData->nFormType=FORM_GET; else _psSessionData->nFormType=FORM_UNKNOWN; pTemp = strtok_r(NULL, "&", &pStrtokSavePtr); if (pTemp != NULL) { _psSessionData->szFormUser = malloc( strlen(pTemp) + 1 ); memset(_psSessionData->szFormUser, 0, strlen(pTemp) + 1); strncpy(_psSessionData->szFormUser, pTemp, strlen(pTemp)); } pTemp = strtok_r(NULL, "&", &pStrtokSavePtr); if (pTemp != NULL) { _psSessionData->szFormPass = malloc( strlen(pTemp) + 1); memset(_psSessionData->szFormPass, 0, strlen(pTemp) + 1); strncpy(_psSessionData->szFormPass, pTemp, strlen(pTemp)); } pTemp = strtok_r(NULL, "", &pStrtokSavePtr); if (pTemp != NULL) { _psSessionData->szFormRest = malloc( strlen(pTemp) + 1 ); memset(_psSessionData->szFormRest, 0, strlen(pTemp) + 1); strncpy(_psSessionData->szFormRest, pTemp, strlen(pTemp)); } } writeError(ERR_DEBUG_MODULE, "[%s] User-supplied Form User Field: %s", MODULE_NAME, _psSessionData->szFormUser); writeError(ERR_DEBUG_MODULE, "[%s] User-supplied Form Pass Field: %s", MODULE_NAME, _psSessionData->szFormPass); writeError(ERR_DEBUG_MODULE, "[%s] User-supplied Form Rest Field: %s", MODULE_NAME, _psSessionData->szFormRest); if ((_psSessionData->nFormType == FORM_UNKNOWN) || (_psSessionData->szFormUser == NULL) || (_psSessionData->szFormPass == NULL)) { writeError(ERR_WARNING, "Invalid FORM-DATA format. Using default format: \"post?username=&password=\""); _psSessionData->szFormRest = malloc(1); memset(_psSessionData->szFormRest, 0, 1); _psSessionData->szFormUser = malloc(10); memset(_psSessionData->szFormUser, 0, 10); sprintf(_psSessionData->szFormUser, "username="); _psSessionData->szFormPass = malloc(10); memset(_psSessionData->szFormPass, 0, 10); sprintf(_psSessionData->szFormPass, "password="); _psSessionData->nFormType=FORM_POST; } } if (!_psSessionData->szUserAgent) { _psSessionData->szUserAgent = malloc(31); memset(_psSessionData->szUserAgent, 0, 31); sprintf(_psSessionData->szUserAgent, "I'm not Mozilla, I'm Ming Mong"); } if (!_psSessionData->szDenySignal) { _psSessionData->szDenySignal = malloc(19); memset(_psSessionData->szDenySignal, 0, 19); sprintf(_psSessionData->szDenySignal, "Login Incorrect"); } if (!_psSessionData->szCustomHeader) { _psSessionData->szCustomHeader = malloc(1); memset(_psSessionData->szCustomHeader, 0, 1); } nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, _psSessionData, &_psLogin, params.nPort, psCredSet->psUser->pUser, psCredSet->pPass); if (_psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown HTTP module state (%d). Exiting...", nState); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; break; } } /* clean up memory */ FREE(_psSessionData->szDir); FREE(_psSessionData->szHostHeader); FREE(_psSessionData->szUserAgent); FREE(_psSessionData->szDenySignal); FREE(_psSessionData->szFormData); FREE(_psSessionData->szFormRest); FREE(_psSessionData->szFormUser); FREE(_psSessionData->szFormPass); FREE(_psSessionData->szCustomHeader); FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ char *urlencodeup(char* szStr){ int i=0,j=0; size_t iLen=strlen(szStr); char * szRet = (char*)malloc(sizeof(char)*((iLen*3) + 1)); static char safechars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; for(i=0;iszFormRest == NULL) || (_psSessionData->szFormRest[0] == 0)) nFormBufferSize = asprintf(&bufForm, "%s%s&%s%s", _psSessionData->szFormUser, szLogin, _psSessionData->szFormPass, szPassword); else nFormBufferSize = asprintf(&bufForm, "%s%s&%s%s&%s", _psSessionData->szFormUser, szLogin, _psSessionData->szFormPass, szPassword, _psSessionData->szFormRest); nSendBufferSize = asprintf(&bufSend, "POST /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n%sConnection: close\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\n%s", _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, _psSessionData->szCustomHeader, nFormBufferSize, bufForm); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); nRet = FAILURE; } free(bufSend); free(bufForm); return nRet; } int sendGet(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { char* bufSend = NULL; int nSendBufferSize = 0; int nRet = SUCCESS; if ((_psSessionData->szFormRest == NULL) || (_psSessionData->szFormRest[0] == 0)) nSendBufferSize = asprintf(&bufSend, "GET /%s?%s%s&%s%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n%sConnection: close\r\n\r\n", _psSessionData->szDir, _psSessionData->szFormUser, szLogin, _psSessionData->szFormPass, szPassword, _psSessionData->szHostHeader, _psSessionData->szUserAgent, _psSessionData->szCustomHeader); else nSendBufferSize = asprintf(&bufSend, "GET /%s?%s%s&%s%s&%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n%sConnection: close\r\n\r\n", _psSessionData->szDir, _psSessionData->szFormUser, szLogin, _psSessionData->szFormPass, szPassword, _psSessionData->szFormRest, _psSessionData->szHostHeader, _psSessionData->szUserAgent, _psSessionData->szCustomHeader); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); nRet = FAILURE; } free(bufSend); return nRet; } int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, int nPort, char* szLogin, char* szPassword) { char* pReceiveBuffer = NULL; int nReceiveBufferSize, nRet; char* pTemp = NULL; char* szPasswordEncoded = NULL; szPasswordEncoded = urlencodeup(szPassword); switch(_psSessionData->nFormType) { case FORM_GET: writeError(ERR_DEBUG_MODULE, "[%s] Sending Web Form Authentication (GET).", MODULE_NAME); nRet = sendGet(hSocket, _psSessionData, szLogin, szPasswordEncoded); break; case FORM_POST: writeError(ERR_DEBUG_MODULE, "[%s] Sending Web Form Authentication (POST).", MODULE_NAME); nRet = sendPost(hSocket, _psSessionData, szLogin, szPasswordEncoded); break; default: break; } if (nRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); pReceiveBuffer = medusaReceiveLine(hSocket, &nReceiveBufferSize); if ((pReceiveBuffer == NULL) || (pReceiveBuffer[0] == '\0')) { writeError(ERR_ERROR, "[%s] No data received", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } pTemp = (char*)index(pReceiveBuffer, ' '); if ( !pTemp || strncmp(pTemp + 1, "200 OK", 6) != 0 ) { writeError(ERR_ERROR, "The answer was NOT successfully received, understood, and accepted: error code %.4s", pTemp); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } while ((strcasestr(pReceiveBuffer, _psSessionData->szDenySignal) == NULL) && (pReceiveBuffer[0] != '\0')) { free(pReceiveBuffer); pReceiveBuffer = medusaReceiveLine(hSocket, &nReceiveBufferSize); } if (strcasestr(pReceiveBuffer, _psSessionData->szDenySignal) != NULL) { (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } writeError(ERR_DEBUG_MODULE, "Login Successful"); (*login)->iResult = LOGIN_RESULT_SUCCESS; setPassResult(*login, szPassword); return MSTATE_NEW; } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif medusa-2.1.1/src/modsrc/rexec.c0000644000175000001440000002154011723732127013245 00000000000000/* ** REXEC Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "rexec.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for REXEC sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: rexec.c 1301 2010-02-09 22:54:18Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define BUF_SIZE 300 #define PORT_REXEC 512 // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins); } return SUCCESS; } int initModule(sLogin* psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) writeError(ERR_ERROR, "[%s] module asked for REXEC with SSL. Don't know if such a thing exists...\n"); else params.nPort = PORT_REXEC; params.nSourcePort = 1023; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int tryLogin(int hSocket, sLogin** psLogin, char* szLogin, char* szPassword) { int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* send username */ memset(bufSend, 0, sizeof(bufSend)); bufSend[0]=0x00; strncpy(bufSend+1, szLogin, strlen(szLogin)); bufSend[strlen(szLogin)+1]=0x00; strncpy(bufSend+2+strlen(szLogin), szPassword, strlen(szPassword)); bufSend[strlen(szLogin)+1+strlen(szPassword)+1]=0x00; strncpy(bufSend+1+strlen(szLogin)+1+strlen(szPassword)+1, "id", 3); bufSend[strlen(szLogin)+1+strlen(szPassword)+1+3]=0x00; if (medusaSend(hSocket, bufSend, strlen(szLogin)+1+strlen(szPassword)+1+4 , 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL ) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive,"Login incorrect") != NULL) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed up here.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; /* Why do I need this? */ sleep(1); iRet = MSTATE_NEW; FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive,"uid") != NULL) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else if (strstr(bufReceive,"Command ID in library") != NULL) { writeError(ERR_DEBUG_MODULE, "%s : AS/400 Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed down here.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } medusa-2.1.1/src/modsrc/hmacmd5.c0000644000175000001440000001060011741166633013453 00000000000000/* Unix SMB/CIFS implementation. HMAC MD5 code for use in NTLMv2 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 Copyright (C) Andrew Tridgell 1992-2000 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* taken direct from rfc2104 implementation and modified for suitable use * for ntlmv2. */ #include #include #include "hmacmd5.h" #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) /*********************************************************************** the rfc 2104 version of hmac_md5 initialisation. ***********************************************************************/ void hmac_md5_init_rfc2104(const unsigned char *key, int key_len, HMACMD5Context *ctx) { int i; unsigned char tk[16]; /* if key is longer than 64 bytes reset it to key=MD5(key) */ if (key_len > 64) { MD5_CTX tctx; MD5_Init(&tctx); MD5_Update(&tctx, (void *)key, key_len); MD5_Final(tk, &tctx); key = tk; key_len = 16; } /* start out by storing key in pads */ ZERO_STRUCT(ctx->k_ipad); ZERO_STRUCT(ctx->k_opad); memcpy( ctx->k_ipad, key, key_len); memcpy( ctx->k_opad, key, key_len); /* XOR key with ipad and opad values */ for (i=0; i<64; i++) { ctx->k_ipad[i] ^= 0x36; ctx->k_opad[i] ^= 0x5c; } MD5_Init(&ctx->ctx); MD5_Update(&ctx->ctx, ctx->k_ipad, 64); } /*********************************************************************** the microsoft version of hmac_md5 initialisation. ***********************************************************************/ void hmac_md5_init_limK_to_64(const unsigned char* key, int key_len, HMACMD5Context *ctx) { int i; /* if key is longer than 64 bytes truncate it */ if (key_len > 64) { key_len = 64; } /* start out by storing key in pads */ ZERO_STRUCT(ctx->k_ipad); ZERO_STRUCT(ctx->k_opad); memcpy( ctx->k_ipad, key, key_len); memcpy( ctx->k_opad, key, key_len); /* XOR key with ipad and opad values */ for (i=0; i<64; i++) { ctx->k_ipad[i] ^= 0x36; ctx->k_opad[i] ^= 0x5c; } MD5_Init(&ctx->ctx); MD5_Update(&ctx->ctx, ctx->k_ipad, 64); } /*********************************************************************** update hmac_md5 "inner" buffer ***********************************************************************/ void hmac_md5_update(const unsigned char *text, int text_len, HMACMD5Context *ctx) { MD5_Update(&ctx->ctx, (void *)text, text_len); /* then text of datagram */ } /*********************************************************************** finish off hmac_md5 "inner" buffer and generate outer one. ***********************************************************************/ void hmac_md5_final(unsigned char *digest, HMACMD5Context *ctx) { MD5_CTX ctx_o; MD5_Final(digest, &ctx->ctx); MD5_Init(&ctx_o); MD5_Update(&ctx_o, ctx->k_opad, 64); MD5_Update(&ctx_o, digest, 16); MD5_Final(digest, &ctx_o); } /*********************************************************** single function to calculate an HMAC MD5 digest from data. use the microsoft hmacmd5 init method because the key is 16 bytes. ************************************************************/ void hmac_md5( unsigned char key[16], unsigned char *data, int data_len, unsigned char *digest) { HMACMD5Context ctx; hmac_md5_init_limK_to_64(key, 16, &ctx); if (data_len != 0) { hmac_md5_update(data, data_len, &ctx); } hmac_md5_final(digest, &ctx); } medusa-2.1.1/src/modsrc/wrapper.c0000644000175000001440000005126711723732127013630 00000000000000/* ** Generic Wrapper Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "wrapper.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Generic Wrapper Module" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: wrapper.c 1406 2010-09-02 18:29:18Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PARENT_READ iReadPipe[0] #define CHILD_WRITE iReadPipe[1] #define CHILD_READ iWritePipe[0] #define PARENT_WRITE iWritePipe[1] #define TYPE_SINGLE 1 #define TYPE_STDIN 2 typedef struct __MODULE_DATA { unsigned char *szCmd; unsigned char *szCmdFull; unsigned char *szCmdParam; unsigned char *szCmdParamFull; int iReadPipe[2]; int iWritePipe[2]; int nType; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(_MODULE_DATA* _psSessionData, sLogin** login, char* szLogin, char* szPassword); int initModule(_MODULE_DATA* _psSessionData, sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " TYPE:? (SINGLE, STDIN)"); writeVerbose(VB_NONE, " Option sets type of script being called by module. See included sample scripts"); writeVerbose(VB_NONE, " for ideas how to use this module."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " SINGLE: Script expects all user input comes from original command line."); writeVerbose(VB_NONE, " STDIN: Host and user information passed to script via command line."); writeVerbose(VB_NONE, " Passwords to test are passed via STDIN to script."); writeVerbose(VB_NONE, " "); writeVerbose(VB_NONE, " PROG:? "); writeVerbose(VB_NONE, " Option for setting path to executable file."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " ARGS:? "); writeVerbose(VB_NONE, " Option for setting executable parameters. The following substitutions can be used:"); writeVerbose(VB_NONE, " %H: Replaced with target IP address."); writeVerbose(VB_NONE, " %U: Replaced with username to test."); writeVerbose(VB_NONE, " %P: Replaced with password to test."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \'-M wrapper -m TYPE:SINGLE -m PROG:./foo.pl -m ARGS:\"-h %H -u %U -p %P\"\'"); writeVerbose(VB_NONE, "Usage example: \'-M wrapper -m TYPE:STDIN -m PROG:./bar.pl -m ARGS:\"--host %H --user %U\"\'"); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i, iRet; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !(argc == 3) ) { writeError(ERR_ERROR, "%s : Incorrect number of paramenters. Use \"-q\" option to display module usage.", MODULE_NAME); iRet = FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inType = TYPE_SINGLE; else if (strcmp(pOpt, "STDIN") == 0) psSessionData->nType = TYPE_STDIN; else writeError(ERR_WARNING, "Invalid value for method TYPE."); } else if (strcmp(pOpt, "PROG") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szCmd = malloc(strlen(pOpt) + 1); memset(psSessionData->szCmd, 0, strlen(pOpt) + 1); strncpy(psSessionData->szCmd, pOpt, strlen(pOpt) + 1); } else writeError(ERR_WARNING, "Method PROG requires value to be set."); } else if (strcmp(pOpt, "ARGS") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szCmdParam = malloc(strlen(pOpt) + 1); memset(psSessionData->szCmdParam, 0, strlen(pOpt) + 1); strncpy(psSessionData->szCmdParam, pOpt, strlen(pOpt) + 1); } else writeError(ERR_WARNING, "Method ARGS requires value to be set."); } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } free(pOptTmp); } initModule(psSessionData, logins); iRet = SUCCESS; } FREE(psSessionData); return iRet; } int initModule(_MODULE_DATA *_psSessionData, sLogin* psLogin) { enum MODULE_STATE nState = MSTATE_NEW; char *szTmp = NULL; char *szCmdTmp = NULL; int iRet, nCmdLength; int64_t nCmdPartLength; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: /* perform parameter substitution -- this is messy... */ writeError(ERR_DEBUG_MODULE, "User-supplied parameters: %s", _psSessionData->szCmdParam); /* --host %H --user %U --pass %P */ if (_psSessionData->nType == TYPE_SINGLE) { nCmdLength = strlen(_psSessionData->szCmdParam); nCmdLength -= 6; nCmdLength += strlen(psLogin->psServer->pHostIP); nCmdLength += strlen(psCredSet->psUser->pUser); nCmdLength += strlen(psCredSet->pPass); } /* --host %H --user %U */ else { nCmdLength = strlen(_psSessionData->szCmdParam); nCmdLength -= 4; nCmdLength += strlen(psLogin->psServer->pHostIP); nCmdLength += strlen(psCredSet->psUser->pUser); } /* adding in 6 characters to temporarily account for %H %U %P values - needed if username/password are shorter than 2 characters each */ _psSessionData->szCmdParamFull = malloc(nCmdLength + 6 + 1); memset(_psSessionData->szCmdParamFull, 0, nCmdLength + 6 + 1); szCmdTmp = malloc(nCmdLength + 6 + 1); memset(szCmdTmp, 0, nCmdLength + 6 + 1); if (szTmp = strstr(_psSessionData->szCmdParam, "%H")) { nCmdPartLength = (int64_t) szTmp - (int64_t) _psSessionData->szCmdParam; writeError(ERR_DEBUG_MODULE, "Processing \%H... Copying (%d) parameter characters.", nCmdPartLength); strncpy(szCmdTmp, _psSessionData->szCmdParam, nCmdPartLength); strncpy(szCmdTmp + nCmdPartLength, psLogin->psServer->pHostIP, strlen(psLogin->psServer->pHostIP)); strncpy(szCmdTmp + nCmdPartLength + strlen(psLogin->psServer->pHostIP), szTmp + 2, strlen(szTmp) - 2); } else { writeError(ERR_ERROR, "Invalid command parameter format. Missing %H format."); psLogin->iResult = LOGIN_RESULT_UNKNOWN; FREE(szCmdTmp); nState = MSTATE_EXITING; break; } writeError(ERR_DEBUG_MODULE, "Parameters (pass 1): %s", szCmdTmp); if (szTmp = strstr(szCmdTmp, "%U")) { nCmdPartLength = (int64_t) szTmp - (int64_t) szCmdTmp; writeError(ERR_DEBUG_MODULE, "Processing \%U... Copying (%d) parameter characters.", nCmdPartLength); strncpy(_psSessionData->szCmdParamFull, szCmdTmp, nCmdPartLength); strncpy(_psSessionData->szCmdParamFull + nCmdPartLength, psCredSet->psUser->pUser, strlen(psCredSet->psUser->pUser)); strncpy(_psSessionData->szCmdParamFull + nCmdPartLength + strlen(psCredSet->psUser->pUser), szTmp + 2, strlen(szTmp) - 2); } else { writeError(ERR_ERROR, "Invalid command parameter format. Missing %U format."); psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; FREE(szCmdTmp); break; } writeError(ERR_DEBUG_MODULE, "Parameters (pass 2): %s", _psSessionData->szCmdParamFull); if ((_psSessionData->nType == TYPE_SINGLE) && (szTmp = strstr(_psSessionData->szCmdParamFull, "%P"))) { nCmdPartLength = (int64_t) szTmp - (int64_t) _psSessionData->szCmdParamFull; writeError(ERR_DEBUG_MODULE, "Processing \%P... Copying (%d) parameter characters.", nCmdPartLength); strncpy(szCmdTmp, _psSessionData->szCmdParamFull, nCmdPartLength); strncpy(szCmdTmp + nCmdPartLength, psCredSet->pPass, strlen(psCredSet->pPass)); strncpy(szCmdTmp + nCmdPartLength + strlen(psCredSet->pPass), szTmp + 2, strlen(szTmp) - 2); strncpy(_psSessionData->szCmdParamFull, szCmdTmp, nCmdLength + 1); } else if (_psSessionData->nType == TYPE_SINGLE) { writeError(ERR_ERROR, "Invalid command parameter format. Missing %P format."); psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; FREE(szCmdTmp); break; } /* clean-up any extra characters left over from %H %U %P */ memset(_psSessionData->szCmdParamFull + nCmdLength, 0, 6 + 1); FREE(szCmdTmp); writeError(ERR_DEBUG_MODULE, "Parameters (pass 3): %s", _psSessionData->szCmdParamFull); _psSessionData->szCmdFull = malloc(strlen(_psSessionData->szCmd) + strlen(_psSessionData->szCmdParamFull) + 7); memset(_psSessionData->szCmdFull, 0, strlen(_psSessionData->szCmd) + strlen(_psSessionData->szCmdParamFull) + 7); strncpy(_psSessionData->szCmdFull, _psSessionData->szCmd, strlen(_psSessionData->szCmd)); strncat(_psSessionData->szCmdFull, " ", 1); strncat(_psSessionData->szCmdFull, _psSessionData->szCmdParamFull, strlen(_psSessionData->szCmdParamFull)); strncat(_psSessionData->szCmdFull, " 1>&2", 5); writeError(ERR_DEBUG_MODULE, "Command line: %s", _psSessionData->szCmdFull); /* end command-line argument parsing */ iRet = initProcess(_psSessionData); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(_psSessionData, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: iRet = closeProcess(_psSessionData); nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } closeProcess(_psSessionData); /* clean up memory */ FREE(_psSessionData->szCmd); FREE(_psSessionData->szCmdFull); FREE(_psSessionData->szCmdParam); FREE(_psSessionData->szCmdParamFull); FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int initProcess(_MODULE_DATA* _psSessionData, sLogin* psLogin) { pid_t fork_result; if ((pipe(_psSessionData->iReadPipe) == 0) && (pipe(_psSessionData->iWritePipe) == 0)) { fork_result = fork(); if (fork_result == (pid_t)-1) { writeError(ERR_ERROR, "Failed to fork management process."); return(FAILURE); } if (fork_result == (pid_t)0) { writeError(ERR_DEBUG_MODULE, "Child process sucessfully forked"); /* connect parent pipes */ close(_psSessionData->PARENT_WRITE); close(_psSessionData->PARENT_READ); /* connect pipes to STDIN/STDOUT */ if (dup2(_psSessionData->CHILD_READ, STDIN_FILENO) < 0) { writeError(ERR_ERROR, "dup2() Mapping pipe to child's STDIN failed."); exit(EXIT_FAILURE); } if (dup2(_psSessionData->CHILD_WRITE, STDERR_FILENO) < 0) { writeError(ERR_ERROR, "dup2() Mapping pipe to child's STDOUT failed."); exit(EXIT_FAILURE); } if (dup2(_psSessionData->CHILD_WRITE, STDOUT_FILENO) < 0) { writeError(ERR_ERROR, "dup2() Mapping pipe to child's STDOUT failed."); exit(EXIT_FAILURE); } /* STDOUT issue: STDOUT is buffered, while STDERR is not. The child process doesn't send any of its STDOUT down the pipe until it terminates. How does one get rid of this buffering? The following doesn't seem to work like one would think it should: setlinebuf(stdout); writeError() below does not function since STDOUT is directed through the pipe. No real way to tell the user that the child failed... */ /* close old pipes */ close(_psSessionData->CHILD_READ); close(_psSessionData->CHILD_WRITE); /* check if file exists */ if ((fopen(_psSessionData->szCmd, "r")) == NULL) { //writeError(ERR_DEBUG_MODULE, "Failed to open file %s - %s", _psSessionData->szCmd, strerror( errno ) ); fprintf(stderr, "LOGIN_CHILD_FILE_ERROR\n"); } else { /* launch application */ //execlp(_psSessionData->szCmd, _psSessionData->szCmd, _psSessionData->szCmdParamFull, (char *)0); if (system(_psSessionData->szCmdFull) < 0) writeError(ERR_ERROR, "[%s] system() call return error", MODULE_NAME); } /* give the parent a chance to read the error message */ sleep(5); exit(0); } else { writeError(ERR_DEBUG_MODULE, "Parent process sucessfully forked"); /* connect child pipes */ close(_psSessionData->CHILD_WRITE); close(_psSessionData->CHILD_READ); } } else { writeError(ERR_FATAL, "Failed to create communication pipes."); } return(SUCCESS); } int closeProcess(_MODULE_DATA* _psSessionData) { writeError(ERR_DEBUG_MODULE, "Parent process completed. Closing communication pipes."); close(_psSessionData->PARENT_WRITE); close(_psSessionData->PARENT_READ); } int tryLogin(_MODULE_DATA* _psSessionData, sLogin** psLogin, char* szLogin, char* szPassword) { int iRet, iDataProcessed; int nDone = 0; char buffer[BUFSIZ + 1]; char *bufSend; char *strtok_ptr, *pBuf, *pBufTmp; if (_psSessionData->nType == TYPE_STDIN) { bufSend = malloc(strlen(szPassword) + 2); memset(bufSend, 0, strlen(szPassword) + 2); sprintf(bufSend, "%s\n", szPassword); iDataProcessed = write(_psSessionData->PARENT_WRITE, bufSend, strlen(bufSend)); writeError(ERR_DEBUG_MODULE, "Sending account login credentials to child process: %s (%d)", bufSend, iDataProcessed); if (iDataProcessed < 0) { writeError(ERR_ERROR, "Error writing to child process buffer."); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; nDone = 1; } } writeError(ERR_DEBUG_MODULE, "Reading data from child process."); while (!nDone) { iDataProcessed = read(_psSessionData->PARENT_READ, buffer, BUFSIZ); if (iDataProcessed <= 0) { writeError(ERR_ERROR, "Error reading from child process buffer."); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; nDone = 1; } else { writeError(ERR_DEBUG_MODULE, "Processing child process buffer."); if (strstr(buffer, "LOGIN_RESULT_FAIL")) { writeError(ERR_DEBUG_MODULE, "Child process responded with: LOGIN_RESULT_FAIL."); (*psLogin)->iResult = LOGIN_RESULT_FAIL; if (_psSessionData->nType == TYPE_STDIN) iRet = MSTATE_RUNNING; else iRet = MSTATE_NEW; nDone = 1; } else if (strstr(buffer, "LOGIN_RESULT_SUCCESS")) { writeError(ERR_DEBUG_MODULE, "Child process responded with: LOGIN_RESULT_SUCCESS."); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; nDone = 1; } else if (strstr(buffer, "LOGIN_RESULT_ERROR")) { /* Allow simple error messages to be passed back to Medusa */ pBufTmp = malloc( sizeof(buffer) ); memset(pBufTmp, 0, sizeof(buffer)); strncpy(pBufTmp, buffer, sizeof(buffer)); pBuf = strtok_r(pBufTmp, ":", &strtok_ptr); pBuf = strtok_r(NULL, "\n", &strtok_ptr); writeError(ERR_ERROR, "Child process responded with: LOGIN_RESULT_ERROR (%s).", pBuf); FREE(pBufTmp); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; nDone = 1; } else if (strstr(buffer, "LOGIN_CHILD_FILE_ERROR")) { writeError(ERR_ERROR, "Child process failed to execute file: %s", _psSessionData->szCmd); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; nDone = 1; } else { writeError(ERR_DEBUG_MODULE, "Child process: %s", buffer); } } } setPassResult((*psLogin), szPassword); return(iRet); } medusa-2.1.1/src/modsrc/http-digest.h0000644000175000001440000000212411723732127014375 00000000000000/* TAKEN from rcf2617.txt */ #ifndef _HTTP_DIGEST_H_ #define _HTTP_DIGEST_H_ #include #define HASHLEN 16 typedef char HASH[HASHLEN]; #define HASHHEXLEN 32 typedef char HASHHEX[HASHHEXLEN+1]; #define IN #define OUT /* calculate H(A1) as per HTTP Digest spec */ void DigestCalcHA1( IN char * pszAlg, IN char * pszUserName, IN char * pszRealm, IN char * pszPassword, IN char * pszNonce, IN char * pszCNonce, OUT HASHHEX SessionKey ); /* calculate request-digest/response-digest as per HTTP Digest spec */ void DigestCalcResponse( IN HASHHEX HA1, /* H(A1) */ IN char * pszNonce, /* nonce from server */ IN char * pszNonceCount, /* 8 hex digits */ IN char * pszCNonce, /* client nonce */ IN char * pszQop, /* qop-value: "", "auth", "auth-int" */ IN char * pszMethod, /* method from the request */ IN char * pszDigestUri, /* requested URL */ IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ OUT HASHHEX Response /* request-digest or response-digest */ ); #endif medusa-2.1.1/src/modsrc/d3des.h0000644000175000001440000000316311723732127013147 00000000000000 /* * This is D3DES (V5.09) by Richard Outerbridge with the double and * triple-length support removed for use in VNC. * * These changes are: * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. * * This software 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. */ /* d3des.h - * * Headers and defines for d3des.c * Graven Imagery, 1992. * * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge * (GEnie : OUTER; CIS : [71755,204]) */ #define EN0 0 /* MODE == encrypt */ #define DE1 1 /* MODE == decrypt */ extern void deskey(unsigned char *, int); /* hexkey[8] MODE * Sets the internal key register according to the hexadecimal * key contained in the 8 bytes of hexkey, according to the DES, * for encryption or decryption according to MODE. */ extern void usekey(unsigned long *); /* cookedkey[32] * Loads the internal key register with the data in cookedkey. */ extern void cpkey(unsigned long *); /* cookedkey[32] * Copies the contents of the internal key register into the storage * located at &cookedkey[0]. */ extern void des(unsigned char *, unsigned char *); /* from[8] to[8] * Encrypts/Decrypts (according to the key currently loaded in the * internal key register) one block of eight bytes at address 'from' * into the block at address 'to'. They can be the same. */ /* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery ********************************************************************/ medusa-2.1.1/src/modsrc/snmp.c0000644000175000001440000006533411723732127013125 00000000000000/* ** SNMPv1/2C Community String Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on ideas from: ** Hydra 5.2 [van Hauser ] ** onesixtyone [solareclipse@phreedom.org] ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "snmp.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for SNMP Community Strings" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: snmp.c 1399 2010-08-04 21:04:25Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_SNMP 161 #define SNMP_VER_V1 1 #define SNMP_VER_V2C 2 #define SNMP_READ 1 #define SNMP_WRITE 2 #define SNMP_SUCCESS_READ 1 #define SNMP_SUCCESS_WRITE 2 #define SEND_DELAY 200 /* Delay between sending SNMP requests (usec) */ #define RECEIVE_DELAY 5*1000000 /* Response wait time (usec) */ typedef struct __SNMP_DATA { int nVersion; int nReadWrite; int nReadTimeout; int nSendDelay; } _SNMP_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int sendRead(int hSocket, _SNMP_DATA* _psSessionData, char* szPassword); int sendWrite(int hSocket, _SNMP_DATA* _psSessionData, char* szPassword, char* szLocation); int receiveRequest(int hSocket, _SNMP_DATA* _psSessionData, int* nPassCount, char*** arrszPassList, char** szLocation); int initModule(sLogin* login, _SNMP_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " TIMEOUT:? "); writeVerbose(VB_NONE, " Sets the number of seconds to wait for the UDP responses (default: 5 sec)."); writeVerbose(VB_NONE, " SEND_DELAY:? "); writeVerbose(VB_NONE, " Sets the number of microseconds to wait between sending queries (default: 200 usec)."); writeVerbose(VB_NONE, " VERSION:? (1*, 2C)"); writeVerbose(VB_NONE, " Set the SNMP client version."); writeVerbose(VB_NONE, " ACCESS:? (READ*, WRITE)"); writeVerbose(VB_NONE, " Set level of access to test for with the community string."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "(*) Default value"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "It should be noted that when testing for WRITE capability, the module will read"); writeVerbose(VB_NONE, "the current value of sysLocation and then write that same value back to the system."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Since SNMP is a UDP-based protocol, there is no handshaking between sending and "); writeVerbose(VB_NONE, "receiving transport-layer entities. Due to this connectionless communication, about"); writeVerbose(VB_NONE, "the only time we know a SNMP service exists, is if we send the correct community"); writeVerbose(VB_NONE, "string and the server sends a response. All other queries result in no response"); writeVerbose(VB_NONE, "whatsoever. The approach we use here is to initially just send all of our SNMP GET"); writeVerbose(VB_NONE, "requests. After that completes, we wait TIMEOUT seconds for any responses. If we"); writeVerbose(VB_NONE, "get any responses back, we examine them to see which community strings were successful."); writeVerbose(VB_NONE, "If ACCESS:WRITE was specified, we check for write access on each of the previously"); writeVerbose(VB_NONE, "successful values. This techique should allow for quick brute forcing. However, one"); writeVerbose(VB_NONE, "should take care with the TIMEOUT and SEND_DELAY values as to avoid causing issues"); writeVerbose(VB_NONE, "with the target service or missing response data."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M snmp -m TIMEOUT:2 -m ACCESS:WRITE\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _SNMP_DATA *psSessionData; psSessionData = malloc(sizeof(_SNMP_DATA)); memset(psSessionData, 0, sizeof(_SNMP_DATA)); psSessionData->nVersion = SNMP_VER_V1; psSessionData->nReadWrite = SNMP_READ; psSessionData->nReadTimeout = RECEIVE_DELAY; psSessionData->nSendDelay = SEND_DELAY; if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inReadTimeout = atoi(pOpt) * 1000000; else writeError(ERR_WARNING, "Method TIMEOUT requires value to be set."); } else if (strcmp(pOpt, "SEND_DELAY") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) psSessionData->nSendDelay = atoi(pOpt); else writeError(ERR_WARNING, "Method TIMEOUT requires value to be set."); } else if (strcmp(pOpt, "VERSION") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method VERSION requires value to be set."); else if ( strcmp(pOpt, "1") == 0 ) psSessionData->nVersion = SNMP_VER_V1; else if ( strcmp(pOpt, "2C") == 0 ) psSessionData->nVersion = SNMP_VER_V2C; else writeError(ERR_WARNING, "Method VERSION requires a value of either \"1\" or \"2C\" to be set."); } else if (strcmp(pOpt, "ACCESS") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method ACCESS requires value to be set."); else if ( strcmp(pOpt, "READ") == 0 ) psSessionData->nReadWrite = SNMP_READ; else if ( strcmp(pOpt, "WRITE") == 0 ) psSessionData->nReadWrite = SNMP_WRITE; else writeError(ERR_WARNING, "Method ACCESS requires value of \"READ\" or \"WRITE\" to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _SNMP_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; int i = 0, nPassCount, nPassCountWrite; char **arrszPassList = NULL; char **arrszPassListWrite = NULL; char *szLocation = NULL; sCredentialSet *psCredSet = NULL; sUser *psUser = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); params.nPort = PORT_SNMP; initConnectionParams(psLogin, ¶ms); writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s", MODULE_NAME, psLogin->psServer->pHostIP); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnectUDP(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = sendRead(hSocket, _psSessionData, psCredSet->pPass); if (nState == FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* don't want to overwhelm the device being tested */ writeError(ERR_DEBUG_MODULE, "Delaying %d microseconds before sending next query.", _psSessionData->nSendDelay); usleep(_psSessionData->nSendDelay); /* initially set all passwords as invalid -- we don't know their validity yet */ psLogin->iResult = LOGIN_RESULT_FAIL; setPassResult(psLogin, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); /* Medusa has exhausted all credential sets and reset psLogin->psUser to NULL. This creates issues as we haven't actually received the responses yet from our SNMP queries. Our solution is to create a temporary sUser structure, which allows us to report on successful community strings via normal methods. */ psUser = malloc(sizeof(sUser)); memset(psUser, 0, sizeof(sUser)); psLogin->psUser = psUser; nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_RUNNING; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } /* check if server responded to GET queries */ if (receiveRequest(hSocket, _psSessionData, &nPassCount, &arrszPassList, &szLocation) == FAILURE) { writeError(ERR_DEBUG_MODULE, "[%s] Failed to find valid READ community string.", MODULE_NAME); return SUCCESS; } for (i=0; i < nPassCount; i++) { writeError(ERR_DEBUG_MODULE, "[%s] Located valid community string (%d/%d): %s.", MODULE_NAME, i+1, nPassCount, arrszPassList[i]); if (_psSessionData->nReadWrite == SNMP_WRITE) { writeError(ERR_DEBUG_MODULE, "[%s] Checking if community string has WRITE access.", MODULE_NAME); /* send SET request to server */ if (sendWrite(hSocket, _psSessionData, arrszPassList[i], szLocation)) { writeError(ERR_ERROR, "[%s] Failed to send SET request.", MODULE_NAME); return FAILURE; } FREE(szLocation); /* check if community string has WRITE access */ if (receiveRequest(hSocket, _psSessionData, &nPassCountWrite, &arrszPassListWrite, &szLocation) == SUCCESS) { writeError(ERR_DEBUG_MODULE, "[%s] Located valid WRITE community string: %s.", MODULE_NAME, arrszPassList[i]); psLogin->iResult = LOGIN_RESULT_SUCCESS; setPassResult(psLogin, arrszPassList[i]); } else { writeError(ERR_ERROR, "[%s] Community string appears to have only READ access.", MODULE_NAME); psLogin->iResult = LOGIN_RESULT_ERROR; setPassResult(psLogin, arrszPassList[i]); } FREE(arrszPassListWrite); } else { writeError(ERR_DEBUG_MODULE, "[%s] Located valid READ community string: %s.", MODULE_NAME, arrszPassList[i]); psLogin->iResult = LOGIN_RESULT_SUCCESS; setPassResult(psLogin, arrszPassList[i]); } FREE(arrszPassList[i]); FREE(szLocation); } if (hSocket > 0) medusaDisconnect(hSocket); FREE(psUser); FREE(psCredSet); FREE(arrszPassList); FREE(arrszPassListWrite); return SUCCESS; } /* Module Specific Functions */ /* http://book.opensourceproject.org.cn/embedded/tcpipembedded/opensource/0061.html The first TLV in the request is called sequence and is used to identify the length of the following TLVs. The sequence type is 0x30 and the next octet is used to decode the length of this TLV. If the length octet has the high-order bit set (0x80), then the length octet masked with 0x7f yields the number of bytes that follow that will make up the value length (in big-endian order). If the high-order bit is not set, then this octet is the length (no length octets follow). Example: 0x30 0x2f 0x02 0x01 0x00 Sequence: 0x30 0x2f Version: 0x02 0x01 0x00 Example: 0x30 0x82 0x00 0x2f 0x02 0x01 0x00 Sequence: 0x30 0x82 0x00 0x2f Version: 0x02 0x01 0x00 */ int parseLength(int nReceiveBufferSize, unsigned char* bufReceive) { int nLength = 0; int nOctets = 0; if (bufReceive[0] == 0x30) { if (bufReceive[1] & 0x80) /* multi-octet mode */ { nOctets = bufReceive[1] & 0x7f; /* limited to 4 octets worth of length data */ if (nOctets == 1) nLength = bufReceive[2]; else if (nOctets == 2) nLength = (bufReceive[2] << 8) + bufReceive[3]; else if (nOctets == 3) nLength = (bufReceive[2] << 16) + (bufReceive[3] << 8) + bufReceive[4]; else if (nOctets == 4) nLength = (bufReceive[2] << 24) + (bufReceive[3] << 16) + (bufReceive[4] << 8) + bufReceive[5]; if ((nLength > 0) && ((bufReceive[2+nOctets] == 0x02) && (bufReceive[2+nOctets+1] == 0x01))) writeError(ERR_DEBUG_MODULE, "[%s] Multi-octet mode length: %d", MODULE_NAME, nLength); else { writeError(ERR_ERROR, "[%s] Failed to parse length or SNMP version (multi-octet mode).", MODULE_NAME); nLength = -1; } } else if ((bufReceive[2] == 0x02) && (bufReceive[3] == 0x01)) /* single octet mode, version check */ { nLength = bufReceive[1]; writeError(ERR_DEBUG_MODULE, "[%s] Single octet mode length: %d", MODULE_NAME, nLength); } else { writeError(ERR_ERROR, "[%s] Failed to parse length or SNMP version.", MODULE_NAME); nLength = -1; } } return nLength; } int countResponses(int nReceiveBufferSize, unsigned char* bufReceive) { int i = 0; int nLength = 0; int nResponseCount = 0; for (i = 0; i < nReceiveBufferSize; i++) { if (bufReceive[i] == 0x30) { nLength = parseLength(nReceiveBufferSize - i, &bufReceive[i]); if (nLength > 0) { writeError(ERR_DEBUG_MODULE, "[%s] Located start of SNMP response (%d bytes).", MODULE_NAME, nLength); nResponseCount++; i += nLength; } } } return nResponseCount; } int processResponse(int nReceiveBufferSize, unsigned char* bufReceive, int *nSNMPLength, char** szPassword, char** szLocation) { int i; writeError(ERR_DEBUG_MODULE, "[%s] Parsing SNMP response data.", MODULE_NAME); for (i = 0; i < nReceiveBufferSize; i++) { *nSNMPLength = parseLength(nReceiveBufferSize - i, &bufReceive[i]); if (*nSNMPLength > 0) { writeError(ERR_DEBUG_MODULE, "[%s] Located start of SNMP response (%d bytes).", MODULE_NAME, *nSNMPLength); for (; i < nReceiveBufferSize; i++) { if (bufReceive[i] == 0x04) { writeError(ERR_DEBUG_MODULE, "[%s] Located start of SNMP community string.", MODULE_NAME); if (bufReceive[i+1] > 0) { writeError(ERR_DEBUG_MODULE, "[%s] Located SNMP community string size: %d.", MODULE_NAME, bufReceive[i+1]); *szPassword = malloc(bufReceive[i+1] + 1); memset(*szPassword, 0, bufReceive[i+1] + 1); memcpy(*szPassword, bufReceive + i + 2, bufReceive[i+1]); writeError(ERR_DEBUG_MODULE, "[%s] Located community string: %s.", MODULE_NAME, *szPassword); } else { writeError(ERR_DEBUG_MODULE, "[%s] Failed to locate community string.", MODULE_NAME); return FAILURE; } for (i = i + bufReceive[i + 1]; i + 2 < nReceiveBufferSize; i++) { /* skip community string */ if (bufReceive[i] == 0xa2) { writeError(ERR_DEBUG_MODULE, "[%s] Located PDU Response.", MODULE_NAME); for (; i + 2 < nReceiveBufferSize; i++) { if (bufReceive[i] == 0x02) { writeError(ERR_DEBUG_MODULE, "[%s] Located ID.", MODULE_NAME); for (i = i + (bufReceive[i + 1]); i + 2 < nReceiveBufferSize; i++) { /* skip Request ID */ if ((bufReceive[i] == 0x02) && (bufReceive[i + 1] == 0x01) && (bufReceive[i + 2] == 0x00)) { writeError(ERR_DEBUG_MODULE, "[%s] Located success status flag.", MODULE_NAME); *szLocation = malloc(bufReceive[i + 6 + 14 + 1] + 1); memset(*szLocation, 0, bufReceive[i + 6 + 14 + 1] + 1); memcpy(*szLocation, bufReceive + i + 6 + 14 + 2, bufReceive[i + 6 + 14 + 1]); writeError(ERR_DEBUG_MODULE, "[%s] sysLocation: %s.", MODULE_NAME, *szLocation); return(SUCCESS); } } } } } } } } } } return FAILURE; } int sendRead(int hSocket, _SNMP_DATA* _psSessionData, char* szPassword) { unsigned char* bufSend; int nSendBufferSize = 0; struct _SNMPV1_A { char ID; char len; char ver[3]; char comid; char comlen; } snmpv1_a = { .ID = '\x30', .len = '\x00', .ver = "\x02\x01\x00", /* \x02\x01\x01 for snmp v2c */ .comid = '\x04', .comlen = '\x00' }; struct _SNMPV1_R { char type[2]; char identid[2]; char ident[4]; char errstat[3]; char errind[3]; char objectid[2]; char object[12]; char value[3]; } snmpv1_r = { .type = "\xa0\x1c", /* GET */ .identid = "\x02\x04", .ident = "\x6f\x67\x4e\xe1", /* request id - doesn't matter */ .errstat = "\x02\x01\x00", /* no error */ .errind = "\x02\x01\x00", /* error index 0 */ .objectid = "\x30\x0e", .object = "\x30\x0c\x06\x08\x2b\x06\x01\x02\x01\x01\x06\x00", /* sysLocation */ .value = "\x05\x00" /* we just read, so value = 0 */ }; if (_psSessionData->nVersion == SNMP_VER_V2C) snmpv1_a.ver[2] = '\x01'; /* GET system.sysLocation */ nSendBufferSize = sizeof(snmpv1_a) + sizeof(snmpv1_r) + strlen(szPassword); snmpv1_a.comlen = (char) strlen(szPassword); snmpv1_a.len = nSendBufferSize - 3; bufSend = malloc(nSendBufferSize); memset(bufSend, 0, nSendBufferSize); memcpy(bufSend, &snmpv1_a, sizeof(snmpv1_a)); memcpy(bufSend + sizeof(snmpv1_a), szPassword, strlen(szPassword)); memcpy(bufSend + sizeof(snmpv1_a) + strlen(szPassword), &snmpv1_r, sizeof(snmpv1_r)); writeError(ERR_DEBUG_MODULE, "[%s] Sending GET request for system.sysLocation.", MODULE_NAME); if (medusaSend(hSocket, bufSend, nSendBufferSize - 1, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); free(bufSend); return(FAILURE); } free(bufSend); return(MSTATE_RUNNING); } int sendWrite(int hSocket, _SNMP_DATA* _psSessionData, char* szPassword, char* szLocation) { unsigned char* bufSend; int nSendBufferSize = 0; struct _SNMPV1_A { char ID; char len; char ver[3]; char comid; char comlen; } snmpv1_a = { .ID = '\x30', .len = '\x00', .ver = "\x02\x01\x00", /* \x02\x01\x01 for snmp v2c */ .comid = '\x04', .comlen = '\x00' }; struct _SNMPV1_W { char type[2]; char identid[2]; char ident[4]; char errstat[3]; char errind[3]; char objectid[2]; char object[12]; char value[2]; } snmpv1_w = { .type = "\xa3\x20", /* SET */ .identid = "\x02\x04", .ident = "\x6f\x67\x4e\xe1", /* request id - doesn't matter */ .errstat = "\x02\x01\x00", /* no error */ .errind = "\x02\x01\x00", /* error index 0 */ .objectid = "\x30\x0c", .object = "\x30\x0c\x06\x08\x2b\x06\x01\x02\x01\x01\x06\x00", /* sysLocation */ .value = "\x04\x00" /* write value */ }; if (_psSessionData->nVersion == SNMP_VER_V2C) snmpv1_a.ver[2] = '\x01'; if (szLocation == NULL) szLocation = ""; nSendBufferSize = sizeof(snmpv1_a) + sizeof(snmpv1_w) + strlen(szPassword) + strlen(szLocation) + 1; snmpv1_a.comlen = (char) strlen(szPassword); snmpv1_a.len = nSendBufferSize - 3; bufSend = malloc(nSendBufferSize); memset(bufSend, 0, nSendBufferSize); memcpy(bufSend, &snmpv1_a, sizeof(snmpv1_a)); memcpy(bufSend + sizeof(snmpv1_a), szPassword, strlen(szPassword)); memcpy(bufSend + sizeof(snmpv1_a) + strlen(szPassword), &snmpv1_w, sizeof(snmpv1_w)); memset(bufSend + sizeof(snmpv1_a) + strlen(szPassword) + 1, 28 + strlen(szLocation), 1); /* set length remaining */ memset(bufSend + sizeof(snmpv1_a) + strlen(szPassword) + 15, 14 + strlen(szLocation), 1); /* set length remaining */ memset(bufSend + sizeof(snmpv1_a) + strlen(szPassword) + 17, 12 + strlen(szLocation), 1); /* set length remaining */ memset(bufSend + sizeof(snmpv1_a) + strlen(szPassword) + sizeof(snmpv1_w) - 1, strlen(szLocation), 1); strncpy(bufSend + sizeof(snmpv1_a) + strlen(szPassword) + sizeof(snmpv1_w), szLocation, strlen(szLocation)); writeError(ERR_DEBUG_MODULE, "[%s] Sending SET request for system.sysLocation.", MODULE_NAME); if (medusaSend(hSocket, bufSend, nSendBufferSize - 1, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); free(bufSend); return(FAILURE); } free(bufSend); return(SUCCESS); } int receiveRequest(int hSocket, _SNMP_DATA* _psSessionData, int* nPassCount, char*** arrszPassList, char** szLocation) { unsigned char *bufReceive, *bufReceiveTmp; int i, nReceiveBufferSize, nReceiveBufferSizeTmp; int nResponse, nSNMPLength; char *szPasswordTmp1 = NULL; char *szPasswordTmp2 = NULL; nReceiveBufferSize = 0; bufReceive = medusaReceiveRawDelay(hSocket, &nReceiveBufferSize, _psSessionData->nReadTimeout, _psSessionData->nReadTimeout); if (bufReceive == NULL) { writeError(ERR_DEBUG_MODULE, "[%s] No data received. Possible incorrect community string.", MODULE_NAME); return(FAILURE); } *nPassCount = countResponses(nReceiveBufferSize, bufReceive); if (*nPassCount <= 0) { writeError(ERR_ERROR, "[%s] Responses received, however, no community strings were located.", MODULE_NAME); return(FAILURE); } else { writeError(ERR_DEBUG_MODULE, "[%s] Creating password array for %d entries.", MODULE_NAME, *nPassCount); *arrszPassList = malloc(*nPassCount * sizeof(char*)); memset(*arrszPassList, 0, *nPassCount * sizeof(char*)); } bufReceiveTmp = bufReceive; nReceiveBufferSizeTmp = nReceiveBufferSize; for (i = 0; i < *nPassCount; i++) { writeError(ERR_DEBUG_MODULE, "[%s] Retrieving data for response: %d.", MODULE_NAME, i+1); nResponse = processResponse(nReceiveBufferSizeTmp, bufReceiveTmp, &nSNMPLength, &(*arrszPassList)[i], szLocation); if (nResponse == SUCCESS) { writeError(ERR_DEBUG_MODULE, "[%s] Retrieved SNMP data (%d bytes). Community String: %s Location: %s.", MODULE_NAME, nSNMPLength, (*arrszPassList)[i], *szLocation); } else writeError(ERR_ERROR, "[%s] Error processing SNMP response (%d).", MODULE_NAME, i+1); bufReceiveTmp += (nSNMPLength + 2); nReceiveBufferSizeTmp -= (nSNMPLength + 2); } free(bufReceive); return(nResponse); } medusa-2.1.1/src/modsrc/cvs.c0000644000175000001440000002723511723732127012741 00000000000000/* ** CVS pserver Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ** Hydra 5.2 [van Hauser ] ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "cvs.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for CVS sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: cvs.c 1301 2010-02-09 22:54:18Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_CVS 2401 typedef struct __CVS_DATA { char *szDir; } _CVS_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _CVS_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _CVS_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " DIR:? "); writeVerbose(VB_NONE, " Sets target directory name. If left unset, the default is \"/root\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M cvs -m DIR:/some_project\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _CVS_DATA *psSessionData; psSessionData = malloc(sizeof(_CVS_DATA)); memset(psSessionData, 0, sizeof(_CVS_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszDir = malloc(strlen(pOpt) + 1); memset(psSessionData->szDir, 0, (strlen(pOpt) + 1)); strncpy((char *)psSessionData->szDir, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method DIR requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return 0; } int initModule(sLogin* psLogin, _CVS_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_CVS; initConnectionParams(psLogin, ¶ms); /* set directory name, if not specified by user */ if (_psSessionData->szDir == NULL) { _psSessionData->szDir = malloc(6); memset(_psSessionData->szDir, 0, 6); sprintf(_psSessionData->szDir, "/root"); } writeError(ERR_DEBUG_MODULE, "[%s] Set directory name: %s", MODULE_NAME, _psSessionData->szDir); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int tryLogin(int hSocket, sLogin** psLogin, _CVS_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet, i, nSendBufferSize, nReceiveBufferSize; char* bufReceive; char *szAuth, *szPassTmp; /* evil cvs encryption sheme... 0 111 P 125 p 58 ! 120 1 52 A 57 Q 55 a 121 q 113 " 53 2 75 B 83 R 54 b 117 r 32 3 119 C 43 S 66 c 104 s 90 4 49 D 46 T 124 d 101 t 44 % 109 5 34 E 102 U 126 e 100 u 98 & 72 6 82 F 40 V 59 f 69 v 60 ' 108 7 81 G 89 W 47 g 73 w 51 ( 70 8 95 H 38 X 92 h 99 x 33 ) 64 9 65 I 103 Y 71 i 63 y 97 * 76 : 112 J 45 Z 115 j 94 z 62 + 67 ; 86 K 50 k 93 , 116 < 118 L 42 l 39 - 74 = 110 M 123 m 37 . 68 > 122 N 91 n 61 / 87 ? 105 O 35 _ 56 o 48 */ char key[] = { 0, 120, 53, 0, 0, 109, 72, 108, 70, 64, 76, 67, 116, 74, 68, 87, 111, 52, 75, 119, 49, 34, 82, 81, 95, 65, 112, 86, 118, 110, 122, 105, 0, 57, 83, 43, 46, 102, 40, 89, 38, 103, 45, 50, 42, 123, 91, 35, 125, 55, 54, 66, 124, 126, 59, 47, 92, 71, 115, 0, 0, 0, 0, 56, 0, 121, 117, 104, 101, 100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48, 58, 113, 32, 90, 44, 98, 60, 51, 33, 97, 62 }; /* 92 characters */ if (strlen(szPassword) > 92) { writeError(ERR_ERROR, "[%s] Password must be limited to 92 or less characters.", MODULE_NAME); return FAILURE; } szPassTmp = malloc(strlen(szPassword) + 1); memset(szPassTmp, 0, strlen(szPassword) + 1); strncpy(szPassTmp, szPassword, strlen(szPassword)); for (i = 0; i < strlen(szPassTmp); i++) szPassTmp[i] = key[szPassTmp[i] - 0x20]; nSendBufferSize = strlen(_psSessionData->szDir) + strlen(szLogin) + strlen(szPassTmp) + 56; szAuth = malloc(nSendBufferSize + 1); memset(szAuth, 0, nSendBufferSize + 1); sprintf(szAuth, "BEGIN VERIFICATION REQUEST\n%s\n%s\nA%s\nEND VERIFICATION REQUEST\n", _psSessionData->szDir, szLogin, szPassTmp); if (medusaSend(hSocket, szAuth, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; if (strstr(bufReceive, "I LOVE YOU\n")) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else if (strstr(bufReceive, "E PAM start error: Critical error - immediate abort\n")) { writeError(ERR_ERROR, "[%s] User (%s) does not exist.", MODULE_NAME, szLogin); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else if (strstr(bufReceive, "I HATE YOU\n")) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { writeError(ERR_ERROR, "[%s] Unknown Error Message: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } setPassResult((*psLogin), szPassword); free(szPassTmp); free(szAuth); return(iRet); } medusa-2.1.1/src/modsrc/ftp.c0000644000175000001440000004552211723732127012736 00000000000000/* ** FTP Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** CHANGE LOG ** 09/2007 - FTPS Support Added by JoMo-Kun ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "ftp.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for FTP/FTPS sessions" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: ftp.c 1665 2012-02-09 19:35:40Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define BUF_SIZE 300 #define PORT_FTP 21 #define PORT_FTPS 990 #define AUTH_NORMAL 0 #define AUTH_EXPLICIT 1 #define AUTH_IMPLICIT 2 typedef struct __MODULE_DATA { sConnectParams *params; int nAuthType; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initAuthSSL(int hSocket, _MODULE_DATA* _psSessionData); int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA* _psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, "MODE:? (NORMAL*, EXPLICIT, IMPLICIT)"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " EXPLICIT: AUTH TLS Mode as defined in RFC 4217"); writeVerbose(VB_NONE, " Explicit FTPS (FTP/SSL) connects to a FTP service in the clear. Prior to"); writeVerbose(VB_NONE, " sending any credentials, however, an \"AUTH TLS\" command is issued and a"); writeVerbose(VB_NONE, " SSL session is negotiated."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " IMPLICIT: FTP over SSL (990/tcp)"); writeVerbose(VB_NONE, " Implicit FTPS requires a SSL handshake to be performed before any FTP"); writeVerbose(VB_NONE, " commands are sent. This service typically resides on tcp/990. If the user"); writeVerbose(VB_NONE, " specifies this option or uses the \"-n\" (SSL) option, the module will"); writeVerbose(VB_NONE, " default to this mode and tcp/990."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " NORMAL"); writeVerbose(VB_NONE, " The default behaviour if no MODE is specified. Authentication is attempted"); writeVerbose(VB_NONE, " in the clear. If the server requests encryption for the given user,"); writeVerbose(VB_NONE, " Explicit FTPS is utilized."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Example Usage:"); writeVerbose(VB_NONE, " medusa -M ftp -h host -u username -p password"); writeVerbose(VB_NONE, " medusa -M ftp -s -h host -u username -p password"); writeVerbose(VB_NONE, " medusa -M ftp -m MODE:EXPLICIT -h host -u username -p password"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "(*) Default value"); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inAuthType = AUTH_EXPLICIT; else if (strcmp(pOpt, "IMPLICIT") == 0) psSessionData->nAuthType = AUTH_IMPLICIT; else if (strcmp(pOpt, "NORMAL") == 0) psSessionData->nAuthType = AUTH_NORMAL; else writeError(ERR_WARNING, "Invalid value for method MODE."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; unsigned char* bufReceive; int nReceiveBufferSize = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } _psSessionData->params = malloc( sizeof(sConnectParams) ); memset(_psSessionData->params, 0, sizeof(sConnectParams)); if (_psSessionData->nAuthType == AUTH_IMPLICIT) { psLogin->psServer->psHost->iUseSSL = 1; _psSessionData->params->nPort = PORT_FTPS; } else { _psSessionData->params->nPort = PORT_FTP; } if (psLogin->psServer->psAudit->iPortOverride > 0) _psSessionData->params->nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) _psSessionData->params->nPort = PORT_FTPS; initConnectionParams(psLogin, _psSessionData->params); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(_psSessionData->params); else hSocket = medusaConnect(_psSessionData->params); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, _psSessionData->params->nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* establish initial connection */ /* http://www.faqs.org/rfcs/rfc959.html Thus the format for multi-line replies is that the first line will begin with the exact required reply code, followed immediately by a Hyphen, "-" (also known as Minus), followed by text. The last line will begin with the same code, followed immediately by Space , optionally some text, and the Telnet end-of-line code. */ writeError(ERR_DEBUG_MODULE, "[%s] Retrieving FTP banner.", MODULE_NAME); bufReceive = NULL; nReceiveBufferSize = 0; /* Grab entire banner and verify format */ if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] failed: Server sent unknown response. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } if (strncmp(bufReceive, "220", 3) == 0) { writeError(ERR_DEBUG_MODULE, "[%s] Server sent 220 response.", MODULE_NAME); FREE(bufReceive); } else if (strncmp(bufReceive, "421", 3) == 0) { writeError(ERR_ERROR, "[%s] Server sent 421 response (too many connections).", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { writeError(ERR_ERROR, "[%s] Server sent unknown response code: %c%c%c", MODULE_NAME, bufReceive[0], bufReceive[1], bufReceive[2]); FREE(bufReceive); return FAILURE; } /* Establish Explicit FTPS mode authentication if requested */ if (_psSessionData->nAuthType == AUTH_EXPLICIT) { if (initAuthSSL(hSocket, _psSessionData) == FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; } } nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: /* The FTP service may be configured to drop connections after an arbitrary number of failed logon attempts. We will reuse the established connection to send authentication attempts until that disconnect happens. At that point the connection should be reestablished. */ if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) ) { nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nState = MSTATE_NEW; if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int initAuthSSL(int hSocket, _MODULE_DATA* _psSessionData) { unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive = NULL; int nReceiveBufferSize; writeError(ERR_NOTICE, "[%s] Establishing Explicit FTPS (FTP/SSL) session.", MODULE_NAME); memset(bufSend, 0, BUF_SIZE); sprintf(bufSend, "AUTH TLS\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] failed: Server sent unknown or no response. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* 234 Proceed with negotiation. */ if (strncmp(bufReceive, "234 ", 4) == 0) { FREE(bufReceive); if (medusaConnectSocketSSL(_psSessionData->params, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish SSL connection.", MODULE_NAME); return FAILURE; } } else { writeError(ERR_ERROR, "[%s] Failed to establish SSL connection. Server sent response: %c%c%c", MODULE_NAME, bufReceive[0], bufReceive[1], bufReceive[2]); return FAILURE; } return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; /* send username */ memset(bufSend, 0, sizeof(bufSend)); sprintf(bufSend, "USER %.250s\r\n", szLogin); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server sent unknown or no response. Server may have dropped connection due to lack of encryption or due to anti-bruteforce measures. Enabling EXPLICIT mode may help with the former cause and increasing the socket check delay (e.g. -c 1000) may help with the later.", MODULE_NAME); return FAILURE; } /* FTP service may be configured to require protected authentication for specific users */ if ( (strstr(bufReceive, "530 Non-anonymous sessions must use encryption.") != NULL) || (strstr(bufReceive, "331 Non-anonymous sessions must use encryption.") != NULL) || (strstr(bufReceive, "331 Rejected--secure connection required") != NULL) ) { writeError(ERR_NOTICE, "[%s] FTP server (%s) appears to require SSL for specified user.", MODULE_NAME, (*psLogin)->psServer->pHostIP); FREE(bufReceive); if ( medusaCheckSocket(hSocket, (*psLogin)->psServer->psAudit->iSocketWait) ) { writeError(ERR_DEBUG_MODULE, "[%s] Checking socket status: OK", MODULE_NAME); if (initAuthSSL(hSocket, _psSessionData) == FAILURE) return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "[%s] Checking socket status: FAIL - restart connection", MODULE_NAME); _psSessionData->nAuthType = AUTH_EXPLICIT; return MSTATE_NEW; } /* re-send username */ memset(bufSend, 0, sizeof(bufSend)); sprintf(bufSend, "USER %.250s\r\n", szLogin); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server sent unknown or no response. Exiting...", MODULE_NAME); return FAILURE; } } /* Standard FTP [PR85] specifies a 530 response to the USER command when the username is rejected. "Not logged in." */ if (strncmp(bufReceive, "530 ", 4) == 0) { writeError(ERR_ERROR, "[%s] Server sent 530 response (rejected username).", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* 421 There are too many connections from your internet address. */ else if (strncmp(bufReceive, "421 ", 4) == 0) { writeError(ERR_ERROR, "[%s] Server sent 421 response (too many connections).", MODULE_NAME); FREE(bufReceive); return MSTATE_EXITING; } /* Expect: "331 Please specify the password." */ else if (strncmp(bufReceive, "331 ", 4) != 0) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with a '331'.", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); /* send password */ memset(bufSend, 0, sizeof(bufSend)); sprintf(bufSend, "PASS %.250s\r\n", szPassword); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } if (bufReceive[0] == '2') { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; /* Restarting session for now as it's currently faster when dealing with anti-bruteforce services */ iRet = MSTATE_NEW; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } medusa-2.1.1/src/modsrc/http.c0000644000175000001440000010775311723732127013131 00000000000000/*************************************************************************** * http.c * * Copyright (C) 2009 by fizzgig * * fizzgig@foofus.net * * * * Implementation of a http brute force module for * * medusa. Module concept by the one-and-only Foofus. * * Protocol stuff based on the original hydra telnet code by * * VanHauser and the good folks at thc (vh@thc.org) * * * * * * CHANGE LOG * * 04/15/2005 - Created by fizzgig (fizzgig@foofus.net) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2, * * as published by the Free Software Foundation * * * * 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. See the * * GNU General Public License for more details. * * * * http://www.gnu.org/licenses/gpl.txt * * * * This program is released under the GPL with the additional exemption * * that compiling, linking, and/or using OpenSSL is allowed. * * * * Modifications: (JoMo-Kun) * * Support for user specified URL/User-Agent * * Replaced Base64 function from Hydra with Wget version * * Hydra Base64 appears partially broken... * * Added NTLM authentication using code from Wget * * Wget came be found here: http://wget.sunsite.dk/ * * * ***************************************************************************/ #include "module.h" #define MODULE_NAME "http.mod" #define MODULE_AUTHOR "fizzgig " #define MODULE_SUMMARY_USAGE "Brute force module for HTTP" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: http.c 1673 2012-02-14 00:03:14Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define OPENSSL_WARNING "No usable OPENSSL. Module disabled." #ifdef HAVE_LIBSSL #include "ntlm.h" #include "http-digest.h" #define PORT_HTTP 80 #define PORT_HTTPS 443 #define AUTH_UNKNOWN 0 #define AUTH_NONE 1 #define AUTH_BASIC 2 #define AUTH_NTLM 3 #define AUTH_DIGEST 4 typedef struct __MODULE_DATA { char *szDomain; char *szDir; char *szHostHeader; char *szUserAgent; int nAuthType; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum HTTP_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int getAuthType(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, int nPort); int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, int nPort, char* szLogin, char* szPassword); int initModule(_MODULE_DATA* _psSessionData, sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " USER-AGENT:? (User-Agent. Default: Teh Forest Lobster.)"); writeVerbose(VB_NONE, " DIR:? (Target directory. Default \"/\")"); writeVerbose(VB_NONE, " AUTH:? (Authentication Type (BASIC/DIGEST/NTLM). Default: automatic)"); writeVerbose(VB_NONE, " DOMAIN:? [optional]"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M http -m USER-AGENT:\"g3rg3 gerg\" -m DIR:exchange/\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !( 0 <= argc <= 2) ) { // Show usage information writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module.", MODULE_NAME); return FAILURE; } else { // Parameters are good - make module go now writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszDir = malloc(strlen(pOpt) + 1); memset(psSessionData->szDir, 0, strlen(pOpt) + 1); strncpy(psSessionData->szDir, pOpt, strlen(pOpt) + 1); } else writeError(ERR_WARNING, "Method DIR requires value to be set."); } else if (strcmp(pOpt, "USER-AGENT") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szUserAgent = malloc(strlen(pOpt) + 1); memset(psSessionData->szUserAgent, 0, strlen(pOpt) + 1); strncpy(psSessionData->szUserAgent, pOpt, strlen(pOpt) + 1); } else writeError(ERR_WARNING, "Method USER-AGENT requires value to be set."); } else if (strcmp(pOpt, "AUTH") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method AUTH requires value to be set."); else if (strcmp(pOpt, "BASIC") == 0) psSessionData->nAuthType = AUTH_BASIC; else if (strcmp(pOpt, "DIGEST") == 0) psSessionData->nAuthType = AUTH_DIGEST; else if (strcmp(pOpt, "NTLM") == 0) psSessionData->nAuthType = AUTH_NTLM; else writeError(ERR_WARNING, "Invalid value for method AUTH."); } else if (strcmp(pOpt, "DOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDomain = malloc(strlen(pOpt) + 1); memset(psSessionData->szDomain, 0, strlen(pOpt) + 1); strncpy((char *) psSessionData->szDomain, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } FREE(pOptTmp); } initModule(psSessionData, logins); } FREE(psSessionData->szDir); FREE(psSessionData->szUserAgent); FREE(psSessionData->szDomain); FREE(psSessionData); return SUCCESS; } int initModule(_MODULE_DATA *_psSessionData, sLogin* _psLogin) { int hSocket = -1; enum HTTP_STATE nState = MSTATE_NEW; int nBufLength = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, _psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME, _psLogin->psServer->pHostIP); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (_psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = _psLogin->psServer->psAudit->iPortOverride; else if (_psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_HTTPS; else params.nPort = PORT_HTTP; initConnectionParams(_psLogin, ¶ms); /* Set request parameters */ if (!_psSessionData->szDir) { _psSessionData->szDir = malloc(1); memset(_psSessionData->szDir, 0, 1); } if (!_psSessionData->szHostHeader) { nBufLength = strlen(_psLogin->psServer->psHost->pHost) + 1 + log(params.nPort) + 1; _psSessionData->szHostHeader = malloc(nBufLength + 1); memset(_psSessionData->szHostHeader, 0, nBufLength + 1); sprintf(_psSessionData->szHostHeader, "%s:%d", _psLogin->psServer->psHost->pHost, params.nPort); } if (!_psSessionData->szUserAgent) { _psSessionData->szUserAgent = malloc(19); memset(_psSessionData->szUserAgent, 0, 19); sprintf(_psSessionData->szUserAgent, "Teh Forest Lobster"); } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (_psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* Get required authorization method */ if (_psSessionData->nAuthType == AUTH_UNKNOWN) { if ((getAuthType(hSocket, _psSessionData, &_psLogin, params.nPort) == FAILURE) || (_psSessionData->nAuthType == AUTH_UNKNOWN)) { _psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } nState = MSTATE_NEW; } else nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, _psSessionData, &_psLogin, params.nPort, psCredSet->psUser->pUser, psCredSet->pPass); if (_psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown HTTP module state (%d). Exiting...", nState); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; break; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int getAuthType(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, int nPort) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; nSendBufferSize = 5 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 4; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "GET /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n", _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent); writeError(ERR_DEBUG_MODULE, "[%s] Sending initial non-authentication request: %s", MODULE_NAME, bufSend); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "HTTP/1.* .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received: %s", MODULE_NAME, bufReceive); return FAILURE; } writeError(ERR_DEBUG_MODULE, "[%s] Parsing authentication header: %s", MODULE_NAME, bufReceive); if ((strcasestr(bufReceive, "WWW-Authenticate: Basic")) || (strcasestr(bufReceive, "WWW-Authenticate:Basic"))) { writeError(ERR_DEBUG_MODULE, "[%s] Server requested basic authentication.", MODULE_NAME); _psSessionData->nAuthType = AUTH_BASIC; } else if ((strcasestr(bufReceive, "WWW-Authenticate: NTLM")) || (strcasestr(bufReceive, "WWW-Authenticate:NTLM"))) { writeError(ERR_DEBUG_MODULE, "[%s] Server requested integrated windows authentication.", MODULE_NAME); _psSessionData->nAuthType = AUTH_NTLM; } else if ((strcasestr(bufReceive, "WWW-Authenticate: Digest")) || strcasestr(bufReceive, "WWW-Authenticate:Digest")) { writeError(ERR_DEBUG_MODULE, "[%s] Server requested digest authentication.", MODULE_NAME); _psSessionData->nAuthType = AUTH_DIGEST; } else if (strcasestr(bufReceive, "WWW-Authenticate:")) { writeError(ERR_ERROR, "[%s] Server requested unknown authentication type.", MODULE_NAME); _psSessionData->nAuthType = AUTH_UNKNOWN; } else { writeError(ERR_DEBUG_MODULE, "[%s] No authentication header located.", MODULE_NAME); _psSessionData->nAuthType = AUTH_NONE; } FREE(bufReceive); return(SUCCESS); } int sendAuthBasic(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* szEncodedAuth = NULL; unsigned char* szLoginDomain = NULL; int nSendBufferSize = 0; int nRet = SUCCESS; if (_psSessionData->szDomain) { /* DOMAIN\USERNAME */ szLoginDomain = malloc(strlen(_psSessionData->szDomain) + 1 + strlen(szLogin) + 1); memset(szLoginDomain, 0, strlen(_psSessionData->szDomain) + 1 + strlen(szLogin) + 1); sprintf(szLoginDomain, "%s\\%s", _psSessionData->szDomain, szLogin); } else szLoginDomain = szLogin; writeError(ERR_DEBUG_MODULE, "[%s] Base64 encoding: %s:%s", MODULE_NAME, szLoginDomain, szPassword); szEncodedAuth = basic_authentication_encode(szLoginDomain, szPassword); writeError(ERR_DEBUG_MODULE, "[%s] Base64 encoded data is: %s", MODULE_NAME, szEncodedAuth); if (_psSessionData->szDomain) FREE(szLoginDomain); nSendBufferSize = 5 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 23 + strlen(szEncodedAuth) + 4; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "GET /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nAuthorization: Basic %s\r\n\r\n", _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, szEncodedAuth); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); nRet = FAILURE; } FREE(szEncodedAuth); FREE(bufSend); return nRet; } int sendAuthNTLM(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; tSmbNtlmAuthRequest sTmpReq; tSmbNtlmAuthChallenge sTmpChall; tSmbNtlmAuthResponse sTmpResp; unsigned char *szTmpBuf = NULL; unsigned char *szTmpBuf64 = NULL; /* --- Send Type-1 NTLM request --- */ buildAuthRequest(&sTmpReq, 0, NULL, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpReq) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpReq) + 2); base64_encode((char *)&sTmpReq, SmbLength(&sTmpReq), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] Sending initial challenge (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = 5 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 22 + strlen(szTmpBuf64) + 28; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "GET /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nAuthorization: NTLM %s\r\nConnection: keep-alive\r\n\r\n", _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, szTmpBuf64); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szTmpBuf64); FREE(bufSend); /* --- Retrieve NTLM challenge from server --- */ if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "HTTP/1.* .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received: %s", MODULE_NAME, bufReceive); return FAILURE; } if (bufReceive[0] == '\0') { writeError(ERR_ERROR, "[%s] Service did not respond to our authentication request.", MODULE_NAME); return FAILURE; } /* --- Extract NTLM challenge from Type-2 NTLM response --- */ szTmpBuf64 = (char *)strcasestr(bufReceive, "WWW-Authenticate: NTLM "); if (szTmpBuf64 == NULL) { writeError(ERR_ERROR, "[%s] Failed to locate NTLM challenge within server response.", MODULE_NAME); return FAILURE; } szTmpBuf = ((char*)index(szTmpBuf64, '\r')); szTmpBuf[0] = '\0'; writeError(ERR_DEBUG_MODULE, "[%s] NTLM Challenge (B64 Encoded): %s", MODULE_NAME, szTmpBuf64 + 23); base64_decode(szTmpBuf64 + 23, (char *)&sTmpChall); FREE(bufReceive); /* --- Send Type-3 NTLM reply --- */ buildAuthResponse(&sTmpChall, &sTmpResp, 0, szLogin, szPassword, _psSessionData->szDomain, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpResp) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpResp) + 2); base64_encode((char *)&sTmpResp, SmbLength(&sTmpResp), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] NTLM Response (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = 5 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 22 + strlen(szTmpBuf64) + 23; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "GET /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nAuthorization: NTLM %s\r\nConnection: close\r\n\r\n", _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, szTmpBuf64); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szTmpBuf64); FREE(bufSend); return SUCCESS; } /* http://www.ietf.org/rfc/rfc2617.txt */ int sendAuthDigest(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; int i; unsigned char *szTmp = NULL; unsigned char *szTmp1 = NULL; unsigned char *szAuthenticate = NULL; unsigned char *szAuthorization = NULL; char *szNonce = NULL; char *szCNonce = "31337"; char *szRealm = NULL; char *szAlg = NULL; char szNonceCount[9] = "00000001"; char *szMethod = "GET"; char *szQop = NULL; char *szURI = NULL; char *szOpaque = NULL; HASHHEX HA1; HASHHEX HA2 = ""; HASHHEX Response; /* uri should start with a "/" */ if (strncmp(_psSessionData->szDir, "/", 1) == 0) { szURI = malloc(strlen(_psSessionData->szDir) + 1); memset(szURI, 0, strlen(_psSessionData->szDir) + 1); strncat(szURI, _psSessionData->szDir, strlen(_psSessionData->szDir)); } else { szURI = malloc(1 + strlen(_psSessionData->szDir) + 1); memset(szURI, 0, 1 + strlen(_psSessionData->szDir) + 1); strncat(szURI, "/", 1); strncat(szURI, _psSessionData->szDir, strlen(_psSessionData->szDir)); } /* Send initial request */ writeError(ERR_DEBUG_MODULE, "[%s] Sending initial request for digest authentication.", MODULE_NAME); nSendBufferSize = 5 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 28; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "GET /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nConnection: keep-alive\r\n\r\n", _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); /* Retrieve digest challenge from server */ bufReceive = medusaReceiveLine(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] No data received", MODULE_NAME); return FAILURE; } if (bufReceive[0] == '\0') { writeError(ERR_ERROR, "[%s] Failed to locate digest challenge.", MODULE_NAME); return FAILURE; } /* Parse WWW-Authenticate Digest Response */ /* Example: WWW-Authenticate: Digest realm="Inter-Tel 5000 (00103605AB8A)", nonce="86591bebf1330b5e57b8de2e4ac216b2", qop="auth" */ if ( szTmp = (char *)strcasestr(bufReceive, "WWW-Authenticate: Digest ") ) { szTmp += 18; } else if ( szTmp = (char *)strcasestr(bufReceive, "WWW-Authenticate:Digest ") ) { szTmp += 17; } else { writeError(ERR_ERROR, "[%s] Failed to locate digest challenge.", MODULE_NAME); return FAILURE; } szTmp1 = ((char*)index(szTmp, '\r')); szAuthenticate = malloc (szTmp1 - szTmp + 1); memset(szAuthenticate, 0, szTmp1 - szTmp + 1); strncpy(szAuthenticate, szTmp, szTmp1 - szTmp); FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] Server WWW-Authenticate Digest Response: %s", MODULE_NAME, szAuthenticate); /* Extract Digest Algorithm, if Specified */ /* We currently only support MD5 and MD5-Sess (session) - Do others exist? */ if ( strcasestr(szAuthenticate, "algorithm=MD5-sess") || strcasestr(szAuthenticate, "algorithm=\"MD5-sess\"") ) { writeError(ERR_DEBUG_MODULE, "[%s] Server requested Digest MD5-sess algorithm.", MODULE_NAME); szAlg = malloc(9); memset(szAlg, 0, 9); sprintf(szAlg, "MD5-sess"); } else if ( strcasestr(szAuthenticate, "algorithm=MD5") || strcasestr(szAuthenticate, "algorithm=\"MD5\"")) { writeError(ERR_DEBUG_MODULE, "[%s] Server requested Digest MD5 algorithm.", MODULE_NAME); szAlg = malloc(4); memset(szAlg, 0, 4); sprintf(szAlg, "MD5"); } else if ( strcasestr(szAuthenticate, "algorithm=") ) { writeError(ERR_ERROR, "[%s] Server requested unknown Digest algorithm.", MODULE_NAME); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "[%s] Server did not specify a Digest algorithm, so we're assuming MD5.", MODULE_NAME); szAlg = malloc(4); memset(szAlg, 0, 4); sprintf(szAlg, "MD5"); } /* Extract Digest Realm */ szTmp = (char *)strcasestr(szAuthenticate, "realm=\""); if (szTmp) { szTmp += 7; szTmp1 = ((char*)index(szTmp, '"')); szRealm = malloc (szTmp1 - szTmp + 1); memset(szRealm, 0, szTmp1 - szTmp + 1); strncpy(szRealm, szTmp, szTmp1 - szTmp); writeError(ERR_DEBUG_MODULE, "[%s] Extracted Realm Response: %s", MODULE_NAME, szRealm); } else { writeError(ERR_ERROR, "[%s] Failed to extract server Realm response.", MODULE_NAME); szRealm = malloc(1); memset(szRealm, 0, 1); } /* Extract Digest Server Nonce */ szTmp = (char *)strcasestr(szAuthenticate, "nonce=\""); if (szTmp) { szTmp += 7; szTmp1 = ((char*)index(szTmp, '"')); szNonce = malloc (szTmp1 - szTmp + 1); memset(szNonce, 0, szTmp1 - szTmp + 1); strncpy(szNonce, szTmp, szTmp1 - szTmp); writeError(ERR_DEBUG_MODULE, "[%s] Extracted Nonce Response: %s", MODULE_NAME, szNonce); } else { writeError(ERR_ERROR, "[%s] Failed to extract server Nonce response.", MODULE_NAME); szNonce = malloc(1); memset(szNonce, 0, 1); } /* Extract Digest Quality of Protection (QoP) - If Specified */ szTmp = (char *)strcasestr(szAuthenticate, "qop=\""); if (szTmp) { szTmp += 5; szTmp1 = ((char*)index(szTmp, '"')); szQop = malloc (szTmp1 - szTmp + 1); memset(szQop, 0, szTmp1 - szTmp + 1); strncpy(szQop, szTmp, szTmp1 - szTmp); writeError(ERR_DEBUG_MODULE, "[%s] Extracted Quality of Protection (QoP) Response: %s", MODULE_NAME, szQop); } else { writeError(ERR_DEBUG_MODULE, "[%s] Failed to extract server Quality of Protection (QoP) response.", MODULE_NAME); szQop = NULL; } /* Extract Digest Opaque Value - If Specified */ szTmp = (char *)strcasestr(szAuthenticate, "opaque=\""); if (szTmp) { szTmp += 8; szTmp1 = ((char*)index(szTmp, '"')); szOpaque = malloc (szTmp1 - szTmp + 1); memset(szOpaque, 0, szTmp1 - szTmp + 1); strncpy(szOpaque, szTmp, szTmp1 - szTmp); writeError(ERR_DEBUG_MODULE, "[%s] Extracted Server Opaque Value: %s", MODULE_NAME, szOpaque); } else { writeError(ERR_DEBUG_MODULE, "[%s] Failed to extract server Opaque value.", MODULE_NAME); szOpaque = NULL; } FREE(szAuthenticate); /* Send digest response */ /* Example: Authorization: Digest username="it5k", realm="Inter-Tel 5000 (00103605AB8A)", nonce="94144a2abae7411d0f6af2b533425497", uri="/", response="b9c3980ae4e7fb69796772a3bacc5c18"\r\n */ writeError(ERR_DEBUG_MODULE, "[%s] szAlg: %s", MODULE_NAME, szAlg); writeError(ERR_DEBUG_MODULE, "[%s] szLogin: %s", MODULE_NAME, szLogin); writeError(ERR_DEBUG_MODULE, "[%s] szRealm: %s", MODULE_NAME, szRealm); writeError(ERR_DEBUG_MODULE, "[%s] szPassword: %s", MODULE_NAME, szPassword); writeError(ERR_DEBUG_MODULE, "[%s] szNonce: %s", MODULE_NAME, szNonce); writeError(ERR_DEBUG_MODULE, "[%s] szCNonce: %s", MODULE_NAME, szCNonce); writeError(ERR_DEBUG_MODULE, "[%s] szNonceCount: %s", MODULE_NAME, szNonceCount); writeError(ERR_DEBUG_MODULE, "[%s] szQop: %s", MODULE_NAME, szQop); writeError(ERR_DEBUG_MODULE, "[%s] szOpaque: %s", MODULE_NAME, szOpaque); writeError(ERR_DEBUG_MODULE, "[%s] szMethod: %s", MODULE_NAME, szMethod); writeError(ERR_DEBUG_MODULE, "[%s] szURI: %s", MODULE_NAME, szURI); DigestCalcHA1(szAlg, szLogin, szRealm, szPassword, szNonce, szCNonce, HA1); DigestCalcResponse(HA1, szNonce, szNonceCount, szCNonce, szQop, szMethod, szURI, HA2, Response); writeError(ERR_DEBUG_MODULE, "[%s] Calculated Digest Response: %s", MODULE_NAME, Response); /* BASE: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=\"%s\", response=\"%s\" QOP: , qop=%s, nc=%s, cnonce=\"%s\" OPAQUE: , opaque=\"%s\" */ nSendBufferSize = 17 + strlen(szLogin) + 10 + strlen(szRealm) + 10 + strlen(szNonce) + 8 + strlen(szURI) + 14 + strlen(szAlg) + 13 + strlen(Response); /* If the server specified a QoP, the client must use a cnonce */ if ( strcasestr(szQop, "auth-int") ) { writeError(ERR_ERROR, "[%s] Integrity protection (i.e. qop: auth-int) is currently not supported.", MODULE_NAME); return FAILURE; } else if ( strcasestr(szQop, "auth") ) { nSendBufferSize += 7 + strlen(szQop) + 5 + strlen(szNonceCount) + 10 + strlen(szCNonce) + 1; } /* If the server specified an opaque value, that same value should be included in our response. */ if ( szOpaque ) { nSendBufferSize += 10 + strlen(szOpaque) + 1; } szAuthorization = malloc(nSendBufferSize + 1); memset(szAuthorization, 0, nSendBufferSize + 1); if ( (szQop != NULL) && (szOpaque != NULL) ) sprintf(szAuthorization, "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=%s, response=\"%s\", qop=%s, nc=00000001, cnonce=\"%s\", opaque=\"%s\"", szLogin, szRealm, szNonce, szURI, szAlg, Response, szQop, szCNonce, szOpaque); else if (szQop != NULL) sprintf(szAuthorization, "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=%s, response=\"%s\", qop=%s, nc=00000001, cnonce=\"%s\"", szLogin, szRealm, szNonce, szURI, szAlg, Response, szQop, szCNonce); else if (szOpaque != NULL) sprintf(szAuthorization, "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=%s, response=\"%s\", opaque=\"%s\"", szLogin, szRealm, szNonce, szURI, szAlg, Response, szOpaque); else sprintf(szAuthorization, "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=%s, response=\"%s\"", szLogin, szRealm, szNonce, szURI, szAlg, Response); FREE(szAlg); FREE(szRealm); FREE(szNonce); FREE(szQop); FREE(szOpaque); FREE(szURI); nSendBufferSize = 5 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 17 + strlen(szAuthorization) + 28; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "GET /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nAuthorization: %s\r\nConnection: keep-alive\r\n\r\n", _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, szAuthorization); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szAuthorization); FREE(bufSend); } int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, int nPort, char* szLogin, char* szPassword) { unsigned char* pReceiveBuffer = NULL; int nReceiveBufferSize = 0; int nRet = SUCCESS; char* pTemp = NULL; switch(_psSessionData->nAuthType) { case AUTH_NONE: writeError(ERR_DEBUG_MODULE, "[%s] No authentication required.", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; setPassResult(*login, szPassword); return MSTATE_NEW; break; case AUTH_BASIC: writeError(ERR_DEBUG_MODULE, "[%s] Sending Basic Authentication.", MODULE_NAME); nRet = sendAuthBasic(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_NTLM: writeError(ERR_DEBUG_MODULE, "[%s] Sending Windows Integrated (NTLM) Authentication.", MODULE_NAME); nRet = sendAuthNTLM(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_DIGEST: writeError(ERR_DEBUG_MODULE, "[%s] Sending Digest Authentication.", MODULE_NAME); nRet = sendAuthDigest(hSocket, _psSessionData, szLogin, szPassword); break; default: break; } if (nRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &pReceiveBuffer, &nReceiveBufferSize, "HTTP/1.* [0-9]{3,3} .*\r\n") == FAILURE) || (pReceiveBuffer == NULL)) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received: %s", MODULE_NAME, pReceiveBuffer); return FAILURE; } pTemp = strstr(pReceiveBuffer, "HTTP/1."); pTemp = ((char*)index(pTemp, ' ')) + 1; memset(pTemp + 3, 0, 1); switch (atoi(pTemp)) { case 200: writeError(ERR_DEBUG_MODULE, "[%s] 200 OK", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_NEW; break; case 301: writeError(ERR_DEBUG_MODULE, "[%s] 301 Moved Permanently", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_NEW; break; case 302: writeError(ERR_DEBUG_MODULE, "[%s] 302 Found", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_NEW; break; case 401: writeError(ERR_DEBUG_MODULE, "[%s] 401 Unauthorized", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_NEW; break; case 403: writeError(ERR_DEBUG_MODULE, "[%s] 403 Forbidden", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_NEW; break; case 404: writeError(ERR_DEBUG_MODULE, "[%s] 404 Not Found", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_NEW; break; default: writeError(ERR_ERROR, "Unexpected return code for %s:%s (%.3s)", szLogin, szPassword, pTemp); (*login)->pErrorMsg = malloc( 27 + 1 ); memset((*login)->pErrorMsg, 0, 27 + 1 ); sprintf((*login)->pErrorMsg, "Unexpected return code: %.3s", pTemp); (*login)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; break; } FREE(pReceiveBuffer); setPassResult(*login, szPassword); return nRet; } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif medusa-2.1.1/src/modsrc/nntp.c0000644000175000001440000003070511723732127013121 00000000000000/* ** NNTP Password Checking Medusa Module ** ** Original AUTHINFO Mode ** http://www.mibsoftware.com/userkt/nntpext/0032.htm ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "nntp.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for NNTP sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: nntp.c 1301 2010-02-09 22:54:18Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define BUF_SIZE 300 #define PORT_NNTP 119 #define PORT_NNTPS 563 typedef struct __MODULE_DATA { int nMode; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initConnection(int hSocket, sLogin** psLogin); int terminateConnection(int hSocket, sLogin** psLogin); int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M nntp -U accounts.txt -p password\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_NNTPS; else params.nPort = PORT_NNTP; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } nState = initConnection(hSocket, &psLogin); break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) terminateConnection(hSocket, &psLogin); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int terminateConnection(int hSocket, sLogin** psLogin) { unsigned char bufSend[BUF_SIZE]; memset(bufSend, 0, sizeof(bufSend)); sprintf(bufSend, "QUIT\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); } medusaDisconnect(hSocket); return SUCCESS; } int initConnection(int hSocket, sLogin** psLogin) { int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* Retrieve NNTP server banner */ nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] failed: medusaReceive returned no data. Exiting...", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; return MSTATE_EXITING; } else if ((strstr(bufReceive,"200") != NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] Retrieved NNTP service banner.", MODULE_NAME); } /* 400 Too Many Connections */ else if ((strstr(bufReceive,"400") != NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] Too many connections from host recieved by server.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; return MSTATE_EXITING; } else { writeError(ERR_ERROR, "[%s] Failed to retrieve NNTP service banner.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; return MSTATE_EXITING; } /* Verify that authentication is required */ memset(bufSend, 0, sizeof(bufSend)); sprintf(bufSend, "HELP\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; return MSTATE_EXITING; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] failed: medusaReceive returned no data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iRet = MSTATE_EXITING; } /* 480 Authentication Required */ else if (strstr(bufReceive,"480") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Server requires authentication.", MODULE_NAME); iRet = MSTATE_RUNNING; } else { writeError(ERR_ERROR, "[%s] Server does not appear to require authentication.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } return iRet; } int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* send username */ memset(bufSend, 0, sizeof(bufSend)); sprintf(bufSend, "AUTHINFO USER %.250s\r\n", szLogin); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } /* 381 More Authentication Required */ else if (strstr(bufReceive,"381") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Receive 381 response requesting user password.", MODULE_NAME); } else { writeError(ERR_DEBUG_MODULE, "[%s] Server did not send a 381 response. Password authentication for user may not be required.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } /* send password */ memset(bufSend, 0, sizeof(bufSend)); if (strlen(szPassword) == 0) sprintf(bufSend, "AUTHINFO PASS \"\"\r\n"); else sprintf(bufSend, "AUTHINFO PASS %.250s\r\n", szPassword); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } /* 281 Authentication accepted */ else if (strstr(bufReceive,"281") != NULL) { writeError(ERR_ERROR, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } /* 482 Authentication rejected */ else if (strstr(bufReceive,"482") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt rejected.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } /* 501 Bad Command Usage */ else if (strstr(bufReceive,"501") != NULL) { writeError(ERR_ERROR, "[%s] Bad command usage.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } /* 502 Authentication Failed */ else if (strstr(bufReceive,"502") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } else { writeError(ERR_ERROR, "[%s] Unknown server response.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iRet = MSTATE_RUNNING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } medusa-2.1.1/src/modsrc/mssql.c0000644000175000001440000005277711757213244013317 00000000000000/* ** M$-SQL Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ** Hydra 4.7 [van Hauser ] ** Nessus [HD Moore ] ** ** Tested: ** Microsoft SQL Server 2005 9.00.1399; RTM (mixed authentication) ** Microsoft SQL Server 2005 9.00.2047; SP1 (mixed authentication) ** Microsoft SQL Server 2005 9.00.3042; SP2 (mixed authentication) ** ** Notes: ** SQL 2005: SQL logins use the password policy of the underlying operating system ** Windows Authentication mode is selected during installation, the sa login is disabled ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "mssql.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for M$-SQL sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: mssql.c 1719 2012-05-23 16:56:04Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define OPENSSL_WARNING "No usable OPENSSL. Module disabled." #ifdef HAVE_LIBSSL #include #include #define PORT_MSSQL 1433 #define PORT_MSSQLM 1434 #define MSLEN 30 typedef struct __MODULE_DATA { int nPort; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int connectMSSQL(sLogin *psLogin, _MODULE_DATA *_psSessionData); int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA* _psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "NOTE: MS-SQL Developer Edition or MSDE's concurrent workload governor limits you"); writeVerbose(VB_NONE, " to no more than five concurrent connections to the server at any one time."); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; char* bufReceive = NULL; sCredentialSet *psCredSet = NULL; _psSessionData->nPort = 0; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: if ((hSocket = connectMSSQL(psLogin, _psSessionData)) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish MS-SQL connection.", MODULE_NAME); return FAILURE; } nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* MS-SQL Specific Functions */ /* Establish connection to remote MS-SQL server using the following logic: * if the user specified a TCP port, we use it * else if this is a new connection, we send a SQL ping to the SQL monitor port * * if a response is received, we use the port listed for the first SQL instance * (2433/tcp is used if the first instance is "hiding" its port) * * else we use the default port identified by PORT_MSSQL (i.e. 1433/tcp) */ int connectMSSQL(sLogin *_psLogin, _MODULE_DATA *_psSessionData) { sConnectParams params; int nReceiveBufferSize = 0; char *bufReceive = NULL; int nPort = PORT_MSSQL; int nPortTmp = 0; int hSocket; unsigned char pkt_sqlping[] = { 0x02 }; int nPingResponseLen = 0; int nSQLInstance = 0; int nSQLInstancePort = 0; char *szTmp = NULL; char *szTmp1 = NULL; char *szTmp2 = NULL; writeError(ERR_DEBUG_MODULE, "[%s] Querying MS-SQL monitor port to enumerate MS-SQL server TCP port.", MODULE_NAME); /* Query MS-SQL Monitor (SQL Server Browser) port to enumerate MS-SQL server TCP port The MS-SQL server instances and information about those instances for a given system can be enumerated anonymous via a simple query. For additional information about this operation, see "Threat Profiling Microsoft SQL Server" (www.nextgenss.com/papers/tp-SQL2000.pdf). The following are two example responses: Single SQL Server Instance Installation: [0x05][0x76][0x00]ServerName;WIN2K3STD;InstanceName;MSSQLSERVER;IsClustered;No;Version;8.00.194;tcp;1433;np;\\WIN2K3STD\pipe\sql\query;; Three SQL Server Instance Installation (first using port hiding option): [0x05[0x85][0x01]ServerName;WIN2K3STD;InstanceName;MSSQLSERVER;IsClustered;No;Version;8.00.194;np;\\WIN2K3STD\pipe\sql\query;; ServerName;WIN2K3STD;InstanceName;SQL_INSTANCE_2;IsClustered;No;Version;8.00.194;tcp;1308;np;\\WIN2K3STD\pipe\MSSQL$SQL_INSTANCE_2\sql\query;; ServerName;WIN2K3STD;InstanceName;SQLINSTANCE3;IsClustered;No;Version;8.00.194;tcp;1422;np;\\WIN2K3STD\pipe\MSSQL$SQLINSTANCE3\sql\query;; It is assumed the first byte of the response (0x05) signals a valid response. The next two bytes indicate the length of the actual data. For example, [0x85][0x01] -> 0x0185 -> 389 bytes It's possible that if a system has many instances, the UDP packet may exceed our default recv() buffer, or arrive in multiple datagrams. We don't currently handle either of these situations and some of the information would be lost. */ if ((_psLogin->psServer->psAudit->iPortOverride == 0) && (_psSessionData->nPort == 0)) { memset(¶ms, 0, sizeof(sConnectParams)); params.nPort = PORT_MSSQLM; initConnectionParams(_psLogin, ¶ms); hSocket = medusaConnectUDP(¶ms); if (hSocket < 0) { writeError(ERR_ERROR, "[%s] Failed to connect to MS-SQL monitor UDP port (%d). Auto-identification of MS-SQL port unsuccessful on host: %s.", MODULE_NAME, PORT_MSSQLM, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (medusaSend(hSocket, pkt_sqlping, 1, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] SQL server (%s) did not response to port query request. Using default value of 1433/tcp.", MODULE_NAME, _psLogin->psServer->pHostIP); nPort = 1433; } else if (bufReceive[0] == 0x05) { writeError(ERR_DEBUG_MODULE, "[%s] Processing SQL ping response.", MODULE_NAME); nPingResponseLen = ((bufReceive[2] & 0xFF) << 8) | (bufReceive[1] & 0xFF); writeError(ERR_DEBUG_MODULE, "[%s] SQL ping response packet reported data length: %d", MODULE_NAME, nPingResponseLen); if (nReceiveBufferSize != nPingResponseLen + 3) writeError(ERR_ERROR, "[%s] Reported SQL ping data length does not match our receive buffer length. Response data may have been lost.", MODULE_NAME); nSQLInstance = 1; szTmp = bufReceive + 3; while (szTmp = strstr(szTmp, "ServerName;")) { szTmp1 = strstr(szTmp, ";;"); if (szTmp1 == NULL) { writeError(ERR_ERROR, "[%s] Possible incomplete capture of service information on host %s. There may be additional SQL services.", MODULE_NAME, _psLogin->psServer->pHostIP); break; } memset(szTmp1, 0, 1); szTmp1 += 2; writeError(ERR_DEBUG_MODULE, "[%s] SQL server (%s) ping response (instance: %d) - %s", MODULE_NAME, _psLogin->psServer->pHostIP, nSQLInstance, szTmp); /* ServerName;MACHINE_NAME;InstanceName;MICROSOFT##SSEE;IsClustered;No;Version;9.00.4035.00;np; */ if (strstr(szTmp, "InstanceName;MICROSOFT##SSEE") != NULL) { writeError(ERR_ERROR, "[%s] Internal database (SQL Server Embedded Edition) identified (NOT TESTED) - server %s", MODULE_NAME, _psLogin->psServer->psHost->pHost); writeVerbose(VB_NONE_FILE, "[%s] Internal database (SQL Server Embedded Edition) identified (NOT TESTED) - server %s\n", MODULE_NAME, _psLogin->psServer->psHost->pHost); } /* ServerName;MACHINE_NAME;InstanceName;DATABASE_NAME;IsClustered;No;Version;9.00.3042.00 */ else if ((szTmp2 = strstr(szTmp, ";tcp;")) == NULL) { writeError(ERR_ERROR, "[%s] Internal or hidden database identified (NOT TESTED) - server %s. (Default hidden value is 2433/tcp)", MODULE_NAME, _psLogin->psServer->psHost->pHost); writeVerbose(VB_NONE_FILE, "[%s] Internal or hidden database identified (NOT TESTED) - server %s. (Default hidden value is 2433/tcp)\n", MODULE_NAME, _psLogin->psServer->psHost->pHost); } /* ServerName;MACHINE_NAME;InstanceName;MSSQLSERVER;IsClustered;No;Version;8.00.194;tcp;1433;np; */ else { szTmp2 += 5; /* skip ";tcp;" */ if ( index(szTmp2, 0x3B) ) { memset( index(szTmp2, 0x3B), 0, 1); } /* ";" */ nPortTmp = atoi(szTmp2); if (nSQLInstancePort == 0) { nPort = nPortTmp; nSQLInstancePort++; writeError(ERR_DEBUG_MODULE, "[%s] Connecting to SQL server %s on port %d/tcp.", MODULE_NAME, _psLogin->psServer->pHostIP, nPort); } else { writeError(ERR_ERROR, "[%s] Additional SQL server identified (NOT TESTED) - server %s on port %d/tcp", MODULE_NAME, _psLogin->psServer->psHost->pHost, nPortTmp); writeVerbose(VB_NONE_FILE, "[%s] Additional SQL server identified (NOT TESTED) - server %s on port %d/tcp\n", MODULE_NAME, _psLogin->psServer->psHost->pHost, nPortTmp); } } szTmp = szTmp1; nSQLInstance++; } } else { writeError(ERR_ERROR, "[%s] SQL server (%s) sent unknown response to \"SQL Ping\" request.", MODULE_NAME, _psLogin->psServer->pHostIP); } FREE(bufReceive); if (hSocket > 0) medusaDisconnect(hSocket); } else if ((_psLogin->psServer->psAudit->iPortOverride == 0) && (_psSessionData->nPort != 0)) { nPort = _psSessionData->nPort; writeError(ERR_DEBUG_MODULE, "[%s] Using previously set port: %d/tcp", MODULE_NAME, nPort); } memset(¶ms, 0, sizeof(sConnectParams)); if (_psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = _psLogin->psServer->psAudit->iPortOverride; else params.nPort = nPort; initConnectionParams(_psLogin, ¶ms); _psSessionData->nPort = params.nPort; hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] Failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, _psLogin->psServer->psHost->pHost); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } return hSocket; } void makeSQLLogin(char* szLogin, char* szPassword, unsigned char* buffer) { unsigned char pkt_hdr[] = { 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned char pkt_pt2[] = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x61, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x18, 0x81, 0xb8, 0x2c, 0x08, 0x03, 0x01, 0x06, 0x0a, 0x09, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x71, 0x75, 0x65, 0x6c, 0x64, 0x61, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned char pkt_pt3[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x4d, 0x53, 0x44, 0x42, 0x4c, 0x49, 0x42, 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; char ms_login[MSLEN + 1]; char ms_pass[MSLEN + 1]; memset(ms_login, 0, MSLEN + 1); memset(ms_pass, 0, MSLEN + 1); strncpy(ms_login, szLogin, MSLEN); strncpy(ms_pass, szPassword, MSLEN); unsigned char len_login, len_pass; len_login = (unsigned char)strlen(ms_login); len_pass = (unsigned char)strlen(ms_pass); memcpy(buffer, pkt_hdr, 39); memcpy(buffer + 39, ms_login, MSLEN); memcpy(buffer + MSLEN + 39, &len_login, 1); memcpy(buffer + MSLEN + 1 + 39, ms_pass, MSLEN); memcpy(buffer + MSLEN + 1 + 39 + MSLEN, &len_pass, 1); memcpy(buffer + MSLEN + 1 + 39 + MSLEN + 1, pkt_pt2, 110); memcpy(buffer + MSLEN + 1 + 39 + MSLEN + 1 + 110, &len_pass, 1); memcpy(buffer + MSLEN + 1 + 39 + MSLEN + 1 + 110 + 1, ms_pass, MSLEN); memcpy(buffer + MSLEN + 1 + 39 + MSLEN + 1 + 110 + 1 + MSLEN, pkt_pt3, 270); return; } int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet; unsigned char bufSend[3 * MSLEN + 422 + 1]; unsigned char* bufReceive; int nReceiveBufferSize = 0; unsigned char pkt_langp[] = { 0x02, 0x01, 0x00, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00 }; memset(bufSend, 0, 3 * MSLEN + 422 + 1); makeSQLLogin(szLogin, szPassword, bufSend); if (medusaSend(hSocket, bufSend, MSLEN + 1 + 39 + MSLEN + 1 + 110 + 1 + MSLEN + 270, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } if (medusaSend(hSocket, pkt_langp, 71, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { return FAILURE; } writeError(ERR_DEBUG_MODULE, "[tryLogin] medusaReceiveRaw set nReceiveBufferSize: %d", nReceiveBufferSize); if (bufReceive[8] == 0xe3) { (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } writeError(ERR_DEBUG_MODULE, "[tryLogin] set iRet: %d", iRet); FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif medusa-2.1.1/src/modsrc/d3des.c0000644000175000001440000003724711723732127013154 00000000000000 /* 2001 van Hauser for Hydra: commented out KnR Kn3 and Df_Key to remove compiler warnings for unused definitions. */ /* * This is D3DES (V5.09) by Richard Outerbridge with the double and * triple-length support removed for use in VNC. Also the bytebit[] array * has been reversed so that the most significant bit in each byte of the * key is ignored, not the least significant. * * These changes are: * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. * * This software 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. */ /* D3DES (V5.09) - * * A portable, public domain, version of the Data Encryption Standard. * * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau, * for humouring me on. * * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. */ #include "d3des.h" static void scrunch(unsigned char *, unsigned long *); static void unscrun(unsigned long *, unsigned char *); static void desfunc(unsigned long *, unsigned long *); static void cookey(unsigned long *); static unsigned long KnL[32] = { 0L }; /* not needed ... static unsigned long KnR[32] = { 0L }; static unsigned long Kn3[32] = { 0L }; static unsigned char Df_Key[24] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 }; */ static unsigned short bytebit[8] = { 01, 02, 04, 010, 020, 040, 0100, 0200 }; static unsigned long bigbyte[24] = { 0x800000L, 0x400000L, 0x200000L, 0x100000L, 0x80000L, 0x40000L, 0x20000L, 0x10000L, 0x8000L, 0x4000L, 0x2000L, 0x1000L, 0x800L, 0x400L, 0x200L, 0x100L, 0x80L, 0x40L, 0x20L, 0x10L, 0x8L, 0x4L, 0x2L, 0x1L }; /* Use the key schedule specified in the Standard (ANSI X3.92-1981). */ static unsigned char pc1[56] = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; static unsigned char totrot[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 }; static unsigned char pc2[48] = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; void deskey(key, edf) /* Thanks to James Gillogly & Phil Karn! */ unsigned char *key; int edf; { register int i, j, l, m, n; unsigned char pc1m[56], pcr[56]; unsigned long kn[32]; for (j = 0; j < 56; j++) { l = pc1[j]; m = l & 07; pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; } for (i = 0; i < 16; i++) { if (edf == DE1) m = (15 - i) << 1; else m = i << 1; n = m + 1; kn[m] = kn[n] = 0L; for (j = 0; j < 28; j++) { l = j + totrot[i]; if (l < 28) pcr[j] = pc1m[l]; else pcr[j] = pc1m[l - 28]; } for (j = 28; j < 56; j++) { l = j + totrot[i]; if (l < 56) pcr[j] = pc1m[l]; else pcr[j] = pc1m[l - 28]; } for (j = 0; j < 24; j++) { if (pcr[pc2[j]]) kn[m] |= bigbyte[j]; if (pcr[pc2[j + 24]]) kn[n] |= bigbyte[j]; } } cookey(kn); return; } static void cookey(raw1) register unsigned long *raw1; { register unsigned long *cook, *raw0; unsigned long dough[32]; register int i; cook = dough; for (i = 0; i < 16; i++, raw1++) { raw0 = raw1++; *cook = (*raw0 & 0x00fc0000L) << 6; *cook |= (*raw0 & 0x00000fc0L) << 10; *cook |= (*raw1 & 0x00fc0000L) >> 10; *cook++ |= (*raw1 & 0x00000fc0L) >> 6; *cook = (*raw0 & 0x0003f000L) << 12; *cook |= (*raw0 & 0x0000003fL) << 16; *cook |= (*raw1 & 0x0003f000L) >> 4; *cook++ |= (*raw1 & 0x0000003fL); } usekey(dough); return; } void cpkey(into) register unsigned long *into; { register unsigned long *from, *endp; from = KnL, endp = &KnL[32]; while (from < endp) *into++ = *from++; return; } void usekey(from) register unsigned long *from; { register unsigned long *to, *endp; to = KnL, endp = &KnL[32]; while (to < endp) *to++ = *from++; return; } void des(inblock, outblock) unsigned char *inblock, *outblock; { unsigned long work[2]; scrunch(inblock, work); desfunc(work, KnL); unscrun(work, outblock); return; } static void scrunch(outof, into) register unsigned char *outof; register unsigned long *into; { *into = (*outof++ & 0xffL) << 24; *into |= (*outof++ & 0xffL) << 16; *into |= (*outof++ & 0xffL) << 8; *into++ |= (*outof++ & 0xffL); *into = (*outof++ & 0xffL) << 24; *into |= (*outof++ & 0xffL) << 16; *into |= (*outof++ & 0xffL) << 8; *into |= (*outof & 0xffL); return; } static void unscrun(outof, into) register unsigned long *outof; register unsigned char *into; { *into++ = (*outof >> 24) & 0xffL; *into++ = (*outof >> 16) & 0xffL; *into++ = (*outof >> 8) & 0xffL; *into++ = *outof++ & 0xffL; *into++ = (*outof >> 24) & 0xffL; *into++ = (*outof >> 16) & 0xffL; *into++ = (*outof >> 8) & 0xffL; *into = *outof & 0xffL; return; } static unsigned long SP1[64] = { 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; static unsigned long SP2[64] = { 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; static unsigned long SP3[64] = { 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; static unsigned long SP4[64] = { 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; static unsigned long SP5[64] = { 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; static unsigned long SP6[64] = { 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; static unsigned long SP7[64] = { 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; static unsigned long SP8[64] = { 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; static void desfunc(block, keys) register unsigned long *block, *keys; { register unsigned long fval, work, right, leftt; register int round; leftt = block[0]; right = block[1]; work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; right ^= work; leftt ^= (work << 4); work = ((leftt >> 16) ^ right) & 0x0000ffffL; right ^= work; leftt ^= (work << 16); work = ((right >> 2) ^ leftt) & 0x33333333L; leftt ^= work; right ^= (work << 2); work = ((right >> 8) ^ leftt) & 0x00ff00ffL; leftt ^= work; right ^= (work << 8); right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; work = (leftt ^ right) & 0xaaaaaaaaL; leftt ^= work; right ^= work; leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; for (round = 0; round < 8; round++) { work = (right << 28) | (right >> 4); work ^= *keys++; fval = SP7[work & 0x3fL]; fval |= SP5[(work >> 8) & 0x3fL]; fval |= SP3[(work >> 16) & 0x3fL]; fval |= SP1[(work >> 24) & 0x3fL]; work = right ^ *keys++; fval |= SP8[work & 0x3fL]; fval |= SP6[(work >> 8) & 0x3fL]; fval |= SP4[(work >> 16) & 0x3fL]; fval |= SP2[(work >> 24) & 0x3fL]; leftt ^= fval; work = (leftt << 28) | (leftt >> 4); work ^= *keys++; fval = SP7[work & 0x3fL]; fval |= SP5[(work >> 8) & 0x3fL]; fval |= SP3[(work >> 16) & 0x3fL]; fval |= SP1[(work >> 24) & 0x3fL]; work = leftt ^ *keys++; fval |= SP8[work & 0x3fL]; fval |= SP6[(work >> 8) & 0x3fL]; fval |= SP4[(work >> 16) & 0x3fL]; fval |= SP2[(work >> 24) & 0x3fL]; right ^= fval; } right = (right << 31) | (right >> 1); work = (leftt ^ right) & 0xaaaaaaaaL; leftt ^= work; right ^= work; leftt = (leftt << 31) | (leftt >> 1); work = ((leftt >> 8) ^ right) & 0x00ff00ffL; right ^= work; leftt ^= (work << 8); work = ((leftt >> 2) ^ right) & 0x33333333L; right ^= work; leftt ^= (work << 2); work = ((right >> 16) ^ leftt) & 0x0000ffffL; leftt ^= work; right ^= (work << 16); work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; leftt ^= work; right ^= (work << 4); *block++ = right; *block = leftt; return; } /* Validation sets: * * Single-length key, single-length plaintext - * Key : 0123 4567 89ab cdef * Plain : 0123 4567 89ab cde7 * Cipher : c957 4425 6a5e d31d * * Double-length key, single-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 * Plain : 0123 4567 89ab cde7 * Cipher : 7f1d 0a77 826b 8aff * * Double-length key, double-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 * * Triple-length key, single-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 * Plain : 0123 4567 89ab cde7 * Cipher : de0b 7c06 ae5e 0ed5 * * Triple-length key, double-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 * * d3des V5.0a rwo 9208.07 18:44 Graven Imagery **********************************************************************/ medusa-2.1.1/src/modsrc/Makefile.in0000644000175000001440000010634211760000304014026 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ EXTRA_PROGRAMS = afp.mod$(EXEEXT) cvs.mod$(EXEEXT) ftp.mod$(EXEEXT) \ http.mod$(EXEEXT) imap.mod$(EXEEXT) mssql.mod$(EXEEXT) \ mysql.mod$(EXEEXT) ncp.mod$(EXEEXT) nntp.mod$(EXEEXT) \ pcanywhere.mod$(EXEEXT) pop3.mod$(EXEEXT) \ postgres.mod$(EXEEXT) rexec.mod$(EXEEXT) rlogin.mod$(EXEEXT) \ rsh.mod$(EXEEXT) smbnt.mod$(EXEEXT) smtp.mod$(EXEEXT) \ smtp-vrfy.mod$(EXEEXT) snmp.mod$(EXEEXT) ssh.mod$(EXEEXT) \ svn.mod$(EXEEXT) telnet.mod$(EXEEXT) vmauthd.mod$(EXEEXT) \ vnc.mod$(EXEEXT) web-form.mod$(EXEEXT) wrapper.mod$(EXEEXT) modules_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \ $(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_9) \ $(am__EXEEXT_10) $(am__EXEEXT_11) $(am__EXEEXT_12) \ $(am__EXEEXT_13) $(am__EXEEXT_14) $(am__EXEEXT_15) \ $(am__EXEEXT_16) $(am__EXEEXT_17) $(am__EXEEXT_18) \ $(am__EXEEXT_19) $(am__EXEEXT_20) $(am__EXEEXT_21) \ $(am__EXEEXT_22) $(am__EXEEXT_23) $(am__EXEEXT_24) \ $(am__EXEEXT_25) $(am__EXEEXT_26) @BUILD_MODULE_AFP_TRUE@am__append_1 = afp.mod @BUILD_MODULE_CVS_TRUE@am__append_2 = cvs.mod @BUILD_MODULE_FTP_TRUE@am__append_3 = ftp.mod @BUILD_MODULE_HTTP_TRUE@am__append_4 = http.mod @BUILD_MODULE_IMAP_TRUE@am__append_5 = imap.mod @BUILD_MODULE_MSSQL_TRUE@am__append_6 = mssql.mod @BUILD_MODULE_MYSQL_TRUE@am__append_7 = mysql.mod @BUILD_MODULE_NCP_TRUE@am__append_8 = ncp.mod @BUILD_MODULE_NNTP_TRUE@am__append_9 = nntp.mod @BUILD_MODULE_PCANYWHERE_TRUE@am__append_10 = pcanywhere.mod @BUILD_MODULE_POP3_TRUE@am__append_11 = pop3.mod @BUILD_MODULE_POSTGRES_TRUE@am__append_12 = postgres.mod @BUILD_MODULE_REXEC_TRUE@am__append_13 = rexec.mod @BUILD_MODULE_RLOGIN_TRUE@am__append_14 = rlogin.mod @BUILD_MODULE_RSH_TRUE@am__append_15 = rsh.mod @BUILD_MODULE_SMBNT_TRUE@am__append_16 = smbnt.mod @BUILD_MODULE_SMTP_TRUE@am__append_17 = smtp.mod @BUILD_MODULE_SMTP_VRFY_TRUE@am__append_18 = smtp-vrfy.mod @BUILD_MODULE_SNMP_TRUE@am__append_19 = snmp.mod @BUILD_MODULE_SSH_TRUE@am__append_20 = ssh.mod @BUILD_MODULE_SVN_TRUE@am__append_21 = svn.mod @BUILD_MODULE_TELNET_TRUE@am__append_22 = telnet.mod @BUILD_MODULE_VMAUTHD_TRUE@am__append_23 = vmauthd.mod @BUILD_MODULE_VNC_TRUE@am__append_24 = vnc.mod @BUILD_MODULE_WEB_FORM_TRUE@am__append_25 = web-form.mod @BUILD_MODULE_WRAPPER_TRUE@am__append_26 = wrapper.mod subdir = src/modsrc DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @BUILD_MODULE_AFP_TRUE@am__EXEEXT_1 = afp.mod$(EXEEXT) @BUILD_MODULE_CVS_TRUE@am__EXEEXT_2 = cvs.mod$(EXEEXT) @BUILD_MODULE_FTP_TRUE@am__EXEEXT_3 = ftp.mod$(EXEEXT) @BUILD_MODULE_HTTP_TRUE@am__EXEEXT_4 = http.mod$(EXEEXT) @BUILD_MODULE_IMAP_TRUE@am__EXEEXT_5 = imap.mod$(EXEEXT) @BUILD_MODULE_MSSQL_TRUE@am__EXEEXT_6 = mssql.mod$(EXEEXT) @BUILD_MODULE_MYSQL_TRUE@am__EXEEXT_7 = mysql.mod$(EXEEXT) @BUILD_MODULE_NCP_TRUE@am__EXEEXT_8 = ncp.mod$(EXEEXT) @BUILD_MODULE_NNTP_TRUE@am__EXEEXT_9 = nntp.mod$(EXEEXT) @BUILD_MODULE_PCANYWHERE_TRUE@am__EXEEXT_10 = pcanywhere.mod$(EXEEXT) @BUILD_MODULE_POP3_TRUE@am__EXEEXT_11 = pop3.mod$(EXEEXT) @BUILD_MODULE_POSTGRES_TRUE@am__EXEEXT_12 = postgres.mod$(EXEEXT) @BUILD_MODULE_REXEC_TRUE@am__EXEEXT_13 = rexec.mod$(EXEEXT) @BUILD_MODULE_RLOGIN_TRUE@am__EXEEXT_14 = rlogin.mod$(EXEEXT) @BUILD_MODULE_RSH_TRUE@am__EXEEXT_15 = rsh.mod$(EXEEXT) @BUILD_MODULE_SMBNT_TRUE@am__EXEEXT_16 = smbnt.mod$(EXEEXT) @BUILD_MODULE_SMTP_TRUE@am__EXEEXT_17 = smtp.mod$(EXEEXT) @BUILD_MODULE_SMTP_VRFY_TRUE@am__EXEEXT_18 = smtp-vrfy.mod$(EXEEXT) @BUILD_MODULE_SNMP_TRUE@am__EXEEXT_19 = snmp.mod$(EXEEXT) @BUILD_MODULE_SSH_TRUE@am__EXEEXT_20 = ssh.mod$(EXEEXT) @BUILD_MODULE_SVN_TRUE@am__EXEEXT_21 = svn.mod$(EXEEXT) @BUILD_MODULE_TELNET_TRUE@am__EXEEXT_22 = telnet.mod$(EXEEXT) @BUILD_MODULE_VMAUTHD_TRUE@am__EXEEXT_23 = vmauthd.mod$(EXEEXT) @BUILD_MODULE_VNC_TRUE@am__EXEEXT_24 = vnc.mod$(EXEEXT) @BUILD_MODULE_WEB_FORM_TRUE@am__EXEEXT_25 = web-form.mod$(EXEEXT) @BUILD_MODULE_WRAPPER_TRUE@am__EXEEXT_26 = wrapper.mod$(EXEEXT) am__installdirs = "$(DESTDIR)$(modulesdir)" PROGRAMS = $(modules_PROGRAMS) am_afp_mod_OBJECTS = afp.$(OBJEXT) medusa-trace.$(OBJEXT) afp_mod_OBJECTS = $(am_afp_mod_OBJECTS) afp_mod_LDADD = $(LDADD) afp_mod_DEPENDENCIES = afp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(afp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_cvs_mod_OBJECTS = cvs.$(OBJEXT) medusa-trace.$(OBJEXT) cvs_mod_OBJECTS = $(am_cvs_mod_OBJECTS) cvs_mod_LDADD = $(LDADD) cvs_mod_DEPENDENCIES = cvs_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(cvs_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_ftp_mod_OBJECTS = ftp.$(OBJEXT) medusa-trace.$(OBJEXT) ftp_mod_OBJECTS = $(am_ftp_mod_OBJECTS) ftp_mod_LDADD = $(LDADD) ftp_mod_DEPENDENCIES = ftp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ftp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_http_mod_OBJECTS = http.$(OBJEXT) ntlm.$(OBJEXT) \ http-digest.$(OBJEXT) medusa-trace.$(OBJEXT) http_mod_OBJECTS = $(am_http_mod_OBJECTS) http_mod_LDADD = $(LDADD) http_mod_DEPENDENCIES = http_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(http_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_imap_mod_OBJECTS = imap.$(OBJEXT) ntlm.$(OBJEXT) \ medusa-trace.$(OBJEXT) imap_mod_OBJECTS = $(am_imap_mod_OBJECTS) imap_mod_LDADD = $(LDADD) imap_mod_DEPENDENCIES = imap_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(imap_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_mssql_mod_OBJECTS = mssql.$(OBJEXT) medusa-trace.$(OBJEXT) mssql_mod_OBJECTS = $(am_mssql_mod_OBJECTS) mssql_mod_LDADD = $(LDADD) mssql_mod_DEPENDENCIES = mssql_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(mssql_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_mysql_mod_OBJECTS = mysql.$(OBJEXT) medusa-trace.$(OBJEXT) \ sha1.$(OBJEXT) mysql_mod_OBJECTS = $(am_mysql_mod_OBJECTS) mysql_mod_LDADD = $(LDADD) mysql_mod_DEPENDENCIES = mysql_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(mysql_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_ncp_mod_OBJECTS = ncp.$(OBJEXT) medusa-trace.$(OBJEXT) ncp_mod_OBJECTS = $(am_ncp_mod_OBJECTS) ncp_mod_LDADD = $(LDADD) ncp_mod_DEPENDENCIES = ncp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ncp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_nntp_mod_OBJECTS = nntp.$(OBJEXT) medusa-trace.$(OBJEXT) nntp_mod_OBJECTS = $(am_nntp_mod_OBJECTS) nntp_mod_LDADD = $(LDADD) nntp_mod_DEPENDENCIES = nntp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(nntp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_pcanywhere_mod_OBJECTS = pcanywhere.$(OBJEXT) \ medusa-trace.$(OBJEXT) pcanywhere_mod_OBJECTS = $(am_pcanywhere_mod_OBJECTS) pcanywhere_mod_LDADD = $(LDADD) pcanywhere_mod_DEPENDENCIES = pcanywhere_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pcanywhere_mod_LDFLAGS) $(LDFLAGS) -o $@ am_pop3_mod_OBJECTS = pop3.$(OBJEXT) ntlm.$(OBJEXT) \ medusa-trace.$(OBJEXT) pop3_mod_OBJECTS = $(am_pop3_mod_OBJECTS) pop3_mod_LDADD = $(LDADD) pop3_mod_DEPENDENCIES = pop3_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(pop3_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_postgres_mod_OBJECTS = postgres.$(OBJEXT) medusa-trace.$(OBJEXT) postgres_mod_OBJECTS = $(am_postgres_mod_OBJECTS) postgres_mod_LDADD = $(LDADD) postgres_mod_DEPENDENCIES = postgres_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(postgres_mod_LDFLAGS) $(LDFLAGS) -o $@ am_rexec_mod_OBJECTS = rexec.$(OBJEXT) medusa-trace.$(OBJEXT) rexec_mod_OBJECTS = $(am_rexec_mod_OBJECTS) rexec_mod_LDADD = $(LDADD) rexec_mod_DEPENDENCIES = rexec_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(rexec_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_rlogin_mod_OBJECTS = rlogin.$(OBJEXT) medusa-trace.$(OBJEXT) rlogin_mod_OBJECTS = $(am_rlogin_mod_OBJECTS) rlogin_mod_LDADD = $(LDADD) rlogin_mod_DEPENDENCIES = rlogin_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(rlogin_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_rsh_mod_OBJECTS = rsh.$(OBJEXT) medusa-trace.$(OBJEXT) rsh_mod_OBJECTS = $(am_rsh_mod_OBJECTS) rsh_mod_LDADD = $(LDADD) rsh_mod_DEPENDENCIES = rsh_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(rsh_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_smbnt_mod_OBJECTS = smbnt.$(OBJEXT) hmacmd5.$(OBJEXT) \ medusa-trace.$(OBJEXT) smbnt_mod_OBJECTS = $(am_smbnt_mod_OBJECTS) smbnt_mod_LDADD = $(LDADD) smbnt_mod_DEPENDENCIES = smbnt_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(smbnt_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_smtp_vrfy_mod_OBJECTS = smtp-vrfy.$(OBJEXT) medusa-trace.$(OBJEXT) smtp_vrfy_mod_OBJECTS = $(am_smtp_vrfy_mod_OBJECTS) smtp_vrfy_mod_LDADD = $(LDADD) smtp_vrfy_mod_DEPENDENCIES = smtp_vrfy_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(smtp_vrfy_mod_LDFLAGS) $(LDFLAGS) -o $@ am_smtp_mod_OBJECTS = smtp.$(OBJEXT) ntlm.$(OBJEXT) \ medusa-trace.$(OBJEXT) smtp_mod_OBJECTS = $(am_smtp_mod_OBJECTS) smtp_mod_LDADD = $(LDADD) smtp_mod_DEPENDENCIES = smtp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(smtp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_snmp_mod_OBJECTS = snmp.$(OBJEXT) medusa-trace.$(OBJEXT) snmp_mod_OBJECTS = $(am_snmp_mod_OBJECTS) snmp_mod_LDADD = $(LDADD) snmp_mod_DEPENDENCIES = snmp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(snmp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_ssh_mod_OBJECTS = ssh.$(OBJEXT) medusa-trace.$(OBJEXT) ssh_mod_OBJECTS = $(am_ssh_mod_OBJECTS) ssh_mod_LDADD = $(LDADD) ssh_mod_DEPENDENCIES = ssh_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ssh_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_svn_mod_OBJECTS = svn.$(OBJEXT) medusa-trace.$(OBJEXT) svn_mod_OBJECTS = $(am_svn_mod_OBJECTS) svn_mod_LDADD = $(LDADD) svn_mod_DEPENDENCIES = svn_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(svn_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_telnet_mod_OBJECTS = telnet.$(OBJEXT) medusa-trace.$(OBJEXT) telnet_mod_OBJECTS = $(am_telnet_mod_OBJECTS) telnet_mod_LDADD = $(LDADD) telnet_mod_DEPENDENCIES = telnet_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(telnet_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_vmauthd_mod_OBJECTS = vmauthd.$(OBJEXT) medusa-trace.$(OBJEXT) vmauthd_mod_OBJECTS = $(am_vmauthd_mod_OBJECTS) vmauthd_mod_LDADD = $(LDADD) vmauthd_mod_DEPENDENCIES = vmauthd_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(vmauthd_mod_LDFLAGS) $(LDFLAGS) -o $@ am_vnc_mod_OBJECTS = vnc.$(OBJEXT) d3des.$(OBJEXT) \ medusa-trace.$(OBJEXT) vnc_mod_OBJECTS = $(am_vnc_mod_OBJECTS) vnc_mod_LDADD = $(LDADD) vnc_mod_DEPENDENCIES = vnc_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(vnc_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_web_form_mod_OBJECTS = web-form.$(OBJEXT) medusa-trace.$(OBJEXT) web_form_mod_OBJECTS = $(am_web_form_mod_OBJECTS) web_form_mod_LDADD = $(LDADD) web_form_mod_DEPENDENCIES = web_form_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(web_form_mod_LDFLAGS) $(LDFLAGS) -o $@ am_wrapper_mod_OBJECTS = wrapper.$(OBJEXT) medusa-trace.$(OBJEXT) wrapper_mod_OBJECTS = $(am_wrapper_mod_OBJECTS) wrapper_mod_LDADD = $(LDADD) wrapper_mod_DEPENDENCIES = wrapper_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(wrapper_mod_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(afp_mod_SOURCES) $(cvs_mod_SOURCES) $(ftp_mod_SOURCES) \ $(http_mod_SOURCES) $(imap_mod_SOURCES) $(mssql_mod_SOURCES) \ $(mysql_mod_SOURCES) $(ncp_mod_SOURCES) $(nntp_mod_SOURCES) \ $(pcanywhere_mod_SOURCES) $(pop3_mod_SOURCES) \ $(postgres_mod_SOURCES) $(rexec_mod_SOURCES) \ $(rlogin_mod_SOURCES) $(rsh_mod_SOURCES) $(smbnt_mod_SOURCES) \ $(smtp_vrfy_mod_SOURCES) $(smtp_mod_SOURCES) \ $(snmp_mod_SOURCES) $(ssh_mod_SOURCES) $(svn_mod_SOURCES) \ $(telnet_mod_SOURCES) $(vmauthd_mod_SOURCES) \ $(vnc_mod_SOURCES) $(web_form_mod_SOURCES) \ $(wrapper_mod_SOURCES) DIST_SOURCES = $(afp_mod_SOURCES) $(cvs_mod_SOURCES) \ $(ftp_mod_SOURCES) $(http_mod_SOURCES) $(imap_mod_SOURCES) \ $(mssql_mod_SOURCES) $(mysql_mod_SOURCES) $(ncp_mod_SOURCES) \ $(nntp_mod_SOURCES) $(pcanywhere_mod_SOURCES) \ $(pop3_mod_SOURCES) $(postgres_mod_SOURCES) \ $(rexec_mod_SOURCES) $(rlogin_mod_SOURCES) $(rsh_mod_SOURCES) \ $(smbnt_mod_SOURCES) $(smtp_vrfy_mod_SOURCES) \ $(smtp_mod_SOURCES) $(snmp_mod_SOURCES) $(ssh_mod_SOURCES) \ $(svn_mod_SOURCES) $(telnet_mod_SOURCES) \ $(vmauthd_mod_SOURCES) $(vnc_mod_SOURCES) \ $(web_form_mod_SOURCES) $(wrapper_mod_SOURCES) HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ APR_CONFIG = @APR_CONFIG@ APR_INCLUDE_DIR = @APR_INCLUDE_DIR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_MOD_PATH = @DEFAULT_MOD_PATH@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODULE_LIBS = @MODULE_LIBS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ modulesdir = $(libdir)/medusa/modules afp_mod_SOURCES = afp.c ../medusa-trace.c cvs_mod_SOURCES = cvs.c ../medusa-trace.c ftp_mod_SOURCES = ftp.c ../medusa-trace.c http_mod_SOURCES = http.c ntlm.c http-digest.c ../medusa-trace.c imap_mod_SOURCES = imap.c ntlm.c ../medusa-trace.c mssql_mod_SOURCES = mssql.c ../medusa-trace.c mysql_mod_SOURCES = mysql.c ../medusa-trace.c sha1.c ncp_mod_SOURCES = ncp.c ../medusa-trace.c nntp_mod_SOURCES = nntp.c ../medusa-trace.c pcanywhere_mod_SOURCES = pcanywhere.c ../medusa-trace.c pop3_mod_SOURCES = pop3.c ntlm.c ../medusa-trace.c postgres_mod_SOURCES = postgres.c ../medusa-trace.c rexec_mod_SOURCES = rexec.c ../medusa-trace.c rlogin_mod_SOURCES = rlogin.c ../medusa-trace.c rsh_mod_SOURCES = rsh.c ../medusa-trace.c smbnt_mod_SOURCES = smbnt.c hmacmd5.c ../medusa-trace.c smtp_mod_SOURCES = smtp.c ntlm.c ../medusa-trace.c smtp_vrfy_mod_SOURCES = smtp-vrfy.c ../medusa-trace.c snmp_mod_SOURCES = snmp.c ../medusa-trace.c ssh_mod_SOURCES = ssh.c ../medusa-trace.c svn_mod_SOURCES = svn.c ../medusa-trace.c telnet_mod_SOURCES = telnet.c ../medusa-trace.c vmauthd_mod_SOURCES = vmauthd.c ../medusa-trace.c vnc_mod_SOURCES = vnc.c d3des.c ../medusa-trace.c web_form_mod_SOURCES = web-form.c ../medusa-trace.c wrapper_mod_SOURCES = wrapper.c ../medusa-trace.c INCLUDES = -I$(top_srcdir)/src $(all_includes) afp_mod_LDFLAGS = -fPIC cvs_mod_LDFLAGS = -fPIC ftp_mod_LDFLAGS = -fPIC http_mod_LDFLAGS = -fPIC imap_mod_LDFLAGS = -fPIC mssql_mod_LDFLAGS = -fPIC mysql_mod_LDFLAGS = -fPIC ncp_mod_LDFLAGS = -fPIC nntp_mod_LDFLAGS = -fPIC pcanywhere_mod_LDFLAGS = -fPIC pop3_mod_LDFLAGS = -fPIC postgres_mod_LDFLAGS = -fPIC rexec_mod_LDFLAGS = -fPIC rlogin_mod_LDFLAGS = -fPIC rsh_mod_LDFLAGS = -fPIC smbnt_mod_LDFLAGS = -fPIC smtp_mod_LDFLAGS = -fPIC smtp_vrfy_mod_LDFLAGS = -fPIC snmp_mod_LDFLAGS = -fPIC ssh_mod_LDFLAGS = -fPIC svn_mod_LDFLAGS = -fPIC telnet_mod_LDFLAGS = -fPIC vmauthd_mod_LDFLAGS = -fPIC vnc_mod_LDFLAGS = -fPIC web_form_mod_LDFLAGS = -fPIC wrapper_mod_LDFLAGS = -fPIC LDADD = @MODULE_LIBS@ noinst_HEADERS = module.h d3des.h sha1.h hmacmd5.h http-digest.h ntlm.h EXTRA_DIST = wrapper/*.pl all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/modsrc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/modsrc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-modulesPROGRAMS: $(modules_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(modulesdir)" || $(MKDIR_P) "$(DESTDIR)$(modulesdir)" @list='$(modules_PROGRAMS)'; test -n "$(modulesdir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(modulesdir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(modulesdir)$$dir" || exit $$?; \ } \ ; done uninstall-modulesPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(modules_PROGRAMS)'; test -n "$(modulesdir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(modulesdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(modulesdir)" && rm -f $$files clean-modulesPROGRAMS: -test -z "$(modules_PROGRAMS)" || rm -f $(modules_PROGRAMS) afp.mod$(EXEEXT): $(afp_mod_OBJECTS) $(afp_mod_DEPENDENCIES) @rm -f afp.mod$(EXEEXT) $(afp_mod_LINK) $(afp_mod_OBJECTS) $(afp_mod_LDADD) $(LIBS) cvs.mod$(EXEEXT): $(cvs_mod_OBJECTS) $(cvs_mod_DEPENDENCIES) @rm -f cvs.mod$(EXEEXT) $(cvs_mod_LINK) $(cvs_mod_OBJECTS) $(cvs_mod_LDADD) $(LIBS) ftp.mod$(EXEEXT): $(ftp_mod_OBJECTS) $(ftp_mod_DEPENDENCIES) @rm -f ftp.mod$(EXEEXT) $(ftp_mod_LINK) $(ftp_mod_OBJECTS) $(ftp_mod_LDADD) $(LIBS) http.mod$(EXEEXT): $(http_mod_OBJECTS) $(http_mod_DEPENDENCIES) @rm -f http.mod$(EXEEXT) $(http_mod_LINK) $(http_mod_OBJECTS) $(http_mod_LDADD) $(LIBS) imap.mod$(EXEEXT): $(imap_mod_OBJECTS) $(imap_mod_DEPENDENCIES) @rm -f imap.mod$(EXEEXT) $(imap_mod_LINK) $(imap_mod_OBJECTS) $(imap_mod_LDADD) $(LIBS) mssql.mod$(EXEEXT): $(mssql_mod_OBJECTS) $(mssql_mod_DEPENDENCIES) @rm -f mssql.mod$(EXEEXT) $(mssql_mod_LINK) $(mssql_mod_OBJECTS) $(mssql_mod_LDADD) $(LIBS) mysql.mod$(EXEEXT): $(mysql_mod_OBJECTS) $(mysql_mod_DEPENDENCIES) @rm -f mysql.mod$(EXEEXT) $(mysql_mod_LINK) $(mysql_mod_OBJECTS) $(mysql_mod_LDADD) $(LIBS) ncp.mod$(EXEEXT): $(ncp_mod_OBJECTS) $(ncp_mod_DEPENDENCIES) @rm -f ncp.mod$(EXEEXT) $(ncp_mod_LINK) $(ncp_mod_OBJECTS) $(ncp_mod_LDADD) $(LIBS) nntp.mod$(EXEEXT): $(nntp_mod_OBJECTS) $(nntp_mod_DEPENDENCIES) @rm -f nntp.mod$(EXEEXT) $(nntp_mod_LINK) $(nntp_mod_OBJECTS) $(nntp_mod_LDADD) $(LIBS) pcanywhere.mod$(EXEEXT): $(pcanywhere_mod_OBJECTS) $(pcanywhere_mod_DEPENDENCIES) @rm -f pcanywhere.mod$(EXEEXT) $(pcanywhere_mod_LINK) $(pcanywhere_mod_OBJECTS) $(pcanywhere_mod_LDADD) $(LIBS) pop3.mod$(EXEEXT): $(pop3_mod_OBJECTS) $(pop3_mod_DEPENDENCIES) @rm -f pop3.mod$(EXEEXT) $(pop3_mod_LINK) $(pop3_mod_OBJECTS) $(pop3_mod_LDADD) $(LIBS) postgres.mod$(EXEEXT): $(postgres_mod_OBJECTS) $(postgres_mod_DEPENDENCIES) @rm -f postgres.mod$(EXEEXT) $(postgres_mod_LINK) $(postgres_mod_OBJECTS) $(postgres_mod_LDADD) $(LIBS) rexec.mod$(EXEEXT): $(rexec_mod_OBJECTS) $(rexec_mod_DEPENDENCIES) @rm -f rexec.mod$(EXEEXT) $(rexec_mod_LINK) $(rexec_mod_OBJECTS) $(rexec_mod_LDADD) $(LIBS) rlogin.mod$(EXEEXT): $(rlogin_mod_OBJECTS) $(rlogin_mod_DEPENDENCIES) @rm -f rlogin.mod$(EXEEXT) $(rlogin_mod_LINK) $(rlogin_mod_OBJECTS) $(rlogin_mod_LDADD) $(LIBS) rsh.mod$(EXEEXT): $(rsh_mod_OBJECTS) $(rsh_mod_DEPENDENCIES) @rm -f rsh.mod$(EXEEXT) $(rsh_mod_LINK) $(rsh_mod_OBJECTS) $(rsh_mod_LDADD) $(LIBS) smbnt.mod$(EXEEXT): $(smbnt_mod_OBJECTS) $(smbnt_mod_DEPENDENCIES) @rm -f smbnt.mod$(EXEEXT) $(smbnt_mod_LINK) $(smbnt_mod_OBJECTS) $(smbnt_mod_LDADD) $(LIBS) smtp-vrfy.mod$(EXEEXT): $(smtp_vrfy_mod_OBJECTS) $(smtp_vrfy_mod_DEPENDENCIES) @rm -f smtp-vrfy.mod$(EXEEXT) $(smtp_vrfy_mod_LINK) $(smtp_vrfy_mod_OBJECTS) $(smtp_vrfy_mod_LDADD) $(LIBS) smtp.mod$(EXEEXT): $(smtp_mod_OBJECTS) $(smtp_mod_DEPENDENCIES) @rm -f smtp.mod$(EXEEXT) $(smtp_mod_LINK) $(smtp_mod_OBJECTS) $(smtp_mod_LDADD) $(LIBS) snmp.mod$(EXEEXT): $(snmp_mod_OBJECTS) $(snmp_mod_DEPENDENCIES) @rm -f snmp.mod$(EXEEXT) $(snmp_mod_LINK) $(snmp_mod_OBJECTS) $(snmp_mod_LDADD) $(LIBS) ssh.mod$(EXEEXT): $(ssh_mod_OBJECTS) $(ssh_mod_DEPENDENCIES) @rm -f ssh.mod$(EXEEXT) $(ssh_mod_LINK) $(ssh_mod_OBJECTS) $(ssh_mod_LDADD) $(LIBS) svn.mod$(EXEEXT): $(svn_mod_OBJECTS) $(svn_mod_DEPENDENCIES) @rm -f svn.mod$(EXEEXT) $(svn_mod_LINK) $(svn_mod_OBJECTS) $(svn_mod_LDADD) $(LIBS) telnet.mod$(EXEEXT): $(telnet_mod_OBJECTS) $(telnet_mod_DEPENDENCIES) @rm -f telnet.mod$(EXEEXT) $(telnet_mod_LINK) $(telnet_mod_OBJECTS) $(telnet_mod_LDADD) $(LIBS) vmauthd.mod$(EXEEXT): $(vmauthd_mod_OBJECTS) $(vmauthd_mod_DEPENDENCIES) @rm -f vmauthd.mod$(EXEEXT) $(vmauthd_mod_LINK) $(vmauthd_mod_OBJECTS) $(vmauthd_mod_LDADD) $(LIBS) vnc.mod$(EXEEXT): $(vnc_mod_OBJECTS) $(vnc_mod_DEPENDENCIES) @rm -f vnc.mod$(EXEEXT) $(vnc_mod_LINK) $(vnc_mod_OBJECTS) $(vnc_mod_LDADD) $(LIBS) web-form.mod$(EXEEXT): $(web_form_mod_OBJECTS) $(web_form_mod_DEPENDENCIES) @rm -f web-form.mod$(EXEEXT) $(web_form_mod_LINK) $(web_form_mod_OBJECTS) $(web_form_mod_LDADD) $(LIBS) wrapper.mod$(EXEEXT): $(wrapper_mod_OBJECTS) $(wrapper_mod_DEPENDENCIES) @rm -f wrapper.mod$(EXEEXT) $(wrapper_mod_LINK) $(wrapper_mod_OBJECTS) $(wrapper_mod_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d3des.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmacmd5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http-digest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medusa-trace.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mssql.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mysql.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ncp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nntp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntlm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcanywhere.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pop3.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/postgres.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rexec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rlogin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smbnt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smtp-vrfy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smtp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snmp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/svn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/telnet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmauthd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vnc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/web-form.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapper.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` medusa-trace.o: ../medusa-trace.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT medusa-trace.o -MD -MP -MF $(DEPDIR)/medusa-trace.Tpo -c -o medusa-trace.o `test -f '../medusa-trace.c' || echo '$(srcdir)/'`../medusa-trace.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/medusa-trace.Tpo $(DEPDIR)/medusa-trace.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../medusa-trace.c' object='medusa-trace.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o medusa-trace.o `test -f '../medusa-trace.c' || echo '$(srcdir)/'`../medusa-trace.c medusa-trace.obj: ../medusa-trace.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT medusa-trace.obj -MD -MP -MF $(DEPDIR)/medusa-trace.Tpo -c -o medusa-trace.obj `if test -f '../medusa-trace.c'; then $(CYGPATH_W) '../medusa-trace.c'; else $(CYGPATH_W) '$(srcdir)/../medusa-trace.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/medusa-trace.Tpo $(DEPDIR)/medusa-trace.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../medusa-trace.c' object='medusa-trace.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o medusa-trace.obj `if test -f '../medusa-trace.c'; then $(CYGPATH_W) '../medusa-trace.c'; else $(CYGPATH_W) '$(srcdir)/../medusa-trace.c'; fi` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(modulesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-modulesPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-modulesPROGRAMS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-modulesPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-modulesPROGRAMS ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-modulesPROGRAMS \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-modulesPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: medusa-2.1.1/src/modsrc/pop3.c0000644000175000001440000007761011757213370013032 00000000000000/* ** POP3 Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #include "ntlm.h" #define MODULE_NAME "pop3.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for POP3 sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: pop3.c 1722 2012-05-23 16:57:27Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define BUF_SIZE 300 #define PORT_POP3 110 #define PORT_POP3S 995 #define MODE_NORMAL 0 #define MODE_AS400 1 #define AUTH_UNKNOWN 0 #define AUTH_USER 1 #define AUTH_PLAIN 2 #define AUTH_LOGIN 3 #define AUTH_NTLM 4 typedef struct __MODULE_DATA { int nMode; int nAuthType; char* szDomain; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int getAuthType(int hSocket, _MODULE_DATA* _psSessionData); int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " MODE:? (NORMAL, AS400) [optional]"); writeVerbose(VB_NONE, " Sets the mode for error detection."); writeVerbose(VB_NONE, " AUTH:? (Authentication Type (USER/PLAIN/LOGIN/NTLM). Default: automatic)"); writeVerbose(VB_NONE, " Module will query service for accepted methods via an \"AUTH\" request."); writeVerbose(VB_NONE, " USER (clear-text), SASL PLAIN, SASL LOGIN, and SASL NTLM authentication methods are supported."); writeVerbose(VB_NONE, " DOMAIN:? [optional]"); writeVerbose(VB_NONE, " AUTH USER - Appends domain to username (e.g. user@domain.com)."); writeVerbose(VB_NONE, " AUTH NTLM - Supplies specified domain during NTLM authentication. The default"); writeVerbose(VB_NONE, " behaviour is to use the server supplied domain value."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: "); writeVerbose(VB_NONE, " \"medusa -M pop3 -m MODE:AS400 -U accounts.txt -p password\""); writeVerbose(VB_NONE, " \"medusa -M pop3 -m DOMAIN:foo.com -U accounts.txt -p password\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inMode = MODE_AS400; else writeError(ERR_WARNING, "Invalid value for method MODE."); } else if (strcmp(pOpt, "AUTH") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method AUTH requires value to be set."); else if (strcmp(pOpt, "USER") == 0) psSessionData->nAuthType = AUTH_USER; else if (strcmp(pOpt, "PLAIN") == 0) psSessionData->nAuthType = AUTH_PLAIN; else if (strcmp(pOpt, "LOGIN") == 0) psSessionData->nAuthType = AUTH_LOGIN; else if (strcmp(pOpt, "NTLM") == 0) psSessionData->nAuthType = AUTH_NTLM; else writeError(ERR_WARNING, "Invalid value for method AUTH."); } else if (strcmp(pOpt, "DOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDomain = malloc(strlen(pOpt) + 1); memset(psSessionData->szDomain, 0, strlen(pOpt) + 1); strncpy((char *) psSessionData->szDomain, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_POP3S; else params.nPort = PORT_POP3; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* establish initial connection */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_DEBUG_MODULE, "%s failed: Server did not respond with '+OK'. Exiting...", MODULE_NAME); psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; } /* POP3 STARTTLS Extension http://www.faqs.org/rfcs/rfc2595.html */ /* The capability name "STLS" indicates this command is present and permitted in the current state. "CAPA" can be used to test for its presence. Are there cases where "STLS" may not be implemented? */ /* Initiate STLS only if we don't already have a SSL connection */ if (psLogin->psServer->psHost->iUseSSL == 0) { memset(bufSend, 0, BUF_SIZE); sprintf(bufSend, "STLS\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; if (medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n|-ERR.*\r\n") == FAILURE) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received: %s", MODULE_NAME, bufReceive); return FAILURE; } /* [SUPPORTED] +OK Begin TLS negotiation / +OK Ready to start TLS [NOT SUPPORTED] +OK STLS completed [ERROR] -ERR Command not permitted when TLS active */ else if (strstr(bufReceive, "+OK") != NULL) { FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] Starting TLS negotiation.", MODULE_NAME); params.nSSLVersion = 3.1; /* Force the use of TLSv1 */ if (medusaConnectSocketSSL(¶ms, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish SSLv3 connection.", MODULE_NAME); return FAILURE; } } else { writeError(ERR_DEBUG_MODULE, "[%s] TLS negotiation not available.", MODULE_NAME); FREE(bufReceive); } } /* Query service for accepted authentication methods */ if (_psSessionData->nAuthType == AUTH_UNKNOWN) { getAuthType(hSocket, _psSessionData); if (_psSessionData->nAuthType == AUTH_UNKNOWN) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } break; case MSTATE_RUNNING: /* The POP3 service may be configured to drop connections after an arbitrary number of failed logon attempts. We will reuse the established connection to send authentication attempts until that disconnect happens. At that point the connection should be reestablished. */ if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) ) { nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nState = MSTATE_NEW; if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int getAuthType(int hSocket, _MODULE_DATA* _psSessionData) { unsigned char* bufReceive; unsigned char* bufSend; int nSendBufferSize = 0; int nReceiveBufferSize = 0; bufSend = malloc(6 + 1); memset(bufSend, 0, 6 + 1); sprintf(bufSend, "CAPA\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n\\.*\r\n|-ERR.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: Server did not respond that it supported any of the authentication types we handle (USER, LOGIN, and NTLM). Use the AUTH module option to force the use of an authentication type: %s", MODULE_NAME, bufReceive); return FAILURE; } else if ((strstr(bufReceive,"USER") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: USER (clear-text)"); _psSessionData->nAuthType = AUTH_USER; } else if ((strstr(bufReceive,"SASL") != NULL)) { if ((strstr(bufReceive,"PLAIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: SASL PLAIN"); _psSessionData->nAuthType = AUTH_PLAIN; } else if ((strstr(bufReceive,"LOGIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: SASL LOGIN"); _psSessionData->nAuthType = AUTH_LOGIN; } else if ((strstr(bufReceive,"NTLM") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: SASL NTLM"); _psSessionData->nAuthType = AUTH_NTLM; } else { writeError(ERR_ERROR, "[%s] Server requested unsupported SASL method.", MODULE_NAME); return FAILURE; } } else if ((strstr(bufReceive,"-ERR") != NULL)) { writeError(ERR_ERROR, "[%s] Server did not understand CAPA request. Defaulting to USER authentication type, use \"-m AUTH\" option to specify alternative method.", MODULE_NAME); _psSessionData->nAuthType = AUTH_USER; } return SUCCESS; } int sendAuthUSER(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nRet = FAILURE; writeError(ERR_DEBUG_MODULE, "[%s] Initiating USER (clear-text) Authentication Attempt.", MODULE_NAME); /* send username */ memset(bufSend, 0, sizeof(bufSend)); if (_psSessionData->szDomain) sprintf(bufSend, "USER %.100s@%.150s\r\n", szLogin, _psSessionData->szDomain); else sprintf(bufSend, "USER %.250s\r\n", szLogin); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n|-ERR.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: Server did not respond as expected to USER authentication attempt: %s", MODULE_NAME, bufReceive); return FAILURE; } else if (strstr(bufReceive, " signing off.")) { writeError(ERR_DEBUG_MODULE, "[%s] Server informed us it was signing off. Restarting connection.", MODULE_NAME); nRet = MSTATE_NEW; return(nRet); } else if (strstr(bufReceive, "ERR Cleartext login on this server requires the use of transport level security (SSL/TLS)")) { writeError(ERR_ERROR, "[%s] Server requires use of SSL/TLS.", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive, "ERR Clear text passwords have been disabled for this protocol.")) { writeError(ERR_ERROR, "[%s] Server does not accept clear-text password authentication.", MODULE_NAME); return FAILURE; } /* send password */ memset(bufSend, 0, sizeof(bufSend)); sprintf(bufSend, "PASS %.250s\r\n", szPassword); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } return SUCCESS; } /* PLAIN SASL Mechanism http://tools.ietf.org/html/rfc5034 http://tools.ietf.org/html/rfc4616 Example: AUTH PLAIN dGVzdAB0ZXN0AHRlc3Q= */ int sendAuthPLAIN(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufReceive = NULL; unsigned char* bufSend = NULL; unsigned char* szTmpBuf = NULL; unsigned char* szTmpBuf64 = NULL; int nSendBufferSize = 0; int nReceiveBufferSize = 0; int nRet = SUCCESS; writeError(ERR_DEBUG_MODULE, "[%s] Initiating PLAIN Authentication Attempt.", MODULE_NAME); /* AUTH PLAIN B64(USERNAME\0USERNAME\0PASSWORD) */ nSendBufferSize = strlen(szLogin) + 1 + strlen(szLogin) + 1 + strlen(szPassword); szTmpBuf = malloc(nSendBufferSize + 1); memset(szTmpBuf, 0, nSendBufferSize + 1); strncpy(szTmpBuf, szLogin, strlen(szLogin)); strncpy(szTmpBuf + strlen(szLogin) + 1, szLogin, strlen(szLogin)); strncpy(szTmpBuf + strlen(szLogin) + 1 + strlen(szLogin) + 1, szPassword, strlen(szPassword)); szTmpBuf64 = malloc((2 * nSendBufferSize + 2) + 1); memset(szTmpBuf64, 0, (2 * nSendBufferSize + 2) + 1); base64_encode(szTmpBuf, nSendBufferSize, szTmpBuf64); FREE(szTmpBuf); bufSend = malloc(11 + strlen(szTmpBuf64) + 2 + 1); memset(bufSend, 0, 11 + strlen(szTmpBuf64) + 2 + 1); sprintf(bufSend, "AUTH PLAIN %s\r\n", szTmpBuf64); FREE(szTmpBuf64); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); return SUCCESS; } /* AUTH LOGIN method base64-encodes both prompts and credentials. For example: AUTH LOGIN + VXNlcm5hbWU6 (Username:) Zm9v (foo) + UGFzc3dvcmQ6 (Password:) YmFy (bar) */ int sendAuthLOGIN(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufReceive = NULL; unsigned char* bufSend = NULL; unsigned char* szPrompt = NULL; unsigned char* szTmpBuf = NULL; int nSendBufferSize = 0; int nReceiveBufferSize = 0; int nRet = SUCCESS; writeError(ERR_DEBUG_MODULE, "[%s] Initiating LOGIN Authentication Attempt.", MODULE_NAME); /* --- Send initial AUTH LOGIN command --- */ bufSend = malloc(12 + 1); memset(bufSend, 0, 12 + 1); sprintf(bufSend, "AUTH LOGIN\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); /* Server should respond with a base64-encoded username prompt */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+ .*\r\n|-ERR.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] POP3 server did not respond with \"+ \" to AUTH LOGIN request.", MODULE_NAME); return FAILURE; } else if (strstr(bufReceive,"-ERR The specified authentication package is not supported.") != NULL) { writeError(ERR_ERROR, "[%s] Server response: The specified authentication package is not supported.", MODULE_NAME); return FAILURE; } szTmpBuf = ((char*)index(bufReceive, '\r')); szTmpBuf[0] = '\0'; szPrompt = malloc(strlen(bufReceive + 2) + 1); memset(szPrompt, 0, strlen(bufReceive + 2) + 1); base64_decode(bufReceive + 2, szPrompt); FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] POP3 server sent the following prompt: %s", MODULE_NAME, szPrompt); FREE(szPrompt); /* --- Send username --- */ /* Base64 encoded value can be up to 2x+2 original text. Leave additional space for "\r\n" and NULL */ bufSend = malloc((2 * strlen(szLogin) + 2) + 2 + 1); memset(bufSend, 0, (2 * strlen(szLogin) + 2) + 2 + 1); base64_encode(szLogin, strlen(szLogin), bufSend); strncat(bufSend, "\r\n", 2); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } /* Server should respond with a base64-encoded password prompt */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+ .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] POP3 server did not respond with \"+ \" to AUTH LOGIN request.", MODULE_NAME); return FAILURE; } szTmpBuf = ((char*)index(bufReceive, '\r')); szTmpBuf[0] = '\0'; szPrompt = malloc(strlen(bufReceive + 2) + 1); memset(szPrompt, 0, strlen(bufReceive + 2) + 1); base64_decode(bufReceive + 2, szPrompt); FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] POP3 server sent the following prompt: %s", MODULE_NAME, szPrompt); FREE(szPrompt); /* --- Send password --- */ /* Base64 encoded value can be up to 2x+2 original text. Leave additional space for "\r\n" and NULL */ bufSend = malloc((2 * strlen(szPassword) + 2) + 2 + 1); memset(bufSend, 0, (2 * strlen(szPassword) + 2) + 2 + 1); base64_encode(szPassword, strlen(szPassword), bufSend); strncat(bufSend, "\r\n", 2); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } return SUCCESS; } /* NTLM POP3 Authentication Based on: http://curl.haxx.se/rfc/ntlm.html#ntlmPop3Authentication http://src.opensolaris.org/source/xref/sfw/usr/src/cmd/fetchmail/fetchmail-6.3.8/README.NTLM */ int sendAuthNTLM(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; tSmbNtlmAuthRequest sTmpReq; tSmbNtlmAuthChallenge sTmpChall; tSmbNtlmAuthResponse sTmpResp; unsigned char* szTmpBuf = NULL; unsigned char* szTmpBuf64 = NULL; writeError(ERR_DEBUG_MODULE, "[%s] Initiating NTLM Authentication Attempt.", MODULE_NAME); /* --- Send initial AUTHENTICATE NTLM command --- */ bufSend = malloc(11 + 1); memset(bufSend, 0, 11 + 1); sprintf(bufSend, "AUTH NTLM\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); /* Server should respond with an empty challenge, consisting simply of a "+" */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+ *OK.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] POP3 server did not respond with \"+ OK\" to AUTH NTLM request.", MODULE_NAME); return FAILURE; } FREE(bufReceive); /* --- Send Base-64 encoded Type-1 message --- */ buildAuthRequest(&sTmpReq, 0, NULL, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpReq) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpReq) + 2); base64_encode((char *)&sTmpReq, SmbLength(&sTmpReq), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] Sending initial challenge (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(szTmpBuf64) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "%s\r\n", szTmpBuf64); FREE(szTmpBuf64); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); /* Server should respond with a Base-64 encoded Type-2 challenge message. The challenge response format is specified by RFC 1730 ("+", followed by a space, followed by the challenge message). */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+ .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Server did not send valid Type-2 challenge response.", MODULE_NAME); return FAILURE; } szTmpBuf = ((char*)index(bufReceive, '\r')); szTmpBuf[0] = '\0'; writeError(ERR_DEBUG_MODULE, "[%s] NTLM Challenge (B64 Encoded): %s", MODULE_NAME, bufReceive + 2); base64_decode(bufReceive + 2, (char *)&sTmpChall); FREE(bufReceive); /* --- Calculate and send Base-64 encoded Type 3 response --- */ buildAuthResponse(&sTmpChall, &sTmpResp, 0, szLogin, szPassword, _psSessionData->szDomain, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpResp) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpResp) + 2); base64_encode((char *)&sTmpResp, SmbLength(&sTmpResp), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] NTLM Response (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(szTmpBuf64) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf(bufSend, "%s\r\n", szTmpBuf64); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szTmpBuf64); FREE(bufSend); /* Server should validate the response and indicate the result of authentication. e.g. +OK User successfully logged on */ return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { int nRet = FAILURE; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; switch(_psSessionData->nAuthType) { case AUTH_USER: writeError(ERR_DEBUG_MODULE, "[%s] Sending USER (clear-text) Authentication.", MODULE_NAME); nRet = sendAuthUSER(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_PLAIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending PLAIN Authentication.", MODULE_NAME); nRet = sendAuthPLAIN(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_LOGIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending LOGIN Authentication.", MODULE_NAME); nRet = sendAuthLOGIN(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_NTLM: writeError(ERR_DEBUG_MODULE, "[%s] Sending NTLM Authentication.", MODULE_NAME); nRet = sendAuthNTLM(hSocket, _psSessionData, szLogin, szPassword); break; default: break; } if (nRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n|-ERR.*\r\n") == FAILURE) || (bufReceive == NULL)) { /* The POP3 service may be configured to drop connections after an arbitrary number of failed logon attempts. We will reuse the established connection to send authentication attempts until that disconnect happens. A default install of Debian (6.0.3 Squeeze) and the Courier Mail Server (0.65) was found to drop connections immediately after the 8th failed attempt. */ if ( medusaCheckSocket(hSocket, (*psLogin)->psServer->psAudit->iSocketWait) ) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; return FAILURE; } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_NEW; } } else if (bufReceive[0] == '+') { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_EXITING; } else if (strstr(bufReceive,"-ERR The specified authentication package is not supported.") != NULL) { writeError(ERR_ERROR, "[%s] Server response: The specified authentication package is not supported.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else { if (_psSessionData->nMode == MODE_AS400) { /* www.venera.com/downloads/Enumeration_of_AS400_users_via_pop3.pdf Example: -ERR Logon attempt invalid CPF2204 */ if (strstr(bufReceive, "CPF2204")) { writeError(ERR_ERROR, "[%s] User profile was not found.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr(bufReceive, "CPF22E2")) { writeError(ERR_DEBUG_MODULE, "[%s] Valid user, incorrect password.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_NEW; } else if (strstr(bufReceive, "CPF22E3")) { writeError(ERR_ERROR, "[%s] Valid user, but profile is disabled.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr(bufReceive, "CPF22E4")) { writeError(ERR_ERROR, "[%s] Valid user, but password for profile has expired.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr(bufReceive, "CPF22E5")) { writeError(ERR_ERROR, "[%s] Valid user, but no password associated with user profile.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr(bufReceive, "-ERR Logon attempt invalid")) { writeError(ERR_DEBUG_MODULE, "[%s] Generic POP3 invalid attempt message. AS/400 may not be configured for verbose messages.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_EXITING; } else { writeError(ERR_ERROR, "[%s] Unknown AS/400 error message: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } } else { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; //nRet = MSTATE_RUNNING; nRet = MSTATE_NEW; } } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(nRet); } medusa-2.1.1/src/modsrc/http-digest.c0000644000175000001440000000716711723732127014404 00000000000000/* TAKEN from rcf2617.txt */ /* Modified calculation of HA1 for MD5-sess. The sample code does not convert the result of MD5(username:realm:password) to HEX prior to the final stage of the HA1 calculation. Not sure if this due to using a different md5.h/.c file set than the original version or if it is indeed a bug in the RFC sample code. */ #include #include "http-digest.h" void CvtHex( IN HASH Bin, OUT HASHHEX Hex ) { unsigned short i; unsigned char j; for (i = 0; i < HASHLEN; i++) { j = (Bin[i] >> 4) & 0xf; if (j <= 9) Hex[i*2] = (j + '0'); else Hex[i*2] = (j + 'a' - 10); j = Bin[i] & 0xf; if (j <= 9) Hex[i*2+1] = (j + '0'); else Hex[i*2+1] = (j + 'a' - 10); }; Hex[HASHHEXLEN] = '\0'; }; /* calculate H(A1) as per spec */ void DigestCalcHA1( IN char * pszAlg, IN char * pszUserName, IN char * pszRealm, IN char * pszPassword, IN char * pszNonce, IN char * pszCNonce, OUT HASHHEX SessionKey ) { MD5_CTX Md5Ctx; HASH HA1; MD5_Init(&Md5Ctx); MD5_Update(&Md5Ctx, pszUserName, strlen(pszUserName)); MD5_Update(&Md5Ctx, ":", 1); MD5_Update(&Md5Ctx, pszRealm, strlen(pszRealm)); MD5_Update(&Md5Ctx, ":", 1); MD5_Update(&Md5Ctx, pszPassword, strlen(pszPassword)); MD5_Final(HA1, &Md5Ctx); if (strcasecmp(pszAlg, "md5-sess") == 0) { CvtHex(HA1, SessionKey); MD5_Init(&Md5Ctx); MD5_Update(&Md5Ctx, SessionKey, strlen(SessionKey)); MD5_Update(&Md5Ctx, ":", 1); MD5_Update(&Md5Ctx, pszNonce, strlen(pszNonce)); MD5_Update(&Md5Ctx, ":", 1); MD5_Update(&Md5Ctx, pszCNonce, strlen(pszCNonce)); MD5_Final(HA1, &Md5Ctx); }; CvtHex(HA1, SessionKey); }; /* calculate request-digest/response-digest as per HTTP Digest spec */ void DigestCalcResponse( IN HASHHEX HA1, /* H(A1) */ IN char * pszNonce, /* nonce from server */ IN char * pszNonceCount, /* 8 hex digits */ IN char * pszCNonce, /* client nonce */ IN char * pszQop, /* qop-value: "", "auth", "auth-int" */ IN char * pszMethod, /* method from the request */ IN char * pszDigestUri, /* requested URL */ IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ OUT HASHHEX Response /* request-digest or response-digest */ ) { MD5_CTX Md5Ctx; HASH HA2; HASH RespHash; HASHHEX HA2Hex; // calculate H(A2) MD5_Init(&Md5Ctx); MD5_Update(&Md5Ctx, pszMethod, strlen(pszMethod)); MD5_Update(&Md5Ctx, ":", 1); MD5_Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri)); if (strcasecmp(pszQop, "auth-int") == 0) { MD5_Update(&Md5Ctx, ":", 1); MD5_Update(&Md5Ctx, HEntity, HASHHEXLEN); }; MD5_Final(HA2, &Md5Ctx); CvtHex(HA2, HA2Hex); // calculate response MD5_Init(&Md5Ctx); MD5_Update(&Md5Ctx, HA1, HASHHEXLEN); MD5_Update(&Md5Ctx, ":", 1); MD5_Update(&Md5Ctx, pszNonce, strlen(pszNonce)); MD5_Update(&Md5Ctx, ":", 1); if (*pszQop) { MD5_Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount)); MD5_Update(&Md5Ctx, ":", 1); MD5_Update(&Md5Ctx, pszCNonce, strlen(pszCNonce)); MD5_Update(&Md5Ctx, ":", 1); MD5_Update(&Md5Ctx, pszQop, strlen(pszQop)); MD5_Update(&Md5Ctx, ":", 1); }; MD5_Update(&Md5Ctx, HA2Hex, HASHHEXLEN); MD5_Final(RespHash, &Md5Ctx); CvtHex(RespHash, Response); }; medusa-2.1.1/src/modsrc/smbnt.c0000644000175000001440000020223311723732127013262 00000000000000/* ** SMB LAN Manager Password/HASH Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: SMB Auditing Tool ** [Copyright (C) Patrik Karlsson 2001] ** ** This code allows Medusa to directly test NTLM hashes against ** a Windows host. This may be useful for an auditor who has aquired ** a sam._ or pwdump file and would like to quickly determine ** which are valid entries. ** ** Several "-m 'METHOD:VALUE'" options can be used with this module. The ** following are valid methods: GROUP, GROUP_OTHER, PASS, AUTH and NETBIOS. ** The following values are useful for these methods: ** ** GROUP:? ** LOCAL == Check local account. ** DOMAIN == Check credentials against this hosts primary ** domain controller via this host. ** BOTH == Check both. This leaves the workgroup field set ** blank and then attempts to check the credentials ** against the host. If the account does not exist ** locally on the host being tested, that host then ** queries its domain controller. ** ** GROUP_OTHER:? ** Configure arbitrary domain for host to authenticate against. ** ** PASS:? ** PASSWORD == Use a normal password. ** HASH == Use a NTLM hash rather than a password. ** MACHINE == Use the Machine's NetBIOS name as the password. ** ** AUTH:? ** LM == LM authentication (case-insensitive) ** NTLM == NTLMv1 authentication ** LMv2 == LMv2 authentication ** NTLMv2 == NTLMv2 authentication ** ** NETBIOS ** Force NetBIOS Mode (Disable Native Win2000 Mode) ** ** Be careful of mass domain account lockout with this. For ** example, assume you are checking several accounts against ** many domain workstations. If you are not using the 'LOCAL' ** option and these accounts do not exist locally on the ** workstations, each workstation will in turn check their ** respective domain controller. This could cause a bunch of ** lockouts. Of course, it'd look like the workstations, not ** you, were doing it. ;) ** ** **FYI, this code is unable to test accounts on default XP ** hosts which are not part of a domain and do not have normal ** file sharing enabled. Default XP does not allow shares and ** returns STATUS_LOGON_FAILED for both valid and invalid ** credentials. XP with simple sharing enabled returns SUCCESS ** for both valid and invalid credentials. If anyone knows a ** way to test in these configurations... ** ** See http://www.foofus.net/jmk/passhash.html for further ** examples. */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "smbnt.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for SMB (LM/NTLM/LMv2/NTLMv2) sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: smbnt.c 1682 2012-02-29 19:13:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define OPENSSL_WARNING "No usable OPENSSL. Module disabled." #ifdef HAVE_LIBSSL #include #include #include #include "hmacmd5.h" #define PORT_SMB 139 #define PORT_SMBNT 445 #define WIN2000_NATIVEMODE 1 #define WIN_NETBIOSMODE 2 #define PASSWORD 3 #define HASH 4 #define MACHINE 5 #define LOCAL 6 #define NTDOMAIN 7 #define BOTH 8 #define OTHER 9 #define PLAINTEXT 10 #define ENCRYPTED 11 #define AUTH_LM 12 #define AUTH_NTLM 13 #define AUTH_LMv2 14 #define AUTH_NTLMv2 15 #ifndef CHAR_BIT #define CHAR_BIT 8 #endif #ifndef TIME_T_MIN #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \ : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)) #endif #ifndef TIME_T_MAX #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN) #endif #define IVAL_NC(buf,pos) (*(unsigned int *)((char *)(buf) + (pos))) /* Non const version of above. */ #define SIVAL(buf,pos,val) IVAL_NC(buf,pos)=((unsigned int)(val)) #if (SIZEOF_LONG == 8) #define TIME_FIXUP_CONSTANT_INT 11644473600L #elif (SIZEOF_LONG_LONG == 8) #define TIME_FIXUP_CONSTANT_INT 11644473600LL #endif typedef struct __SMBNT_DATA { char challenge[8]; unsigned char workgroup[16]; unsigned char workgroup_other[16]; unsigned char machine_name[16]; int security_mode; int authLevel; int hashFlag; int accntFlag; int protoFlag; } _SMBNT_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _SMBNT_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _SMBNT_DATA *_psSessionData); char* parseFullyQualifiedUsername(_SMBNT_DATA *_psSessionData, char* szLogin); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " GROUP:? (DOMAIN, LOCAL*, BOTH)"); writeVerbose(VB_NONE, " Option sets NetBIOS workgroup field."); writeVerbose(VB_NONE, " DOMAIN: Check credentials against this hosts primary domain controller via this host."); writeVerbose(VB_NONE, " LOCAL: Check local account."); writeVerbose(VB_NONE, " BOTH: Check both. This leaves the workgroup field set blank and then attempts to check"); writeVerbose(VB_NONE, " the credentials against the host. If the account does not exist locally on the "); writeVerbose(VB_NONE, " host being tested, that host then queries its domain controller."); writeVerbose(VB_NONE, " GROUP_OTHER:? "); writeVerbose(VB_NONE, " Option allows manual setting of domain to check against. Use instead of GROUP."); writeVerbose(VB_NONE, " PASS:? (PASSWORD*, HASH, MACHINE)"); writeVerbose(VB_NONE, " PASSWORD: Use normal password."); writeVerbose(VB_NONE, " HASH: Use a NTLM hash rather than a password."); writeVerbose(VB_NONE, " MACHINE: Use the machine's NetBIOS name as the password."); writeVerbose(VB_NONE, " AUTH:? (LM, NTLM, LMv2*, NTLMv2)"); writeVerbose(VB_NONE, " Option sets LAN Manager Authentication level."); writeVerbose(VB_NONE, " LM: "); writeVerbose(VB_NONE, " NTLM: "); writeVerbose(VB_NONE, " LMv2: "); writeVerbose(VB_NONE, " NTLMv2: "); writeVerbose(VB_NONE, " NETBIOS"); writeVerbose(VB_NONE, " Force NetBIOS Mode (Disable Native Win2000 Mode). Win2000 mode is the default."); writeVerbose(VB_NONE, " Default mode is to test TCP/445 using Native Win2000. If this fails, module will"); writeVerbose(VB_NONE, " fall back to TCP/139 using NetBIOS mode. To test only TCP/139, use the following:"); writeVerbose(VB_NONE, " medusa -M smbnt -m NETBIOS -n 139"); writeVerbose(VB_NONE, "\n(*) Default value"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage examples:"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "1: Normal boring check..."); writeVerbose(VB_NONE, " medusa -M smbnt -h somehost -u someuser -p somepassword"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "2: Testing domain credentials against a client system..."); writeVerbose(VB_NONE, " medusa -M smbnt -h somehost -U users.txt -p password -m GROUP:DOMAIN"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "3: Testing each credential from a PwDump file against the target's domain via the target..."); writeVerbose(VB_NONE, " medusa -M smbnt -h somehost -C pwdump.txt -m PASS:HASH -m GROUP:DOMAIN"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "4: Testing each hash from a PwDump file against a specific user local to the target..."); writeVerbose(VB_NONE, " medusa -M smbnt -H hosts.txt -C pwdump.txt -u someuser -m PASS:HASH"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "5: Testing an individual NTLM hash..."); writeVerbose(VB_NONE, " medusa -M smbnt -H hosts.txt -u administrator -p 92D887C8010492C2944E2DF489A880E4:7A2EDE4F51BC5A03984C6BA2C239CF63::: -m PASS:HASH"); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr = NULL, *pOpt = NULL, *pOptTmp = NULL; _SMBNT_DATA *psSessionData = NULL; psSessionData = malloc(sizeof(_SMBNT_DATA)); memset(psSessionData, 0, sizeof(_SMBNT_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); psSessionData->authLevel = AUTH_LMv2; psSessionData->accntFlag = LOCAL; psSessionData->hashFlag = PASSWORD; psSessionData->protoFlag = WIN2000_NATIVEMODE; for (i=0; iaccntFlag = LOCAL; else if (strcmp(pOpt, "DOMAIN") == 0) psSessionData->accntFlag = NTDOMAIN; else if (strcmp(pOpt, "BOTH") == 0) psSessionData->accntFlag = BOTH; else writeError(ERR_WARNING, "Invalid value for method GROUP."); } else if (strcmp(pOpt, "GROUP_OTHER") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { strncpy((char *) psSessionData->workgroup_other, pOpt, 16); psSessionData->accntFlag = OTHER; } else writeError(ERR_WARNING, "Method GROUP_OTHER requires value to be set."); } else if (strcmp(pOpt, "PASS") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method PASS requires value to be set."); else if (strcmp(pOpt, "PASSWORD") == 0) psSessionData->hashFlag = PASSWORD; else if (strcmp(pOpt, "HASH") == 0) psSessionData->hashFlag = HASH; else if (strcmp(pOpt, "MACHINE") == 0) psSessionData->hashFlag = MACHINE; else writeError(ERR_WARNING, "Invalid value for method PASS."); } else if (strcmp(pOpt, "AUTH") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method AUTH requires value to be set."); else if (strcmp(pOpt, "LM") == 0) psSessionData->authLevel = AUTH_LM; else if (strcmp(pOpt, "NTLM") == 0) psSessionData->authLevel = AUTH_NTLM; else if (strcmp(pOpt, "LMv2") == 0) psSessionData->authLevel = AUTH_LMv2; else if (strcmp(pOpt, "NTLMv2") == 0) psSessionData->authLevel = AUTH_NTLMv2; else writeError(ERR_WARNING, "Invalid value for method AUTH."); } else if (strcmp(pOpt, "NETBIOS") == 0) { psSessionData->protoFlag = WIN_NETBIOSMODE; } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _SMBNT_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; char *bufReceive = NULL; char *strtok_ptr = NULL, *pOpt = NULL, *pOptTmp = NULL; char *szUser = NULL; sConnectParams params; sCredentialSet *psCredSet = NULL; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); szUser = parseFullyQualifiedUsername(_psSessionData, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_SMBNT; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (params.nPort == PORT_SMBNT) { hSocket = medusaConnect(¶ms); if ( hSocket < 0 ) { writeError(ERR_NOTICE, "%s Failed to establish WIN2000_NATIVE mode. Attempting WIN_NETBIOS mode.)", MODULE_NAME); params.nPort = PORT_SMB; _psSessionData->protoFlag = WIN_NETBIOSMODE; hSocket = medusaConnect(¶ms); } } else { hSocket = medusaConnect(¶ms); } if (hSocket < 0) { writeError(ERR_ERROR, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); if (NBSSessionRequest(hSocket, _psSessionData) < 0) { writeError(ERR_ERROR, "Session Setup Failed with host: %s. Is the server service running?", psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (SMBNegProt(hSocket, _psSessionData) < 0) { writeError(ERR_ERROR, "SMB Protocol Negotiation Failed with host: %s", psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } else { nState = MSTATE_RUNNING; } break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, szUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); FREE(szUser); szUser = parseFullyQualifiedUsername(_psSessionData, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module (%d) state %d host: %s", MODULE_NAME, psLogin->iId, nState, psLogin->psServer->pHostIP); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } writeError(ERR_DEBUG_MODULE, "[%s] Exiting module...", MODULE_NAME); FREE(psCredSet); FREE(szUser); return SUCCESS; } /* SMBNT Specific Functions */ /* Split DOMAIN\USER style usernames */ char* parseFullyQualifiedUsername(_SMBNT_DATA *_psSessionData, char* szLogin) { char *strtok_ptr = NULL, *pOpt = NULL, *pOptTmp = NULL; char *szUser = NULL; if ( strstr(szLogin, "\\") || strstr(szLogin, "\\\\") ) { if ((_psSessionData->accntFlag == NTDOMAIN) || (_psSessionData->accntFlag == OTHER)) { writeError(ERR_NOTICE, "[%s] Using the DOMAIN\\USER format with the GROUP/GROUP_OTHER module options is redundant.", MODULE_NAME); } pOptTmp = malloc( strlen(szLogin) + 1); memset(pOptTmp, 0, strlen(szLogin) + 1); strncpy(pOptTmp, szLogin, strlen(szLogin)); writeError(ERR_DEBUG_MODULE, "Processing domain and username: %s", pOptTmp); pOpt = strtok_r(pOptTmp, "\\", &strtok_ptr); strncpy((char *) _psSessionData->workgroup_other, pOpt, 16); writeError(ERR_DEBUG_MODULE, "Processing domain: %s", _psSessionData->workgroup_other); pOpt = strtok_r(NULL, "\\", &strtok_ptr); szUser = malloc(strlen(pOpt) + 1); memset(szUser, 0, strlen(pOpt) + 1); strncpy(szUser, pOpt, strlen(pOpt)); writeError(ERR_DEBUG_MODULE, "Processing username: %s", szUser); FREE(pOptTmp); _psSessionData->accntFlag = OTHER; } else { szUser = malloc(strlen(szLogin) + 1); memset(szUser, 0, strlen(szLogin) + 1); strncpy(szUser, szLogin, strlen(szLogin)); writeError(ERR_DEBUG_MODULE, "Processing username: %s", szUser); } return szUser; } static unsigned char Get7Bits(unsigned char *input, int startBit) { register unsigned int word; word = (unsigned) input[startBit / 8] << 8; word |= (unsigned) input[startBit / 8 + 1]; word >>= 15 - (startBit % 8 + 7); return word & 0xFE; } /* Make the key */ static void MakeKey(unsigned char *key, unsigned char *des_key) { des_key[0] = Get7Bits(key, 0); des_key[1] = Get7Bits(key, 7); des_key[2] = Get7Bits(key, 14); des_key[3] = Get7Bits(key, 21); des_key[4] = Get7Bits(key, 28); des_key[5] = Get7Bits(key, 35); des_key[6] = Get7Bits(key, 42); des_key[7] = Get7Bits(key, 49); DES_set_odd_parity((DES_cblock *) des_key); } /* Do the DesEncryption */ void DesEncrypt(unsigned char *clear, unsigned char *key, unsigned char *cipher) { DES_cblock des_key; DES_key_schedule key_schedule; MakeKey(key, des_key); DES_set_key(&des_key, &key_schedule); DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cipher, &key_schedule, 1); } /* HashLM Function: Create a LM hash from the challenge Variables: lmhash = the hash created from this function pass = users password challenge = the challenge recieved from the server */ int HashLM(_SMBNT_DATA *_psSessionData, unsigned char **lmhash, unsigned char *pass, unsigned char *challenge) { static unsigned char magic[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; unsigned char password[14 + 1]; unsigned char lm_hash[21]; unsigned char lm_response[24]; int i = 0, j = 0; unsigned char *p = NULL; char HexChar; int HexValue; memset(password, 0, 14 + 1); memset(lm_hash, 0, 21); memset(lm_response, 0, 24); /* Use LM Hash instead of password */ /* D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: */ if (_psSessionData->hashFlag == HASH) { p = pass; while ((*p != '\0') && (i < 1)) { if (*p == ':') i++; p++; } } /* If "-e ns" was used, don't treat these values as hashes. */ if ((_psSessionData->hashFlag == HASH) && (i >= 1)) { p = pass; if (*p == '\0') { writeError(ERR_ERROR, "Error reading PwDump file."); return FAILURE; } else if (*p == 'N') { writeError(ERR_DEBUG_MODULE, "Found \"NO PASSWORD\" for LM Hash."); /* Generate 16-byte LM hash */ DesEncrypt(magic, &password[0], &lm_hash[0]); DesEncrypt(magic, &password[7], &lm_hash[8]); } else { writeError(ERR_DEBUG_MODULE, "Convert ASCII PwDump LM Hash (%s).", p); for (i = 0; i < 16; i++) { HexValue = 0x0; for (j = 0; j < 2; j++) { HexChar = (char) p[2 * i + j]; if (HexChar > 0x39) HexChar = HexChar | 0x20; /* convert upper case to lower */ if (!(((HexChar >= 0x30) && (HexChar <= 0x39)) || /* 0 - 9 */ ((HexChar >= 0x61) && (HexChar <= 0x66)))) { /* a - f */ writeError(ERR_ERROR, "Error invalid char (%c) for hash.", HexChar); return FAILURE; } HexChar -= 0x30; if (HexChar > 0x09) /* HexChar is "a" - "f" */ HexChar -= 0x27; HexValue = (HexValue << 4) | (char) HexChar; } lm_hash[i] = (unsigned char) HexValue; } } } else { /* Password == Machine Name */ if (_psSessionData->hashFlag == MACHINE) { for (i = 0; i < 16; i++) { if (_psSessionData->machine_name[i] > 0x39) _psSessionData->machine_name[i] = _psSessionData->machine_name[i] | 0x20; /* convert upper case to lower */ pass = _psSessionData->machine_name; } } /* convert lower case characters to upper case */ strncpy(password, pass, 14); for (i = 0; i < 14; i++) { if ((password[i] >= 0x61) && (password[i] <= 0x7a)) /* a - z */ password[i] -= 0x20; } /* Generate 16-byte LM hash */ DesEncrypt(magic, &password[0], &lm_hash[0]); DesEncrypt(magic, &password[7], &lm_hash[8]); } /* NULL-pad 16-byte LM hash to 21-bytes Split resultant value into three 7-byte thirds DES-encrypt challenge using each third as a key Concatenate three 8-byte resulting values to form 24-byte LM response */ DesEncrypt(challenge, &lm_hash[0], &lm_response[0]); DesEncrypt(challenge, &lm_hash[7], &lm_response[8]); DesEncrypt(challenge, &lm_hash[14], &lm_response[16]); memcpy(*lmhash, lm_response, 24); return SUCCESS; } /* MakeNTLM Function: Create a NTLM hash from the password */ int MakeNTLM(_SMBNT_DATA *_psSessionData, unsigned char *ntlmhash, unsigned char *pass) { MD4_CTX md4Context; unsigned char hash[16]; /* MD4_SIGNATURE_SIZE = 16 */ unsigned char unicodePassword[256 * 2]; /* MAX_NT_PASSWORD = 256 */ unsigned char p21[21]; unsigned char ntlm_response[24]; int i = 0, j = 0; int mdlen; unsigned char *p = NULL; char HexChar; int HexValue; /* Use NTLM Hash instead of password */ if (_psSessionData->hashFlag == HASH) { /* [OLD] 1000:D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: */ /* [NEW] D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: */ p = pass; while ((*p != '\0') && (i < 1)) { if (*p == ':') i++; p++; } } /* If "-e ns" was used, don't treat these values as hashes. */ if ((_psSessionData->hashFlag == HASH) && (i >= 1)) { if (*p == '\0') { writeError(ERR_ERROR, "Error reading PwDump file."); return FAILURE; } else if (*p == 'N') { writeError(ERR_DEBUG_MODULE, "Found \"NO PASSWORD\" for NTLM Hash."); pass = ""; /* Initialize the Unicode version of the secret (== password). */ /* This implicitly supports 8-bit ISO8859/1 characters. */ bzero(unicodePassword, sizeof(unicodePassword)); for (i = 0; i < strlen((char *) pass); i++) unicodePassword[i * 2] = (unsigned char) pass[i]; mdlen = strlen((char *) pass) * 2; /* length in bytes */ MD4_Init(&md4Context); MD4_Update(&md4Context, unicodePassword, mdlen); MD4_Final(hash, &md4Context); /* Tell MD4 we're done */ } else { writeError(ERR_DEBUG_MODULE, "Convert ASCII PwDump NTLM Hash (%s).", p); for (i = 0; i < 16; i++) { HexValue = 0x0; for (j = 0; j < 2; j++) { HexChar = (char) p[2 * i + j]; if (HexChar > 0x39) HexChar = HexChar | 0x20; /* convert upper case to lower */ if (!(((HexChar >= 0x30) && (HexChar <= 0x39)) || /* 0 - 9 */ ((HexChar >= 0x61) && (HexChar <= 0x66)))) { /* a - f */ writeError(ERR_ERROR, "Error invalid char (%c) for hash.", HexChar); return FAILURE; } HexChar -= 0x30; if (HexChar > 0x09) /* HexChar is "a" - "f" */ HexChar -= 0x27; HexValue = (HexValue << 4) | (char) HexChar; } hash[i] = (unsigned char) HexValue; } } } else { /* Password == Machine Name */ if (_psSessionData->hashFlag == MACHINE) { for (i = 0; i < 16; i++) { if (_psSessionData->machine_name[i] > 0x39) _psSessionData->machine_name[i] = _psSessionData->machine_name[i] | 0x20; /* convert upper case to lower */ pass = _psSessionData->machine_name; } } /* Initialize the Unicode version of the secret (== password). */ /* This implicitly supports 8-bit ISO8859/1 characters. */ bzero(unicodePassword, sizeof(unicodePassword)); for (i = 0; i < strlen((char *) pass); i++) unicodePassword[i * 2] = (unsigned char) pass[i]; mdlen = strlen((char *) pass) * 2; /* length in bytes */ MD4_Init(&md4Context); MD4_Update(&md4Context, unicodePassword, mdlen); MD4_Final(hash, &md4Context); /* Tell MD4 we're done */ } memcpy(ntlmhash, hash, 16); return SUCCESS; } /* HashNTLM Function: Create a NTLM hash from the challenge Variables: ntlmhash = the hash created from this function pass = users password challenge = the challenge recieved from the server */ int HashNTLM(_SMBNT_DATA *_psSessionData, unsigned char **ntlmhash, unsigned char *pass, unsigned char *challenge) { int ret; unsigned char hash[16]; /* MD4_SIGNATURE_SIZE = 16 */ unsigned char p21[21]; unsigned char ntlm_response[24]; ret = MakeNTLM(_psSessionData, (unsigned char *)&hash, (unsigned char *)pass); if (ret == FAILURE) return FAILURE; memset(p21, '\0', 21); memcpy(p21, hash, 16); DesEncrypt(challenge, p21 + 0, ntlm_response + 0); DesEncrypt(challenge, p21 + 7, ntlm_response + 8); DesEncrypt(challenge, p21 + 14, ntlm_response + 16); memcpy(*ntlmhash, ntlm_response, 24); return SUCCESS; } /* HashLMv2 This function implements the LMv2 response algorithm. The LMv2 response is used to provide pass-through authentication compatibility with older servers. The response is based on the NTLM password hash and is exactly 24 bytes. The below code is based heavily on the following resources: http://davenport.sourceforge.net/ntlm.html#theLmv2Response samba-3.0.28a - libsmb/smbencrypt.c jcifs - packet capture of LMv2-only connection */ int HashLMv2(_SMBNT_DATA *_psSessionData, unsigned char **LMv2hash, unsigned char *szLogin, unsigned char *szPassword) { unsigned char ntlm_hash[16]; unsigned char lmv2_response[24]; unsigned char unicodeUsername[20 * 2]; unsigned char unicodeTarget[256 * 2]; HMACMD5Context ctx; unsigned char kr_buf[16]; int ret, i; unsigned char client_challenge[8] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }; memset(ntlm_hash, 0, 16); memset(lmv2_response, 0, 24); memset(kr_buf, 0, 16); /* --- HMAC #1 Caculations --- */ /* Calculate and set NTLM password hash */ ret = MakeNTLM(_psSessionData, (unsigned char *)&ntlm_hash, (unsigned char *) szPassword); if (ret == FAILURE) return FAILURE; /* The Unicode uppercase username is concatenated with the Unicode authentication target (the domain or server name specified in the Target Name field of the Type 3 message). Note that this calculation always uses the Unicode representation, even if OEM encoding has been negotiated; also note that the username is converted to uppercase, while the authentication target is case-sensitive and must match the case presented in the Target Name field. The HMAC-MD5 message authentication code algorithm (described in RFC 2104) is applied to this value using the 16-byte NTLM hash as the key. This results in a 16-byte value - the NTLMv2 hash. */ /* Initialize the Unicode version of the username and target. */ /* This implicitly supports 8-bit ISO8859/1 characters. */ /* convert lower case characters to upper case */ bzero(unicodeUsername, sizeof(unicodeUsername)); for (i = 0; i < strlen((char *)szLogin); i++) { if ((szLogin[i] >= 0x61) && (szLogin[i] <= 0x7a)) /* a - z */ unicodeUsername[i * 2] = (unsigned char) szLogin[i] - 0x20; else unicodeUsername[i * 2] = (unsigned char) szLogin[i]; } bzero(unicodeTarget, sizeof(unicodeTarget)); for (i = 0; i < strlen((char *)_psSessionData->workgroup); i++) unicodeTarget[i * 2] = (unsigned char)_psSessionData->workgroup[i]; hmac_md5_init_limK_to_64(ntlm_hash, 16, &ctx); hmac_md5_update((const unsigned char *)unicodeUsername, 2 * strlen((char *)szLogin), &ctx); hmac_md5_update((const unsigned char *)unicodeTarget, 2 * strlen((char *)_psSessionData->workgroup), &ctx); hmac_md5_final(kr_buf, &ctx); /* --- HMAC #2 Calculations --- */ /* The challenge from the Type 2 message is concatenated with our fixed client nonce. The HMAC-MD5 message authentication code algorithm is applied to this value using the 16-byte NTLMv2 hash (calculated above) as the key. This results in a 16-byte output value. */ hmac_md5_init_limK_to_64(kr_buf, 16, &ctx); hmac_md5_update(_psSessionData->challenge, 8, &ctx); hmac_md5_update(client_challenge, 8, &ctx); hmac_md5_final(lmv2_response, &ctx); /* --- 24-byte LMv2 Response Complete --- */ *LMv2hash = malloc(24); memset(*LMv2hash, 0, 24); memcpy(*LMv2hash, lmv2_response, 16); memcpy(*LMv2hash + 16, client_challenge, 8); return SUCCESS; } /* HashNTLMv2 This function implements the NTLMv2 response algorithm. Support for this algorithm was added with Microsoft Windows with NT 4.0 SP4. It should be noted that code doesn't currently work with Microsoft Vista. While NTLMv2 authentication with Samba and Windows 2003 functions as expected, Vista systems respond with the oh-so-helpful "INVALID_PARAMETER" error code. LMv2-only authentication appears to work against Vista in cases where LM and NTLM are refused. The below code is based heavily on the following two resources: http://davenport.sourceforge.net/ntlm.html#theNtlmv2Response samba-3.0.28 - libsmb/smbencrypt.c NTLMv2 network authentication is required when attempting to authenticated to a system which has the following policy enforced: GPO: "Network Security: LAN Manager authentication level" Setting: "Send NTLMv2 response only\refuse LM & NTLM" */ int HashNTLMv2(_SMBNT_DATA *_psSessionData, unsigned char **NTLMv2hash, int *iByteCount, unsigned char *szLogin, unsigned char *szPassword) { unsigned char ntlm_hash[16]; unsigned char ntlmv2_response[56 + 20 * 2 + 256 * 2]; unsigned char unicodeUsername[20 * 2]; unsigned char unicodeTarget[256 * 2]; HMACMD5Context ctx; unsigned char kr_buf[16]; int ret, i, iTargetLen; unsigned char client_challenge[8] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }; /* -- Example NTLMv2 Response Data -- [0] HMAC: (16 bytes) [16] Header: Blob Signature [01 01 00 00] (4 bytes) [20] Reserved: [00 00 00 00] (4 bytes) [24] Time: Little-endian, 64-bit signed value representing the number of tenths of a microsecond since January 1, 1601. (8 bytes) [32] Client Nonce: (8 bytes) [40] Unknown: 00 00 00 00 (4 bytes) [44] Target Information (from the Type 2 message) NetBIOS domain/workgroup: Type: domain 02 00 (2 bytes) Length: 12 00 (2 bytes) Name: WORKGROUP [NULL spacing -> 57 00 4f 00 ...] (18 bytes) End-of-list: 00 00 00 00 (4 bytes) Termination: 00 00 00 00 (4 bytes) */ iTargetLen = 2 * strlen((char *)_psSessionData->workgroup); memset(ntlm_hash, 0, 16); memset(ntlmv2_response, 0, 56 + 20 * 2 + 256 * 2); memset(kr_buf, 0, 16); /* --- HMAC #1 Caculations --- */ /* Calculate and set NTLM password hash */ ret = MakeNTLM(_psSessionData, (unsigned char *)&ntlm_hash, (unsigned char *) szPassword); if (ret == FAILURE) return FAILURE; /* The Unicode uppercase username is concatenated with the Unicode authentication target (the domain or server name specified in the Target Name field of the Type 3 message). Note that this calculation always uses the Unicode representation, even if OEM encoding has been negotiated; also note that the username is converted to uppercase, while the authentication target is case-sensitive and must match the case presented in the Target Name field. The HMAC-MD5 message authentication code algorithm (described in RFC 2104) is applied to this value using the 16-byte NTLM hash as the key. This results in a 16-byte value - the NTLMv2 hash. */ /* Initialize the Unicode version of the username and target. */ /* This implicitly supports 8-bit ISO8859/1 characters. */ /* convert lower case characters to upper case */ bzero(unicodeUsername, sizeof(unicodeUsername)); for (i = 0; i < strlen((char *)szLogin); i++) { if ((szLogin[i] >= 0x61) && (szLogin[i] <= 0x7a)) /* a - z */ unicodeUsername[i * 2] = (unsigned char) szLogin[i] - 0x20; else unicodeUsername[i * 2] = (unsigned char) szLogin[i]; } bzero(unicodeTarget, sizeof(unicodeTarget)); for (i = 0; i < strlen((char *)_psSessionData->workgroup); i++) unicodeTarget[i * 2] = (unsigned char)_psSessionData->workgroup[i]; hmac_md5_init_limK_to_64(ntlm_hash, 16, &ctx); hmac_md5_update((const unsigned char *)unicodeUsername, 2 * strlen((char *)szLogin), &ctx); hmac_md5_update((const unsigned char *)unicodeTarget, 2 * strlen((char *)_psSessionData->workgroup), &ctx); hmac_md5_final(kr_buf, &ctx); /* --- Blob Construction --- */ memset(ntlmv2_response + 16, 1, 2); /* Blob Signature 0x01010000 */ memset(ntlmv2_response + 18, 0, 2); memset(ntlmv2_response + 20, 0, 4); /* Reserved */ /* Time -- Take a Unix time and convert to an NT TIME structure: Little-endian, 64-bit signed value representing the number of tenths of a microsecond since January 1, 1601. */ struct timespec ts; unsigned long long nt; ts.tv_sec = (time_t)time(NULL); ts.tv_nsec = 0; if (ts.tv_sec ==0) nt = 0; else if (ts.tv_sec == TIME_T_MAX) nt = 0x7fffffffffffffffLL; else if (ts.tv_sec == (time_t)-1) nt = (unsigned long)-1; else { nt = ts.tv_sec; nt += TIME_FIXUP_CONSTANT_INT; nt *= 1000*1000*10; /* nt is now in the 100ns units */ } SIVAL(ntlmv2_response + 24, 0, nt & 0xFFFFFFFF); SIVAL(ntlmv2_response + 24, 4, nt >> 32); /* End time calculation */ /* Set client challenge - using a non-random value in this case. */ memcpy(ntlmv2_response + 32, client_challenge, 8); /* Client Nonce */ memset(ntlmv2_response + 40, 0, 4); /* Unknown */ /* Target Information Block */ /* 0x0100 Server name 0x0200 Domain name 0x0300 Fully-qualified DNS host name 0x0400 DNS domain name TODO: Need to rework negotiation code to correctly extract target information */ memset(ntlmv2_response + 44, 0x02, 1); /* Type: Domain */ memset(ntlmv2_response + 45, 0x00, 1); memset(ntlmv2_response + 46, iTargetLen, 1); /* Length */ memset(ntlmv2_response + 47, 0x00, 1); /* Name of domain or workgroup */ for (i = 0; i < strlen((char *)_psSessionData->workgroup); i++) ntlmv2_response[48 + i * 2] = (unsigned char)_psSessionData->workgroup[i]; memset(ntlmv2_response + 48 + iTargetLen, 0, 4); /* End-of-list */ /* --- HMAC #2 Caculations --- */ /* The challenge from the Type 2 message is concatenated with the blob. The HMAC-MD5 message authentication code algorithm is applied to this value using the 16-byte NTLMv2 hash (calculated above) as the key. This results in a 16-byte output value. */ hmac_md5_init_limK_to_64(kr_buf, 16, &ctx); hmac_md5_update(_psSessionData->challenge, 8, &ctx); hmac_md5_update(ntlmv2_response + 16, 48 - 16 + iTargetLen + 4, &ctx); hmac_md5_final(ntlmv2_response, &ctx); *iByteCount = 48 + iTargetLen + 4; *NTLMv2hash = malloc(*iByteCount); memset(*NTLMv2hash, 0, *iByteCount); memcpy(*NTLMv2hash, ntlmv2_response, *iByteCount); return SUCCESS; } /* NBS Session Request Function: Request a new session from the server Returns: TRUE on success else FALSE. */ int NBSSessionRequest(int hSocket, _SMBNT_DATA* _psSessionData) { char nb_name[32]; /* netbiosname */ char nb_local[32]; /* netbios localredirector */ unsigned char rqbuf[7] = { 0x81, 0x00, 0x00, 0x48, 0x20, 0x00, 0x20 }; char *buf = NULL; char *bufReceive = NULL; int nReceiveBufferSize = 0; /* if we are running in native mode (aka port 445) don't do netbios */ if (_psSessionData->protoFlag == WIN2000_NATIVEMODE) return 0; /* convert computer name to netbios name */ memset(nb_name, 0, 32); memset(nb_local, 0, 32); memcpy(nb_name, "CKFDENECFDEFFCFGEFFCCACACACACACA", 32); /* *SMBSERVER */ /* smbat/netbios.c/getNetbiosName */ /* memcpy(nb_local, "EHGFHCGHFDHFHIEMGPGCHDHEGFHCCACA", 32); */ memcpy(nb_local, "ENEFEEFFFDEBCACACACACACACACACACA", 32); /* MEDUSA */ buf = (char *) malloc(100); memset(buf, 0, 100); memcpy(buf, (char *) rqbuf, 5); memcpy(buf + 5, nb_name, 32); memcpy(buf + 37, (char *) rqbuf + 5, 2); memcpy(buf + 39, nb_local, 32); memcpy(buf + 71, (char *) rqbuf + 5, 1); if (medusaSend(hSocket, (char *) buf, 76, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } free(buf); nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; if ((unsigned char)bufReceive[0] == 0x82) return SUCCESS; /* success */ else return FAILURE; /* failed */ } /* SMBNegProt Function: Negotiate protocol with server ... Actually a pseudo negotiation since the whole program counts on NTLM support :) The challenge is retrieved from the answer No error checking is performed i.e cross your fingers.... */ int SMBNegProt(int hSocket, _SMBNT_DATA* _psSessionData) { unsigned char buf[168] = { 0x00, 0x00, 0x00, 0xa4, 0xff, 0x53, 0x4d, 0x42, 0x72, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x81, 0x00, 0x02, 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, 0x54, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x33, 0x00, 0x02, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, 0x54, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x20, 0x33, 0x2e, 0x30, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, 0x32, 0x00, 0x02, 0x53, 0x61, 0x6d, 0x62, 0x61, 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, 0x00 }; char* bufReceive; int nReceiveBufferSize = 0; int i = 0, j = 0; int iLength = 168; int iResponseOffset = 73; if (_psSessionData->authLevel == AUTH_LM) { writeError(ERR_DEBUG_MODULE, "[%s] Setting Negotiate Protocol Response for LM.", MODULE_NAME); buf[3] = 0x89; /* Set message length */ buf[37] = 0x66; /* Set byte count for dialects */ iLength = 141; iResponseOffset = 65; } if (medusaSend(hSocket, (char *) buf, iLength, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; /* retrieve the security mode */ /* [0] Mode: (0) ? (1) USER security mode [1] Password: (0) PLAINTEXT password (1) ENCRYPTED password. Use challenge/response [2] Signatures: (0) Security signatures NOT enabled (1) ENABLED [3] Sig Req: (0) Security signatures NOT required (1) REQUIRED SAMBA: 0x01 (default) WinXP: 0x0F (default) WinXP: 0x07 (Windows 2003 / DC) */ switch (bufReceive[39]) { case 0x01: writeVerbose(VB_GENERAL, "%s: Server requested PLAINTEXT password.", MODULE_NAME); _psSessionData->security_mode = PLAINTEXT; if (_psSessionData->hashFlag == HASH) { writeError(ERR_ERROR, "%s: Server requested PLAINTEXT password. HASH password mode not supported for this configuration.", MODULE_NAME); return FAILURE; } if (_psSessionData->hashFlag == MACHINE) { writeError(ERR_ERROR, "%s: Server requested PLAINTEXT password. MACHINE password mode not supported for this configuration.", MODULE_NAME); return FAILURE; } break; case 0x03: writeVerbose(VB_GENERAL, "%s: Server requested ENCRYPTED password without security signatures.", MODULE_NAME); _psSessionData->security_mode = ENCRYPTED; break; case 0x07: case 0x0F: writeVerbose(VB_GENERAL, "%s: Server requested ENCRYPTED password.", MODULE_NAME); _psSessionData->security_mode = ENCRYPTED; break; default: writeError(ERR_ERROR, "%s: Unknown security mode request: %2.2X. Proceeding using ENCRYPTED password mode.", MODULE_NAME, bufReceive[39]); _psSessionData->security_mode = ENCRYPTED; break; } /* Retrieve the challenge */ memcpy(_psSessionData->challenge, (char *) bufReceive + iResponseOffset, sizeof(_psSessionData->challenge)); /* Find the primary domain/workgroup name */ memset(_psSessionData->workgroup, 0, 16); memset(_psSessionData->machine_name, 0, 16); while ((bufReceive[iResponseOffset + 8 + i * 2] != 0) && (i < 16)) { _psSessionData->workgroup[i] = bufReceive[iResponseOffset + 8 + i * 2]; i++; } while ((bufReceive[iResponseOffset + 8 + (i + j + 1) * 2] != 0) && (j < 16)) { _psSessionData->machine_name[j] = bufReceive[iResponseOffset + 8 + (i + j + 1) * 2]; j++; } writeVerbose(VB_GENERAL, "%s: Server machine name: %s", MODULE_NAME, _psSessionData->machine_name); writeVerbose(VB_GENERAL, "%s: Server primary domain: %s", MODULE_NAME, _psSessionData->workgroup); return SUCCESS; } /* SMBSessionSetup Function: Send username + response to the challenge from the server. Returns: TRUE on success else FALSE. */ unsigned long SMBSessionSetup(int hSocket, _SMBNT_DATA *_psSessionData, char* szLogin, char* szPassword) { unsigned char buf[512]; unsigned char *LMv2hash = NULL; unsigned char *NTLMv2hash = NULL; unsigned char *NTLMhash = NULL; unsigned char *LMhash = NULL; char *bufReceive = NULL; int nReceiveBufferSize = 0; int i, ret; int iByteCount, iOffset; if (_psSessionData->accntFlag == LOCAL) { strcpy((char *) _psSessionData->workgroup, "localhost"); } else if (_psSessionData->accntFlag == BOTH) { memset(_psSessionData->workgroup, 0, 16); } else if (_psSessionData->accntFlag == OTHER) { strncpy((char *) _psSessionData->workgroup, _psSessionData->workgroup_other, 16); } /* NetBIOS Session Service */ unsigned char szNBSS[4] = { 0x00, /* Message Type: Session Message */ 0x00, 0x00, 0x85 /* Length -- MUST SET */ }; /* SMB Header */ unsigned char szSMB[32] = { 0xff, 0x53, 0x4d, 0x42, /* Server Component */ 0x73, /* SMB Command: Session Setup AndX */ 0x00, 0x00, 0x00, 0x00, /* NT Status: STATUS_SUCCESS */ 0x08, /* Flags */ 0x01, 0x40, /* Flags2 */ 0x00, 0x00, /* Process ID High */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Signature */ 0x00, 0x00, /* Reserved */ 0x00, 0x00, /* Tree ID */ 0x13, 0x37, /* Process ID */ 0x00, 0x00, /* User ID */ 0x01, 0x00 /* Multiplx ID */ }; memset(buf, 0, 512); memcpy(buf, szNBSS, 4); memcpy(buf +4, szSMB, 32); if (_psSessionData->security_mode == ENCRYPTED) { /* Session Setup AndX Request */ if (_psSessionData->authLevel == AUTH_LM) { writeError(ERR_DEBUG_MODULE, "[%s] Attempting LM password authentication.", MODULE_NAME); unsigned char szSessionRequest[23] = { 0x0a, /* Word Count */ 0xff, /* AndXCommand: No further commands */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0xff, 0xff, /* Max Buffer */ 0x02, 0x00, /* Max Mpx Count */ 0x3c, 0x7d, /* VC Number */ 0x00, 0x00, 0x00, 0x00, /* Session Key */ 0x18, 0x00, /* LAN Manager Password Hash Length */ 0x00, 0x00, 0x00, 0x00, /* Reserved */ 0x49, 0x00 /* Byte Count -- MUST SET */ }; iOffset = 59; /* szNBSS + szSMB + szSessionRequest */ iByteCount = 24; /* Start with length of LM hash */ /* Set Session Setup AndX Request header information */ memcpy(buf + 36, szSessionRequest, 23); /* Calculate and set LAN Manager password hash */ LMhash = (unsigned char *) malloc(24); memset(LMhash, 0, 24); ret = HashLM(_psSessionData, &LMhash, (unsigned char *) szPassword, (unsigned char *) _psSessionData->challenge); if (ret == FAILURE) return FAILURE; memcpy(buf + iOffset, LMhash, 24); free(LMhash); } else if (_psSessionData->authLevel == AUTH_NTLM) { writeError(ERR_DEBUG_MODULE, "[%s] Attempting NTLM password authentication.", MODULE_NAME); unsigned char szSessionRequest[29] = { 0x0d, /* Word Count */ 0xff, /* AndXCommand: No further commands */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0xff, 0xff, /* Max Buffer */ 0x02, 0x00, /* Max Mpx Count */ 0x3c, 0x7d, /* VC Number */ 0x00, 0x00, 0x00, 0x00, /* Session Key */ 0x18, 0x00, /* LAN Manager Password Hash Length */ 0x18, 0x00, /* NT LAN Manager Password Hash Length */ 0x00, 0x00, 0x00, 0x00, /* Reserved */ 0x50, 0x00, 0x00, 0x00, /* Capabilities */ 0x49, 0x00 /* Byte Count -- MUST SET */ }; iOffset = 65; /* szNBSS + szSMB + szSessionRequest */ iByteCount = 48; /* Start with length of NTLM and LM hashes */ /* Set Session Setup AndX Request header information */ memcpy(buf + 36, szSessionRequest, 29); /* Calculate and set NTLM password hash */ NTLMhash = (unsigned char *) malloc(24); memset(NTLMhash, 0, 24); /* We don't need to actually calculated a LM hash for this mode, only NTLM */ ret = HashNTLM(_psSessionData, &NTLMhash, (unsigned char *) szPassword, (unsigned char *) _psSessionData->challenge); if (ret == FAILURE) return FAILURE; memcpy(buf + iOffset + 24, NTLMhash, 24); /* Skip space for LM hash */ free(NTLMhash); } else if (_psSessionData->authLevel == AUTH_LMv2) { writeError(ERR_DEBUG_MODULE, "[%s] Attempting LMv2 password authentication.", MODULE_NAME); unsigned char szSessionRequest[29] = { 0x0d, /* Word Count */ 0xff, /* AndXCommand: No further commands */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0xff, 0xff, /* Max Buffer */ 0x02, 0x00, /* Max Mpx Count */ 0x3c, 0x7d, /* VC Number */ 0x00, 0x00, 0x00, 0x00, /* Session Key */ 0x18, 0x00, /* LAN Manager Password Hash Length */ 0x00, 0x00, /* NT LAN Manager Password Hash Length */ 0x00, 0x00, 0x00, 0x00, /* Reserved */ 0x50, 0x00, 0x00, 0x00, /* Capabilities */ 0x49, 0x00 /* Byte Count -- MUST SET */ }; iOffset = 65; /* szNBSS + szSMB + szSessionRequest */ iByteCount = 24; /* Start with length of LMv2 response */ /* Set Session Setup AndX Request header information */ memcpy(buf + 36, szSessionRequest, 29); /* Calculate and set LMv2 response hash */ LMv2hash = (unsigned char *) malloc(24); memset(LMv2hash, 0, 24); ret = HashLMv2(_psSessionData, &LMv2hash, (unsigned char *) szLogin, (unsigned char *) szPassword); if (ret == FAILURE) return FAILURE; memcpy(buf + iOffset, LMv2hash, 24); free(LMv2hash); } else if (_psSessionData->authLevel == AUTH_NTLMv2) { writeError(ERR_DEBUG_MODULE, "[%s] Attempting LMv2/NTLMv2 password authentication.", MODULE_NAME); unsigned char szSessionRequest[29] = { 0x0d, /* Word Count */ 0xff, /* AndXCommand: No further commands */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0xff, 0xff, /* Max Buffer */ 0x02, 0x00, /* Max Mpx Count */ 0x3c, 0x7d, /* VC Number */ 0x00, 0x00, 0x00, 0x00, /* Session Key */ 0x18, 0x00, /* LMv2 Response Hash Length */ 0x4b, 0x00, /* NTLMv2 Response Hash Length -- MUST SET */ 0x00, 0x00, 0x00, 0x00, /* Reserved */ 0x50, 0x00, 0x00, 0x00, /* Capabilities */ 0x49, 0x00 /* Byte Count -- MUST SET */ }; iOffset = 65; /* szNBSS + szSMB + szSessionRequest */ /* Set Session Setup AndX Request header information */ memcpy(buf + 36, szSessionRequest, 29); /* Calculate and set LMv2 response hash */ ret = HashLMv2(_psSessionData, &LMv2hash, (unsigned char *) szLogin, (unsigned char *) szPassword); if (ret == FAILURE) return FAILURE; memcpy(buf + iOffset, LMv2hash, 24); free(LMv2hash); /* Calculate and set NTLMv2 response hash */ ret = HashNTLMv2(_psSessionData, &NTLMv2hash, &iByteCount, (unsigned char *) szLogin, (unsigned char *) szPassword); if (ret == FAILURE) return FAILURE; /* Set NTLMv2 Response Length */ memset(buf + iOffset - 12, iByteCount, 1); writeError(ERR_DEBUG_MODULE, "HashNTLMv2 response length: %d", iByteCount); memcpy(buf + iOffset + 24, NTLMv2hash, iByteCount); free(NTLMv2hash); iByteCount += 24; /* Reflects length of both LMv2 and NTLMv2 responses */ } } else if (_psSessionData->security_mode == PLAINTEXT) { writeError(ERR_DEBUG_MODULE, "[%s] Attempting PLAINTEXT password authentication.", MODULE_NAME); unsigned char szSessionRequest[23] = { 0x0a, /* Word Count */ 0xff, /* AndXCommand: No further commands */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0xff, 0xff, /* Max Buffer */ 0x02, 0x00, /* Max Mpx Count */ 0x3c, 0x7d, /* VC Number */ 0x00, 0x00, 0x00, 0x00, /* Session Key */ 0x00, 0x00, /* Password Length -- MUST SET */ 0x00, 0x00, 0x00, 0x00, /* Reserved */ 0x49, 0x00 /* Byte Count -- MUST SET */ }; iOffset = 59; /* szNBSS + szSMB + szSessionRequest */ /* Set Session Setup AndX Request header information */ memcpy(buf + 36, szSessionRequest, 23); /* Calculate and set password length */ /* Samba appears to append NULL characters equal to the password length plus 2 */ iByteCount = 2 * strlen(szPassword) + 2; buf[iOffset - 8] = (iByteCount) % 256; buf[iOffset - 7] = (iByteCount) / 256; /* set ANSI password */ /* Depending on the SAMBA server configuration, multiple passwords may be successful when dealing with mixed-case values. The SAMBA parameter "password level" appears to determine how many characters within a password are tested by the server both upper and lower case. For example, assume a SAMBA account has a password of "Fred" and the server is configured with "password level = 2". Medusa sends the password "FRED". The SAMBA server will brute-force test this value for us with values like: "FRed", "FrEd", "FreD", "fREd", "fReD", "frED", ... The default setting is "password level = 0". This results in only two attempts to being made by the remote server; the password as is and the password in all-lower case. */ strncpy(buf + iOffset, szPassword, 256); } else { writeError(ERR_ERROR, "%s: security_mode was not properly set. This should not happen.", MODULE_NAME); return FAILURE; } /* Set account and workgroup values */ memcpy(buf + iOffset + iByteCount, szLogin, strlen(szLogin)); iByteCount += strlen(szLogin) + 1; /* NULL pad account name */ memcpy(buf + iOffset + iByteCount, _psSessionData->workgroup, strlen((char *) _psSessionData->workgroup)); iByteCount += strlen((char *) _psSessionData->workgroup) + 1; /* NULL pad workgroup name */ /* Set native OS and LAN Manager values */ sprintf(buf + iOffset + iByteCount, "Unix"); iByteCount += strlen("Unix") + 1; /* NULL pad OS name */ sprintf(buf + iOffset + iByteCount, "Samba"); iByteCount += strlen("Samba") + 1; /* NULL pad LAN Manager name */ /* Set the header length */ buf[2] = (iOffset - 4 + iByteCount) / 256; buf[3] = (iOffset - 4 + iByteCount) % 256; writeError(ERR_DEBUG_MODULE, "[%s] Set NBSS header length: %2.2X", MODULE_NAME, buf[3]); /* Set data byte count */ buf[iOffset - 2] = iByteCount; writeError(ERR_DEBUG_MODULE, "[%s] Set byte count: %2.2X", MODULE_NAME, buf[57]); if (medusaSend(hSocket, (char *) buf, iOffset + iByteCount, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if ((bufReceive == NULL) || (nReceiveBufferSize == 0)) return FAILURE; /* 41 - Action (Guest/Non-Guest Account) */ /* 9 - NT Status (Error code) */ return (((bufReceive[41] & 0x01) << 24) | ((bufReceive[11] & 0xFF) << 16) | ((bufReceive[10] & 0xFF) << 8) | (bufReceive[9] & 0xFF)); } int tryLogin(int hSocket, sLogin** psLogin, _SMBNT_DATA* _psSessionData, char* szLogin, char* szPassword) { int SMBerr, SMBaction; unsigned long SMBSessionRet; char *pErrorMsg = NULL; char ErrorCode[10]; int i, iRet; /* Nessus Plugins: smb_header.inc */ /* Note: we are currently only examining the lower 2 bytes of data */ int smbErrorCode[] = { 0xFFFFFFFF, /* UNKNOWN_ERROR_CODE */ 0x00000000, /* STATUS_SUCCESS */ 0xC000000D, /* STATUS_INVALID_PARAMETER */ 0xC000005E, /* STATUS_NO_LOGON_SERVERS */ 0xC000006D, /* STATUS_LOGON_FAILURE */ 0xC000006E, /* STATUS_ACCOUNT_RESTRICTION */ 0xC000006F, /* STATUS_INVALID_LOGON_HOURS */ 0x00C10002, /* STATUS_INVALID_LOGON_HOURS (LM Authentication) */ 0xC0000070, /* STATUS_INVALID_WORKSTATION */ 0x00C00002, /* STATUS_INVALID_WORKSTATION (LM Authentication) */ 0xC0000071, /* STATUS_PASSWORD_EXPIRED */ 0xC0000072, /* STATUS_ACCOUNT_DISABLED */ 0xC000015B, /* STATUS_LOGON_TYPE_NOT_GRANTED */ 0xC000018D, /* STATUS_TRUSTED_RELATIONSHIP_FAILURE */ 0xC0000193, /* STATUS_ACCOUNT_EXPIRED */ 0x00BF0002, /* STATUS_ACCOUNT_EXPIRED_OR_DISABLED (LM Authentication) */ 0xC0000224, /* STATUS_PASSWORD_MUST_CHANGE */ 0x00C20002, /* STATUS_PASSWORD_MUST_CHANGE (LM Authentication) */ 0xC0000234, /* STATUS_ACCOUNT_LOCKED_OUT (No LM Authentication Code) */ 0x00050001, /* AS400_STATUS_LOGON_FAILURE */ 0x00000064 /* The machine you are logging onto is protected by an authentication firewall. */ }; char *smbErrorMsg[] = { "UNKNOWN_ERROR_CODE", "STATUS_SUCCESS", "STATUS_INVALID_PARAMETER", "STATUS_NO_LOGON_SERVERS", "STATUS_LOGON_FAILURE", "STATUS_ACCOUNT_RESTRICTION", "STATUS_INVALID_LOGON_HOURS", "STATUS_INVALID_LOGON_HOURS (LM)", "STATUS_INVALID_WORKSTATION", "STATUS_INVALID_WORKSTATION (LM)", "STATUS_PASSWORD_EXPIRED", "STATUS_ACCOUNT_DISABLED", "STATUS_LOGON_TYPE_NOT_GRANTED", "STATUS_TRUSTED_RELATIONSHIP_FAILURE", "STATUS_ACCOUNT_EXPIRED", "STATUS_ACCOUNT_EXPIRED_OR_DISABLED (LM)", "STATUS_PASSWORD_MUST_CHANGE", "STATUS_PASSWORD_MUST_CHANGE (LM)", "STATUS_ACCOUNT_LOCKED_OUT", "AS400_STATUS_LOGON_FAILURE", "AUTHENTICATION_FIREWALL_PROTECTION" }; memset(&ErrorCode, 0, 10); SMBSessionRet = SMBSessionSetup(hSocket, _psSessionData, szLogin, szPassword); SMBerr = (unsigned long) SMBSessionRet & 0x00FFFFFF; SMBaction = ((unsigned long) SMBSessionRet & 0xFF000000) >> 24; writeError(ERR_DEBUG_MODULE, "SMBSessionRet: %8.8X SMBerr: %4.4X SMBaction: %2.2X", SMBSessionRet, SMBerr, SMBaction); /* Locate appropriate SMB code message */ pErrorMsg = smbErrorMsg[0]; /* UNKNOWN_ERROR_CODE */ for (i = 0; i < sizeof(smbErrorCode)/4; i++) { if (SMBerr == (smbErrorCode[i] & 0x00FFFFFF)) { pErrorMsg = smbErrorMsg[i]; break; } } switch (SMBerr) { case 0x000000: /* Non-domain connected XP and 2003 hosts map non-existant accounts to the anonymous user and return SUCCESS during password checks. Medusa will check the value of the ACTION flag in the target's response to determine if the account is a legitimate or anonymous success. */ if (SMBaction == 0x01) { (*psLogin)->pErrorMsg = malloc( 40 + 1 ); memset((*psLogin)->pErrorMsg, 0, 40 + 1 ); sprintf((*psLogin)->pErrorMsg, "Non-existant account. Anonymous success."); (*psLogin)->iResult = LOGIN_RESULT_ERROR; } else (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; break; case 0x00006F: /* STATUS_INVALID_LOGON_HOURS - Valid password */ case 0xC10002: /* STATUS_INVALID_LOGON_HOURS - Valid password (LM) */ case 0x000064: /* Valid password, "The machine you are logging onto is protected by an authentication firewall. The specificed account is not allowed to authenticate to the machine." */ case 0x000070: /* STATUS_INVALID_WORKSTATION - Valid password */ case 0xC00002: /* STATUS_INVALID_WORKSTATION - Valid password (LM) */ case 0x000072: /* STATUS_ACCOUNT_DISABLED - Valid password */ case 0x000193: /* STATUS_ACCOUNT_EXPIRED - Valid password */ case 0xBF0002: /* STATUS_ACCOUNT_DISABLED or STATUS_ACCOUNT_EXPIRED - Valid password (LM) */ case 0x000224: /* STATUS_PASSWORD_MUST_CHANGE - Valid password */ case 0xC20002: /* STATUS_PASSWORD_MUST_CHANGE - Valid password (LM) */ case 0x00006E: /* Valid password, GPO Disabling Remote Connections Using NULL Passwords */ case 0x00015B: /* Valid password, GPO "Deny access to this computer from the network" */ case 0x000071: /* Valid password, password expired and must be changed on next logon */ (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; sprintf(ErrorCode, "0x%6.6X:", SMBerr); (*psLogin)->pErrorMsg = malloc( strlen(ErrorCode) + strlen(pErrorMsg) + 1); memset((*psLogin)->pErrorMsg, 0, strlen(ErrorCode) + strlen(pErrorMsg) + 1); strncpy((*psLogin)->pErrorMsg, ErrorCode, strlen(ErrorCode)); strncat((*psLogin)->pErrorMsg, pErrorMsg, strlen(pErrorMsg)); iRet = MSTATE_EXITING; break; case 0x050001: /* AS/400 -- Incorrect password */ writeError(ERR_DEBUG_MODULE, "[%s] AS/400 Access is Denied. Incorrect password or disabled account.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; break; case 0x00006D: /* Incorrect password */ (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; break; default: sprintf(ErrorCode, "0x%6.6X:", SMBerr); (*psLogin)->pErrorMsg = malloc( strlen(ErrorCode) + strlen(pErrorMsg) + 1); memset((*psLogin)->pErrorMsg, 0, strlen(ErrorCode) + strlen(pErrorMsg) + 1); strncpy((*psLogin)->pErrorMsg, ErrorCode, strlen(ErrorCode)); strncat((*psLogin)->pErrorMsg, pErrorMsg, strlen(pErrorMsg)); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; break; } if (_psSessionData->hashFlag == MACHINE) { setPassResult((*psLogin), _psSessionData->machine_name); iRet = MSTATE_EXITING; } else { setPassResult((*psLogin), szPassword); } return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif medusa-2.1.1/src/modsrc/wrapper/0000755000175000001440000000000011760001577013530 500000000000000medusa-2.1.1/src/modsrc/wrapper/oracle.pl0000755000175000001440000000347111723732127015263 00000000000000#!/usr/bin/perl # # Oracle Brute-Force Medusa Wrapper Script # Copyright (C) 2006 Joe Mondloch # JoMo-Kun / jmk@foofus.net # # Based on bfora.pl # See bfora for SID enumeration command. Not valid on all Oracle installs... # # Requires DBD::Oracle # # Gentoo Installation Notes # [/etc/portage/packages.keywords] # app-admin/eselect-oracle ~x86 # dev-db/oracle-instantclient-basic ~x86 # dev-db/oracle-instantclient-sqlplus ~x86 # # g-cpan -i DBD::Oracle # If install fails looking *.mk: # cd .cpan/build/DBD-Oracle-1.17; su # export ORACLE_HOME=/usr/lib/oracle/10.2.0.2/client/lib # export LDPATH=/usr/lib/oracle/10.2.0.2/client/lib # export C_INCLUDE_PATH=/usr/lib/oracle/10.2.0.2/client/include # perl Makefile.PL # make install # # Verify that permissions were set correctly on installed files. # oracle.pl -h 192.168.0.1 -u foo # # medusa -M wrapper -h 192.168.0.1 -u SYSTEM -P passwords.txt -m TYPE:STDIN -m PROG:oracle.pl -m ARGS:"%H %U ORCL" require DBI; require DBD::Oracle; $host = $ARGV[0]; $user = $ARGV[1]; $sid = $ARGV[2]; pop(@ARGV); pop(@ARGV); pop(@ARGV); my $port = "1521"; #my $port = "15004"; while (<>) { chomp; $pass = $_; my $msg = "", $err = 0; $SIG{__WARN__} = sub { $msg = $_[0]; }; DBI->connect("dbi:Oracle:host=$host;sid=$sid;port=$port", "$user", "$pass", { RaiseError => 0, PrintError => 1}) or $err = "1"; if ($err) { if ($msg) { if ($msg =~ /ORA-01017: invalid username\/password; logon denied/) { print STDERR "LOGIN_RESULT_FAIL\n"; } else { $msg =~ /failed: (.*) \(DBD ERROR/; print STDERR "LOGIN_RESULT_ERROR:$1\n"; } } else { print STDERR "LOGIN_RESULT_FAIL\n"; } } else { print STDERR "LOGIN_RESULT_SUCCESS\n"; } } medusa-2.1.1/src/modsrc/wrapper/null-session.pl0000755000175000001440000000341011723732127016442 00000000000000#!/usr/bin/perl # # medusa -M wrapper -m TYPE:SINGLE -m PROG:./null-session.pl -m ARGS:"%H %U %P" -u 'foo' -p 'bar' -h 192.168.4.128 # foo.pl -h 192.168.0.20 -u foo -p bar # # W2K - RA=0 enumusers, lsaquery, lookupsids # W2K - RA=1 lsaquery, lookupsids # W2K - RA=2 # XP SP1a lsaquery # 2K3 # 2K3 DC (Pre-W2K Comp.) enumusers, lsaquery, lookupsids # 2K3 DC lsaquery, lookupsids # # other useful commands: # wksinfo, srvinfo, samgroupmem "Domain admins", samaliasmem BUILTIN\administrators $host = $ARGV[0]; $user = $ARGV[1]; $pass = $ARGV[2]; #my $cmd = 'rpcclient -U "' . $user . '%' . $pass . '" -c "enumdomusers" ' . $host; my $cmd = 'rpcclient -U "%" -c "enumdomusers" ' . $host; open(HAND, "$cmd 2>&1|"); @results = ; close(HAND); #print "Results:\n----\n@results\n----\n"; if ( grep(/Error was NT_STATUS_ACCESS_DENIED/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/error: NT_STATUS_ACCESS_DENIED/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/Error was NT_STATUS_BAD_NETWORK_NAME/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/Error was NT_STATUS_CONNECTION_REFUSED/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/error: ERRnosupport/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/Error was NT_STATUS_UNSUCCESSFUL/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/failed session setup with NT_STATUS_LOGON_FAILURE/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/user:/, @results) ) { print "LOGIN_RESULT_SUCCESS\n"; } elsif ( grep(/result was NT_STATUS_ACCESS_DENIED/, @results) ) { print "LOGIN_RESULT_ERROR:Check lsaquery/lookupsids.\n"; } else { print "LOGIN_RESULT_ERROR:Unknown error.\n"; } medusa-2.1.1/src/modsrc/wrapper/sample-stdin.pl0000755000175000001440000000060211723732127016407 00000000000000#!/usr/bin/perl # # # foo.pl -h 192.168.0.1 -u foo $host = $ARGV[0]; $user = $ARGV[1]; pop(@ARGV); pop(@ARGV); while (<>) { chomp; $pass = $_; sleep(3); if ($pass eq "CORRECT_PASS") { print STDERR "LOGIN_RESULT_SUCCESS\n"; } elsif ($pass eq "ERROR_PASS") { print STDERR "LOGIN_RESULT_ERROR\n"; } else { print STDERR "LOGIN_RESULT_FAIL\n"; } } medusa-2.1.1/src/modsrc/wrapper/apache-userdir.pl0000755000175000001440000000175511723732127016715 00000000000000#!/usr/bin/perl # # # apache-userdir.pl 192.168.0.1 USER PASS 0 [NO SSL] # apache-userdir.pl 192.168.0.1 USER PASS 1 [SSL] # # PASS is ignored... # # HEAD /~username HTTP/1.0 # # medusa -M wrapper -h 192.168.0.1 -U users.txt -p DOESNOTMATTER -m TYPE:SINGLE -m ARGS:"%H %U %P 1" -m PROG:./apache-userdir.pl use LWP::UserAgent; $host = $ARGV[0]; $user = $ARGV[1]; $pass = $ARGV[2]; # ignored $ssl = $ARGV[3]; pop(@ARGV); pop(@ARGV); pop(@ARGV); pop(@ARGV); my $ua = LWP::UserAgent->new(env_proxy => 1, keep_alive => 1, timeout => 3); #$ua->proxy(['http', 'https'], 'http://localhost:8008/'); if ($ssl) { $req = new HTTP::Request GET => "https://$host/~$user"; } else { $req = new HTTP::Request GET => "http://$host/~$user"; } $req->user_agent('MS Internet Exploder/4.0'); my $res = $ua->request($req); if ($res->is_success) { print STDERR "LOGIN_RESULT_SUCCESS\n"; } elsif ($res->code==403) { print STDERR "LOGIN_RESULT_SUCCESS\n"; } else { print STDERR "LOGIN_RESULT_FAIL\n"; } medusa-2.1.1/src/modsrc/wrapper/sample-single.pl0000755000175000001440000000045511723732127016555 00000000000000#!/usr/bin/perl # # # foo.pl -h 192.168.0.20 -u foo -p bar $host = $ARGV[0]; $user = $ARGV[1]; $pass = $ARGV[2]; sleep(1); if ($pass eq "CORRECT_PASS") { print "LOGIN_RESULT_SUCCESS\n"; } elsif ($pass eq "ERROR_PASS") { print "LOGIN_RESULT_ERROR\n"; } else { print "LOGIN_RESULT_FAIL\n"; } medusa-2.1.1/src/modsrc/module.h0000644000175000001440000000601011723732127013424 00000000000000/*************************************************************************** * module.h * * Copyright (C) 2006 by foofus.net * * fizzgig@foofus.net * * * * Common header file for all loadable modules * * * * CHANGE LOG * * 02/18/2004 -- Created by Foofus * * 04/05/2005 -- (fizzgig) Added include for medusa-net * * 04/12/2005 -- Final "alpha" implementation * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2, * * as published by the Free Software Foundation * * * * 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. See the * * GNU General Public License for more details. * * * * http://www.gnu.org/licenses/gpl.txt * * * * This program is released under the GPL with the additional exemption * * that compiling, linking, and/or using OpenSSL is allowed. * * * ***************************************************************************/ /* See to it that we only include this file once */ #ifndef __MODULE_H__ #define __MODULE_H__ 1 /* Includes */ #include "../medusa-net.h" #include "../medusa.h" #include "../medusa-trace.h" #include "../medusa-utils.h" /* Symbols */ #define MODULE_EXTENSION ".mod" extern void initConnectionParams(sLogin* pLogin, sConnectParams* pParams); /* Prototypes for required functions */ int getParamNumber( ); /* Dictates how many parameters the module allows */ void summaryUsage( char **szUsage ); /* Allocates and populates a string with brief descriptive info */ void showUsage( ); /* Displays module usage information */ int go( sLogin* logins, int argc, char *argv[] ); /* Launches the module with available parameters */ /* Typedefs for function pointers */ typedef int (*function_getParamNumber)( ); typedef void (*function_summaryUsage)( char** ); typedef void (*function_showUsage)( ); typedef int (*function_go)( sLogin*, int, char*[] ); #endif /* (was this file already included?) */ medusa-2.1.1/src/modsrc/ssh.c0000644000175000001440000005001011723732127012726 00000000000000/* ** SSH v2 Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** This module requires libssh2 (www.libssh2.org). ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "ssh.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for SSH v2 sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: ssh.c 1681 2012-02-29 19:12:47Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define LIBSSH2_WARNING "No usable LIBSSH2. Module disabled." #ifdef HAVE_LIBSSH2 #include #define PORT_SSH 22 #define SSH_AUTH_UNDEFINED 1 #define SSH_AUTH_KBDINT 2 #define SSH_AUTH_PASSWORD 3 #define SSH_AUTH_ERROR 4 #define SSH_CONN_UNKNOWN 1 #define SSH_CONN_ESTABLISHED 2 pthread_mutex_t ptmLibSSH2Mutex; typedef struct __SSH2_DATA { char *szBannerMsg; int iConnectionStatus; } _SSH2_DATA; typedef struct __ssh2_session_data { char *pPass; int iAnswerCount; } _ssh2_session_data; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(_SSH2_DATA* _psSessionData, int hSocket, LIBSSH2_SESSION *session, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login, _SSH2_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " BANNER:? (Libssh client banner. Default SSH-2.0-MEDUSA.)"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M ssh -m BANNER:SSH-2.0-FOOBAR\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _SSH2_DATA *psSessionData = NULL; psSessionData = malloc(sizeof(_SSH2_DATA)); memset(psSessionData, 0, sizeof(_SSH2_DATA)); if ( !(0 <= argc <= 1) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0/1 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszBannerMsg = malloc(strlen(pOpt)); strncpy((char *) psSessionData->szBannerMsg, pOpt, strlen(pOpt)); } else { writeError(ERR_WARNING, "Method BANNER requires value to be set."); } } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _SSH2_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; int i = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; LIBSSH2_SESSION *session = NULL; char *pErrorMsg; int iErrorMsg; _psSessionData->iConnectionStatus = SSH_CONN_UNKNOWN; _ssh2_session_data ssh2_session_data; ssh2_session_data.pPass = NULL; ssh2_session_data.iAnswerCount = 0; memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_SSH; initConnectionParams(psLogin, ¶ms); /* Retrieve next available credential set to test */ psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME, psLogin->psServer->pHostIP); nState = MSTATE_COMPLETE; } /* libssh2_init uses a global state, and is not thread safe */ pthread_mutex_lock(&ptmLibSSH2Mutex); // Utilize libssh2_init() once more distro include libssh2 1.2.5 or greater //if (libssh2_init(0)) //{ // writeError(ERR_ERROR, "%s: Failed initiating SSH library: Host: %s User: %s Pass: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); // psLogin->iResult = LOGIN_RESULT_UNKNOWN; // return FAILURE; //} // Until then, use: #include ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); pthread_mutex_unlock(&ptmLibSSH2Mutex); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: /* Create a session instance and start it up This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers */ if (session) { writeError(ERR_DEBUG_MODULE, "%s: Destroying previous SSH session structure: Host: %s User: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); libssh2_session_disconnect(session, ""); libssh2_session_free(session); session = NULL; } session = libssh2_session_init_ex(NULL, NULL, NULL, &ssh2_session_data); if (!session) { writeError(ERR_ERROR, "%s: Failed initiating SSH session: Host: %s User: %s Pass: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* Set client SSH banner */ if (_psSessionData->szBannerMsg) { if ((strncmp(_psSessionData->szBannerMsg, "SSH-2.0-", 8) != 0) || (strlen(_psSessionData->szBannerMsg) > 253)) { writeError(ERR_ERROR, "[%s] The selected banner could be rejected be some SSH servers. The banner should begin with \"SSH-2.0-\" and be shorter than 253 characters.", MODULE_NAME); } } else { _psSessionData->szBannerMsg = malloc(20); memset(_psSessionData->szBannerMsg, 0, 20); sprintf(_psSessionData->szBannerMsg, "SSH-2.0-MEDUSA_1.0"); } writeError(ERR_DEBUG_MODULE, "Attempting to set banner: %s", _psSessionData->szBannerMsg); if ( libssh2_banner_set(session, _psSessionData->szBannerMsg) ) { writeError(ERR_DEBUG_MODULE, "Failed to set libssh banner."); } /* Initiate SSH session connection - retry if necessary */ writeError(ERR_DEBUG_MODULE, "Attempting to initiate SSH session."); for (i = 1; i <= psLogin->psServer->psHost->iRetries + 1; i++) { if (hSocket > 0) { medusaDisconnect(hSocket); } hSocket = medusaConnect(¶ms); if ( hSocket < 0 ) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); if (session) { libssh2_session_disconnect(session, ""); libssh2_session_free(session); session = NULL; } psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (libssh2_session_startup(session, hSocket)) { writeError(ERR_ERROR, "%s: Failed establishing SSH session (%d/%d): Host: %s User: %s Pass: %s", MODULE_NAME, i, psLogin->psServer->psHost->iRetries + 1, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); libssh2_session_last_error(session, &pErrorMsg, &iErrorMsg, 1); if ( (pErrorMsg) && (strstr(pErrorMsg, "Unable to exchange encryption keys")) ) { writeError(ERR_ERROR, "[%s] Failed to exchange encryption keys. Are you sure this is a SSHv2 server?", MODULE_NAME); i = psLogin->psServer->psHost->iRetries + 1; } else if (pErrorMsg) { writeError(ERR_DEBUG_MODULE, "libssh2 Error Message: %s", pErrorMsg); } if (i == psLogin->psServer->psHost->iRetries + 1) { if (addMissedCredSet(psLogin, psCredSet) == SUCCESS) writeError(ERR_ERROR, "%s: Failed establishing SSH session. The following credentials have been added to the missed queue for later testing: Host: %s User: %s Pass: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); else writeError(ERR_ERROR, "%s: Failed establishing SSH session. The following credentials were NOT tested: Host: %s User: %s Pass: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); if (session) { libssh2_session_disconnect(session, ""); libssh2_session_free(session); session = NULL; } if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } sleep(psLogin->psServer->psHost->iRetryWait); } else { break; } } writeError(ERR_DEBUG_MODULE, "Id: %d successfully established connection.", psLogin->iId); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: ssh2_session_data.pPass = psCredSet->pPass; ssh2_session_data.iAnswerCount = 0; nState = tryLogin(_psSessionData, hSocket, session, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (session) { libssh2_session_disconnect(session, ""); libssh2_session_free(session); session = NULL; } if (hSocket > 0) { medusaDisconnect(hSocket); hSocket = -1; } nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (session) { libssh2_session_disconnect(session, ""); libssh2_session_free(session); session = NULL; } if (hSocket > 0) { medusaDisconnect(hSocket); hSocket = -1; } psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } void response_callback(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract) { int i; char *pPass = ((_ssh2_session_data*)(*abstract))->pPass; if (((_ssh2_session_data*)(*abstract))->iAnswerCount > 0) { writeError(ERR_DEBUG_MODULE, "libssh2 response_callback: sshd asked a question, but we've already given out answer."); } else { for (i=0; iiAnswerCount++; } else { writeError(ERR_ERROR, "%s received an unknown SSH prompt: %s", MODULE_NAME, prompts[i].text); } } } } int tryLogin(_SSH2_DATA* _psSessionData, int hSocket, LIBSSH2_SESSION *session, sLogin** psLogin, char* szLogin, char* szPassword) { char *pErrorMsg = NULL; int iErrorMsg, iAuthMode, iRet; void (*pResponseCallback) (); char *strtok_ptr = NULL; char *pAuth = NULL; pResponseCallback = response_callback; /* Password authentication failure delay: 2 Password authentication maximum tries: 3 Keyboard-interactive authentication failure delay: 2 Keyboard-interactive authentication maximum tries: 3 */ /* libssh2 supports: none, password, publickey, hostbased, keyboard-interactive */ iAuthMode = SSH_AUTH_UNDEFINED; /* libssh2_userauth_list returns session->userauth_list_data libssh2_session_free() call will handle releasing all session data, including userauth_list_data */ pErrorMsg = libssh2_userauth_list(session, szLogin, strlen(szLogin)); if (pErrorMsg) { writeError(ERR_DEBUG_MODULE, "Supported user-auth modes: %s.", pErrorMsg); pAuth = strtok_r(pErrorMsg, ",", &strtok_ptr); while (pAuth) { if (strcmp(pAuth, "password") == 0) { writeError(ERR_DEBUG_MODULE, "Server supports user-auth type: password"); iAuthMode = SSH_AUTH_PASSWORD; _psSessionData->iConnectionStatus = SSH_CONN_ESTABLISHED; break; } else if (strcmp(pAuth, "keyboard-interactive") == 0) { writeError(ERR_DEBUG_MODULE, "Server supports user-auth type: keyboard-interactive"); iAuthMode = SSH_AUTH_KBDINT; _psSessionData->iConnectionStatus = SSH_CONN_ESTABLISHED; break; } pAuth = strtok_r(NULL, ",", &strtok_ptr); } } else if (_psSessionData->iConnectionStatus == SSH_CONN_ESTABLISHED) { writeError(ERR_DEBUG_MODULE, "Failed to retrieve supported authentication modes. Since previous connections worked, restarting entire session and attempting again."); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iRet = MSTATE_NEW; return(iRet); } else { writeError(ERR_ERROR, "Failed to retrieve supported authentication modes. Aborting..."); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iRet = MSTATE_EXITING; } switch (iAuthMode) { case SSH_AUTH_KBDINT: if (libssh2_userauth_keyboard_interactive(session, szLogin, pResponseCallback) ) { writeError(ERR_DEBUG_MODULE, "Keyboard-Interactive authentication failed: Host: %s User: %s Pass: %s", (*psLogin)->psServer->pHostIP, szLogin, szPassword); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { writeError(ERR_DEBUG_MODULE, "Keyboard-Interactive authentication succeeded: Host: %s User: %s Pass: %s", (*psLogin)->psServer->pHostIP, szLogin, szPassword); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } break; case SSH_AUTH_PASSWORD: if (libssh2_userauth_password(session, szLogin, szPassword)) { libssh2_session_last_error(session, &pErrorMsg, &iErrorMsg, 1); writeError(ERR_DEBUG_MODULE, "Password-based authentication failed: %s: Host: %s User: %s Pass: %s", pErrorMsg, (*psLogin)->psServer->pHostIP, szLogin, szPassword); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } else { writeError(ERR_DEBUG_MODULE, "Password-based authentication succeeded: Host: %s User: %s Pass: %s", (*psLogin)->psServer->pHostIP, szLogin, szPassword); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } break; default: writeError(ERR_ERROR, "No supported authentication methods located."); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iRet = MSTATE_EXITING; break; } setPassResult((*psLogin), szPassword); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(LIBSSH2_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, LIBSSH2_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is libssh2 (www.libssh2.org) installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is libssh2 (www.libssh2.org) installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif medusa-2.1.1/src/modsrc/sha1.h0000644000175000001440000000362111741166633013003 00000000000000/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* This is the header file for code which implements the Secure Hashing Algorithm 1 as defined in FIPS PUB 180-1 published April 17, 1995. Many of the variable names in this code, especially the single character names, were used because those were the names used in the publication. Please read the file sha1.c for more information. Modified 2002 by Peter Zaitsev to better follow MySQL standards */ #include enum sha_result_codes { SHA_SUCCESS = 0, SHA_NULL, /* Null pointer parameter */ SHA_INPUT_TOO_LONG, /* input data too long */ SHA_STATE_ERROR /* called Input after Result */ }; #define SHA1_HASH_SIZE 20 /* Hash size in bytes */ /* This structure will hold context information for the SHA-1 hashing operation */ typedef struct SHA1_CONTEXT { ulonglong Length; /* Message length in bits */ uint32 Intermediate_Hash[SHA1_HASH_SIZE/4]; /* Message Digest */ int Computed; /* Is the digest computed? */ int Corrupted; /* Is the message digest corrupted? */ int16 Message_Block_Index; /* Index into message block array */ uint8 Message_Block[64]; /* 512-bit message blocks */ } SHA1_CONTEXT; medusa-2.1.1/src/modsrc/ntlm.h0000644000175000001440000000675411723732127013130 00000000000000/* ** NTLM Authentication Protocol Support Functions ** ** ------------------------------------------------------------------------ ** Copyright (C) 2008 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Functions for processing Type-1, Type-2 and Type-3 messages used during ** NTLM authentication. The following document is an excellent resource ** on this topic: ** ** http://davenport.sourceforge.net/ntlm.html ** ** The ntlm.h/.c files combine content from multiple sources into a single ** convenient location. It is based on code contributed to the Hydra ** project (ilo@reversing.org) along with analysis of the Fetchmail and ** Samba source. */ #ifndef _MEDUSA_NTLM_H_ #define _MEDUSA_NTLM_H_ /* These structures are byte-order dependant, and should not be manipulated except by the use of the routines provided */ typedef unsigned short uint16; typedef unsigned int uint32; typedef unsigned char uint8; typedef struct { uint16 len; uint16 maxlen; uint32 offset; } tSmbStrHeader; typedef struct { char ident[8]; uint32 msgType; uint32 flags; tSmbStrHeader host; tSmbStrHeader domain; uint8 buffer[1024]; uint32 bufIndex; } tSmbNtlmAuthRequest; typedef struct { char ident[8]; uint32 msgType; tSmbStrHeader uDomain; uint32 flags; uint8 challengeData[8]; uint8 reserved[8]; tSmbStrHeader emptyString; uint8 buffer[1024]; uint32 bufIndex; } tSmbNtlmAuthChallenge; typedef struct { char ident[8]; uint32 msgType; tSmbStrHeader lmResponse; tSmbStrHeader ntResponse; tSmbStrHeader uDomain; tSmbStrHeader uUser; tSmbStrHeader uWks; tSmbStrHeader sessionKey; uint32 flags; uint8 buffer[1024]; uint32 bufIndex; } tSmbNtlmAuthResponse; /* - public - */ #define SmbLength(ptr) (((ptr)->buffer - (uint8*)(ptr)) + (ptr)->bufIndex) /* A flags value of 0 selects the minimum security level. Host and domain values are optional and can be set to NULL. */ void buildAuthRequest(tSmbNtlmAuthRequest *request, long flags, char *host, char *domain); /* Generates a Type-3 response for a given Type-2 request (challenge) and user credentials. If the user defines the optional parameters (flags, host, and domain), these values will superseed what the server specified. Leave the values set to 0 and NULL to use the server specified values. */ void buildAuthResponse(tSmbNtlmAuthChallenge *challenge, tSmbNtlmAuthResponse *response, long flags, char *user, char *password, char *domain, char *host); /* Debugging Functions */ void dumpAuthRequest(tSmbNtlmAuthRequest *request); void dumpAuthChallenge(tSmbNtlmAuthChallenge *challenge); void dumpAuthResponse(tSmbNtlmAuthResponse *response); #endif medusa-2.1.1/src/modsrc/afp.c0000644000175000001440000002724011723732127012710 00000000000000/* ** Apple Filing Protocol AFP Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Module designed using afpfs-ng 0.8.1 ** AFPFS-NG: http://alexthepuffin.googlepages.com/home ** ** The following steps needed to be performed: ** copy afpfs-ng-0.8.1/include/* to /usr/include/afpfs-ng ** ** NOTE: autoconf is currently hard-coded to use /usr/lib/libafpclient.so.0. ** This may need to be tweaked if afpfs-ng is installed to some other ** location. ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "afp.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for AFP sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: afp.c 1301 2010-02-09 22:54:18Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define LIBAFP_WARNING "No usable LIBAFPFS. Module disabled." #ifdef HAVE_LIBAFPFS #include #include #include #define PORT_AFP 548 typedef struct __MODULE_DATA { } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, char* szLogin, char* szPassword); int initModule(_MODULE_DATA* _psSessionData, sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !(0 <= argc <= 2) ) { // Show usage information writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module.", MODULE_NAME); return FAILURE; } else { // Parameters are good - make module go now writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; ipsUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_AFP; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, _psSessionData, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ static int server_subconnect(struct afp_url url) { struct afp_connection_request *conn_req; struct afp_server * server = NULL; conn_req = malloc( sizeof(struct afp_connection_request) ); server = malloc( sizeof(struct afp_server) ); memset(conn_req, 0, sizeof(struct afp_connection_request)); conn_req->url=url; conn_req->url.requested_version=31; writeError(ERR_DEBUG_MODULE, "[%s] AFP connection - username: %s password: %s server: %s", MODULE_NAME, url.username, url.password, url.servername); if (strlen(url.uamname) > 0) { if ((conn_req->uam_mask = find_uam_by_name(url.uamname)) == 0) { writeError(ERR_ERROR, "[%s] Unknown UAM: %s", MODULE_NAME, url.uamname); FREE(conn_req); FREE(server); return FAILURE; } } else { conn_req->uam_mask=default_uams_mask(); } writeError(ERR_DEBUG_MODULE, "[%s] Initiating connection attempt.", MODULE_NAME); if ((server = afp_server_full_connect(NULL, conn_req)) == NULL) { FREE(conn_req); FREE(server); return FAILURE; } writeError(ERR_DEBUG_MODULE, "[%s] Connected to server: %s via UAM: %s", MODULE_NAME, server->server_name_printable, uam_bitmap_to_string(server->using_uam)); FREE(conn_req); FREE(server); return SUCCESS; } /* This is to replace the afp library log callback function with a more medusa friendly one */ void stdout_log_for_medusa(void * priv, enum loglevels loglevel, int logtype, const char *message) { writeError(ERR_DEBUG_MODULE, "[%s] libafpclient message: %s", MODULE_NAME, message); } static struct libafpclient afpclient = { .unmount_volume = NULL, .log_for_client = stdout_log_for_medusa, .forced_ending_hook = NULL, .scan_extra_fds = NULL, .loop_started = NULL , }; int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** psLogin, char* szLogin, char* szPassword) { int iRet; unsigned char* szTmp = NULL; unsigned char* szEncodedAuth = NULL; int nSendBufferSize = 0; struct afp_url tmpurl; /* Build AFP authentication request */ libafpclient_register(&afpclient); afp_main_quick_startup(NULL); init_uams(); afp_default_url(&tmpurl); memcpy(&tmpurl.servername, (*psLogin)->psServer->pHostIP, AFP_SERVER_NAME_LEN); memcpy(&tmpurl.username, szLogin, AFP_MAX_USERNAME_LEN); memcpy(&tmpurl.password, szPassword, AFP_MAX_PASSWORD_LEN); if ( server_subconnect(tmpurl) == SUCCESS ) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } setPassResult((*psLogin), szPassword); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(LIBAFP_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, LIBAFP_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Are the afpfs-ng headers and static library installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Are the afpfs-ng headers and static library installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif medusa-2.1.1/src/modsrc/smtp-vrfy.c0000644000175000001440000003544311723732127014115 00000000000000/* ** SMTP VRFY Account Enumeration Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. See the ** GNU General Public License for more details. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "smtp-vrfy.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for enumerating accounts via SMTP VRFY" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: smtp-vrfy.c 1581 2011-07-07 21:34:27Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_SMTP 25 #define BUF_SIZE 300 #define RECEIVE_DELAY_1 20 * 1000000 #define RECEIVE_DELAY_2 0.5 * 1000000 typedef struct __MODULE_DATA { char *szHELO; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int sayHELO(int hSocket, _MODULE_DATA* _psSessionData); int sayQUIT(int hSocket); int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " HELO:? (optional)"); writeVerbose(VB_NONE, " Sets the name sent via the HELO command."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M smtp-vrfy -m HELO:g3rg3 -U accounts.txt -p domain.com\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ( !(0 <= argc <= 3) ) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszHELO = malloc(strlen(pOpt) + 1); memset(psSessionData->szHELO, 0, strlen(pOpt) + 1); strncpy((char *)psSessionData->szHELO, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method HELO requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; char* bufReceive; int nReceiveBufferSize = 0; int nStatus = FAILURE; int nBannerStatus = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); params.nPort = PORT_SMTP; initConnectionParams(psLogin, ¶ms); if (_psSessionData->szHELO == NULL) { _psSessionData->szHELO = malloc(7); memset(_psSessionData->szHELO, 0, 7); sprintf(_psSessionData->szHELO, "MEDUSA"); } writeError(ERR_DEBUG_MODULE, "[%s] Set HELO value: %s", MODULE_NAME, _psSessionData->szHELO); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* establish initial connection */ bufReceive = NULL; nReceiveBufferSize = 0; nStatus = FAILURE; nBannerStatus = 0; while (bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize)) { if (strstr(bufReceive, "220 ") != NULL) nBannerStatus = 1; if (nBannerStatus > 0 && (strstr(bufReceive, "\r\n") != NULL)) nBannerStatus = 2; if (nBannerStatus > 1) { writeError(ERR_DEBUG_MODULE, "[%s] Server sent '220' code.", MODULE_NAME); nStatus = SUCCESS; FREE(bufReceive); break; } FREE(bufReceive); } if (nStatus == FAILURE) { writeError(ERR_DEBUG_MODULE, "[%s] Server did not respond with '220' code. Exiting...", MODULE_NAME); psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; return FAILURE; break; } else { writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; } /* send HELO */ writeError(ERR_DEBUG_MODULE, "[%s] Sending HELO command.", MODULE_NAME); if (sayHELO(hSocket, _psSessionData) == SUCCESS) nState = MSTATE_RUNNING; else nState = MSTATE_EXITING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: sayQUIT(hSocket); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ /* HELO foo 250-spamfirewall.domain.com 250-PIPELINING 250-SIZE 100000000 250-VRFY 250-ETRN 250 8BITMIME */ int sayHELO(int hSocket, _MODULE_DATA* _psSessionData) { unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; int nStatus; int nBannerStatus = 0; /* send helo string */ memset(bufSend, 0, sizeof(bufSend)); sprintf(bufSend, "HELO %.250s\r\n", _psSessionData->szHELO); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } bufReceive = NULL; nReceiveBufferSize = 0; nStatus = FAILURE; nBannerStatus = 0; while (bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize)) { /* From: http://www.faqs.org/rfcs/rfc959.html [SMTP VRFY appears to act in same manner as FTP] Thus the format for multi-line replies is that the first line will begin with the exact required reply code, followed immediately by a Hyphen, "-" (also known as Minus), followed by text. The last line will begin with the same code, followed immediately by Space , optionally some text, and the Telnet end-of-line code. */ if (strstr(bufReceive, "250 ") != NULL) nBannerStatus = 1; if (nBannerStatus > 0 && (strstr(bufReceive, "\r\n") != NULL)) nBannerStatus = 2; if (nBannerStatus > 1) { writeError(ERR_DEBUG_MODULE, "[%s] Server sent '250' code.", MODULE_NAME); nStatus = SUCCESS; FREE(bufReceive); break; } FREE(bufReceive); } FREE(bufReceive); return nStatus; } int sayQUIT(int hSocket) { unsigned char bufSend[BUF_SIZE]; memset(bufSend, 0, sizeof(bufSend)); sprintf(bufSend, "QUIT\r\n"); if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } return SUCCESS; } /* VRFY administrator@domain.com 252 administrator@domain.com VRFY foo@domain.com 550 : Recipient address rejected: No such user (foo@domain.com) VRFY foo@bar.com 554 : Relay access denied 421 Error: too many errors */ int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szAccount, char* szDomain) { int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* send helo string */ memset(bufSend, 0, sizeof(bufSend)); if (strlen(szDomain) > 0) { writeError(ERR_DEBUG_MODULE, "[%s] Sending: VRFY %.250s@%.250s\r\n", MODULE_NAME, szAccount, szDomain); sprintf(bufSend, "VRFY %.250s@%.250s\r\n", szAccount, szDomain); } else { writeError(ERR_DEBUG_MODULE, "[%s] Sending: VRFY %.250s\r\n", MODULE_NAME, szAccount); sprintf(bufSend, "VRFY %.250s\r\n", szAccount); } if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strncmp(bufReceive, "250 ", 4) == 0) /* valid account */ { writeError(ERR_DEBUG_MODULE, "[%s] Found valid account: %s", MODULE_NAME, szAccount); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_RUNNING; } else if (strncmp(bufReceive, "252 ", 4) == 0) /* valid account */ { writeError(ERR_DEBUG_MODULE, "[%s] Found valid account: %s", MODULE_NAME, szAccount); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_RUNNING; } else if (strncmp(bufReceive, "550 ", 4) == 0) /* non-existant account */ { writeError(ERR_DEBUG_MODULE, "[%s] Non-existant account: %s", MODULE_NAME, szAccount); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } else if (strncmp(bufReceive, "557 ", 4) == 0) /* 557 5.5.2 String does not match anything. */ { writeError(ERR_DEBUG_MODULE, "[%s] Non-existant account: %s", MODULE_NAME, szAccount); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } else if (strncmp(bufReceive, "554 ", 4) == 0) /* invalid domain name */ { writeError(ERR_ERROR, "[%s] Invalid domain name: %s", MODULE_NAME, szDomain); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else { writeError(ERR_ERROR, "[%s] Unknown response code: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } /* check if more data is waiting */ if (medusaDataReadyTimed(hSocket, 0, 20000) > 0) bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (strstr(bufReceive, "421 Error: too many errors")) { writeError(ERR_DEBUG_MODULE, "[%s] Too many errors. Restarting connection.", MODULE_NAME); iRet = MSTATE_NEW; } setPassResult((*psLogin), szDomain); return(iRet); } medusa-2.1.1/Makefile.in0000644000175000001440000006221411760001577011764 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ TODO config.guess config.sub depcomp install-sh ltmain.sh \ missing mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" NROFF = nroff MANS = $(man_MANS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d "$(distdir)" \ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr "$(distdir)"; }; } am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ APR_CONFIG = @APR_CONFIG@ APR_INCLUDE_DIR = @APR_INCLUDE_DIR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_MOD_PATH = @DEFAULT_MOD_PATH@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODULE_LIBS = @MODULE_LIBS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = gnu SUBDIRS = src man_MANS = doc/medusa.1 EXTRA_DIST = doc/medusa.1 doc/*.html misc/rdesktop/rdp-brute-force.diff misc/rdesktop/rdesktop-1.5.0-brute-force.patch misc/net-analyzer/medusa-2.1.1.ebuild misc/zsh/_medusa all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 install-man1: $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @$(am__cd) '$(distuninstallcheck_dir)' \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(MANS) config.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-man install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-man1 install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ ctags-recursive install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ distclean distclean-generic distclean-hdr distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man1 install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-man uninstall-man1 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: medusa-2.1.1/missing0000755000175000001440000002403611723732130011311 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # 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. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. You can get \`$1Help2man' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 medusa-2.1.1/config.guess0000755000175000001440000012633411723732130012236 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-03-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # 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. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown if [ "${UNAME_SYSTEM}" = "Linux" ] ; then eval $set_cc_for_build cat << EOF > $dummy.c #include #ifdef __UCLIBC__ # ifdef __UCLIBC_CONFIG_VERSION__ LIBC=uclibc __UCLIBC_CONFIG_VERSION__ # else LIBC=uclibc # endif #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep LIBC= | sed -e 's: ::g'` fi # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; amd64:OpenBSD:*:*) echo x86_64-unknown-openbsd${UNAME_RELEASE} exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; cats:OpenBSD:*:*) echo arm-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; luna88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; macppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvmeppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mips64-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sun3:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit 0 ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit 0 ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit 0 ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit 0;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit 0 ;; *:OS400:*:*) echo powerpc-ibm-os400 exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit 0 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7 && exit 0 ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c \ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && exit 0 echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit 0 ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then # avoid double evaluation of $set_cc_for_build test -n "$CC_FOR_BUILD" || eval $set_cc_for_build if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; x86:Interix*:[34]*) echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' exit 0 ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; amd64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit 0 ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit 0 ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit 0 ;; cris:Linux:*:*) echo cris-axis-linux-${LIBC} exit 0 ;; crisv32:Linux:*:*) echo crisv32-axis-linux-${LIBC} exit 0 ;; frv:Linux:*:*) echo frv-unknown-linux-${LIBC} exit 0 ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit 0 ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit 0 ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit 0 ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && echo "${CPU}-unknown-linux-${LIBC}" && exit 0 ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && echo "${CPU}-unknown-linux-${LIBC}" && exit 0 ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit 0 ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit 0 ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit 0 ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit 0 ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit 0 ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit 0 ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit 0 ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit 0 ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit 0 ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-${LIBC} exit 0 ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-${LIBC}" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-${LIBC}aout" exit 0 ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-${LIBC}coff" exit 0 ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-${LIBC}oldld" exit 0 ;; esac if [ "`echo $LIBC | sed -e 's:uclibc::'`" != "$LIBC" ] ; then echo "$TENTATIVE" && exit 0 ; fi # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit 0 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit 0 ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit 0 ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit 0 ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit 0 ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; i*86:*:5:[78]*) case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit 0 ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit 0 ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit 0 ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in *86) UNAME_PROCESSOR=i686 ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit 0 ;; *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit 0 ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit 0 ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit 0 ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit 0 ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit 0 ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit 0 ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit 0 ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit 0 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit 0 ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit 0 ;; *:ITS:*:*) echo pdp10-unknown-its exit 0 ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit 0 ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms && exit 0 ;; I*) echo ia64-dec-vms && exit 0 ;; V*) echo vax-dec-vms && exit 0 ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: medusa-2.1.1/misc/0000755000175000001440000000000011760001577010725 500000000000000medusa-2.1.1/misc/zsh/0000755000175000001440000000000011760001577011531 500000000000000medusa-2.1.1/misc/zsh/_medusa0000644000175000001440000000510211723732130013002 00000000000000#compdef medusa # Copy this file to your global zsh site-functions directory # ex: /usr/local/share/zsh/site-functions # Written by Bismark (bismark@foofus.net) # Date: 09/22/2008 # # Modified by Bismark (bismark@foofus.net) # Date: 01/24/2010 # Changes: # Removed completion prompts for options that do not have a value # Added option removal for conflicting options. typeset -A opt_args _select_module() { local modules modules=( $(medusa -d | grep + | awk '/.mod/ {print $2}' | cut -d"." -f 1) ) _wanted select-module expl 'Module' compadd "$@" -a - modules } _medusa() { local expl context state line ret=1 local -A opt_args _arguments \ '-b[Suppress startup banner]' \ '-O[File to append log information to.]:Log file:_files' \ '-M[Name of the module to execute (without the .mod extension)]:Module:_select_module' \ '*-m[Parameter to pass to the module.]:Module Parameters' \ '-d[Dump all known modules.]:Dump Modules' \ '-n[Use for non-default TCP port number.]:tcp port' \ '-s[Enable SSL.]' \ '-g[Give up after trying to connect for NUM seconds (default 3).]:Retry seconds' \ '-r[Sleep number of seconds between retry attempts (default 3).]:Sleep seconds' \ '-R[Attempted retries before giving up. The total number of attempts will be retries + 1.]:Retries' \ '-t[Total number of logins to be tested concurrently]:Concurrent Logins' \ '-T[Total number of hosts to be tested concurrently.]:Concurrent Hosts' \ '-L[Parallelize logins using one username per thread.]' \ '-f[Stop scanning host after first valid username/password found.]' \ '-F[Stop audit after first valid username/password found on any host.]' \ '-q[Display module’s usage information.]' \ '-v[Verbose level (0 - 6)]:Verbosity:(0 1 2 3 4 5 6)' \ '-w[Error debug level (0 - 10)]:Debug:(0 1 2 3 4 5 6 7 8 9 10)' \ '-V[Display version]' \ "-e[Additional password checks]:Additional password checks:_values 'Additional password checks' 'n[No Password]' 's[Password = Username]' 'ns[No Password & Password = Username]'":'(n s ns)' \ '(-H -C)-h[Target hostname or IP address.]:Hostname or IP Address' \ '(-h -C)-H[Read Targets from a file.]:Hosts file:_files' \ '(-H -U -P -u -p)-C[File containing combo entries. (see man page)]:Combo file':_files \ '(-U -C)-u[Username.]:Username' \ '(-P -C)-p[Password.]:Password' \ '(-u -C)-U[Read Usernames from a file.]:Username file:_files' \ '(-P -C)-P[Read Passwords from a file.]:Password file:_files' && return 0 return 1 } _medusa "$@" medusa-2.1.1/misc/rdesktop/0000755000175000001440000000000011760001577012560 500000000000000medusa-2.1.1/misc/rdesktop/rdesktop-1.5.0-brute-force.patch0000644000175000001440000006470111723732130020231 00000000000000Only in rdesktop-1.5.0: Makefile diff -urp rdesktop-1.5.0.orig/Makefile.in rdesktop-1.5.0/Makefile.in --- rdesktop-1.5.0.orig/Makefile.in 2006-04-10 02:27:50.000000000 +0800 +++ rdesktop-1.5.0/Makefile.in 2007-08-22 16:51:07.000000000 +0800 @@ -57,7 +57,7 @@ install: installbin installkeymaps insta installbin: rdesktop mkdir -p $(DESTDIR)$(bindir) $(INSTALL) rdesktop $(DESTDIR)$(bindir) - $(STRIP) $(DESTDIR)$(bindir)/rdesktop + chmod 755 $(DESTDIR)$(bindir)/rdesktop .PHONY: installman Only in rdesktop-1.5.0: config.log Only in rdesktop-1.5.0: config.status diff -urp rdesktop-1.5.0.orig/configure rdesktop-1.5.0/configure --- rdesktop-1.5.0.orig/configure 2006-09-13 20:10:40.000000000 +0800 +++ rdesktop-1.5.0/configure 2007-08-22 16:51:07.000000000 +0800 @@ -1986,13 +1986,13 @@ if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then - CFLAGS="-g -O2" +cflags="$cflags ${CFLAGS}" else CFLAGS="-g" fi else if test "$GCC" = yes; then - CFLAGS="-O2" +cflags="$cflags ${CFLAGS}" else CFLAGS= fi diff -urp rdesktop-1.5.0.orig/orders.c rdesktop-1.5.0/orders.c --- rdesktop-1.5.0.orig/orders.c 2006-08-07 19:45:43.000000000 +0800 +++ rdesktop-1.5.0/orders.c 2007-08-22 13:03:36.000000000 +0800 @@ -21,10 +21,21 @@ #include "rdesktop.h" #include "orders.h" + extern uint8 *g_next_packet; static RDP_ORDER_STATE g_order_state; extern BOOL g_use_rdp5; +/* brute-force mode */ +#include +#include "scancodes.h" +extern BOOL g_brute_complete; +extern int g_brute_logon_status; +extern int g_brute_mode; +extern int g_server_version; +extern int g_brute_w2k_send_logon; +extern int g_w2k_auth_count; + /* Read field indicating which parameters are present */ static void rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size) @@ -863,6 +874,99 @@ process_text2(STREAM s, TEXT2_ORDER * os DEBUG(("\n")); + /* Check text for failed logon message. This is a complete guess/hack... */ + if (g_brute_mode != BRUTE_NONE) + { + if (!memcmp(os->text, LOGON_AUTH_FAILED, 3)) + { + fprintf(stderr, "Retrieved connection termination packet.\n"); + g_brute_complete = True; + } + + if (g_server_version == VERSION_SRV_2K) + { + if (!memcmp(os->text, LOGON_W2K_BANNER, 23)) + { + fprintf(stderr, "Retrieved Windows 2000 logon window.\n"); + g_brute_w2k_send_logon = LOGIN_WIN_READY; + } + + /* if we see this message twice and we haven't seen "FE 00 00", we must have succeeded, right??? */ + if (!memcmp(os->text, LOGON_W2K_MESSAGE, 4)) + { + g_w2k_auth_count++; + + if ((!g_brute_complete) && (g_w2k_auth_count > 1)) + { + fprintf(stderr, "Windows 2000 successful authentication.\n"); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + g_brute_complete = True; + } + } + else if (g_brute_complete) + { + fprintf(stderr, "Windows 2000 authentication failed.\n"); + if (g_brute_logon_status == LOGIN_RESULT_UNKNOWN) + g_brute_logon_status = LOGIN_RESULT_FAIL; + } + } + + if ((!memcmp(os->text, LOGON_MESSAGE_FAILED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_FAILED_2K3, 18))) + { + fprintf(stderr, "Account credentials are NOT valid.\n"); + g_brute_logon_status = LOGIN_RESULT_FAIL; + } + else if ((!memcmp(os->text, LOGON_MESSAGE_NO_INTERACTIVE_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_NO_INTERACTIVE_2K3, 18))) + { + fprintf(stderr, "Account credentials are valid, however, the account is denied interactive logon.\n"); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + } + else if ((!memcmp(os->text, LOGON_MESSAGE_LOCKED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_LOCKED_2K3, 18))) + { + fprintf(stderr, "Account is currently locked out.\n"); + g_brute_logon_status = LOGIN_RESULT_ERROR; + } + else if ((!memcmp(os->text, LOGON_MESSAGE_DISABLED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_DISABLED_2K3, 18))) + { + fprintf(stderr, "Account is currently disabled or expired. XP appears to report that an account is disabled only for valid credentials.\n"); + g_brute_logon_status = LOGIN_RESULT_ERROR; + } + else if ((!memcmp(os->text, LOGON_MESSAGE_EXPIRED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_EXPIRED_2K3, 18)) || + (!memcmp(os->text, LOGON_MESSAGE_EXPIRED_W2K, 18))) + { + fprintf(stderr, "Account credentials are valid, however, the password has expired and must be changed.\n"); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + } + else if ((!memcmp(os->text, LOGON_MESSAGE_MUST_CHANGE_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_MUST_CHANGE_2K3, 18))) + { + fprintf(stderr, "Account credentials are valid, however, the password must be changed at first logon.\n"); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + } + else if (!memcmp(os->text, LOGON_MESSAGE_MSTS_MAX_2K3, 18)) + { + fprintf(stderr, "Account credentials are valid, however, the maximum number of terminal services connections has been reached.\n"); + rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_ESC ); + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_ESC ); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + } + else if (!memcmp(os->text, LOGON_MESSAGE_CURRENT_USER_XP, 18)) + { + fprintf(stderr, "Valid credentials, however, another user is currently logged on.\n"); + /* Unable to ESC message about booting current user, so say NO. */ + rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_N ); + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_N ); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + g_brute_complete = True; + } + else + { + DEBUG(("Logon failed with unknown text message: ")); + for (i = 0; i < os->length; i++) + DEBUG(("%02x ", os->text[i])); + DEBUG(("\n")); + } + } + ui_draw_text(os->font, os->flags, os->opcode - 1, os->mixmode, os->x, os->y, os->clipleft, os->cliptop, os->clipright - os->clipleft, os->clipbottom - os->cliptop, os->boxleft, os->boxtop, diff -urp rdesktop-1.5.0.orig/orders.h rdesktop-1.5.0/orders.h --- rdesktop-1.5.0.orig/orders.h 2006-08-07 19:45:43.000000000 +0800 +++ rdesktop-1.5.0/orders.h 2007-08-22 13:03:36.000000000 +0800 @@ -18,6 +18,52 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* brute-force code */ + +/* The following is a complete guess... */ + +/* This appears to indicate that our attempt has failed in some way */ +#define LOGON_AUTH_FAILED "\xfe\x00\x00" + +/* Windows 2000 logon banner */ +#define LOGON_W2K_BANNER "\x1d\x00\x0c\x07\x1e\x07\x1f\x08\x20\x08\x21\x07\x1f\x06\x22\x08\x1f\x07\x1e\x08\x23\x08\x24" + +/* Using this string to track if we've successfully logged on */ +#define LOGON_W2K_MESSAGE "\x1f\x00\x26\x08" + +/* The system could not log you on. Make sure your User name and domain are correct [FAILED] */ +#define LOGON_MESSAGE_FAILED_XP "\x17\x00\x18\x06\x10\x06\x1a\x09\x1b\x05\x1a\x06\x1c\x05\x10\x04\x1d\x06" +#define LOGON_MESSAGE_FAILED_2K3 "\x11\x00\x12\x06\x13\x06\x15\x09\x16\x05\x15\x06\x17\x05\x13\x04\x18\x06" + +/* The local policy of this system does not permit you to logon interactively. [SUCCESS] */ +#define LOGON_MESSAGE_NO_INTERACTIVE_XP "\x17\x00\x18\x06\x10\x06\x11\x09\x1a\x02\x0f\x06\x0d\x05\x11\x06\x1b\x05" +#define LOGON_MESSAGE_NO_INTERACTIVE_2K3 "\x11\x00\x12\x06\x13\x06\x15\x09\x16\x02\x17\x06\x18\x05\x15\x06\x19\x05" + +/* Unable to log you on because your account has been locked out */ +#define LOGON_MESSAGE_LOCKED_XP "\x17\x00\x0e\x07\x0d\x06\x18\x06\x11\x06\x10\x02\x1a\x09\x1b\x04\x11\x09" +#define LOGON_MESSAGE_LOCKED_2K3 "\x11\x00\x12\x07\x13\x06\x14\x06\x15\x06\x16\x02\x18\x09\x19\x04\x15\x09" + +/* Your account has been disabled. Please see your system administrator. [ERROR] */ +/* Your account has expired. Please see your system administrator. [ERROR] */ +#define LOGON_MESSAGE_DISABLED_XP "\x17\x00\x18\x06\x19\x06\x1a\x06\x0d\x07\x0f\x06\x0f\x05\x18\x05\x19\x06" +#define LOGON_MESSAGE_DISABLED_2K3 "\x11\x00\x12\x06\x13\x06\x14\x06\x16\x07\x17\x06\x17\x05\x12\x05\x13\x06" + +/* Your password has expired and must be changed. [SUCCESS] */ +#define LOGON_MESSAGE_EXPIRED_XP "\x17\x00\x18\x06\x19\x06\x0d\x09\x1b\x06\x10\x04\x1b\x09\x10\x04\x1c\x06" +#define LOGON_MESSAGE_EXPIRED_2K3 "\x11\x00\x12\x06\x13\x06\x14\x06\x16\x07\x17\x06\x18\x06\x18\x05\x19\x05" +#define LOGON_MESSAGE_EXPIRED_W2K "\x00\x00\x01\x06\x02\x07\x01\x07\x05\x07\x2d\x0a\x2e\x0a\x0b\x07\x0b\x06" + +/* You are required to change your password at first logon. [SUCCESS] */ +#define LOGON_MESSAGE_MUST_CHANGE_XP "\x17\x00\x18\x06\x19\x06\x0d\x09\x1b\x06\x10\x04\x1b\x09\x10\x04\x1c\x06" +#define LOGON_MESSAGE_MUST_CHANGE_2K3 "\x11\x00\x12\x06\x13\x06\x15\x09\x16\x06\x17\x04\x16\x09\x17\x04\x18\x06" + +/* The terminal server has exceeded the maximum number of allowed connections. [SUCCESS] */ +#define LOGON_MESSAGE_MSTS_MAX_2K3 "\x00\x00\x01\x06\x02\x07\x01\x07\x05\x07\x24\x0a\x25\x0a\x0b\x07\x0b\x06\x26" + +/* The user MACHINE_NAME\USER is currently logged on to this computer. [SUCCESS] */ +#define LOGON_MESSAGE_CURRENT_USER_XP "\x12\x00\x13\x07\x10\x05\x14\x06\x0e\x07\x0d\x06\x16\x06\x10\x08\x17\x06" +/* end brute-force code */ + #define RDP_ORDER_STANDARD 0x01 #define RDP_ORDER_SECONDARY 0x02 #define RDP_ORDER_BOUNDS 0x04 diff -urp rdesktop-1.5.0.orig/rdesktop.c rdesktop-1.5.0/rdesktop.c --- rdesktop-1.5.0.orig/rdesktop.c 2006-08-07 19:45:43.000000000 +0800 +++ rdesktop-1.5.0/rdesktop.c 2007-08-22 16:51:07.000000000 +0800 @@ -16,6 +16,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + 2005-07-07 - Added dictionary support for automated login testing + patrik@cqure.net + + 2005-12-22 - Modified stdin password method to support Medusa wrapper + module (www.foofus.net/jmk/medusa/medusa.html). Also heavily + modified brute-force guessing to match various error messages + and kinda work against Windows 2000. + JoMo-Kun */ #include /* va_list va_start va_end */ @@ -47,6 +57,13 @@ #include +int g_brute_mode = BRUTE_NONE; +int g_brute_logon_status = LOGIN_RESULT_UNKNOWN; +int g_server_version = VERSION_SRV_UNKNOWN; +int g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN; +int g_w2k_auth_count = 0; +char *g_password = NULL; + char g_title[64] = ""; char g_username[64]; char g_hostname[16]; @@ -103,6 +120,8 @@ char g_redirect_username[64]; char g_redirect_cookie[128]; uint32 g_redirect_flags = 0; +FILE *g_logger = NULL; + #ifdef WITH_RDPSND BOOL g_rdpsnd = False; #endif @@ -114,6 +133,7 @@ char g_codepage[16] = ""; extern RDPDR_DEVICE g_rdpdr_device[]; extern uint32 g_num_devices; extern char *g_rdpdr_clientname; +extern BOOL g_loggedon; #ifdef RDP2VNC extern int rfb_port; @@ -128,6 +148,8 @@ usage(char *program) { fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n"); fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n"); + fprintf(stderr, "Password guess patch by patrik@cqure.net\n"); + fprintf(stderr, "Modified by jmk@foofus.net for use with the brute-forcer Medusa.\n"); fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n"); fprintf(stderr, "Usage: %s [options] server[:port]\n", program); @@ -139,7 +161,7 @@ usage(char *program) fprintf(stderr, " -d: domain\n"); fprintf(stderr, " -s: shell\n"); fprintf(stderr, " -c: working directory\n"); - fprintf(stderr, " -p: password (- to prompt)\n"); + fprintf(stderr, " -p: password (- to prompt,filename for dictionary)\n"); fprintf(stderr, " -n: client hostname\n"); fprintf(stderr, " -k: keyboard layout on server (en-us, de, sv, etc.)\n"); fprintf(stderr, " -g: desktop geometry (WxH)\n"); @@ -191,6 +213,7 @@ usage(char *program) fprintf(stderr, " -0: attach to console\n"); fprintf(stderr, " -4: use RDP version 4\n"); fprintf(stderr, " -5: use RDP version 5 (default)\n"); + fprintf(stderr, " -l: logfile\n"); } static void @@ -383,6 +406,41 @@ parse_server_and_port(char *server) } +void +chomp( char *p ) +{ + while( *p ) + { + if (( '\r' == *p ) || ( '\n' == *p ) ) + *p = 0; + + *p++; + } +} + +int +logprintf( const char *format, ... ) +{ + + va_list args; + int i; + + va_start( args, format ); + + if ( g_logger ) { + i = vfprintf( g_logger, format, args ); + vprintf( format, args ); + } + else { + i = vprintf( format, args ); + } + + va_end( args ); + + return i; +} + + /* Client program */ int main(int argc, char *argv[]) @@ -393,11 +451,12 @@ main(int argc, char *argv[]) char password[64]; char shell[256]; char directory[256]; + FILE *dicfile = NULL; BOOL prompt_password, deactivated; struct passwd *pw; uint32 flags, ext_disc_reason = 0; char *p; - int c; + int c, i; char *locale = NULL; int username_option = 0; BOOL geometry_option = False; @@ -427,7 +486,7 @@ main(int argc, char *argv[]) #endif while ((c = getopt(argc, argv, - VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1) + VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?l:")) != -1) { switch (c) { @@ -478,6 +537,13 @@ main(int argc, char *argv[]) if ((optarg[0] == '-') && (optarg[1] == 0)) { prompt_password = True; + g_brute_mode = BRUTE_STDIN; + flags |= RDP_LOGON_AUTO; + break; + } + else if ( (dicfile = fopen( optarg, "r" ) ) ) { + g_brute_mode = BRUTE_FILE; + flags |= RDP_LOGON_AUTO; break; } @@ -746,6 +812,13 @@ main(int argc, char *argv[]) case '5': g_use_rdp5 = True; break; + case 'l': + if ( NULL == ( g_logger = fopen( optarg, "w" ) ) ) + { + fprintf(stderr, "Failed to open logfile (%s)\n", optarg); + return 1; + } + break; case 'h': case '?': @@ -857,9 +930,6 @@ main(int argc, char *argv[]) xfree(locale); - if (prompt_password && read_password(password, sizeof(password))) - flags |= RDP_LOGON_AUTO; - if (g_title[0] == 0) { strcpy(g_title, "rdesktop - "); @@ -886,6 +956,7 @@ main(int argc, char *argv[]) while (run_count < 2 && continue_connect) /* add support for Session Directory; only reconnect once */ { + if (g_brute_mode == BRUTE_NONE){ if (run_count == 0) { if (!rdp_connect(server, flags, domain, password, shell, directory)) @@ -894,25 +965,165 @@ main(int argc, char *argv[]) else if (!rdp_reconnect (server, flags, domain, password, shell, directory, g_redirect_cookie)) return 1; + } /*IF BRUTE end */ /* By setting encryption to False here, we have an encrypted login packet but unencrypted transfer of other packets */ if (!packet_encryption) g_encryption = False; - + if (g_brute_mode == BRUTE_NONE) + { DEBUG(("Connection successful.\n")); memset(password, 0, sizeof(password)); + } if (run_count == 0) if (!ui_create_window()) continue_connect = False; - if (continue_connect) + if (continue_connect){ + if ((g_brute_mode == BRUTE_FILE) && (dicfile)) { + logprintf("\nStarting dictionary attack against server %s\n", server); + logprintf("------------------------------------------"); + + for ( i=0; i 15) + { + fprintf(stderr, "This shit is broke, I'm bailing...\n"); + return 1; + } + } + + if (g_server_version == VERSION_SRV_2K) + { + fprintf(stderr, "Server appears to be Windows 2000, brute-force guessing kinda works...\n"); + g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN; + g_w2k_auth_count = 0; + g_password = password; + } + + if (!packet_encryption) + g_encryption = False; + rdp_main_loop(&deactivated, &ext_disc_reason); + rdp_disconnect(); + + switch (g_brute_logon_status) + { + case LOGIN_RESULT_SUCCESS: + logprintf("[success] User \"%s\" Password \"%s\"\n", g_username, password ); + break; + case LOGIN_RESULT_FAIL: + logprintf( "[failure] User \"%s\" Password \"%s\"\n", g_username, password ); + break; + case LOGIN_RESULT_ERROR: + logprintf( "[error] User \"%s\" Password \"%s\"\n", g_username, password ); + return 1; + break; + default: + logprintf( "[error] User \"%s\" Password \"%s\". Connection terminated due to unknown error.\n", g_username, password ); + return 1; + break; + } + } + } + else if (g_brute_mode == BRUTE_STDIN) + { + fprintf(stderr, "Starting brute-force attack via STDIN against %s\n", server); + + while(!g_loggedon) + { + read_password(password, sizeof(password)); + + g_encryption = True; + + int sleep_count = 0; + while (!rdp_connect(server, flags, domain, password, shell, directory)) + { + /* rdesktop seems to flake out after brute-forcing a bit. let's try again... */ + fprintf(stderr, "Server appears to be flaking out. Sleeping (%d) seconds...\n", sleep_count); + sleep(sleep_count); + sleep_count += 5; + + if (sleep_count > 15) + { + fprintf(stderr, "This shit is broke, I'm bailing...\n"); + fprintf(stderr, "LOGIN_RESULT_ERROR:Server stopped responding.\n"); + return 1; + } + } + + if (g_server_version == VERSION_SRV_2K) + { + fprintf(stderr, "Server appears to be Windows 2000, brute-force guessing kinda works...\n"); + g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN; + g_w2k_auth_count = 0; + g_password = password; + } + + if (!packet_encryption) + g_encryption = False; + + rdp_main_loop(&deactivated, &ext_disc_reason); + rdp_disconnect(); + + switch (g_brute_logon_status) + { + case LOGIN_RESULT_SUCCESS: + fprintf(stderr, "LOGIN_RESULT_SUCCESS\n"); + break; + case LOGIN_RESULT_FAIL: + fprintf(stderr, "LOGIN_RESULT_FAILURE\n"); + break; + case LOGIN_RESULT_ERROR: + fprintf(stderr, "LOGIN_RESULT_ERROR\n"); + return 1; + break; + default: + fprintf(stderr, "LOGIN_RESULT_ERROR:Connection terminated due to unknown error.\n"); + return 1; + break; + } + } + } + else + { + rdp_main_loop(&deactivated, &ext_disc_reason); + } + + + } /* continue connect */ + + + if (g_brute_mode == BRUTE_NONE) { DEBUG(("Disconnecting...\n")); rdp_disconnect(); + } + else + { + if (g_logger) + fclose( g_logger ); + } + if ((g_redirect == True) && (run_count == 0)) /* Support for Session Directory */ { @@ -1366,7 +1577,6 @@ subprocess(char *const argv[], str_handl return True; } - /* not all clibs got ltoa */ #define LTOA_BUFSIZE (sizeof(long) * 8 + 1) diff -urp rdesktop-1.5.0.orig/rdesktop.h rdesktop-1.5.0/rdesktop.h --- rdesktop-1.5.0.orig/rdesktop.h 2006-09-13 20:09:14.000000000 +0800 +++ rdesktop-1.5.0/rdesktop.h 2007-08-22 13:03:36.000000000 +0800 @@ -33,6 +33,20 @@ #define VERSION "1.5.0" +#define BRUTE_NONE 1 +#define BRUTE_STDIN 2 +#define BRUTE_FILE 3 +#define VERSION_SRV_UNKNOWN 0 +#define VERSION_SRV_XP2K3 1 +#define VERSION_SRV_2K 2 +#define LOGIN_RESULT_UNKNOWN 1 +#define LOGIN_RESULT_SUCCESS 2 +#define LOGIN_RESULT_FAIL 3 +#define LOGIN_RESULT_ERROR 4 +#define LOGIN_WIN_UNKNOWN 0 +#define LOGIN_WIN_PROC 1 +#define LOGIN_WIN_READY 2 + #ifdef WITH_DEBUG #define DEBUG(args) printf args; #else diff -urp rdesktop-1.5.0.orig/rdp.c rdesktop-1.5.0/rdp.c --- rdesktop-1.5.0.orig/rdp.c 2006-08-07 19:45:43.000000000 +0800 +++ rdesktop-1.5.0/rdp.c 2007-08-22 13:03:36.000000000 +0800 @@ -16,12 +16,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + 2005-07-07 Addedd support for detecting failed/successful login attempts + */ #include #include #include #include "rdesktop.h" +#include "scancodes.h" #ifdef HAVE_ICONV #ifdef HAVE_ICONV_H @@ -74,6 +78,20 @@ static uint32 g_packetno; static BOOL g_iconv_works = True; #endif +/* brute-force stuff */ +extern int g_brute_mode; +extern int g_server_version; +extern int g_brute_logon_status; +extern char* g_password; +extern BOOL g_brute_w2k_send_logon; +BOOL g_loggedon = False; +BOOL g_brute_complete = False; +#define KEYMAP_MASK 0xffff +#define KEYMAP_SIZE 0xffff+1 +extern key_translation keymap[KEYMAP_SIZE]; +/* end brute-force */ + + /* Receive an RDP packet */ static STREAM rdp_recv(uint8 * type) @@ -1288,6 +1306,7 @@ process_data_pdu(STREAM s, uint32 * ext_ case RDP_DATA_PDU_LOGON: DEBUG(("Received Logon PDU\n")); + g_loggedon = True; /* User logged on */ break; @@ -1375,6 +1394,63 @@ rdp_loop(BOOL * deactivated, uint32 * ex while (cont) { + if (g_brute_mode != BRUTE_NONE) + { + if ( g_loggedon ) + { + DEBUG(("Brute-force complete, successful authentication.\n")); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + disc = True; + } + else if ( g_brute_complete ) + { + /* failed */ + DEBUG(("Brute-force complete, terminating connection.\n")); + rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_ESC ); + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_ESC ); + g_brute_complete = False; + + /* w2k success */ + if (g_server_version == VERSION_SRV_2K) + disc = True; + } + + if ((g_server_version == VERSION_SRV_2K) && (g_brute_w2k_send_logon == LOGIN_WIN_READY)) + { + g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN; + + DEBUG(("Sending password: %s\n", g_password)); + int i; + char keysym; + uint8 scancode; + + /* TAB to username field to view text */ + //for(i = 0; i < 5; i++) + //{ + // rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_TAB ); + // rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_TAB ); + //} + + for(i = 0; i < strlen(g_password); i++) + { + keysym = g_password[i]; + scancode = keymap[keysym & KEYMAP_MASK].scancode; + DEBUG(("Sending CHAR: %c KEYSYM: 0x%x SCANCODE: 0x%x\n", keysym, (unsigned int) keysym, scancode)); + + if (keymap[keysym & KEYMAP_MASK].modifiers == 0x0) + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT); + else + rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT); + + rdp_send_scancode( time(NULL), RDP_KEYPRESS, scancode ); + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, scancode ); + } + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT); + rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_ENTER ); + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_ENTER ); + } + } + s = rdp_recv(&type); if (s == NULL) return False; @@ -1396,6 +1472,15 @@ rdp_loop(BOOL * deactivated, uint32 * ex break; case 0: break; + case 15: + /* Intermittent with W2K brute-forcing issue */ + if (g_server_version == VERSION_SRV_2K) + { + DEBUG(("Brute-force connection to Windows 2000 is fubar'd.\n")); + g_brute_logon_status = LOGIN_RESULT_ERROR; + disc = True; + } + break; default: unimpl("PDU %d\n", type); } Only in rdesktop-1.5.0: rdp.c.orig diff -urp rdesktop-1.5.0.orig/secure.c rdesktop-1.5.0/secure.c --- rdesktop-1.5.0.orig/secure.c 2006-08-07 19:45:43.000000000 +0800 +++ rdesktop-1.5.0/secure.c 2007-08-22 13:03:36.000000000 +0800 @@ -42,6 +42,8 @@ extern uint16 mcs_userid; extern VCHANNEL g_channels[]; extern unsigned int g_num_channels; +extern int g_server_version; + static int rc4_key_len; static RC4_KEY rc4_decrypt_key; static RC4_KEY rc4_encrypt_key; @@ -786,6 +788,33 @@ sec_process_srv_info(STREAM s) g_use_rdp5 = 0; g_server_depth = 8; } + + /* + Attempting to determine server OS version. It appears that the 21st + byte in the response is 0x02 for XP/2K3 and 0x01 for W2K. Don't know + what this byte actually represents, so this is a complete hack... + + -0010 02 0c ec 00 01 00 00 00 02 00 00 00 20 00 00 00 ............ ... + +0010 02 0c ec 00 02 00 00 00 02 00 00 00 20 00 00 00 ............ ... + */ + + //int datalen = s->end - s->p; + //hexdump(s->p, datalen); + switch ( *(s->p + 18) ) + { + case 0x01: + DEBUG_RDP5(("Server version appears to be Windows 2000.\n")); + g_server_version = VERSION_SRV_2K; + break; + case 0x02: + DEBUG_RDP5(("Server version appears to be Windows XP/2003.\n")); + g_server_version = VERSION_SRV_XP2K3; + break; + default: + DEBUG_RDP5(("Server version unknown. Interesting data: %d.\n", *(s->p + 18))); + g_server_version = VERSION_SRV_UNKNOWN; + break; + } } diff -urp rdesktop-1.5.0.orig/xkeymap.c rdesktop-1.5.0/xkeymap.c --- rdesktop-1.5.0.orig/xkeymap.c 2006-08-07 19:45:44.000000000 +0800 +++ rdesktop-1.5.0/xkeymap.c 2007-08-22 16:48:57.000000000 +0800 @@ -51,7 +51,8 @@ extern BOOL g_use_rdp5; extern BOOL g_numlock_sync; static BOOL keymap_loaded; -static key_translation *keymap[KEYMAP_SIZE]; +//static key_translation *keymap[KEYMAP_SIZE]; +key_translation *keymap[KEYMAP_SIZE]; static int min_keycode; static uint16 remote_modifier_state = 0; static uint16 saved_remote_modifier_state = 0; medusa-2.1.1/misc/rdesktop/rdp-brute-force.diff0000644000175000001440000005770311723732130016341 00000000000000diff -rub rdesktop-1.4.1/orders.c rdesktop-jmk/orders.c --- rdesktop-1.4.1/orders.c 2005-04-23 17:38:37.000000000 -0500 +++ rdesktop-jmk/orders.c 2006-01-16 13:10:40.000000000 -0600 @@ -21,10 +21,21 @@ #include "rdesktop.h" #include "orders.h" + extern uint8 *g_next_packet; static RDP_ORDER_STATE g_order_state; extern BOOL g_use_rdp5; +/* brute-force mode */ +#include +#include "scancodes.h" +extern BOOL g_brute_complete; +extern int g_brute_logon_status; +extern int g_brute_mode; +extern int g_server_version; +extern int g_brute_w2k_send_logon; +extern int g_w2k_auth_count; + /* Read field indicating which parameters are present */ static void rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size) @@ -863,6 +874,99 @@ DEBUG(("\n")); + /* Check text for failed logon message. This is a complete guess/hack... */ + if (g_brute_mode != BRUTE_NONE) + { + if (!memcmp(os->text, LOGON_AUTH_FAILED, 3)) + { + fprintf(stderr, "Retrieved connection termination packet.\n"); + g_brute_complete = True; + } + + if (g_server_version == VERSION_SRV_2K) + { + if (!memcmp(os->text, LOGON_W2K_BANNER, 23)) + { + fprintf(stderr, "Retrieved Windows 2000 logon window.\n"); + g_brute_w2k_send_logon = LOGIN_WIN_READY; + } + + /* if we see this message twice and we haven't seen "FE 00 00", we must have succeeded, right??? */ + if (!memcmp(os->text, LOGON_W2K_MESSAGE, 4)) + { + g_w2k_auth_count++; + + if ((!g_brute_complete) && (g_w2k_auth_count > 1)) + { + fprintf(stderr, "Windows 2000 successful authentication.\n"); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + g_brute_complete = True; + } + } + else if (g_brute_complete) + { + fprintf(stderr, "Windows 2000 authentication failed.\n"); + if (g_brute_logon_status == LOGIN_RESULT_UNKNOWN) + g_brute_logon_status = LOGIN_RESULT_FAIL; + } + } + + if ((!memcmp(os->text, LOGON_MESSAGE_FAILED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_FAILED_2K3, 18))) + { + fprintf(stderr, "Account credentials are NOT valid.\n"); + g_brute_logon_status = LOGIN_RESULT_FAIL; + } + else if ((!memcmp(os->text, LOGON_MESSAGE_NO_INTERACTIVE_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_NO_INTERACTIVE_2K3, 18))) + { + fprintf(stderr, "Account credentials are valid, however, the account is denied interactive logon.\n"); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + } + else if ((!memcmp(os->text, LOGON_MESSAGE_LOCKED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_LOCKED_2K3, 18))) + { + fprintf(stderr, "Account is currently locked out.\n"); + g_brute_logon_status = LOGIN_RESULT_ERROR; + } + else if ((!memcmp(os->text, LOGON_MESSAGE_DISABLED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_DISABLED_2K3, 18))) + { + fprintf(stderr, "Account is currently disabled or expired. XP appears to report that an account is disabled only for valid credentials.\n"); + g_brute_logon_status = LOGIN_RESULT_ERROR; + } + else if ((!memcmp(os->text, LOGON_MESSAGE_EXPIRED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_EXPIRED_2K3, 18)) || + (!memcmp(os->text, LOGON_MESSAGE_EXPIRED_W2K, 18))) + { + fprintf(stderr, "Account credentials are valid, however, the password has expired and must be changed.\n"); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + } + else if ((!memcmp(os->text, LOGON_MESSAGE_MUST_CHANGE_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_MUST_CHANGE_2K3, 18))) + { + fprintf(stderr, "Account credentials are valid, however, the password must be changed at first logon.\n"); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + } + else if (!memcmp(os->text, LOGON_MESSAGE_MSTS_MAX_2K3, 18)) + { + fprintf(stderr, "Account credentials are valid, however, the maximum number of terminal services connections has been reached.\n"); + rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_ESC ); + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_ESC ); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + } + else if (!memcmp(os->text, LOGON_MESSAGE_CURRENT_USER_XP, 18)) + { + fprintf(stderr, "Valid credentials, however, another user is currently logged on.\n"); + /* Unable to ESC message about booting current user, so say NO. */ + rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_N ); + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_N ); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + g_brute_complete = True; + } + else + { + DEBUG(("Logon failed with unknown text message: ")); + for (i = 0; i < os->length; i++) + DEBUG(("%02x ", os->text[i])); + DEBUG(("\n")); + } + } + ui_draw_text(os->font, os->flags, os->opcode - 1, os->mixmode, os->x, os->y, os->clipleft, os->cliptop, os->clipright - os->clipleft, os->clipbottom - os->cliptop, os->boxleft, os->boxtop, diff -rub rdesktop-1.4.1/orders.h rdesktop-jmk/orders.h --- rdesktop-1.4.1/orders.h 2005-03-10 16:40:20.000000000 -0600 +++ rdesktop-jmk/orders.h 2006-01-16 12:41:04.000000000 -0600 @@ -18,6 +18,52 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* brute-force code */ + +/* The following is a complete guess... */ + +/* This appears to indicate that our attempt has failed in some way */ +#define LOGON_AUTH_FAILED "\xfe\x00\x00" + +/* Windows 2000 logon banner */ +#define LOGON_W2K_BANNER "\x1d\x00\x0c\x07\x1e\x07\x1f\x08\x20\x08\x21\x07\x1f\x06\x22\x08\x1f\x07\x1e\x08\x23\x08\x24" + +/* Using this string to track if we've successfully logged on */ +#define LOGON_W2K_MESSAGE "\x1f\x00\x26\x08" + +/* The system could not log you on. Make sure your User name and domain are correct [FAILED] */ +#define LOGON_MESSAGE_FAILED_XP "\x17\x00\x18\x06\x10\x06\x1a\x09\x1b\x05\x1a\x06\x1c\x05\x10\x04\x1d\x06" +#define LOGON_MESSAGE_FAILED_2K3 "\x11\x00\x12\x06\x13\x06\x15\x09\x16\x05\x15\x06\x17\x05\x13\x04\x18\x06" + +/* The local policy of this system does not permit you to logon interactively. [SUCCESS] */ +#define LOGON_MESSAGE_NO_INTERACTIVE_XP "\x17\x00\x18\x06\x10\x06\x11\x09\x1a\x02\x0f\x06\x0d\x05\x11\x06\x1b\x05" +#define LOGON_MESSAGE_NO_INTERACTIVE_2K3 "\x11\x00\x12\x06\x13\x06\x15\x09\x16\x02\x17\x06\x18\x05\x15\x06\x19\x05" + +/* Unable to log you on because your account has been locked out */ +#define LOGON_MESSAGE_LOCKED_XP "\x17\x00\x0e\x07\x0d\x06\x18\x06\x11\x06\x10\x02\x1a\x09\x1b\x04\x11\x09" +#define LOGON_MESSAGE_LOCKED_2K3 "\x11\x00\x12\x07\x13\x06\x14\x06\x15\x06\x16\x02\x18\x09\x19\x04\x15\x09" + +/* Your account has been disabled. Please see your system administrator. [ERROR] */ +/* Your account has expired. Please see your system administrator. [ERROR] */ +#define LOGON_MESSAGE_DISABLED_XP "\x17\x00\x18\x06\x19\x06\x1a\x06\x0d\x07\x0f\x06\x0f\x05\x18\x05\x19\x06" +#define LOGON_MESSAGE_DISABLED_2K3 "\x11\x00\x12\x06\x13\x06\x14\x06\x16\x07\x17\x06\x17\x05\x12\x05\x13\x06" + +/* Your password has expired and must be changed. [SUCCESS] */ +#define LOGON_MESSAGE_EXPIRED_XP "\x17\x00\x18\x06\x19\x06\x0d\x09\x1b\x06\x10\x04\x1b\x09\x10\x04\x1c\x06" +#define LOGON_MESSAGE_EXPIRED_2K3 "\x11\x00\x12\x06\x13\x06\x14\x06\x16\x07\x17\x06\x18\x06\x18\x05\x19\x05" +#define LOGON_MESSAGE_EXPIRED_W2K "\x00\x00\x01\x06\x02\x07\x01\x07\x05\x07\x2d\x0a\x2e\x0a\x0b\x07\x0b\x06" + +/* You are required to change your password at first logon. [SUCCESS] */ +#define LOGON_MESSAGE_MUST_CHANGE_XP "\x17\x00\x18\x06\x19\x06\x0d\x09\x1b\x06\x10\x04\x1b\x09\x10\x04\x1c\x06" +#define LOGON_MESSAGE_MUST_CHANGE_2K3 "\x11\x00\x12\x06\x13\x06\x15\x09\x16\x06\x17\x04\x16\x09\x17\x04\x18\x06" + +/* The terminal server has exceeded the maximum number of allowed connections. [SUCCESS] */ +#define LOGON_MESSAGE_MSTS_MAX_2K3 "\x00\x00\x01\x06\x02\x07\x01\x07\x05\x07\x24\x0a\x25\x0a\x0b\x07\x0b\x06\x26" + +/* The user MACHINE_NAME\USER is currently logged on to this computer. [SUCCESS] */ +#define LOGON_MESSAGE_CURRENT_USER_XP "\x12\x00\x13\x07\x10\x05\x14\x06\x0e\x07\x0d\x06\x16\x06\x10\x08\x17\x06" +/* end brute-force code */ + #define RDP_ORDER_STANDARD 0x01 #define RDP_ORDER_SECONDARY 0x02 #define RDP_ORDER_BOUNDS 0x04 diff -rub rdesktop-1.4.1/rdesktop.c rdesktop-jmk/rdesktop.c --- rdesktop-1.4.1/rdesktop.c 2005-04-22 17:12:28.000000000 -0500 +++ rdesktop-jmk/rdesktop.c 2006-01-16 13:34:07.000000000 -0600 @@ -16,6 +16,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + 2005-07-07 - Added dictionary support for automated login testing + patrik@cqure.net + + 2005-12-22 - Modified stdin password method to support Medusa wrapper + module (www.foofus.net/jmk/medusa/medusa.html). Also heavily + modified brute-force guessing to match various error messages + and kinda work against Windows 2000. + JoMo-Kun */ #include /* va_list va_start va_end */ @@ -47,6 +57,13 @@ #include +int g_brute_mode = BRUTE_NONE; +int g_brute_logon_status = LOGIN_RESULT_UNKNOWN; +int g_server_version = VERSION_SRV_UNKNOWN; +int g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN; +int g_w2k_auth_count = 0; +char *g_password = NULL; + char g_title[64] = ""; char g_username[64]; char g_hostname[16]; @@ -88,6 +105,7 @@ uint32 g_embed_wnd; uint32 g_rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS; +FILE *g_logger = NULL; #ifdef WITH_RDPSND BOOL g_rdpsnd = False; @@ -100,6 +118,7 @@ extern RDPDR_DEVICE g_rdpdr_device[]; extern uint32 g_num_devices; extern char *g_rdpdr_clientname; +extern BOOL g_loggedon; #ifdef RDP2VNC extern int rfb_port; @@ -114,6 +133,8 @@ { fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n"); fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n"); + fprintf(stderr, "Password guess patch by patrik@cqure.net\n"); + fprintf(stderr, "Modified by jmk@foofus.net for use with the brute-forcer Medusa.\n"); fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n"); fprintf(stderr, "Usage: %s [options] server[:port]\n", program); @@ -125,7 +146,7 @@ fprintf(stderr, " -d: domain\n"); fprintf(stderr, " -s: shell\n"); fprintf(stderr, " -c: working directory\n"); - fprintf(stderr, " -p: password (- to prompt)\n"); + fprintf(stderr, " -p: password (- to prompt,filename for dictionary)\n"); fprintf(stderr, " -n: client hostname\n"); fprintf(stderr, " -k: keyboard layout on server (en-us, de, sv, etc.)\n"); fprintf(stderr, " -g: desktop geometry (WxH)\n"); @@ -169,6 +190,7 @@ fprintf(stderr, " -0: attach to console\n"); fprintf(stderr, " -4: use RDP version 4\n"); fprintf(stderr, " -5: use RDP version 5 (default)\n"); + fprintf(stderr, " -l: logfile\n"); } void @@ -355,6 +377,41 @@ } +void +chomp( char *p ) +{ + while( *p ) + { + if (( '\r' == *p ) || ( '\n' == *p ) ) + *p = 0; + + *p++; + } +} + +int +logprintf( const char *format, ... ) +{ + + va_list args; + int i; + + va_start( args, format ); + + if ( g_logger ) { + i = vfprintf( g_logger, format, args ); + vprintf( format, args ); + } + else { + i = vprintf( format, args ); + } + + va_end( args ); + + return i; +} + + /* Client program */ int main(int argc, char *argv[]) @@ -365,11 +422,12 @@ char password[64]; char shell[128]; char directory[32]; + FILE *dicfile = NULL; BOOL prompt_password, deactivated; struct passwd *pw; uint32 flags, ext_disc_reason = 0; char *p; - int c; + int c, i; int username_option = 0; @@ -388,7 +446,7 @@ #endif while ((c = getopt(argc, argv, - VNCOPT "u:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1) + VNCOPT "u:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?l:")) != -1) { switch (c) { @@ -435,6 +493,13 @@ if ((optarg[0] == '-') && (optarg[1] == 0)) { prompt_password = True; + g_brute_mode = BRUTE_STDIN; + flags |= RDP_LOGON_AUTO; + break; + } + else if ( (dicfile = fopen( optarg, "r" ) ) ) { + g_brute_mode = BRUTE_FILE; + flags |= RDP_LOGON_AUTO; break; } @@ -681,6 +746,13 @@ case '5': g_use_rdp5 = True; break; + case 'l': + if ( NULL == ( g_logger = fopen( optarg, "w" ) ) ) + { + fprintf(stderr, "Failed to open logfile (%s)\n", optarg); + return 1; + } + break; case 'h': case '?': @@ -740,9 +812,6 @@ STRNCPY(g_hostname, fullhostname, sizeof(g_hostname)); } - if (prompt_password && read_password(password, sizeof(password))) - flags |= RDP_LOGON_AUTO; - if (g_title[0] == 0) { strcpy(g_title, "rdesktop - "); @@ -763,6 +832,7 @@ #endif rdpdr_init(); + if (g_brute_mode == BRUTE_NONE) if (!rdp_connect(server, flags, domain, password, shell, directory)) return 1; @@ -771,19 +841,154 @@ if (!packet_encryption) g_encryption = False; - + if (g_brute_mode == BRUTE_NONE) + { DEBUG(("Connection successful.\n")); memset(password, 0, sizeof(password)); + } if (ui_create_window()) { + if ((g_brute_mode == BRUTE_FILE) && (dicfile)) { + logprintf("\nStarting dictionary attack against server %s\n", server); + logprintf("------------------------------------------"); + + for ( i=0; i 15) + { + fprintf(stderr, "This shit is broke, I'm bailing...\n"); + return 1; + } + } + + if (g_server_version == VERSION_SRV_2K) + { + fprintf(stderr, "Server appears to be Windows 2000, brute-force guessing kinda works...\n"); + g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN; + g_w2k_auth_count = 0; + g_password = password; + } + + if (!packet_encryption) + g_encryption = False; + rdp_main_loop(&deactivated, &ext_disc_reason); + rdp_disconnect(); + + switch (g_brute_logon_status) + { + case LOGIN_RESULT_SUCCESS: + logprintf("[success] User \"%s\" Password \"%s\"\n", g_username, password ); + break; + case LOGIN_RESULT_FAIL: + logprintf( "[failure] User \"%s\" Password \"%s\"\n", g_username, password ); + break; + case LOGIN_RESULT_ERROR: + logprintf( "[error] User \"%s\" Password \"%s\"\n", g_username, password ); + return 1; + break; + default: + logprintf( "[error] User \"%s\" Password \"%s\". Connection terminated due to unknown error.\n", g_username, password ); + return 1; + break; + } + } + } + else if (g_brute_mode == BRUTE_STDIN) + { + fprintf(stderr, "Starting brute-force attack via STDIN against %s\n", server); + + while(!g_loggedon) + { + read_password(password, sizeof(password)); + + g_encryption = True; + + int sleep_count = 0; + while (!rdp_connect(server, flags, domain, password, shell, directory)) + { + /* rdesktop seems to flake out after brute-forcing a bit. let's try again... */ + fprintf(stderr, "Server appears to be flaking out. Sleeping (%d) seconds...\n", sleep_count); + sleep(sleep_count); + sleep_count += 5; + + if (sleep_count > 15) + { + fprintf(stderr, "This shit is broke, I'm bailing...\n"); + fprintf(stderr, "LOGIN_RESULT_ERROR:Server stopped responding.\n"); + return 1; + } + } + + if (g_server_version == VERSION_SRV_2K) + { + fprintf(stderr, "Server appears to be Windows 2000, brute-force guessing kinda works...\n"); + g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN; + g_w2k_auth_count = 0; + g_password = password; + } + + if (!packet_encryption) + g_encryption = False; + + rdp_main_loop(&deactivated, &ext_disc_reason); + rdp_disconnect(); + + switch (g_brute_logon_status) + { + case LOGIN_RESULT_SUCCESS: + fprintf(stderr, "LOGIN_RESULT_SUCCESS\n"); + break; + case LOGIN_RESULT_FAIL: + fprintf(stderr, "LOGIN_RESULT_FAILURE\n"); + break; + case LOGIN_RESULT_ERROR: + fprintf(stderr, "LOGIN_RESULT_ERROR\n"); + return 1; + break; + default: + fprintf(stderr, "LOGIN_RESULT_ERROR:Connection terminated due to unknown error.\n"); + return 1; + break; + } + } + } + else + { + rdp_main_loop(&deactivated, &ext_disc_reason); + } + ui_destroy_window(); } + if (g_brute_mode == BRUTE_NONE) { DEBUG(("Disconnecting...\n")); rdp_disconnect(); cache_save_state(); + } + else + { + if (g_logger) + fclose( g_logger ); + } + ui_deinit(); if (ext_disc_reason >= 2) @@ -1081,7 +1286,6 @@ } } - /* not all clibs got ltoa */ #define LTOA_BUFSIZE (sizeof(long) * 8 + 1) diff -rub rdesktop-1.4.1/rdesktop.h rdesktop-jmk/rdesktop.h --- rdesktop-1.4.1/rdesktop.h 2005-05-04 15:32:41.000000000 -0500 +++ rdesktop-jmk/rdesktop.h 2006-01-11 17:09:43.000000000 -0600 @@ -32,6 +32,20 @@ #define VERSION "1.4.1" +#define BRUTE_NONE 1 +#define BRUTE_STDIN 2 +#define BRUTE_FILE 3 +#define VERSION_SRV_UNKNOWN 0 +#define VERSION_SRV_XP2K3 1 +#define VERSION_SRV_2K 2 +#define LOGIN_RESULT_UNKNOWN 1 +#define LOGIN_RESULT_SUCCESS 2 +#define LOGIN_RESULT_FAIL 3 +#define LOGIN_RESULT_ERROR 4 +#define LOGIN_WIN_UNKNOWN 0 +#define LOGIN_WIN_PROC 1 +#define LOGIN_WIN_READY 2 + #ifdef WITH_DEBUG #define DEBUG(args) printf args; #else diff -rub rdesktop-1.4.1/rdp.c rdesktop-jmk/rdp.c --- rdesktop-1.4.1/rdp.c 2005-04-22 17:12:28.000000000 -0500 +++ rdesktop-jmk/rdp.c 2006-01-13 16:28:56.000000000 -0600 @@ -16,12 +16,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + 2005-07-07 Addedd support for detecting failed/successful login attempts + */ #include #include #include #include "rdesktop.h" +#include "scancodes.h" #ifdef HAVE_ICONV #ifdef HAVE_ICONV_H @@ -64,6 +68,20 @@ static BOOL g_iconv_works = True; #endif +/* brute-force stuff */ +extern int g_brute_mode; +extern int g_server_version; +extern int g_brute_logon_status; +extern char* g_password; +extern BOOL g_brute_w2k_send_logon; +BOOL g_loggedon = False; +BOOL g_brute_complete = False; +#define KEYMAP_MASK 0xffff +#define KEYMAP_SIZE 0xffff+1 +extern key_translation keymap[KEYMAP_SIZE]; +/* end brute-force */ + + /* Receive an RDP packet */ static STREAM rdp_recv(uint8 * type) @@ -1241,6 +1259,7 @@ case RDP_DATA_PDU_LOGON: DEBUG(("Received Logon PDU\n")); + g_loggedon = True; /* User logged on */ break; @@ -1274,6 +1293,63 @@ while (cont) { + if (g_brute_mode != BRUTE_NONE) + { + if ( g_loggedon ) + { + DEBUG(("Brute-force complete, successful authentication.\n")); + g_brute_logon_status = LOGIN_RESULT_SUCCESS; + disc = True; + } + else if ( g_brute_complete ) + { + /* failed */ + DEBUG(("Brute-force complete, terminating connection.\n")); + rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_ESC ); + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_ESC ); + g_brute_complete = False; + + /* w2k success */ + if (g_server_version == VERSION_SRV_2K) + disc = True; + } + + if ((g_server_version == VERSION_SRV_2K) && (g_brute_w2k_send_logon == LOGIN_WIN_READY)) + { + g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN; + + DEBUG(("Sending password: %s\n", g_password)); + int i; + char keysym; + uint8 scancode; + + /* TAB to username field to view text */ + //for(i = 0; i < 5; i++) + //{ + // rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_TAB ); + // rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_TAB ); + //} + + for(i = 0; i < strlen(g_password); i++) + { + keysym = g_password[i]; + scancode = keymap[keysym & KEYMAP_MASK].scancode; + DEBUG(("Sending CHAR: %c KEYSYM: 0x%x SCANCODE: 0x%x\n", keysym, (unsigned int) keysym, scancode)); + + if (keymap[keysym & KEYMAP_MASK].modifiers == 0x0) + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT); + else + rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT); + + rdp_send_scancode( time(NULL), RDP_KEYPRESS, scancode ); + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, scancode ); + } + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT); + rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_ENTER ); + rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_ENTER ); + } + } + s = rdp_recv(&type); if (s == NULL) return False; @@ -1292,6 +1368,15 @@ break; case 0: break; + case 15: + /* Intermittent with W2K brute-forcing issue */ + if (g_server_version == VERSION_SRV_2K) + { + DEBUG(("Brute-force connection to Windows 2000 is fubar'd.\n")); + g_brute_logon_status = LOGIN_RESULT_ERROR; + disc = True; + } + break; default: unimpl("PDU %d\n", type); } diff -rub rdesktop-1.4.1/secure.c rdesktop-jmk/secure.c --- rdesktop-1.4.1/secure.c 2005-03-06 15:11:17.000000000 -0600 +++ rdesktop-jmk/secure.c 2006-01-11 16:52:51.000000000 -0600 @@ -39,6 +39,8 @@ extern VCHANNEL g_channels[]; extern unsigned int g_num_channels; +extern int g_server_version; + static int rc4_key_len; static RC4_KEY rc4_decrypt_key; static RC4_KEY rc4_encrypt_key; @@ -761,6 +763,33 @@ g_use_rdp5 = 0; g_server_bpp = 8; } + + /* + Attempting to determine server OS version. It appears that the 21st + byte in the response is 0x02 for XP/2K3 and 0x01 for W2K. Don't know + what this byte actually represents, so this is a complete hack... + + -0010 02 0c ec 00 01 00 00 00 02 00 00 00 20 00 00 00 ............ ... + +0010 02 0c ec 00 02 00 00 00 02 00 00 00 20 00 00 00 ............ ... + */ + + //int datalen = s->end - s->p; + //hexdump(s->p, datalen); + switch ( *(s->p + 18) ) + { + case 0x01: + DEBUG_RDP5(("Server version appears to be Windows 2000.\n")); + g_server_version = VERSION_SRV_2K; + break; + case 0x02: + DEBUG_RDP5(("Server version appears to be Windows XP/2003.\n")); + g_server_version = VERSION_SRV_XP2K3; + break; + default: + DEBUG_RDP5(("Server version unknown. Interesting data: %d.\n", *(s->p + 18))); + g_server_version = VERSION_SRV_UNKNOWN; + break; + } } diff -rub rdesktop-1.4.1/xkeymap.c rdesktop-jmk/xkeymap.c --- rdesktop-1.4.1/xkeymap.c 2005-04-28 04:41:57.000000000 -0500 +++ rdesktop-jmk/xkeymap.c 2006-01-12 14:05:24.000000000 -0600 @@ -47,7 +47,8 @@ extern BOOL g_numlock_sync; static BOOL keymap_loaded; -static key_translation keymap[KEYMAP_SIZE]; +//static key_translation keymap[KEYMAP_SIZE]; +key_translation keymap[KEYMAP_SIZE]; static int min_keycode; static uint16 remote_modifier_state = 0; static uint16 saved_remote_modifier_state = 0; medusa-2.1.1/misc/net-analyzer/0000755000175000001440000000000011760001577013336 500000000000000medusa-2.1.1/misc/net-analyzer/medusa-2.1.1.ebuild0000644000175000001440000000142311723732130016352 00000000000000# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ DESCRIPTION="Parallel Network Login Auditor" HOMEPAGE="http://www.foofus.net/jmk/medusa.html" SRC_URI="http://www.foofus.net/jmk/tools/${P}.tar.gz" RESTRICT="nomirror" LICENSE="GPL-2" SLOT="0" KEYWORDS="~amd64 ~x86" RESTRICT="nostrip" IUSE="" DEPEND=" dev-libs/libpcre ssl? ( dev-libs/openssl ) ssh2? ( net-libs/libssh2 ) ncp? ( net-fs/ncpfs ) postgres? ( dev-db/libpq ) svn? ( dev-util/subversion ) " src_compile() { econf \ --with-default-mod-path="/usr/lib/medusa/modules" \ || die "econf failed" emake || die "emake failed" } src_install() { make DESTDIR="${D}" install || die "Install failed!" dodoc README TODO ChangeLog dohtml doc/*.html } medusa-2.1.1/mkinstalldirs0000755000175000001440000000370411723732130012517 00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" 1>&2 exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac case $dirmode in '') if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # End: # mkinstalldirs ends here medusa-2.1.1/depcomp0000755000175000001440000003117411723732130011270 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # 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. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Must come before tru64. # Intel's C compiler understands `-MD -MF file'. However # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^[^:]*: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 AIX compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. tmpdepfile1="$object.d" tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` if test "$libtool" = yes; then "$@" -Wc,-MD else "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. test -z "$dashmflag" && dashmflag=-M ( IFS=" " case " $* " in *" --mode=compile "*) # this is libtool, let us make it quiet for arg do # cycle over the arguments case "$arg" in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) # X makedepend ( shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift;; -*) ;; *) set fnord "$@" "$arg"; shift;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tail +3 "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. ( IFS=" " case " $* " in *" --mode=compile "*) for arg do # cycle over the arguments case $arg in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. ( IFS=" " case " $* " in *" --mode=compile "*) for arg do # cycle over the arguments case $arg in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 medusa-2.1.1/aclocal.m40000644000175000001440000010432511760000303011541 00000000000000# generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, [m4_warning([this file was generated for autoconf 2.68. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 10 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR medusa-2.1.1/INSTALL0000644000175000001440000001547211723732130010747 00000000000000Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Type `make install' to install the programs and any data files and documentation. 4. You can remove the program binaries and object files from the source code directory by typing `make clean'. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. medusa-2.1.1/ltmain.sh0000644000175000001440000056236011723732130011541 00000000000000# ltmain.sh - Provide generalized library-building support services. # NOTE: Changing this file will not affect anything until you rerun configure. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # Originally by Gordon Matzigkeit , 1996 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # 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. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. basename="s,^.*/,,g" # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" # define SED for historic ltconfig's generated by Libtool 1.3 test -z "$SED" && SED=sed # The name of this program: progname=`echo "$progpath" | $SED $basename` modename="$progname" # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 PROGRAM=ltmain.sh PACKAGE=libtool VERSION=1.5.18 TIMESTAMP=" (1.1220.2.246 2005/05/16 10:00:18)" # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Same for EGREP, and just to be sure, do LTCC as well if test "X$EGREP" = X ; then EGREP=egrep fi if test "X$LTCC" = X ; then LTCC=${CC-gcc} fi # Check that we have a working $echo. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then # Yippee, $echo works! : else # Restart under the correct shell, and then maybe $echo will work. exec $SHELL "$progpath" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <&2 $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit $EXIT_FAILURE fi # Global variables. mode=$default_mode nonopt= prev= prevopt= run= show="$echo" show_help= execute_dlfiles= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" quote_scanset='[[~#^*{};<>?'"'"' ]' if test -z "$max_cmd_len"; then i=0 testring="ABCD" new_result= # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while (test "X"`$SHELL $0 --fallback-echo "X$testring" 2>/dev/null` \ = "XX$testring") >/dev/null 2>&1 && new_result=`expr "X$testring" : ".*" 2>&1` && max_cmd_len="$new_result" && test "$i" != 17 # 1/2 MB should be enough do i=`expr $i + 1` testring="$testring$testring" done testring= # Add a significant safety factor because C++ compilers can tack on massive # amounts of additional arguments before passing them to the linker. # It appears as though 1/2 is a usable value. max_cmd_len=`expr $max_cmd_len \/ 2` fi ##################################### # Shell function definitions: # This seems to be the best place for them # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. func_win32_libid () { win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then win32_nmres=`eval $NM -f posix -A $1 | \ sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` if test "X$win32_nmres" = "Ximport" ; then win32_libid_type="x86 archive import" else win32_libid_type="x86 archive static" fi fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $echo $win32_libid_type } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac CC_quoted="$CC_quoted $arg" done case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac CC_quoted="$CC_quoted $arg" done # user sometimes does CC=-gcc so we need to match that to 'gcc' trimedcc=`echo ${CC} | $SED -e "s/${host}-//g"` # and sometimes libtool has CC=-gcc but user does CC=gcc extendcc=${host}-${CC} case "$@ " in "cc "* | " cc "* | "${host}-cc "* | " ${host}-cc "*|\ "gcc "* | " gcc "* | "${host}-gcc "* | " ${host}-gcc "*) tagname=CC break ;; "$trimedcc "* | " $trimedcc "* | "`$echo $trimedcc` "* | " `$echo $trimedcc` "*|\ "$extendcc "* | " $extendcc "* | "`$echo $extendcc` "* | " `$echo $extendcc` "*|\ " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then $echo "$modename: unable to infer tagged configuration" $echo "$modename: specify a tag with \`--tag'" 1>&2 exit $EXIT_FAILURE # else # $echo "$modename: using $tagname tagged configuration" fi ;; esac fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 exit $EXIT_FAILURE fi } # func_extract_archives gentop oldlib ... func_extract_archives () { my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" my_status="" $show "${rm}r $my_gentop" $run ${rm}r "$my_gentop" $show "$mkdir $my_gentop" $run $mkdir "$my_gentop" my_status=$? if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then exit $my_status fi for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` my_xdir="$my_gentop/$my_xlib" $show "${rm}r $my_xdir" $run ${rm}r "$my_xdir" $show "$mkdir $my_xdir" $run $mkdir "$my_xdir" status=$? if test "$status" -ne 0 && test ! -d "$my_xdir"; then exit $status fi case $host in *-darwin*) $show "Extracting $my_xabs" # Do not bother doing anything if just a dry run if test -z "$run"; then darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` if test -n "$darwin_arches"; then darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= $show "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we have a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` lipo -create -output "$darwin_file" $darwin_files done # $darwin_filelist ${rm}r unfat-$$ cd "$darwin_orig_dir" else cd "$darwin_orig_dir" func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches fi # $run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # End of Shell function definitions ##################################### # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Parse our command line options once, thoroughly. while test "$#" -gt 0 do arg="$1" shift case $arg in -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in execute_dlfiles) execute_dlfiles="$execute_dlfiles $arg" ;; tag) tagname="$arg" preserve_args="${preserve_args}=$arg" # Check whether tagname contains only valid characters case $tagname in *[!-_A-Za-z0-9,/]*) $echo "$progname: invalid tag name: $tagname" 1>&2 exit $EXIT_FAILURE ;; esac case $tagname in CC) # Don't test for the "default" C tag, as we know, it's there, but # not specially marked. ;; *) if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then taglist="$taglist $tagname" # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" else $echo "$progname: ignoring unknown tag $tagname" 1>&2 fi ;; esac ;; *) eval "$prev=\$arg" ;; esac prev= prevopt= continue fi # Have we seen a non-optional argument yet? case $arg in --help) show_help=yes ;; --version) $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" $echo $echo "Copyright (C) 2005 Free Software Foundation, Inc." $echo "This is free software; see the source for copying conditions. There is NO" $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." exit $? ;; --config) ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath # Now print the configurations for the tags. for tagname in $taglist; do ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" done exit $? ;; --debug) $echo "$progname: enabling shell trace mode" set -x preserve_args="$preserve_args $arg" ;; --dry-run | -n) run=: ;; --features) $echo "host: $host" if test "$build_libtool_libs" = yes; then $echo "enable shared libraries" else $echo "disable shared libraries" fi if test "$build_old_libs" = yes; then $echo "enable static libraries" else $echo "disable static libraries" fi exit $? ;; --finish) mode="finish" ;; --mode) prevopt="--mode" prev=mode ;; --mode=*) mode="$optarg" ;; --preserve-dup-deps) duplicate_deps="yes" ;; --quiet | --silent) show=: preserve_args="$preserve_args $arg" ;; --tag) prevopt="--tag" prev=tag ;; --tag=*) set tag "$optarg" ${1+"$@"} shift prev=tag preserve_args="$preserve_args --tag" ;; -dlopen) prevopt="-dlopen" prev=execute_dlfiles ;; -*) $echo "$modename: unrecognized option \`$arg'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; *) nonopt="$arg" break ;; esac done if test -n "$prevopt"; then $echo "$modename: option \`$prevopt' requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= if test -z "$show_help"; then # Infer the operation mode. if test -z "$mode"; then $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 case $nonopt in *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) mode=link for arg do case $arg in -c) mode=compile break ;; esac done ;; *db | *dbx | *strace | *truss) mode=execute ;; *install*|cp|mv) mode=install ;; *rm) mode=uninstall ;; *) # If we have no mode, but dlfiles were specified, then do execute mode. test -n "$execute_dlfiles" && mode=execute # Just use the default operation mode. if test -z "$mode"; then if test -n "$nonopt"; then $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 else $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 fi fi ;; esac fi # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then $echo "$modename: unrecognized option \`-dlopen'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$modename --help --mode=$mode' for more information." # These modes are in order of execution frequency so that they run quickly. case $mode in # libtool compile mode compile) modename="$modename: compile" # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= for arg do case "$arg_mode" in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) if test -n "$libobj" ; then $echo "$modename: you cannot specify \`-o' more than once" 1>&2 exit $EXIT_FAILURE fi arg_mode=target continue ;; -static | -prefer-pic | -prefer-non-pic) later="$later $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac lastarg="$lastarg $arg" done IFS="$save_ifs" lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` # Add the arguments to base_compile. base_compile="$base_compile $lastarg" continue ;; * ) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` case $lastarg in # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, and some SunOS ksh mistreat backslash-escaping # in scan sets (worked around with variable expansion), # and furthermore cannot handle '|' '&' '(' ')' in scan sets # at all, so we specify them separately. *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") lastarg="\"$lastarg\"" ;; esac base_compile="$base_compile $lastarg" done # for arg case $arg_mode in arg) $echo "$modename: you must specify an argument for -Xcompile" exit $EXIT_FAILURE ;; target) $echo "$modename: you must specify a target with \`-o'" 1>&2 exit $EXIT_FAILURE ;; *) # Get the name of the library object. [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo xform='[cCFSifmso]' case $libobj in *.ada) xform=ada ;; *.adb) xform=adb ;; *.ads) xform=ads ;; *.asm) xform=asm ;; *.c++) xform=c++ ;; *.cc) xform=cc ;; *.ii) xform=ii ;; *.class) xform=class ;; *.cpp) xform=cpp ;; *.cxx) xform=cxx ;; *.f90) xform=f90 ;; *.for) xform=for ;; *.java) xform=java ;; esac libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` case $libobj in *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; *) $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 exit $EXIT_FAILURE ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -static) build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` case $qlibobj in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") qlibobj="\"$qlibobj\"" ;; esac if test "X$libobj" != "X$qlibobj"; then $echo "$modename: libobj name \`$libobj' may not contain shell special characters." exit $EXIT_FAILURE fi objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$obj"; then xdir= else xdir=$xdir/ fi lobj=${xdir}$objdir/$objname if test -z "$base_compile"; then $echo "$modename: you must specify a compilation command" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi $run $rm $removelist trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" removelist="$removelist $output_obj $lockfile" trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $run ln "$srcfile" "$lockfile" 2>/dev/null; do $show "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $echo "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi $echo "$srcfile" > "$lockfile" fi if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` case $qsrcfile in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") qsrcfile="\"$qsrcfile\"" ;; esac $run $rm "$libobj" "${libobj}T" # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then $echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then $show "$mv $output_obj $lobj" if $run $mv $output_obj $lobj; then : else error=$? $run $rm $removelist exit $error fi fi # Append the name of the PIC object to the libtool object file. test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then $echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then $show "$mv $output_obj $obj" if $run $mv $output_obj $obj; then : else error=$? $run $rm $removelist exit $error fi fi # Append the name of the non-PIC object the libtool object file. # Only append if the libtool object file exists. test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi else if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi fi build_libtool_libs=no build_old_libs=yes prefer_static_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test ;; *) qarg=$arg ;; esac libtool_args="$libtool_args $qarg" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) compile_command="$compile_command @OUTPUT@" finalize_command="$finalize_command @OUTPUT@" ;; esac case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. compile_command="$compile_command @SYMFILE@" finalize_command="$finalize_command @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" if test ! -f "$arg"; then $echo "$modename: symbol file \`$arg' does not exist" exit $EXIT_FAILURE fi prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat $save_arg` do # moreargs="$moreargs $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then pic_object= non_pic_object= # Read the .lo file # If there is no directory component, then add one. case $arg in */* | *\\*) . $arg ;; *) . ./$arg ;; esac if test -z "$pic_object" || \ test -z "$non_pic_object" || test "$pic_object" = none && \ test "$non_pic_object" = none; then $echo "$modename: cannot find name of object for \`$arg'" 1>&2 exit $EXIT_FAILURE fi # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. libobjs="$libobjs $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object non_pic_objects="$non_pic_objects $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi fi else # Only an error if not doing a dry-run. if test -z "$run"; then $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 exit $EXIT_FAILURE else # Dry-run case. # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` libobjs="$libobjs $pic_object" non_pic_objects="$non_pic_objects $non_pic_object" fi fi done else $echo "$modename: link input file \`$save_arg' does not exist" exit $EXIT_FAILURE fi arg=$save_arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit $EXIT_FAILURE ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= compile_command="$compile_command $qarg" finalize_command="$finalize_command $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $wl$qarg" prev= compile_command="$compile_command $wl$qarg" finalize_command="$finalize_command $wl$qarg" continue ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" prev= compile_command="$compile_command $qarg" finalize_command="$finalize_command $qarg" continue ;; shrext) shrext_cmds="$arg" prev= continue ;; darwin_framework) compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" prev= continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then compile_command="$compile_command $link_static_flag" finalize_command="$finalize_command $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 continue ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: more than one -exported-symbols argument is not allowed" exit $EXIT_FAILURE fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=darwin_framework compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" ;; esac continue ;; -L*) dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 exit $EXIT_FAILURE fi dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) case :$dllsearchpath: in *":$dir:"*) ;; *) dllsearchpath="$dllsearchpath:$dir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-pw32* | *-*-beos*) # These systems don't actually have a C or math library (as such) continue ;; *-*-mingw* | *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs="$deplibs -framework System" continue esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. -model) compile_command="$compile_command $arg" compiler_flags="$compiler_flags $arg" finalize_command="$finalize_command $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" continue ;; -module) module=yes continue ;; # -64, -mips[0-9] enable 64-bit mode on the SGI compiler # -r[0-9][0-9]* specifies the processor on the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler # +DA*, +DD* enable 64-bit mode on the HP compiler # -q* pass through compiler args for the IBM compiler # -m* pass through architecture-specific compiler args for GCC -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" if test "$with_gcc" = "yes" ; then compiler_flags="$compiler_flags $arg" fi continue ;; -shrext) prev=shrext continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) # The PATH hackery in wrapper scripts is required on Windows # in order for the loader to find any dlls it needs. $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit $EXIT_FAILURE ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -static) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -Wc,*) args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" case $flag in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") flag="\"$flag\"" ;; esac arg="$arg $wl$flag" compiler_flags="$compiler_flags $flag" done IFS="$save_ifs" arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ;; -Wl,*) args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" case $flag in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") flag="\"$flag\"" ;; esac arg="$arg $wl$flag" compiler_flags="$compiler_flags $wl$flag" linker_flags="$linker_flags $flag" done IFS="$save_ifs" arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; -Kthread | -mthreads | -mt | -pthread | -pthreads | -threads | -qthreaded | -kthread ) compiler_flags="$compiler_flags $arg" continue ;; # Some other compiler flag. -* | +*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac ;; *.$objext) # A standard object. objs="$objs $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then pic_object= non_pic_object= # Read the .lo file # If there is no directory component, then add one. case $arg in */* | *\\*) . $arg ;; *) . ./$arg ;; esac if test -z "$pic_object" || \ test -z "$non_pic_object" || test "$pic_object" = none && \ test "$non_pic_object" = none; then $echo "$modename: cannot find name of object for \`$arg'" 1>&2 exit $EXIT_FAILURE fi # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. libobjs="$libobjs $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object non_pic_objects="$non_pic_objects $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi fi else # Only an error if not doing a dry-run. if test -z "$run"; then $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 exit $EXIT_FAILURE else # Dry-run case. # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` libobjs="$libobjs $pic_object" non_pic_objects="$non_pic_objects $non_pic_object" fi fi ;; *.$libext) # An archive. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi done # argument parsing loop if test -n "$prev"; then $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi oldlibs= # calculate the name of the file, without its directory outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` if test "X$output_objdir" = "X$output"; then output_objdir="$objdir" else output_objdir="$output_objdir/$objdir" fi # Create the object directory. if test ! -d "$output_objdir"; then $show "$mkdir $output_objdir" $run $mkdir $output_objdir status=$? if test "$status" -ne 0 && test ! -d "$output_objdir"; then exit $status fi fi # Determine the type of output case $output in "") $echo "$modename: you must specify an output file" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac case $host in *cygwin* | *mingw* | *pw32*) # don't eliminate duplications in $postdeps and $predeps duplicate_compiler_generated_deps=yes ;; *) duplicate_compiler_generated_deps=$duplicate_deps ;; esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if test "X$duplicate_deps" = "Xyes" ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; esac pre_post_deps="$pre_post_deps $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 exit $EXIT_FAILURE ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags="$compiler_flags $deplib" fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 continue fi name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then library_names= old_library= case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` test "X$ladir" = "X$lib" && ladir="." lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ;; *) $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` if eval $echo \"$deplib\" 2>/dev/null \ | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then $echo $echo "*** Warning: Trying to link with static lib archive $deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because the file extensions .$libext of this argument makes me believe" $echo "*** that it is just a static archive that I should not used here." else $echo $echo "*** Warning: Linking the shared library $output against the" $echo "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else $echo "$modename: cannot find the library \`$lib'" 1>&2 exit $EXIT_FAILURE fi # Check to see that this really is a libtool archive. if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` test "X$ladir" = "X$lib" && ladir="." dlname= dlopen= dlpreopen= libdir= library_names= old_library= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 exit $EXIT_FAILURE fi # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then $echo "$modename: \`$lib' is not a convenience library" 1>&2 exit $EXIT_FAILURE fi continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 exit $EXIT_FAILURE fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 exit $EXIT_FAILURE fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. dlprefiles="$dlprefiles $lib $dependency_libs" else newdlfiles="$newdlfiles $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 abs_ladir="$ladir" fi ;; esac laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then $echo "$modename: warning: library \`$lib' was moved." 1>&2 dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" fi fi # $installed = yes name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir"; then $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 exit $EXIT_FAILURE fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$newdlprefiles $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { test "$prefer_static_libs" = no || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath " in *" $dir "*) ;; *" $absdir "*) ;; *) temp_rpath="$temp_rpath $dir" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically if test -n "$library_names" && { test "$prefer_static_libs" = no || test -z "$old_library"; }; then if test "$installed" = no; then notinst_deplibs="$notinst_deplibs $lib" need_relink=yes fi # This is a shared library # Warn about portability, can't link against -module's on # some systems (darwin) if test "$shouldnotlink" = yes && test "$pass" = link ; then $echo if test "$linkmode" = prog; then $echo "*** Warning: Linking the executable $output against the loadable module" else $echo "*** Warning: Linking the shared library $output against the loadable module" fi $echo "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names realname="$2" shift; shift libname=`eval \\$echo \"$libname_spec\"` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw*) major=`expr $current - $age` versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" soname=`$echo $soroot | ${SED} -e 's/^.*\///'` newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else $show "extracting exported symbol list from \`$soname'" save_ifs="$IFS"; IFS='~' cmds=$extract_expsyms_cmds for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else $show "generating import library for \`$soname'" save_ifs="$IFS"; IFS='~' cmds=$old_archive_from_expsyms_cmds for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5* ) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a module then we can not link against # it, someone is ignoring the new warnings I added if /usr/bin/file -L $add 2> /dev/null | $EGREP "bundle" >/dev/null ; then $echo "** Warning, lib $linklib is a module, not a shared library" if test -z "$old_library" ; then $echo $echo "** And there doesn't seem to be a static archive available" $echo "** The link will probably fail, sorry" else add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case "$libdir" in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then $echo "$modename: configuration error: unsupported hardcode properties" exit $EXIT_FAILURE fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && \ test "$hardcode_minus_L" != yes && \ test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case "$libdir" in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. $echo $echo "*** Warning: This system can not link to static lib archive $lib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then $echo "*** But as you try to build a module library, libtool will still create " $echo "*** a static module, that should work as long as the dlopening application" $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then $echo $echo "*** However, this would only work if libtool was able to extract symbol" $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" $echo "*** not find such a program. So, this module is probably useless." $echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else convenience="$convenience $dir/$old_library" old_convenience="$old_convenience $dir/$old_library" deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do case $deplib in -L*) path="$deplib" ;; *.la) dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$deplib" && dir="." # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 absdir="$dir" fi ;; esac if grep "^installed=no" $deplib > /dev/null; then path="$absdir/$objdir" else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` if test -z "$libdir"; then $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi if test "$absdir" != "$libdir"; then $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 fi path="$absdir" fi depdepl= case $host in *-*-darwin*) # we do not want to link against static libs, # but need to link against shared eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$path/$depdepl" ; then depdepl="$path/$depdepl" fi # do not add paths which are already there case " $newlib_search_path " in *" $path "*) ;; *) newlib_search_path="$newlib_search_path $path";; esac fi path="" ;; *) path="-L$path" ;; esac ;; -l*) case $host in *-*-darwin*) # Again, we only want to link against shared libraries eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` for tmp in $newlib_search_path ; do if test -f "$tmp/lib$tmp_libs.dylib" ; then eval depdepl="$tmp/lib$tmp_libs.dylib" break fi done path="" ;; *) continue ;; esac ;; *) continue ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac case " $deplibs " in *" $depdepl "*) ;; *) deplibs="$depdepl $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then tmp_libs="$tmp_libs $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 fi if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 fi # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs="$objs$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) if test "$module" = no; then $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 exit $EXIT_FAILURE else $echo $echo "*** Warning: Linking the shared library $output against the non-libtool" $echo "*** objects $objs is not portable!" libobjs="$libobjs $objs" fi fi if test "$dlself" != no; then $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 fi set dummy $rpath if test "$#" -gt 2; then $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 fi install_libdir="$2" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 fi else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 IFS="$save_ifs" if test -n "$8"; then $echo "$modename: too many parameters to \`-version-info'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$2" number_minor="$3" number_revision="$4" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows) current=`expr $number_major + $number_minor` age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) current=`expr $number_major + $number_minor - 1` age="$number_minor" revision="$number_minor" ;; esac ;; no) current="$2" revision="$3" age="$4" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac if test "$age" -gt "$current"; then $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header major=.`expr $current - $age` versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... minor_current=`expr $current + 1` verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current"; ;; irix | nonstopux) major=`expr $current - $age + 1` case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do iface=`expr $revision - $loop` loop=`expr $loop - 1` verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) major=.`expr $current - $age` versuffix="$major.$age.$revision" ;; osf) major=.`expr $current - $age` versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do iface=`expr $current - $loop` loop=`expr $loop - 1` verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. major=`expr $current - $age` versuffix="-$major" ;; *) $echo "$modename: unknown library version type \`$version_type'" 1>&2 $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit $EXIT_FAILURE ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi if test "$mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$echo "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist="$removelist $p" ;; *) ;; esac done if test -n "$removelist"; then $show "${rm}r $removelist" $run ${rm}r $removelist fi fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. for path in $notinst_path; do lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles="$dlfiles $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$deplibs -framework System" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then deplibs="$deplibs -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $rm conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null \ | grep " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done # It is ok to link against an archive when # building a shared library. if $AR -t $potlib > /dev/null 2>&1; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ | ${SED} 10q \ | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $echo $echo "*** Warning: linker path does not have real file for library $a_deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $echo "*** with $libname but no candidates were found. (...for file magic test)" else $echo "*** with $libname and none of the candidates passed a file format test" $echo "*** using a file magic. Last file checked: $potlib" fi fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` for a_deplib in $deplibs; do name="`expr $a_deplib : '-l\(.*\)'`" # If $name is empty we are operating on a -L argument. if test -n "$name" && test "$name" != "0"; then if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs="$newdeplibs $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval \\$echo \"$libname_spec\"` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval $echo \"$potent_lib\" 2>/dev/null \ | ${SED} 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $echo $echo "*** Warning: linker path does not have real file for library $a_deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $echo "*** with $libname but no candidates were found. (...for regex pattern test)" else $echo "*** with $libname and none of the candidates passed a file format test" $echo "*** using a regex pattern. Last file checked: $potlib" fi fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ -e 's/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` done fi if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ | grep . >/dev/null; then $echo if test "X$deplibs_check_method" = "Xnone"; then $echo "*** Warning: inter-library dependencies are not supported in this platform." else $echo "*** Warning: inter-library dependencies are not known to be supported." fi $echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then $echo $echo "*** Warning: libtool could not satisfy all declared inter-library" $echo "*** dependencies of module $libname. Therefore, libtool will create" $echo "*** a static module, that should work as long as the dlopening" $echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then $echo $echo "*** However, this would only work if libtool was able to extract symbol" $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" $echo "*** not find such a program. So, this module is probably useless." $echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else $echo "*** The inter-library dependencies that have been dropped here will be" $echo "*** automatically added whenever a program is linked with this library" $echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then $echo $echo "*** Since this library must not contain undefined symbols," $echo "*** because either the platform does not support them or" $echo "*** it was explicitly requested with -no-undefined," $echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names realname="$2" shift; shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" for link do linknames="$linknames $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then $show "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" if len=`expr "X$cmd" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then $show "$cmd" $run eval "$cmd" || exit $? skipped_export=false else # The command line is too long to execute in one step. $show "using reloadable object file for export list..." skipped_export=: fi done IFS="$save_ifs" if test -n "$export_symbols_regex"; then $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' $show "$mv \"${export_symbols}T\" \"$export_symbols\"" $run eval '$mv "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) tmp_deplibs="$tmp_deplibs $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" else gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $convenience libobjs="$libobjs $func_extract_archives_result" fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise. $echo "creating reloadable object files..." # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output output_la=`$echo "X$output" | $Xsed -e "$basename"` # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= delfiles= last_robj= k=1 output=$output_objdir/$output_la-${k}.$objext # Loop over the list of objects to be linked. for obj in $save_libobjs do eval test_cmds=\"$reload_cmds $objlist $last_robj\" if test "X$objlist" = X || { len=`expr "X$test_cmds" : ".*"` && test "$len" -le "$max_cmd_len"; }; then objlist="$objlist $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else # All subsequent reloadable object files will link in # the last one created. eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext k=`expr $k + 1` output=$output_objdir/$output_la-${k}.$objext objlist=$obj len=1 fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if ${skipped_export-false}; then $show "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols libobjs=$output # Append the command to create the export file. eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" fi # Set up a command to remove the reloadable object files # after they are used. i=0 while test "$i" -lt "$k" do i=`expr $i + 1` delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" done $echo "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi # Append the command to remove the reloadable object files # to the just-reset $cmds. eval cmds=\"\$cmds~\$rm $delfiles\" fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 fi case $output in *.lo) if test -n "$objs$old_deplibs"; then $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 exit $EXIT_FAILURE fi libobj="$output" obj=`$echo "X$output" | $Xsed -e "$lo2o"` ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $run $rm $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" else gentop="$output_objdir/${obj}x" generated="$generated $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" cmds=$reload_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $run eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" cmds=$reload_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; esac if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 fi if test "$preload" = yes; then if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && test "$dlopen_self_static" = unknown; then $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." fi fi case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` ;; esac case $host in *darwin*) # Don't allow lazy linking, it breaks C++ global constructors if test "$tagname" = CXX ; then compile_command="$compile_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load" fi ;; esac compile_command="$compile_command $compile_deplibs" finalize_command="$finalize_command $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) case :$dllsearchpath: in *":$libdir:"*) ;; *) dllsearchpath="$dllsearchpath:$libdir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then dlsyms="${outputname}S.c" else $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 fi fi if test -n "$dlsyms"; then case $dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${outputname}.nm" $show "$rm $nlist ${nlist}S ${nlist}T" $run $rm "$nlist" "${nlist}S" "${nlist}T" # Parse the name list into a source file. $show "creating $output_objdir/$dlsyms" test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ /* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ /* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ #ifdef __cplusplus extern \"C\" { #endif /* Prevent the only kind of declaration conflicts we can make. */ #define lt_preloaded_symbols some_other_symbol /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then $show "generating symbol list for \`$output'" test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for arg in $progfiles; do $show "extracting global C symbols from \`$arg'" $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi if test -n "$export_symbols_regex"; then $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $run $rm $export_symbols $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' else $run eval "${SED} -e 's/\([ ][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' $run eval 'mv "$nlist"T "$nlist"' fi fi for arg in $dlprefiles; do $show "extracting global C symbols from \`$arg'" name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` $run eval '$echo ": $name " >> "$nlist"' $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -z "$run"; then # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $mv "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if grep -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else grep -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' else $echo '/* NONE */' >> "$output_objdir/$dlsyms" fi $echo >> "$output_objdir/$dlsyms" "\ #undef lt_preloaded_symbols #if defined (__STDC__) && __STDC__ # define lt_ptr void * #else # define lt_ptr char * # define const #endif /* The mapping between symbol names and symbols. */ " case $host in *cygwin* | *mingw* ) $echo >> "$output_objdir/$dlsyms" "\ /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs */ struct { " ;; * ) $echo >> "$output_objdir/$dlsyms" "\ const struct { " ;; esac $echo >> "$output_objdir/$dlsyms" "\ const char *name; lt_ptr address; } lt_preloaded_symbols[] = {\ " eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" $echo >> "$output_objdir/$dlsyms" "\ {0, (lt_ptr) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " fi pic_flag_for_symtable= case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; esac;; *-*-hpux*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag";; esac esac # Now compile the dynamic symbol file. $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? # Clean up the generated files. $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" # Transform the symbol file into the correct name. compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` ;; *) $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 exit $EXIT_FAILURE ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi if test "$need_relink" = no || test "$build_libtool_libs" != yes; then # Replace the output file specification. compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. $show "$link_command" $run eval "$link_command" status=$? # Delete the generated files. if test -n "$dlsyms"; then $show "$rm $output_objdir/${outputname}S.${objext}" $run $rm "$output_objdir/${outputname}S.${objext}" fi exit $status fi if test -n "$shlibpath_var"; then # We should set the shlibpath_var rpath= for dir in $temp_rpath; do case $dir in [\\/]* | [A-Za-z]:[\\/]*) # Absolute path. rpath="$rpath$dir:" ;; *) # Relative path: add a thisdir entry. rpath="$rpath\$thisdir/$dir:" ;; esac done temp_rpath="$rpath" fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $run $rm $output # Link the executable and exit $show "$link_command" $run eval "$link_command" || exit $? exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 $echo "$modename: \`$output' will be relinked during installation" 1>&2 else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname $show "$link_command" $run eval "$link_command" || exit $? # Now create the wrapper script. $show "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` relink_command="$var=\"$var_value\"; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $echo for shipping. if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then case $progpath in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; esac qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if our run command is non-null. if test -z "$run"; then # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) cwrappersource=`$echo ${objdir}/lt-${outputname}.c` cwrapper=`$echo ${output}.exe` $rm $cwrappersource $cwrapper trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 cat > $cwrappersource <> $cwrappersource<<"EOF" #include #include #include #include #include #include #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef DIR_SEPARATOR #define DIR_SEPARATOR '/' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) #define HAVE_DOS_BASED_FILE_SYSTEM #ifndef DIR_SEPARATOR_2 #define DIR_SEPARATOR_2 '\\' #endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) const char *program_name = NULL; void * xmalloc (size_t num); char * xstrdup (const char *string); char * basename (const char *name); char * fnqualify(const char *path); char * strendzap(char *str, const char *pat); void lt_fatal (const char *message, ...); int main (int argc, char *argv[]) { char **newargz; int i; program_name = (char *) xstrdup ((char *) basename (argv[0])); newargz = XMALLOC(char *, argc+2); EOF cat >> $cwrappersource <> $cwrappersource <<"EOF" newargz[1] = fnqualify(argv[0]); /* we know the script has the same name, without the .exe */ /* so make sure newargz[1] doesn't end in .exe */ strendzap(newargz[1],".exe"); for (i = 1; i < argc; i++) newargz[i+1] = xstrdup(argv[i]); newargz[argc+1] = NULL; EOF cat >> $cwrappersource <> $cwrappersource <<"EOF" } void * xmalloc (size_t num) { void * p = (void *) malloc (num); if (!p) lt_fatal ("Memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL ; } char * basename (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha (name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return (char *) base; } char * fnqualify(const char *path) { size_t size; char *p; char tmp[LT_PATHMAX + 1]; assert(path != NULL); /* Is it qualified already? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha (path[0]) && path[1] == ':') return xstrdup (path); #endif if (IS_DIR_SEPARATOR (path[0])) return xstrdup (path); /* prepend the current directory */ /* doesn't handle '~' */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ p = XMALLOC(char, size); sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); return p; } char * strendzap(char *str, const char *pat) { size_t len, patlen; assert(str != NULL); assert(pat != NULL); len = strlen(str); patlen = strlen(pat); if (patlen <= len) { str += len - patlen; if (strcmp(str, pat) == 0) *str = '\0'; } return str; } static void lt_error_core (int exit_status, const char * mode, const char * message, va_list ap) { fprintf (stderr, "%s: %s: ", program_name, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, "FATAL", message, ap); va_end (ap); } EOF # we should really use a build-platform specific compiler # here, but OTOH, the wrappers (shell script and this C one) # are only useful if you want to execute the "real" binary. # Since the "real" binary is built for $host, then this # wrapper might as well be built for $host, too. $run $LTCC -s -o $cwrapper $cwrappersource ;; esac $rm $output trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 $echo > $output "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='${SED} -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variable: notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$echo are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then echo=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then # Yippee, \$echo works! : else # Restart under the correct shell, and then maybe \$echo will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $echo >> $output "\ # Find the directory that this script lives in. thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $echo >> $output "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || \\ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $mkdir \"\$progdir\" else $rm \"\$progdir/\$file\" fi" $echo >> $output "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $echo \"\$relink_command_output\" >&2 $rm \"\$progdir/\$file\" exit $EXIT_FAILURE fi fi $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $rm \"\$progdir/\$program\"; $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } $rm \"\$progdir/\$file\" fi" else $echo >> $output "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $echo >> $output "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $echo >> $output "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $echo >> $output "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $echo >> $output "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2*) $echo >> $output "\ exec \$progdir\\\\\$program \${1+\"\$@\"} " ;; *) $echo >> $output "\ exec \$progdir/\$program \${1+\"\$@\"} " ;; esac $echo >> $output "\ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" exit $EXIT_FAILURE fi else # The program doesn't exist. \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 \$echo \"This script is just a wrapper for \$program.\" 1>&2 $echo \"See the $PACKAGE documentation for more information.\" 1>&2 exit $EXIT_FAILURE fi fi\ " chmod +x $output fi exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $addlibs oldobjs="$oldobjs $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do $echo "X$obj" | $Xsed -e 's%^.*/%%' done | sort | sort -uc >/dev/null 2>&1); then : else $echo "copying selected object files to avoid basename conflicts..." if test -z "$gentop"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" $show "${rm}r $gentop" $run ${rm}r "$gentop" $show "$mkdir $gentop" $run $mkdir "$gentop" status=$? if test "$status" -ne 0 && test ! -d "$gentop"; then exit $status fi fi save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase counter=`expr $counter + 1` case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" $run ln "$obj" "$gentop/$newobj" || $run cp "$obj" "$gentop/$newobj" oldobjs="$oldobjs $gentop/$newobj" ;; *) oldobjs="$oldobjs $obj" ;; esac done fi eval cmds=\"$old_archive_cmds\" if len=`expr "X$cmds" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts $echo "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done for obj in $save_oldobjs do oldobjs="$objlist $obj" objlist="$objlist $obj" eval test_cmds=\"$old_archive_cmds\" if len=`expr "X$test_cmds" : ".*"` && test "$len" -le "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do eval cmd=\"$cmd\" IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$generated"; then $show "${rm}r$generated" $run ${rm}r$generated fi # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" $show "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` relink_command="$var=\"$var_value\"; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. if test -z "$run"; then for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` if test -z "$libdir"; then $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi if test "X$EGREP" = X ; then EGREP=egrep fi # We do not want portage's install root ($D) present. Check only for # this if the .la is being installed. if test "$installed" = yes && test "$D"; then eval mynewdependency_lib=`echo "$libdir/$name" |sed -e "s:$D:/:g" -e 's:/\+:/:g'` else mynewdependency_lib="$libdir/$name" fi # Do not add duplicates if test "$mynewdependency_lib"; then my_little_ninja_foo_1=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"` if test -z "$my_little_ninja_foo_1"; then newdependency_libs="$newdependency_libs $mynewdependency_lib" fi fi ;; *) if test "$installed" = yes; then # Rather use S=WORKDIR if our version of portage supports it. # This is because some ebuild (gcc) do not use $S as buildroot. if test "$PWORKDIR"; then S="$PWORKDIR" fi # We do not want portage's build root ($S) present. my_little_ninja_foo_2=`echo $deplib |$EGREP -e "$S"` if test -n "$my_little_ninja_foo_2" && test "$S"; then mynewdependency_lib="" # We do not want portage's install root ($D) present. my_little_ninja_foo_3=`echo $deplib |$EGREP -e "$D"` elif test -n "$my_little_ninja_foo_3" && test "$D"; then eval mynewdependency_lib=`echo "$deplib" |sed -e "s:$D:/:g" -e 's:/\+:/:g'` else mynewdependency_lib="$deplib" fi else mynewdependency_lib="$deplib" fi # Do not add duplicates if test "$mynewdependency_lib"; then my_little_ninja_foo_4=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"` if test -z "$my_little_ninja_foo_4"; then newdependency_libs="$newdependency_libs $mynewdependency_lib" fi fi ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` if test -z "$libdir"; then $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi newdlfiles="$newdlfiles $libdir/$name" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` if test -z "$libdir"; then $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi newdlprefiles="$newdlprefiles $libdir/$name" done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlfiles="$newdlfiles $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles="$newdlprefiles $abs" done dlprefiles="$newdlprefiles" fi $rm $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac # Do not add duplicates if test "$installed" = yes && test "$D"; then install_libdir=`echo "$install_libdir" |sed -e "s:$D:/:g" -e 's:/\+:/:g'` fi $echo > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $echo >> $output "\ relink_command=\"$relink_command\"" fi done fi # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? ;; esac exit $EXIT_SUCCESS ;; # libtool install mode install) modename="$modename: install" # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then # Aesthetically quote it. arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac install_prog="$arg " arg="$1" shift else install_prog= arg="$nonopt" fi # The real first argument should be the name of the installation program. # Aesthetically quote it. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac install_prog="$install_prog$arg" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest="$arg" continue fi case $arg in -d) isdir=yes ;; -f) prev="-f" ;; -g) prev="-g" ;; -m) prev="-m" ;; -o) prev="-o" ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest="$arg" continue fi ;; esac # Aesthetically quote the argument. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac install_prog="$install_prog $arg" done if test -z "$install_prog"; then $echo "$modename: you must specify an install program" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test -n "$prev"; then $echo "$modename: the \`$prev' option requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test -z "$files"; then if test -z "$dest"; then $echo "$modename: no file or destination specified" 1>&2 else $echo "$modename: you must specify a destination" 1>&2 fi $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Strip any trailing slash from the destination. dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` test "X$destdir" = "X$dest" && destdir=. destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` # Not a directory, so check to see that there is only one file specified. set dummy $files if test "$#" -gt 2; then $echo "$modename: \`$dest' is not a directory" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi library_names= old_library= relink_command= # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ test "X$dir" = "X$file/" && dir= dir="$dir$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. if test "$inst_prefix_dir" = "$destdir"; then $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 exit $EXIT_FAILURE fi if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi $echo "$modename: warning: relinking \`$file'" 1>&2 $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 exit $EXIT_FAILURE fi fi # See the names of the shared library. set dummy $library_names if test -n "$2"; then realname="$2" shift shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. $show "$install_prog $dir/$srcname $destdir/$realname" $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? if test -n "$stripme" && test -n "$striplib"; then $show "$striplib $destdir/$realname" $run eval "$striplib $destdir/$realname" || exit $? fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. for linkname do if test "$linkname" != "$realname"; then $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" fi done fi # Do each command in the postinstall commands. lib="$destdir/$realname" cmds=$postinstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # Install the pseudo-library for information purposes. name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` instname="$dir/$name"i $show "$install_prog $instname $destdir/$name" $run eval "$install_prog $instname $destdir/$name" || exit $? # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` ;; *.$objext) staticdest="$destfile" destfile= ;; *) $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac # Install the libtool object if requested. if test -n "$destfile"; then $show "$install_prog $file $destfile" $run eval "$install_prog $file $destfile" || exit $? fi # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` $show "$install_prog $staticobj $staticdest" $run eval "$install_prog \$staticobj \$staticdest" || exit $? fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then file=`$echo $file|${SED} 's,.exe$,,'` stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin*|*mingw*) wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` ;; *) wrapper=$file ;; esac if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then notinst_deplibs= relink_command= # To insure that "foo" is sourced, and not "foo.exe", # finese the cygwin/MSYS system by explicitly sourcing "foo." # which disallows the automatic-append-.exe behavior. case $build in *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; *) wrapperdot=${wrapper} ;; esac # If there is no directory component, then add one. case $file in */* | *\\*) . ${wrapperdot} ;; *) . ./${wrapperdot} ;; esac # Check the variables that should have been set. if test -z "$notinst_deplibs"; then $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 exit $EXIT_FAILURE fi finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then # If there is no directory component, then add one. case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac fi libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 finalize=no fi done relink_command= # To insure that "foo" is sourced, and not "foo.exe", # finese the cygwin/MSYS system by explicitly sourcing "foo." # which disallows the automatic-append-.exe behavior. case $build in *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; *) wrapperdot=${wrapper} ;; esac # If there is no directory component, then add one. case $file in */* | *\\*) . ${wrapperdot} ;; *) . ./${wrapperdot} ;; esac outputname= if test "$fast_install" = no && test -n "$relink_command"; then if test "$finalize" = yes && test -z "$run"; then tmpdir="/tmp" test -n "$TMPDIR" && tmpdir="$TMPDIR" tmpdir="$tmpdir/libtool-$$" save_umask=`umask` umask 0077 if $mkdir "$tmpdir"; then umask $save_umask else umask $save_umask $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 continue fi file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 ${rm}r "$tmpdir" continue fi file="$outputname" else $echo "$modename: warning: cannot relink \`$file'" 1>&2 fi else # Install the binary that we compiled earlier. file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyways case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` ;; esac ;; esac $show "$install_prog$stripme $file $destfile" $run eval "$install_prog\$stripme \$file \$destfile" || exit $? test -n "$outputname" && ${rm}r "$tmpdir" ;; esac done for file in $staticlibs; do name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` # Set up the ranlib parameters. oldlib="$destdir/$name" $show "$install_prog $file $oldlib" $run eval "$install_prog \$file \$oldlib" || exit $? if test -n "$stripme" && test -n "$old_striplib"; then $show "$old_striplib $oldlib" $run eval "$old_striplib $oldlib" || exit $? fi # Do each command in the postinstall commands. cmds=$old_postinstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$future_libdirs"; then $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 fi if test -n "$current_libdirs"; then # Maybe just do a dry run. test -n "$run" && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi ;; # libtool finish mode finish) modename="$modename: finish" libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. cmds=$finish_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || admincmds="$admincmds $cmd" done IFS="$save_ifs" fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $run eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. test "$show" = : && exit $EXIT_SUCCESS $echo "----------------------------------------------------------------------" $echo "Libraries have been installed in:" for libdir in $libdirs; do $echo " $libdir" done $echo $echo "If you ever happen to want to link against installed libraries" $echo "in a given directory, LIBDIR, you must either use libtool, and" $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" $echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" $echo " during execution" fi if test -n "$runpath_var"; then $echo " - add LIBDIR to the \`$runpath_var' environment variable" $echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $echo " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $echo " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi $echo $echo "See any operating system documentation about shared libraries for" $echo "more information, such as the ld(1) and ld.so(8) manual pages." $echo "----------------------------------------------------------------------" exit $EXIT_SUCCESS ;; # libtool execute mode execute) modename="$modename: execute" # The first argument is the command name. cmd="$nonopt" if test -z "$cmd"; then $echo "$modename: you must specify a COMMAND" 1>&2 $echo "$help" exit $EXIT_FAILURE fi # Handle -dlopen flags immediately. for file in $execute_dlfiles; do if test ! -f "$file"; then $echo "$modename: \`$file' is not a file" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi dir= case $file in *.la) # Check to see that this really is a libtool archive. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Read the libtool library. dlname= library_names= # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" continue fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 exit $EXIT_FAILURE fi ;; *.lo) # Just add the directory containing the .lo file. dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. ;; *) $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -*) ;; *) # Do a test to see if this is really a libtool program. if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` args="$args \"$file\"" done if test -z "$run"; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables if test "${save_LC_ALL+set}" = set; then LC_ALL="$save_LC_ALL"; export LC_ALL fi if test "${save_LANG+set}" = set; then LANG="$save_LANG"; export LANG fi # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" $echo "export $shlibpath_var" fi $echo "$cmd$args" exit $EXIT_SUCCESS fi ;; # libtool clean and uninstall mode clean | uninstall) modename="$modename: $mode" rm="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) rm="$rm $arg"; rmforce=yes ;; -*) rm="$rm $arg" ;; *) files="$files $arg" ;; esac done if test -z "$rm"; then $echo "$modename: you must specify an RM program" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi rmdirs= origobjdir="$objdir" for file in $files; do dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` if test "X$dir" = "X$file"; then dir=. objdir="$origobjdir" else objdir="$dir/$origobjdir" fi name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` test "$mode" = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if (test -L "$file") >/dev/null 2>&1 \ || (test -h "$file") >/dev/null 2>&1 \ || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then . $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" if test "$mode" = uninstall; then if test -n "$library_names"; then # Do each command in the postuninstall commands. cmds=$postuninstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" if test "$?" -ne 0 && test "$rmforce" != yes; then exit_status=1 fi done IFS="$save_ifs" fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. cmds=$old_postuninstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" if test "$?" -ne 0 && test "$rmforce" != yes; then exit_status=1 fi done IFS="$save_ifs" fi # FIXME: should reinstall the best remaining shared library. fi fi ;; *.lo) # Possibly a libtool object, so verify it. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # Read the .lo file . $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" \ && test "$pic_object" != none; then rmfiles="$rmfiles $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" \ && test "$non_pic_object" != none; then rmfiles="$rmfiles $dir/$non_pic_object" fi fi ;; *) if test "$mode" = clean ; then noexename=$name case $file in *.exe) file=`$echo $file|${SED} 's,.exe$,,'` noexename=`$echo $name|${SED} 's,.exe$,,'` # $file with .exe has already been added to rmfiles, # add $file without .exe rmfiles="$rmfiles $file" ;; esac # Do a test to see if this is a libtool program. if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then relink_command= . $dir/$noexename # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c" fi fi fi ;; esac $show "$rm $rmfiles" $run $rm $rmfiles || exit_status=1 done objdir="$origobjdir" # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then $show "rmdir $dir" $run rmdir $dir >/dev/null 2>&1 fi done exit $exit_status ;; "") $echo "$modename: you must specify a MODE" 1>&2 $echo "$generic_help" 1>&2 exit $EXIT_FAILURE ;; esac if test -z "$exec_cmd"; then $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$generic_help" 1>&2 exit $EXIT_FAILURE fi fi # test -z "$show_help" if test -n "$exec_cmd"; then eval exec $exec_cmd exit $EXIT_FAILURE fi # We need to display help for each of the modes. case $mode in "") $echo \ "Usage: $modename [OPTION]... [MODE-ARG]... Provide generalized library-building support services. --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --finish same as \`--mode=finish' --help display this help message and exit --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] --quiet same as \`--silent' --silent don't print informational messages --tag=TAG use configuration variables from tag TAG --version print version information MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for a more detailed description of MODE. Report bugs to ." exit $EXIT_SUCCESS ;; clean) $echo \ "Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $echo \ "Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -prefer-pic try to building PIC objects only -prefer-non-pic try to building non-PIC objects only -static always build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $echo \ "Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $echo \ "Usage: $modename [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $echo \ "Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $echo \ "Usage: $modename [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -static do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $echo \ "Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac $echo $echo "Try \`$modename --help' for more information about other modes." exit $? # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: