LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-20-2012, 10:30 AM   #1
krayher
LQ Newbie
 
Registered: Apr 2012
Posts: 4

Rep: Reputation: Disabled
Post MD5 characters replacement


Hello Guys,

I've a question regarding replacement of some characters in a string.
There should be no user interaction!
I've been working in a script that:

1. Detect the OS [ Linux / Solaris / HP-UX / AIX ]
2. Create an useraccount with information passed by command line
3. Replace the /etc/shadow and /etc/passwd files with the MD5 hash or crypt depending which OS.
4. Ask for the user to replace the password on the next login.

Here is what I've at the moment:
Code:
#!/bin/ksh

OS="`uname`"
CP="     /bin/cp"
NAWK="   /bin/nawk"         ; if [ "$OS" = "HP-UX" ]; then NAWK="/usr/bin/awk" ; fi
PASSWD=" /bin/passwd"
RM="     /bin/rm"
SED="    /usr/bin/sed"      ; if [ "$OS" = "Linux" ]; then SED="/bin/sed"      ; fi
CHMOD="/usr/bin/chmod" ; if [ "$OS" = "Linux" ]; then CHMOD="/bin/chmod" ; fi
USERADD="/usr/sbin/useradd"
ETCPASSWD="/etc/passwd"
ETCSHADOW="/etc/shadow"
TCBDIR="/tcb/files/auth"    ### Needs to set out this way or -r test files.
MIN="  1"
MAX=" 30"
WARN=" 7"

PrintUsage() {
        echo 
        echo "Usage:    `basename $0` [-u uid] [-g gid] [-d homedir] [-s shell] [-n min] [-x max] [-w warn] [-S ] [-md5= ] [-crp= ] [-f days] <login> <fullname>"

        echo "          Example 1: Create user Joe with all the default settings."
        echo
        echo "           ./useradd.sh xzjoe1 Joe Nobody"
        echo
        echo "           This will create the following entries in :"
        echo "           /etc/passwd   xzjoe1:x:61014:1:Joe Nobody:/export/home/xzjoe1:/bin/sh"
        echo "           /etc/shadow   xzjoe1:uJIq6tah3ww7s:0:1:30:7:::"


######
# Main
######

#
# get option arguments if any
#
while getopts d:g:hn:s:u:w:x:S:crp:md5:f: opt ; do
        case $opt in
                d) HOMEDIR="$OPTARG"          ;;
                g) GID="    $OPTARG"          ;;
                n) MIN="    $OPTARG"          ;;
                s) SH="     $OPTARG"          ;;
                u) UID="    $OPTARG"          ;;
                w) WARN="   $OPTARG"          ;;
                x) MAX="    $OPTARG"          ;;
				S) SECURE=" $OPTARG"          ;;  # Specify secure password (DEFAULT password will be used)
				crp) CRYPTHASH="  $OPTARG"  ;;  # Specify the HASH crypt format for HP-UX/AIX/Solaris
				md5) MD5HASH="   $OPTARG"  ;;  # Specify the HASH MD5sum format for Linux
				f) DAYS="   $OPTARG"		  ;;  # Number of days until account become inactive
                h) PrintUsage        ; exit 0 ;;
                ?) PrintUsage        ; exit 2 ::
        esac
done

if [ ! -n "$SECURE" ] ; then 
		PASSHASH=$CRYPTHASH
		
		if [ "$OS" = "Linux" ]; then PASSHASH=$MD5HASH ; fi
else
	PASSHASH="uJIq6tah3ww7s"
    if [ "$OS" = "Linux" ]; then PASSHASH="\$1\$QXBUI7di\$NwC5aBYM9TgHC03mvawSb1" ; fi # 	
		

fi

