#!/bin/sh

## "ldaspw"
## Utility to encrypt an LDAS username & password, and store them in ~/.ldaspw
## Written by Peter Shawhan, October 2000

## The next line tells sh to execute the script using tclshexe \
exec tclsh "$0" ${1+"$@"}

##=========================================================================

;#-- Read the user's .ldaspw file, if it exists
set file "~/.ldaspw"

if { [file exists $file] } {

    ;##- Check that we can read and write this file
    if { ! [file readable $file] } {
	puts "Error: your $file file is not readable by you"
	exit 1
    }
    if { ! [file writable $file] } {
	puts "Error: your $file file is not writable by you"
	exit 1
    }

    ;##- Open the file
    if { [catch {open $file r} fid] } {
	puts "Error opening your $file file for reading"
	exit 1
    }

    ;##- Read in file contents
    set userlist {}
    while { ! [eof $fid] } {
	gets $fid line
	if {[regexp {^(\w+)\s+([0-9A-F]+)} $line match user encpw]} {
	    lappend userlist $user
	    ;##- The first listing is the default user
	    if { [llength $userlist] == 1 } { set defuser $user }
	    set pwlist($user) $encpw
	}
    }

    ;##- Close the file
    close $fid
}


;##- Now get user input

puts "Enter LDAS username"
set user [gets stdin]

;##- Turn off echoing of input
catch { exec /bin/stty -echo }
puts "Enter password (will not be echoed to screen)"
set pw [gets stdin]

;##- Print out stars
puts [string repeat * [string length $pw]]

;##- Turn echoing back on
catch { exec /bin/stty echo }

if {[info exists pwlist]} {
    if { $user != $defuser } {
	set choice ""
	while { ! [regexp {^(y|n)} $choice match val] } {
	    puts "Do you want to make this your default LDAS username? (y/n)"
	    set choice [gets stdin]
	}
	if { $val == "y" } {
	    set defuser $user
	}
    }    
} else {
    set defuser $user
}

;##- Encode the password
set len [string length $pw]
if {$len < 16} { set len 16 }
set logname $::tcl_platform(user)
set lnlen [string length $logname]
set encstr [string range [string repeat $logname 16] 0 [expr {$len-1}]]

binary scan $pw c* list1
set bridge {0}
set modlen [expr {[string length $pw]+1}]
if { $modlen == $lnlen } {
    lappend bridge -$modlen
    incr modlen
} else {
    set delta 1
    foreach factor {2 3 5} {
	if { [expr {$lnlen%$factor}]==0 && [expr {$modlen%$factor}]==0 } {
	    lappend bridge -$modlen
	    incr modlen $delta
	    incr delta
	}
    }
}
while { [llength $list1] < $len } {
    set list1 [concat $list1 $bridge $list1]
}
set list1 [lrange $list1 0 [expr {$len-1}]]

binary scan $encstr c* list2
set encpw ""
foreach val1 $list1 val2 $list2 {
    if {$val1==""} {set val1 0}; if {$val2==""} {set val2 0}
    append encpw [format %02X [expr {(17*($val1+$val2))%256}]]
}

;##- Add/update the new password for the specified username
set pwlist($user) $encpw


;##- DELETE the old file if it exists
if { [file exists $file] } {
    file delete $file
}

;##- Write out the updated file, with appropriate protections
if { [catch {open $file w 0600} fid] } {
    puts "Error opening your $file file for writing; stored password(s) lost"
    exit 1
}

;##- Write out the list, with the default user first
puts $fid "$defuser $pwlist($defuser) (default)"
foreach {user encpw} [array get pwlist] {
    if { $user != $defuser } {
	puts $fid "$user $encpw"
    }
}

;##- Close the file
close $fid

puts "Your LDAS username and encoded password have been stored in ~/.ldaspw"

;##- We're done!
exit 0
