Last active
September 15, 2021 07:22
-
-
Save umrysh/e26ec78bf8428ad4e279 to your computer and use it in GitHub Desktop.
Revisions
-
umrysh revised this gist
Nov 17, 2014 . 2 changed files with 212 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,186 @@ #!/bin/bash # Example Dovecot checkpassword script that may be used as both passdb or userdb. # # Originally written by Nikolay Vizovitin, 2013. # Assumes authentication DB is in /etc/dovecot/users, each line has '<user>:<password>' format. # Place this script into /etc/dovecot/checkpassword.sh file and make executable. # Implementation guidelines at http://wiki2.dovecot.org/AuthDatabase/CheckPassword # The first and only argument is path to checkpassword-reply binary. # It should be executed at the end if authentication succeeds. CHECKPASSWORD_REPLY_BINARY="$1" # Messages to stderr will end up in mail log (prefixed with "dovecot: auth: Error:") LOG=/dev/stderr # User and password will be supplied on file descriptor 3. INPUT_FD=3 # Error return codes. ERR_PERMFAIL=1 ERR_NOUSER=3 ERR_TEMPFAIL=111 # Make testing this script easy. To check it just run: # printf '%s\0%s\0' <user> <password> | ./checkpassword.sh test; echo "$?" if [ "$CHECKPASSWORD_REPLY_BINARY" = "test" ]; then CHECKPASSWORD_REPLY_BINARY=/bin/true INPUT_FD=0 fi # Credentials lookup function. Given a user name it should output 'user:password' if such # account exists or nothing if it does not. Return non-zero code in case of error. credentials_lookup() { local db="$1" local user="$2" awk -F ':' -v USER="$user" '($1 == USER) {print}' "$db" 2>>$LOG } # Credentials verification function. Given a user name and password it should output non-empty # string (this implementation outputs 'user:password') in case supplied credentials are valid # or nothing if they are not. Return non-zero code in case of error. credentials_verify() { local db="$1" local user="$2" local pass="$3" local cached="$4" local ipfile="$5" local ip="$TCPREMOTEIP" #local ip="$TCPLOCALIP" #local ip="192.168.149.100" local timestamp="$(date +%s)" #local defaultTime=300 local defaultTime=10 local expire="" if [ -f "$cached" ]; then expire=`awk -F ':' -v USER="$user" -v IP="$ip" -v PASS="$pass" '($1 == USER && $2 == IP && $3 == PASS) {print $4}' "$cached"` fi if [ ! -z "$expire" ]; then if [ "$timestamp" -gt "$expire" ]; then # Remove from cache sed -i "/$user:$ip:$pass/d" "$cached" #echo "cached is old. fail log in" log_result_basic "cached is old. fail log in" else #echo "cache is current. allow log on" log_result_basic "cache is current. allow log on" echo "true" fi else if python2.7 /etc/dovecot/getTOTP.py -v `awk -F ':' -v USER="$user" '($1 == USER) {print $2}' "$db"` "$pass" | grep 'True'; then #echo "allow log on" log_result_basic "allow log on" if [ -f "$ipfile" ]; then timeforip=`awk -F ':' -v IP="$ip" '($1 == IP) {print $2}' "$ipfile"` if [ -z "$timeforip" ]; then # Use default time cache #echo "Using default time" log_result_basic "Using default time" echo "$user:$ip:$pass:$(($timestamp+$defaultTime))" >> "$cached" else #echo "Using stored time" log_result_basic "Using stored time" echo "$user:$ip:$pass:$(($timestamp+$timeforip))" >> "$cached" fi else # Use default time cache #echo "Using default time" log_result_basic "Using default time" echo "$user:$ip:$pass:$(($timestamp+$defaultTime))" >> "$cached" fi echo "true" fi fi } # Just a simple logging helper. log_result() { echo "$*; Input: $USER:$PASS; Home: $HOME; Reply binary: $CHECKPASSWORD_REPLY_BINARY" >>$LOG } # Just a simpler logging helper. log_result_basic() { echo "$*; Input: $USER:$PASS" >>$LOG } # Read input data. It is available from $INPUT_FD as "${USER}\0${PASS}\0". # Password may be empty if not available (i.e. if doing credentials lookup). read -d $'\0' -r -u $INPUT_FD USER read -d $'\0' -r -u $INPUT_FD PASS # Both mailbox and domain directories should be in lowercase on file system. # So let's convert login user name to lowercase and tell Dovecot that 'user' and 'home' # (which overrides 'mail_home' global parameter) values should be updated. # Of course, conversion to lowercase may be done in Dovecot configuration as well. export USER="`echo \"$USER\" | tr 'A-Z' 'a-z'`" #mail_name="`echo \"$USER\" | awk -F '@' '{ print $1 }'`" #domain_name="`echo \"$USER\" | awk -F '@' '{ print $2 }'`" export HOME=`python2.7 /etc/dovecot/getHome.py $USER` # CREDENTIALS_LOOKUP=1 environment is set when doing non-plaintext authentication. if [ "$CREDENTIALS_LOOKUP" = 1 ]; then action=credentials_lookup else action=credentials_verify fi # Perform credentials lookup/verification. lookup_result=`$action "/etc/dovecot/users" "$USER" "$PASS" "/etc/dovecot/cached" "/etc/dovecot/ipfile"` || { # If it failed, consider it an internal temporary error. # This usually happens due to permission problems. log_result "internal error (ran as `id`)" exit $ERR_TEMPFAIL } if [ -n "$lookup_result" ]; then # Dovecot calls the script with AUTHORIZED=1 environment set when performing a userdb lookup. # The script must acknowledge this by changing the environment to AUTHORIZED=2, # otherwise the lookup fails. [ "$AUTHORIZED" != 1 ] || export AUTHORIZED=2 # And here's how to return extra fields from userdb/passdb lookup, e.g. 'uid' and 'gid'. # All virtual mail users in Plesk actually run under 'popuser'. # See also: # http://wiki2.dovecot.org/PasswordDatabase/ExtraFields # http://wiki2.dovecot.org/UserDatabase/ExtraFields # http://wiki2.dovecot.org/VirtualUsers export userdb_uid=vmail export userdb_gid=vmail export EXTRA="userdb_uid userdb_gid $EXTRA" if [ "$CREDENTIALS_LOOKUP" = 1 ]; then # If this is a credentials lookup, return password together with its scheme. # The password scheme that Dovecot wants is available in SCHEME environment variable # (e.g. SCHEME=CRAM-MD5), however 'PLAIN' scheme can be converted to anything internally # by Dovecot, so we'll just return 'PLAIN' password. found_password="`echo \"$lookup_result\" | awk -F ':' '{ print $2 }'`" export password="{PLAIN}$found_password" export EXTRA="password $EXTRA" log_result "credentials lookup result: '$password' [SCHEME='$SCHEME', EXTRA='$EXTRA']" else log_result "lookup result: '$lookup_result'" fi # At the end of successful authentication execute checkpassword-reply binary. exec $CHECKPASSWORD_REPLY_BINARY else # If matching credentials were not found, return proper error code depending on lookup mode. if [ "$AUTHORIZED" = 1 -a "$CREDENTIALS_LOOKUP" = 1 ]; then log_result "lookup failed (user not found)" exit $ERR_NOUSER else log_result "lookup failed (credentials are invalid)" exit $ERR_PERMFAIL fi fi This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,26 @@ # Built for python 2.7 import MySQLdb as mdb import sys host = "127.0.0.1" database = "vmail" username = "vmail" password = "VeNUlA6xKjpfceGsN3Ull8hLmAVjc3" def main(): if len(sys.argv) == 2: con = mdb.connect(host=host, port=3306,user=username, passwd=password, db=database) cur = con.cursor() cur.execute("SELECT CONCAT(mailbox.storagebasedirectory, '/', mailbox.storagenode, '/', mailbox.maildir) AS home FROM mailbox where username = '%s'" % con.escape_string(sys.argv[1])) row = cur.fetchone() if row is not None: sys.stdout.write("%s" % row[0]) else: sys.stdout.write("") else: sys.stdout.write("") sys.stdout.flush() sys.exit(0) if __name__ == "__main__": main() -
umrysh created this gist
Nov 17, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,23 @@ # Built for python 2.7 import onetimepass as otp import sys,base64,os def main(): if len(sys.argv) >= 2: if sys.argv[1] == "-v": sys.stdout.write("%s" % otp.valid_totp(token=sys.argv[3], secret=sys.argv[2])) elif sys.argv[1] == "-c": try: sys.stdout.write("%s" % otp.get_totp(sys.argv[2])) except: sys.stdout.write("") elif sys.argv[1] == "-g": sys.stdout.write("%s" % base64.b32encode(os.urandom(10))) else: sys.stdout.write("") sys.stdout.flush() sys.exit(0) if __name__ == "__main__": main()