#
# validate that there are at least line arguments, loginname and fullname
#
shift $(($OPTIND - 1))
if [ $# -lt 2 ] ; then
        PrintUsage ; exit 2
fi

#
# first argument is the loginname, the rest goes to fullname
#
UNAME="$1" ; shift ; FNAME="$*"

#
# parse and execute the useradd command
#

CMD="$USERADD -m"
if   [ -n "$HOMEDIR" ] ; then          CMD="$CMD -d $HOMEDIR"
else
     if [ "`uname`" = "SunOS" ] ; then CMD="$CMD -d /export/home/$UNAME"
     else                              CMD="$CMD -d        /home/$UNAME"
     fi
fi
if [ -n "$GID" ] ; then CMD="$CMD -g $GID" ; fi


# - Account will by default not expires = -f 0
if [ -n "$DAYS" ]; then DAYS="0"; fi
if [ -n "$SH"  ] ; then CMD="$CMD -s $SH -f $DAYS "  ; fi
#



if [ -n "$UID" ] ; then CMD="$CMD -u $UID" ; fi
CMD="$CMD -c '$FNAME' $UNAME"
echo $CMD
eval $CMD
if [ $? -ne 0 ] ; then exit 2 ; fi

#
# unlock the account and assign the initial password
#
if [ -d "$TCBDIR" ] ; then
   FIRSTCHAR=`echo $UNAME | cut -c1`
   FILE=$TCBDIR/$FIRSTCHAR/$UNAME
   $NAWK -v P=$PASSHASH '{if ($0 ~ /u_pwd/) print "\t:u_pwd=" P ":\\" ; else print $0 }' $FILE > $FILE.$$
else
   if [ -r $ETCSHADOW ] ; then FILE=$ETCSHADOW
   else                        FILE=$ETCPASSWD
   fi
   case $OS in
      HP-UX) $SED "s/$UNAME:\*/$UNAME:$PASSHASH/"     $FILE > $FILE.$$ ;;
	  Linux) $SED "s/$UNAME:\!\!/$UNAME:$PASSHASH/"   $FILE > $FILE.$$ ;;
		  *) $SED "s/$UNAME:\*LK\*/$UNAME:$PASSHASH/" $FILE > $FILE.$$ ;;
   esac
fi
$CP -p $FILE.$$ $FILE
$RM    $FILE.$$

if [ "$FILE" = "$ETCPASSWD" ] ; then
	$CHMOD 0444 $FILE
fi

#
# assign password attributes and force the user to change the password
#

if [ "$OS" = "Linux" ]; then
CMD="passwd -e"
else
CMD="passwd -f"
if [ "$OS" = "HP-UX" ]; then
    if [ -f $TCBDIR/system/default ]; then
         if [ -n "$MIN"  ] ; then CMD="$CMD -n $MIN"  ; fi
         if [ -n "$MAX"  ] ; then CMD="$CMD -x $MAX"  ; fi
         if [ -n "$WARN" ] ; then CMD="$CMD -w $WARN" ; fi
    fi
else
    if [ -n "$MIN"  ] ; then CMD="$CMD -n $MIN"  ; fi
    if [ -n "$MAX"  ] ; then CMD="$CMD -x $MAX"  ; fi
    if [ -n "$WARN" ] ; then CMD="$CMD -w $WARN" ; fi
fi
fi
CMD="$CMD $UNAME"
echo $CMD
$CMD
My question is how can I deal to validate the HASH that user will input. For example:

./useradd.sh -d /home/krayher -s /bin/ksh -S -md5=$1$.L2s2b59$NApPvutgk4WRMH66MPsZA. krayher Albert Krayher

Because when I get this MD5 value in $PASSHASH, it understands that '$1' is the first argument '$.' is something else. And the string treated by sed to replace the shadow file is totally different that the one the user provided.

The correct MD5 before input on the shadow file, should be:
"\$1\$.L2s2b59\$NApPvutgk4WRMH66MPsZA."

Do you have any ideas how this treatment can be done?
Thanks for your time.

Krayher
 
Old 04-20-2012, 11:14 AM   #2
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Have you tried single quoting the string after -md5= (assuming the string does not contain a single quote character)?
 
Old 04-20-2012, 11:20 AM   #3
krayher
LQ Newbie
 
Registered: Apr 2012
Posts: 4

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by catkin View Post
Have you tried single quoting the string after -md5= (assuming the string does not contain a single quote character)?
Hi bud,
Yes, I tried with "" / '' / "''" etc.
same result. =/

EDIT:

Sorry Catkin.
I did not pay attention to the heads up about the '' on the command line, I trying to input these quotes into the script, not on the command line.
however, I used the '' as you suggested and I got the expected string.

Thanks!

Last edited by krayher; 04-21-2012 at 12:41 PM.
 
