md5crypt.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 package require Tcl 8.2;
00015 package require md5 2;
00016
00017
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
00142
00143
00144
00145