md5crypt.tcl

Go to the documentation of this file.
00001 /*  md5crypt.tcl - Copyright (C) 2003 Pat Thoyts <patthoyts@users.sourceforge.net>*/
00002 /* */
00003 /*  This file provides a pure tcl implementation of the BSD MD5 crypt algorithm.*/
00004 /*  The implementation is based upon the OpenBSD code which is in turn based upon*/
00005 /*  the original code by Poul-Henning Kamp. */
00006 /* */
00007 /*  -------------------------------------------------------------------------*/
00008 /*  See the file "license.terms" for information on usage and redistribution*/
00009 /*  of this file, and for a DISCLAIMER OF ALL WARRANTIES.*/
00010 /*  -------------------------------------------------------------------------*/
00011 
00012 /*  @mdgen EXCLUDE: md5cryptc.tcl*/
00013 
00014 package require Tcl 8.2;                /*  tcl minimum version*/
00015 package require md5 2;                  /*  tcllib 1.5*/
00016 
00017 /*  Try and load a compiled extension to help.*/
00018 if {[catch {package require tcllibc}]} {
00019     catch {package require md5cryptc}
00020 }
00021 
00022 namespace md5crypt {
00023     variable version 1.0.0
00024     variable rcsid {$Id: md5crypt.tcl,v 1.4 2005/12/09 18:27:17 andreas_kupries Exp $}
00025     variable itoa64 \
00026         {./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz}
00027 
00028     namespace import -force ::md5::MD5Init ::md5::MD5Update ::md5::MD5Final
00029     namespace export md5crypt
00030 }
00031 
00032 ret  ::md5crypt::to64_tcl (type v , type n) {
00033     variable itoa64
00034     for {} {$n > 0} {incr n -1} {
00035         set i [expr {$v & 0x3f}]
00036         append s [string index $itoa64 $i]
00037         set v [expr {($v >> 6) & 0x3FFFFFFF}]
00038     }
00039     return $s
00040 }
00041 
00042 ret  ::md5crypt::md5crypt_tcl (type magic , type pw , type salt) {
00043     set sp 0
00044 
00045     set start 0
00046     if {[string match "${magic}*" $salt]} {
00047         set start [string length $magic]
00048     }
00049     set end [string first $ $salt $start]
00050     if {$end < 0} {set end [string length $salt]} else {incr end -1}
00051     if {$end - $start > 7} {set end [expr {$start + 7}]}
00052     set salt [string range $salt $start $end]
00053 
00054     set ctx [MD5Init]
00055     MD5Update $ctx $pw
00056     MD5Update $ctx $magic
00057     MD5Update $ctx $salt
00058 
00059     set ctx2 [MD5Init]
00060     MD5Update $ctx2 $pw
00061     MD5Update $ctx2 $salt
00062     MD5Update $ctx2 $pw
00063     set H2 [MD5Final $ctx2]
00064 
00065     for {set pl [string length $pw]} {$pl > 0} {incr pl -16} {
00066         set tl [expr {($pl > 16 ? 16 : $pl) - 1}]
00067         MD5Update $ctx [string range $H2 0 $tl]
00068     }
00069     
00070     for {set i [string length $pw]} {$i != 0} {set i [expr {$i >> 1}]} {
00071         if {$i & 1} {
00072             set c \0
00073         } else {
00074             set c [string index $pw 0]
00075         }
00076         MD5Update $ctx $c
00077     }
00078     
00079     set result "${magic}${salt}\$"
00080     
00081     set H [MD5Final $ctx]
00082 
00083     for {set i 0} {$i < 1000} {incr i} {
00084         set ctx [MD5Init]
00085         if {$i & 1} {
00086             MD5Update $ctx $pw
00087         } else {
00088             MD5Update $ctx $H
00089         }
00090         if {$i % 3} {
00091             MD5Update $ctx $salt
00092         }
00093         if {$i % 7} {
00094             MD5Update $ctx $pw
00095         }
00096         if {$i & 1} {
00097             MD5Update $ctx $H
00098         } else {
00099             MD5Update $ctx $pw
00100         }
00101         set H [MD5Final $ctx]
00102     }
00103 
00104     binary scan $H c* Vs
00105     foreach v $Vs {lappend V [expr {$v & 0xFF}]}
00106     set l [expr {([lindex $V 0] << 16) | ([lindex $V  6] << 8) | [lindex $V 12]}]
00107     append result [to64 $l 4]
00108     set l [expr {([lindex $V 1] << 16) | ([lindex $V  7] << 8) | [lindex $V 13]}]
00109     append result [to64 $l 4]
00110     set l [expr {([lindex $V 2] << 16) | ([lindex $V  8] << 8) | [lindex $V 14]}]
00111     append result [to64 $l 4]
00112     set l [expr {([lindex $V 3] << 16) | ([lindex $V  9] << 8) | [lindex $V 15]}]
00113     append result [to64 $l 4]
00114     set l [expr {([lindex $V 4] << 16) | ([lindex $V 10] << 8) | [lindex $V  5]}]
00115     append result [to64 $l 4]
00116     set l [expr {[lindex $V 11]}]
00117     append result [to64 $l 2]
00118     
00119     return $result
00120 }
00121 
00122 if {[info command ::md5crypt::to64_c] == {}} {
00123     interp alias {} ::md5crypt::to64 {} ::md5crypt::to64_tcl
00124 } else {
00125     interp alias {} ::md5crypt::to64 {} ::md5crypt::to64_c
00126 }
00127 
00128 if {[info command ::md5crypt::md5crypt_c] == {}} {
00129     interp alias {} ::md5crypt::md5crypt {} ::md5crypt::md5crypt_tcl {$1$}
00130     interp alias {} ::md5crypt::aprcrypt {} ::md5crypt::md5crypt_tcl {$apr1$}
00131 } else {
00132     interp alias {} ::md5crypt::md5crypt {} ::md5crypt::md5crypt_c {$1$}
00133     interp alias {} ::md5crypt::aprcrypt {} ::md5crypt::md5crypt_c {$apr1$}
00134 }
00135 
00136 /*  -------------------------------------------------------------------------*/
00137 
00138 package provide md5crypt $::md5crypt::version
00139 
00140 /*  -------------------------------------------------------------------------*/
00141 /*  Local Variables:*/
00142 /*    mode: tcl*/
00143 /*    indent-tabs-mode: nil*/
00144 /*  End:*/
00145 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1