Old 04-20-2012, 12:39 PM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Quote:
same result. =/
As what? I see what you have passed in but see no evidence of error messages or incorrect output?

As a test, I did:
Code:
#!/bin/bash

echo "$1"
And ran it like so:
Code:
$ ./script '$1$.L2s2b59$NApPvutgk4WRMH66MPsZA'
$1$.L2s2b59$NApPvutgk4WRMH66MPsZA
$ ./script "$1$.L2s2b59$NApPvutgk4WRMH66MPsZA"
$.L2s2b59
These would seem to be wildly different results ... at least from each other as we do not know any of your previous results.
 
Old 04-21-2012, 12:17 PM   #5
krayher
LQ Newbie
 
Registered: Apr 2012
Posts: 4

Original Poster
Rep: Reputation: Disabled
Question

Hello, sry my delay to reply.

The $OPTARG when echoed, displays this value:
bashapptF0cp0wzQYGuQRuknpC8qG7U0

when the MD5 given on the command line is this:
$1$0apptF0c$5p0wzQYGuQRuknpC8qG7U0


I did some changes to the script today, and then I found a work-around to the problem. However I had to specify the '' quotes on the command line arguments, e.g:
./useradd.sh -d /home/kkrayher -s /bin/ksh -S -md5 '$1$0apptF0c$5p0wzQYGuQRuknpC8qG7U0'
however this is something that I wanted to avoid (if possible).

The changes I've done trying to format the string into this format (\$1\$) inserting a \ before any $, is to be used with sed, so I can write exactly the MD5 hash on the /etc/shadow file. On my past attempts, the result that I got into the shadow file was something like: "/etc/shadow xzjoe1:bashapptF0cp0wzQYGuQRuknpC8qG7U0:0:1:30:7:::".
LOL, I was not understanding WHY I could not login with the password that I generated using the "openssl passwd -1 password"!

My objectives with this script are:
1. MD5HASH="$OPTARG" will store the MD5
2. I will used SED to replace the '$' by '\$' from the $MD5HASH variable.
3. I will input the formated $MD5HASH into the shadow file.


Step 1/2:

Code:
if [ -n "$SECURE" ] ; then 
	if [ "$OS" = "Linux" ]; then
				
		PASSHASH=$(echo $MD5HASH|$SED 's|[$]|\\$|g')
	else
		PASSHASH=$CRYPTHASH
		; fi
		
else
	PASSHASH="uJIq6tah3ww7s"
    if [ "$OS" = "Linux" ]; then PASSHASH="\$1\$QXBUI7di\$NwC5aBYM9TgHC03mvawSb1" ; fi
		

fi
Step 3:

Code:
   if [ -r $ETCSHADOW ] ; then FILE=$ETCSHADOW
   else                        FILE=$ETCPASSWD
   fi
   case $OS in
      HP-UX) $SED "s/$UNAME:\*/$UNAME:$PASSHASH/"     $FILE > $FILE.$$ ;;
      Linux) $SED "s/$UNAME:\!\!/$UNAME:$PASSHASH/"   $FILE > $FILE.$$ ;;
	  *) $SED "s/$UNAME:\*LK\*/$UNAME:$PASSHASH/" $FILE > $FILE.$$ ;;
   esac
fi
$CP -p $FILE.$$ $FILE
$RM    $FILE.$$

So, at this point the question I've for you is:

- Is there a way to avoid having to use the '' on this md5 hash on the command line? or is this something that must be used?

Thanks for your time,
 
Old 04-21-2012, 01:00 PM   #6
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Short answer is yes the quotes must be used. This is the only way to stop the shell from interpreting the information. Although I am confused on why the escaping and so forth is needed
as once you quote the string it can be used as is?
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Mastering Characters Sets in Linux (Weird Characters, part 2) LXer Syndicated Linux News 0 11-25-2009 11:30 PM
End-of-line Characters missing from last line of md5 file. Md5sum fails mehorter Linux - General 5 06-29-2009 08:56 PM
need help unpacking hmac-md5 hash into md5 hash lynx5 Programming 3 02-02-2008 04:06 PM
difference between md5 shadow and md5 elsewhere? whysyn Linux - Security 5 12-11-2007 10:11 AM
How to modify the names of files and replace characters with other characters or symb peter88 Linux - General 2 12-10-2006 03:05 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:20 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration