tclhttpd

Check-in [80751cdeac]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added more documentation Renamed the cookieSet method to httpdCookieSet, and moved it to httpd.meta Moved httpdHostName it to httpd.meta Implemented logins using encrypted password hashes Added a module to store javascript password hashing routines. Added a "cat" command to dump files Added the pageHeader and pageFooter methods to httpd.meta Community and its decendents now render pages in bootstrap/jquery. Added jquery to our bootstrap distribution
Timelines: family | ancestors | descendants | both | 4_0
Files: files | file ages | folders
SHA1:80751cdeac4cce1e95c83cb39e7e6dd09e917654
User & Date: hypnotoad 2015-04-03 07:35:02
Context
2015-05-14
10:31
Converted the last of the lassign-brent calls to straight-up lassign Adapted the http::compat to be user selectable as far as how far back we intend to support Adding a qwiki object called MAIN to the default httpd thread Fixed the examples of Taourl so far to now employ the "puts" to buffer architecture. Merging in upsteam changes from tao Broke out the base security system and urls into layers Leaf check-in: ffc189660f user: hypnotoad tags: 4_0
2015-04-03
07:35
Added more documentation Renamed the cookieSet method to httpdCookieSet, and moved it to httpd.meta Moved httpdHostName it to httpd.meta Implemented logins using encrypted password hashes Added a module to store javascript password hashing routines. Added a "cat" command to dump files Added the pageHeader and pageFooter methods to httpd.meta Community and its decendents now render pages in bootstrap/jquery. Added jquery to our bootstrap distribution check-in: 80751cdeac user: hypnotoad tags: 4_0
07:30
Added the pageHeader and pageFooter methods to httpd.meta Community and its decendents now render pages in bootstrap/jquery. Leaf check-in: 6174565fef user: hypnotoad tags: private
2015-04-02
15:43
Adding markdown documentation into the source repo check-in: 001675d4e9 user: hypnotoad tags: 4_0
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to bin/test/qwiki.tcl.

     8      8   
     9      9   # Configure the auto_path so we can find the script library.
    10     10   # home is the directory containing this script
    11     11   
    12     12   set home [string trimright [file dirname [info script]] ./]
    13     13   set home [file normalize [file join [pwd] $home ..]]
    14     14   set Config(lib) [file join $home .. modules]
    15         -
           15  +set Config(dbfile) [file join $home test qwiki.sqlite]
    16     16   source $home/test/common.tcl
    17     17   
    18     18   ###
    19     19   # Begin the test
    20     20   ###
    21     21   package require httpd::qwiki
    22     22   
................................................................................
    24     24     superclass httpd.qwiki
    25     25   
    26     26     ###
    27     27     # title: Implement html content at a toplevel
    28     28     ###
    29     29     method /html {} {
    30     30       my variable result
    31         -    array set result {
    32         -      code 200
    33         -      type text/html
    34         -    }
    35         -    set body {
    36         -<HTML><BODY>
           31  +    my reset
           32  +    set result(title) {Welcome to Qwiki!}
           33  +
           34  +    my puts [my pageHeader]
           35  +    my puts {
    37     36   Hello World!
    38     37   <p>
    39     38       }
    40         -    if {[info exists result(userid)]} {
    41         -      append body "Logged in as user: $result(userid)<br>"
           39  +    my puts "Logged in as user: [dict getnull $result(session) username]<br>"
           40  +    if {[info exists result(sessionid)]} {
           41  +      my puts "Logged with session: $result(sessionid)<br>"
    42     42       }
    43         -    if {[info exists result(sessionid)]} {
    44         -      append body "Logged with session: $result(sessionid)<br>"
    45         -    }
    46         -    append body {
           43  +    my puts {
    47     44   Try the following links:
    48     45   <ul>
    49     46       }
    50     47       set prefix [my cget virtual]
    51     48       foreach {url comment} {
    52     49         errorurl {Throw an internal error from Tcl}
    53     50         deadurl  {Page that generates a 505 error}
    54     51         suburl   {Valid Suburl}
    55     52         missing  {Non-existent url}
           53  +      login    {Log In}
           54  +      logout   {Log Out}
    56     55       } {
    57         -      append body "<li><a href=$prefix/$url>$url</a> - $comment</li>"
           56  +      my puts "<li><a href=$prefix/$url>$url</a> - $comment</li>"
    58     57       }
    59         -    append body {
           58  +    my puts {
    60     59   </ul>
    61     60   </BODY></HTML>
    62     61   }
    63         -    set result(body) $body
    64     62     }
    65     63   
    66     64     method /html/errorurl {} {
    67     65       error "Die Yuppie Scum!"
    68     66     }
    69     67   
    70     68     method /html/deadurl {} {
    71     69       my variable result
    72         -    array set result {
    73         -      code 501
    74         -      body {
    75         -<HTML><BODY>
           70  +    my reset
           71  +    set result(code) 501
           72  +    my puts [my pageHeader]
           73  +    my puts {
    76     74   I threw an error this way
    77         -</BODY></HTML>
    78         -}
    79         -      content-type text/html
    80     75       }
           76  +    my puts [my pageFooter]
    81     77     }
    82     78   
    83     79     ###
    84     80     # title: Implement html content at a toplevel
    85     81     ###
    86     82     method /html/suburl {} {
    87     83       my variable result
    88         -    array set result {
    89         -      code 200
    90         -      body {
    91         -<HTML><BODY>
    92         -Sub Url
    93         -</BODY></HTML>
    94         -}
    95         -      type text/html
           84  +    my reset
           85  +    my puts [my pageHeader]
           86  +    my puts {
           87  +This is a suburl!
    96     88       }
           89  +    my puts [my pageFooter]
    97     90     }
    98     91   
    99     92     ###
   100     93     # title: Implement html content at a toplevel
   101     94     ###
   102     95     method /html/default {} {
   103     96       my variable result
   104         -    array set result {
   105         -      code 404
   106         -      body {
   107         -<HTML><BODY>
           97  +    my reset
           98  +    set result(code) 404
           99  +    my puts [my pageHeader]
          100  +    my puts {
   108    101   Not Found
   109         -</BODY></HTML>
   110         -}
   111         -      type text/html
   112    102       }
          103  +    my puts [my pageFooter]
   113    104     }
   114    105   }
   115    106   
   116         -qwikitest create HOME /home {db {}}
          107  +qwikitest create HOME /home [list dbfile [Config dbfile]]
   117    108   
   118    109   vwait forever
   119    110   if 0 {
   120    111   # Start up the user interface and event loop.
   121    112   package require Tk
   122    113   package require httpd::srvui
   123    114   package require httpd::stdin

Added modules/bootstrap/js/jquery.min.js.

cannot compute difference between binary files

Added modules/community/acl.md.


Added modules/community/acl.tcl.


Changes to modules/community/community.md.

     1         -*httpd.community* is a decendent of [httpd.taourl](wiki?taourl). It adds an sqlite based user, group, and access control system. It is implemented in [community.tcl](finfo?name=modules/community/community.tcl).
            1  +*httpd.community* is a decendent of . It adds an sqlite based user, group, and access control system. It is implemented in [community.tcl](finfo?name=modules/community/community.tcl).
            2  +
            3  +## Ancestors
            4  +
            5  +* [httpd.taourl](../directoo/taourl.md)
            6  +* [yggdrasil](../tao-sqlite/yggdrasil.md)
     2      7   
     3      8   ## Required Packages
     4      9   
     5     10   Community relies on the following external packages:
     6     11   
     7     12   * sha1 from [tcllib](http://core.tcl.tk/tcllib)
     8     13   * sqlite3 from [sqlite](http://www.sqlite.org)
     9     14   
    10     15   Community uses the following internal packages:
    11     16   
    12     17   * tao from [tao](../tao/tao.md)
    13     18   * tao-sqlite [tao-sqlite](../tao-sqlite/tao-sqlite.md)
    14     19   
           20  +## Properties
           21  +
           22  +* create\_sql - An SQL script that implements the schema
    15     23   
    16     24   ## Options
    17     25   
    18     26   * dbfile - Path to a file which stores the sqlite database for the community (default in-memory)
    19     27   * virtual - Root Url of this object.
    20     28   
    21     29   ## Attached Objects
    22     30   
    23     31   Community objects (and their derived classes) contain an embedded sqlite
    24     32   database. This database can be accessed via that \<db\> method.
    25     33   
           34  +## Methods
           35  +
           36  +### method Database\_Functions
           37  +
           38  +Adds the following functions to the database:
           39  +
           40  +* uuid\_generate() - Generates sha1 UUIDs on demand
           41  +* sha1() - Returns the SHA1 hash of the input
           42  +
           43  +### aclAccessTypes
           44  +
           45  +Returns a list of all possible rights.
           46  +
           47  +### aclRights *aclname* *user\_or\_group\_id*
           48  +
           49  +Return a list of rights that the user or group to the access control list (specified by name.)
           50  +
           51  +### method httpdSessionLoad *sock* *prefix* *suffix*
           52  +
           53  +This method looks for a sessionid cookie or a sessionid field in the GET or POST query, and
           54  +pairs it with a session in the *session* table. If no session is found, a new session is generated
           55  +for an anonymous user.
           56  +
           57  +### method httpdSessionSave *sock*
           58  +
           59  +This method compares the current value of **result\(session\)** to **result\(session\_delta\)** (a copy
           60  +of the session when the pageview began. Fields that are in the delta, but not in the current session are delete
           61  +from **session\_property**. Fields that are present in the session but not the delta are inserted into
           62  +**session\_property**. Fields present in both, but with a different value, are updated.
           63  +
           64  +The server will generate a cookie called **sessionid** which will be loaded on the next page view.

Changes to modules/community/community.tcl.

     7      7   package require md5 2
     8      8   package require sha1 2
     9      9   
    10     10   package require httpd::taourl
    11     11   package require httpd::cookie	;# Cookie_GetSock Cookie_Make
    12     12   package require httpd::doc	;# Doc_Root
    13     13   package require httpd::utils	;# Stderr file iscommand randomx
           14  +package require httpd::jshash   ;# Javascript password hashes
           15  +package require httpd::bootstrap
    14     16   
    15     17   tao::class httpd.community {  
    16     18     superclass httpd.taourl taodb::yggdrasil
    17     19     
    18     20     option virtual {}
    19     21     option dbfile {}
           22  +  option community-id {}
           23  +
           24  +  set dir [file dirname [file normalize [info script]]]
           25  +  foreach jsfile [glob -nocomplain [file join $dir *.js]] {
           26  +    property js [file tail $jsfile] [cat $jsfile]
           27  +  }
    20     28   
    21     29     method initialize {} {
    22     30       if {[my cget dbfile] eq {}} {
    23     31         my configure dbfile :memory:
    24     32       }
    25     33       my Database_Attach [my cget dbfile]
           34  +    my configurelist [my <db> eval {select name,value from config}]
           35  +    if {[my cget community-id] eq {}} {
           36  +      my configure community-id [::tao::uuid_generate]
           37  +    }
           38  +    my variable config
    26     39     }
    27     40   
    28     41     ###
    29     42     # This class extents the yggdrasil schema to
    30     43     # include session management, user management,
    31     44     # and access control lists
    32     45     ###
................................................................................
   157    170   userid    string references users (userid) ON UPDATE CASCADE ON DELETE SET NULL,
   158    171   grant     int default 1,
   159    172   right     text,
   160    173   UNIQUE (acl_name,userid,right)
   161    174   );
   162    175   
   163    176   --- POPULATE WITH DATA ---
   164         -insert into users(userid,username,password) VALUES ('local.webmaster','webmaster',sha1('local.webmaster'||'password'));
          177  +insert into config(name,value) VALUES ('community-id',uuid_generate());
          178  +
          179  +insert into users(userid,username,password) VALUES ('local.webmaster','webmaster',sha1((select value from config where name='community-id')||'password'));
   165    180   insert into users(userid,username,password) VALUES ('local.anonymous','anonymous','');
   166    181   
   167    182   insert into groups(groupid,groupname) VALUES ('local.wheel','wheel');
   168    183   insert into group_members(userid,groupid) VALUES ('local.webmaster','local.wheel');
   169    184   
   170    185   insert into acl (acl_name) VALUES ('admin');
   171    186   insert into acl_grants (acl_name,userid,grant,right) VALUES ('admin','local.wheel',1,'all');
................................................................................
   177    192   
   178    193     method Database_Functions {} {
   179    194       set seed [info hostname]
   180    195       my <db> function uuid_generate ::tao::uuid_generate
   181    196       my <db> function sha1    {::sha1::sha1 -hex}
   182    197     }
   183    198   
   184         -  method accessTypes {} {
   185         -    set accessTypes {admin edit view}
          199  +  method aclAccessTypes {} {
          200  +    set aclAccessTypes {admin edit view}
   186    201       foreach type [my <db> eval "select distinct right from acl_grants order by right"] {
   187         -        logicset add accessTypes $type
          202  +        logicset add aclAccessTypes $type
   188    203       }     
   189         -    return $accessTypes    
          204  +    return $aclAccessTypes    
   190    205     }
   191    206   
   192    207     method aclRights {aclname userid} {
   193    208       set parentlist {}
   194    209       set thisnode $aclname
   195    210       
   196    211       while 1 {
................................................................................
   216    231             if { $right == "all" } { 
   217    232                 set rights {}
   218    233             } else {
   219    234                 logicset remove rights $right
   220    235             }
   221    236         } else {
   222    237           if { $right eq "all" } {
   223         -          logicset add rights {*}[my accessTypes]
          238  +          logicset add rights {*}[my aclAccessTypes]
   224    239           } else {
   225    240             logicset add rights $right
   226    241           }
   227    242         }
   228    243       }
   229    244       
   230    245       foreach p $parentlist {
................................................................................
   236    251               if { $right == "all" } { 
   237    252                   set rights {}
   238    253               } else {
   239    254                   logicset remove rights $right
   240    255               }
   241    256           } else {
   242    257             if { $right eq "all" } {
   243         -            logicset add rights {*}[my accessTypes]
          258  +            logicset add rights {*}[my aclAccessTypes]
   244    259             } else {
   245    260               logicset add rights $right
   246    261             }
   247    262           }
   248    263         }
   249    264       }
   250    265       return $rights
   251    266     }
   252    267     
   253         -
   254    268     method httpdSessionLoad {sock prefix suffix} {
   255    269       my variable result
   256    270       array set result {
   257    271         code 200
   258    272         date  0
   259    273         header {}
   260    274         footer {}
................................................................................
   296    310           set result(userid) [my <db> one $stmt]
   297    311           set result(session) [my <db> eval {select field,value from session_property where sesid=:value}]
   298    312           set result(session_delta) $result(session)
   299    313           return
   300    314         }
   301    315       }
   302    316       if {![info exists result(userid)]} {
   303         -      set result(userid) [my <db> one {select userid from users where name='anonymous'}]
          317  +      set result(userid) local.anonymous
          318  +      dict set result(session) username anonymous
   304    319       }
   305    320       set expdate  [expr {14*86400}]
   306    321       set expires [expr {[clock seconds]+$expdate}]]
   307    322       if {![info exists result(sessionid)]} {
   308    323         # Generate a session
   309    324         set sesid [::tao::uuid_generate]
   310    325         set result(sessionid) $sesid
   311    326         my <db> eval {insert into session(sesid,userid,expires) VALUES (:sesid,:result(userid),:expires)}
   312    327       } else {
   313    328         my <db> eval {update session set expires=:expires where sesid=:sesid;}
   314    329       }
   315         -    my cookieSet session $result(sessionid) $expdate
          330  +    my httpdCookieSet session $result(sessionid) $expdate
   316    331     }
   317         -  
   318         -  method cookieSet {field value {expire {}}} {
   319         -    foreach host [my httpdHostName] {
   320         -      if { $host eq "localhost" } { set host {} }
   321         -      set cookie_args [list -name $field \
   322         -        -value $value \
   323         -        -domain $host \
   324         -        -path [my cget virtual]]
   325         -      if {[string is integer expire]} {
   326         -        lappend cookie_args -expires [clock format [expr [clock seconds] + [set expire]] -format "%Y-%m-%d"]
   327         -      }
   328         -      ::Cookie_Set {*}$cookie_args
   329         -    }
   330         -  }
   331         -  
   332         -  method httpdHostName {} {
   333         -    my variable env
   334         -    return [lindex [split [get env(HTTP_HOST)] :] 0]
   335         -  }
   336         -  
          332  +    
   337    333     method httpdSessionSave sock {
   338    334       # Save any return cookies which have been set.
   339    335       # This works with the Doc_SetCookie procedure that populates
   340    336       # the global cookie array.
   341    337       
   342    338       ::Cookie_Save $sock
   343    339       if {![info exists result(sessionid)]} return
................................................................................
   369    365         }
   370    366         foreach {field value} $delete {
   371    367           my <db> eval {delete from session_property where sesid=:sessionid and field=:field;}
   372    368         }
   373    369         my <db> eval "COMMIT"
   374    370       }
   375    371     }
          372  +  
          373  +  method pageHeader {} {
          374  +    return {
          375  +<HTML>
          376  +<HEAD>
          377  +    <TITLE>@TITLE@</TITLE>
          378  +    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
          379  +</HEAD>
          380  +<BODY>
          381  +    }
          382  +  }
          383  +  
          384  +  method pageFooter {} {
          385  +    return {
          386  +<script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
          387  +<script type="text/javascript" src="/bootstrap/js/jquery.min.js"></script>
          388  +</BODY></HTML>
          389  +    }
          390  +  }
          391  +
          392  +  method /html/logout {} {
          393  +    my variable result
          394  +    set sesid $result(sessionid)
          395  +    my <db> eval {
          396  +update session set userid='local.anonymous' where sesid=:sesid;
          397  +delete from session_property where sesid=:sesid;
          398  +}
          399  +    dict set result(session) username anonymous
          400  +    dict set result(session) userid local.anonymous
          401  +    set result(message) {You have been logged out}
          402  +    my /html/login
          403  +  }
          404  +  
          405  +  method /html/login {} {
          406  +    my variable result
          407  +    
          408  +    my reset
          409  +    my puts <html>
          410  +    my puts {
          411  +  <head>
          412  +    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
          413  +    <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
          414  +    <script type="text/javascript" src="/bootstrap/js/jquery.min.js"></script>
          415  +    <TITLE>Log In</TITLE>
          416  +    <script type="text/javascript" src="/jshash/sha1-min.js"></script>
          417  +    <script type="text/javascript">  
          418  +function login() {
          419  +  
          420  +    var p = hex_sha1(document.getElementById('key').value+document.getElementById('pass').value);  
          421  +    var k = document.getElementById('sesid').value;  
          422  +
          423  +    var h = hex_sha1(k+p);  
          424  +    var hash = document.getElementById('hash');  
          425  +    hash.value = h;
          426  +    var f = document.getElementById('finalform');  
          427  +    f.submit();  
          428  +}  
          429  +    </script>
          430  +  </head>
          431  +    }    
          432  +    my puts {
          433  +  <body>
          434  +    }
          435  +    set msg [get result(message)]
          436  +    if { $msg ne {} } {
          437  +      my puts "<pre><font color=”red” face=”sans-serif” size=”1”>$msg</font></pre><hr>"
          438  +    }
          439  +    my puts {
          440  +<table>
          441  +<form action="authenticate" method="post" id="finalform">
          442  +<tr><th>Username:</th><td><input name="uid" id="uid" /></td></tr>
          443  +<input type="hidden" name="hash" id="hash" />  
          444  +</form>
          445  +    }
          446  +    my puts {<form action="javascript:login()" method="post" >}
          447  +    my puts "<input type=\"hidden\" id=\"key\" value=\"[my cget community-id]\" />"  
          448  +    my puts "<input type=\"hidden\" id=\"sesid\" value=\"$result(sessionid)\" />"  
          449  +    my puts {
          450  +<tr><th>Password:</th><td><input type="password" id="pass" /></td></tr>
          451  +<tr><th>&nbsp</th></th><td><input type="submit" value="Log In" /></td></tr>
          452  +</table>
          453  +    </form>  
          454  +
          455  +  </body>
          456  +    }
          457  +    my puts </html>
          458  +  }
          459  +
          460  +  method /html/authenticate {} {
          461  +    my variable result
          462  +    foreach {field value} $result(query) {
          463  +      if {$field eq "uid"} {
          464  +        set username $value
          465  +        foreach {field value} $result(query) {
          466  +          if {$field eq "hash"} {
          467  +            set passhash [my <db> one {select password from users where username=:username}]
          468  +            set realhash [::sha1::sha1 -hex "$result(sessionid)$passhash"]
          469  +            if { $realhash eq $value } {
          470  +              set userid [my <db> one {select username from users where username=:username}]
          471  +              my <db> eval {update session set userid=:userid where sesid=:result(sessionid)}
          472  +              dict set result(session) username $username
          473  +              dict set result(session) userid $userid
          474  +
          475  +              set root [my cget virtual]
          476  +              my puts "<HTML><HEAD><META HTTP-EQUIV=\"Refresh\" CONTENT=\"1; URL=$root\"></HEAD>"
          477  +              my puts {
          478  +<BODY>
          479  +You are now being logged in. You will be redirected in a moment.
          480  +<p>
          481  +              }
          482  +              my puts "<A href=\$root\>Home...</a>"
          483  +              my puts </BODY></HTML>
          484  +              return
          485  +            }
          486  +          }
          487  +        }
          488  +      }
          489  +    }
          490  +    set result(message) {Password or Username was incorrect or invalid.}
          491  +    my /html/login
          492  +  }
   376    493   }
   377    494   
   378    495   package provide httpd::community 0.1

Changes to modules/directoo/directoo.md.

    16     16   
    17     17   * code - HTTP code to return (default 400)
    18     18   * body - The block of data to be sent via *Httpd_ReturnData* or *Httpd_ReturnCacheableData* at the conclusion of the operation.
    19     19   * content-type - The type of content in *block* (default text/html)
    20     20   
    21     21   ## Methods
    22     22   
    23         -### configurelist *keyvaluelist*
           23  +### method configurelist *keyvaluelist*
    24     24   
    25     25   Pass configuration items as a key/value list.
    26     26   
    27         -### cget *field*
           27  +### method cget *field*
    28     28   
    29     29   Retrieve the value of a configuration item
    30     30   
    31     31   ### /html
    32     32   
    33     33   A method which implements the default root page of the object.
    34     34   
    35         -### initialize
           35  +### method initialize
    36     36   
    37     37   A method which is called in the constructor, after the configuration items have been applied and the domain registered with Tclhttpd.
    38     38   
    39         -### httpdDirect *sock* *suffix*
           39  +### method httpdCookieSet *field* *value* *?expire?*
           40  +
           41  +Set a cookie named *field* and value of *value*. If *expire* is a postitive integer,
           42  +it indicates how long (in seconds) this cookie should last.
           43  +
           44  +Note: Cookies destined for "localhost" are mapped to null so
           45  +browser will honor them properly.
           46  +
           47  +### method httpdHostName
           48  +
           49  +Return the host name by which this page was accessed. Derived
           50  +from env\(HTTP\_HOST\).
           51  +
           52  +
           53  +### method httpdDirect *sock* *suffix*
    40     54   
    41     55   This method is the first called when resolving a dynamic page. It calles *httpdSessionLoad* to load the session, *httpdMarshalArguments* do compute the method to call. On error, this method returns an error message. On success it calls *httpdSessionSave*, before sending the resulting data out to TclHttpd via the *Httpd_ReturnData* or *Httpd_ReturnCacheableData* procs.
    42     56   
    43         -### httpdMarshalArguments *sock* *suffix*
           57  +### method httpdMarshalArguments *sock* *suffix*
    44     58   
    45     59   Calculate the command which will implement the current page view.
    46     60   
    47         -### httpdSessionLoad *sock *prefix* *suffix*
           61  +### method httpdSessionLoad *sock *prefix* *suffix*
    48     62   
    49     63   Initializes the *result* variable, and load session data from either cookies or the incoming GET/POST query. This method also calls the *Cgi_SetEnv* and *Url_QuerySetup* procs from Tclhttpd. Rather than populate the global *env* variable, Cgi_SetEnv populates the private *env* variable for this object.
    50     64   
    51         -### httpdSessionSave *sock*
           65  +### method httpdSessionSave *sock*
    52     66   
    53     67   Updates the current session, and writes cookies back to the browser.
    54     68   
    55         -### reset
           69  +### method reset
    56     70   
    57     71   Reset the current value of result(body)
    58     72   
    59         -### puts
           73  +### method puts
    60     74   
    61     75   Append to the value of result(body). Accepts multiple arguments. An implied \n is appended at the tail end.
    62     76   
    63         -### unknown *args*
           77  +### method unknown *args*
    64     78   
    65     79   Handler for unknown, incomplete, or invalid queries.

Changes to modules/directoo/directoo.tcl.

    24     24   oo::class create httpd.meta {
    25     25     
    26     26     destructor {
    27     27       catch {::Url_PrefixRemove [my cget virtual]}
    28     28     }
    29     29     
    30     30     method initialize {} {}
    31         -
           31  +  
           32  +  method httpdCookieSet {field value {expire {}}} {
           33  +    foreach host [my httpdHostName] {
           34  +      if { $host eq "localhost" } { set host {} }
           35  +      set cookie_args [list -name $field \
           36  +        -value $value \
           37  +        -domain $host \
           38  +        -path [my cget virtual]]
           39  +      if {[string is integer expire]} {
           40  +        lappend cookie_args -expires [clock format [expr [clock seconds] + [set expire]] -format "%Y-%m-%d"]
           41  +      }
           42  +      ::Cookie_Set {*}$cookie_args
           43  +    }
           44  +  }
    32     45   
           46  +  method httpdHostName {} {
           47  +    my variable env
           48  +    return [lindex [split [get env(HTTP_HOST)] :] 0]
           49  +  }
           50  +  
    33     51     # This calls out to the Tcl procedure named "$prefix$suffix",
    34     52     # with arguments taken from the form parameters.
    35     53     # Example:
    36     54     # httpdDirect /device Device
    37     55     # if the URL is /device/a/b/c, then the Tcl command to handle it
    38     56     # should be
    39     57     # [self] /html/Device/a/b/c
................................................................................
    68     86     method httpdDirect {sock suffix} {
    69     87       global env
    70     88       upvar #0 Httpd$sock data
    71     89       my variable result
    72     90       set prefix [my cget virtual]
    73     91       my httpdSessionLoad $sock $prefix $suffix
    74     92       set cmd [my httpdMarshalArguments $sock $suffix]
    75         -    ::Stderr $cmd
    76     93       # Eval the command.  Errors can be used to trigger redirects.
    77     94   
    78     95       if [catch $cmd] {
    79     96         set result(code) 505
    80     97         set result(body) "<HTML><BODY>Error: <PRE><VERBATIM>$::errorInfo</VERBATIM></PRE></BODY></HTML>"
    81     98         set result(content-type) text/html 
    82     99       }
................................................................................
    91    108         }
    92    109         404 {
    93    110           ::Doc_NotFound $sock
    94    111           return
    95    112         }
    96    113         302 {
    97    114           # Redirect.
    98         -        ::Httpd_Redirect $result $sock
          115  +        ::Httpd_Redirect $result(redirect) $sock
    99    116           return
   100    117         }
   101    118         default {
          119  +        set body [string map [list @TITLE@ $result(title)] $result(body)]
   102    120           if {$result(date)} {
   103         -          ::Httpd_ReturnCacheableData $sock $result(content-type) $result(body) $result(date) $result(code)
          121  +          ::Httpd_ReturnCacheableData $sock $result(content-type) $body $result(date) $result(code)
   104    122           } else {
   105         -          ::Httpd_ReturnData $sock $result(content-type) $result(body) $result(code)
          123  +          ::Httpd_ReturnData $sock $result(content-type) $body $result(code)
   106    124           }
   107    125           return
   108    126         }
   109    127       }
   110    128     }
   111    129     
   112    130     method httpdSessionLoad {sock prefix suffix} {
   113    131       my variable result
   114    132       array set result {
   115    133         code 200
   116    134         date  0
   117         -      header {}
   118         -      footer {}
          135  +      title {}
   119    136         body {}
          137  +      redirect {}
   120    138         content-type text/html
   121    139       }
   122    140       set result(sock) $sock
   123    141       set result(datavar) ::Httpd$sock 
   124    142   
   125    143       # Set up the environment a-la CGI.
   126    144       ::Cgi_SetEnv $sock $prefix$suffix [my varname env]
................................................................................
   219    237     }
   220    238     
   221    239     ###
   222    240     # title: Implement html content at a toplevel
   223    241     ###
   224    242     method /html {} {
   225    243       my variable result
   226         -    array set result {
   227         -      code 200
   228         -      body {
   229         -<HTML><BODY>
          244  +    set result(title) {Welcome!}
          245  +    my reset
          246  +    my puts [my pageHeader]
          247  +    my puts {
   230    248   Hello World
          249  +    }
          250  +    my puts [my pageFooter]
          251  +  }
          252  +  
          253  +
          254  +  method pageHeader {} {
          255  +    return {
          256  +<HTML>
          257  +<HEAD>
          258  +    <TITLE>@TITLE@</TITLE>
          259  +    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
          260  +</HEAD>
          261  +<BODY>
          262  +    }
          263  +  }
          264  +  
          265  +  method pageFooter {} {
          266  +    return {
          267  +<script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
          268  +<script type="text/javascript" src="/bootstrap/js/jquery.min.js"></script>
   231    269   </BODY></HTML>
   232         -}
   233         -      content-type text/html
   234    270       }
   235    271     }
          272  +
   236    273   }

Added modules/jshash/js/md5-min.js.

            1  +/*
            2  + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
            3  + * Digest Algorithm, as defined in RFC 1321.
            4  + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
            5  + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            6  + * Distributed under the BSD License
            7  + * See http://pajhome.org.uk/crypt/md5 for more info.
            8  + */
            9  +var hexcase=0;function hex_md5(a){return rstr2hex(rstr_md5(str2rstr_utf8(a)))}function hex_hmac_md5(a,b){return rstr2hex(rstr_hmac_md5(str2rstr_utf8(a),str2rstr_utf8(b)))}function md5_vm_test(){return hex_md5("abc").toLowerCase()=="900150983cd24fb0d6963f7d28e17f72"}function rstr_md5(a){return binl2rstr(binl_md5(rstr2binl(a),a.length*8))}function rstr_hmac_md5(c,f){var e=rstr2binl(c);if(e.length>16){e=binl_md5(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binl_md5(a.concat(rstr2binl(f)),512+f.length*8);return binl2rstr(binl_md5(d.concat(g),512+128))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binl(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(c%32)}return a}function binl2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(c%32))&255)}return a}function binl_md5(p,k){p[k>>5]|=128<<((k)%32);p[(((k+64)>>>9)<<4)+14]=k;var o=1732584193;var n=-271733879;var m=-1732584194;var l=271733878;for(var g=0;g<p.length;g+=16){var j=o;var h=n;var f=m;var e=l;o=md5_ff(o,n,m,l,p[g+0],7,-680876936);l=md5_ff(l,o,n,m,p[g+1],12,-389564586);m=md5_ff(m,l,o,n,p[g+2],17,606105819);n=md5_ff(n,m,l,o,p[g+3],22,-1044525330);o=md5_ff(o,n,m,l,p[g+4],7,-176418897);l=md5_ff(l,o,n,m,p[g+5],12,1200080426);m=md5_ff(m,l,o,n,p[g+6],17,-1473231341);n=md5_ff(n,m,l,o,p[g+7],22,-45705983);o=md5_ff(o,n,m,l,p[g+8],7,1770035416);l=md5_ff(l,o,n,m,p[g+9],12,-1958414417);m=md5_ff(m,l,o,n,p[g+10],17,-42063);n=md5_ff(n,m,l,o,p[g+11],22,-1990404162);o=md5_ff(o,n,m,l,p[g+12],7,1804603682);l=md5_ff(l,o,n,m,p[g+13],12,-40341101);m=md5_ff(m,l,o,n,p[g+14],17,-1502002290);n=md5_ff(n,m,l,o,p[g+15],22,1236535329);o=md5_gg(o,n,m,l,p[g+1],5,-165796510);l=md5_gg(l,o,n,m,p[g+6],9,-1069501632);m=md5_gg(m,l,o,n,p[g+11],14,643717713);n=md5_gg(n,m,l,o,p[g+0],20,-373897302);o=md5_gg(o,n,m,l,p[g+5],5,-701558691);l=md5_gg(l,o,n,m,p[g+10],9,38016083);m=md5_gg(m,l,o,n,p[g+15],14,-660478335);n=md5_gg(n,m,l,o,p[g+4],20,-405537848);o=md5_gg(o,n,m,l,p[g+9],5,568446438);l=md5_gg(l,o,n,m,p[g+14],9,-1019803690);m=md5_gg(m,l,o,n,p[g+3],14,-187363961);n=md5_gg(n,m,l,o,p[g+8],20,1163531501);o=md5_gg(o,n,m,l,p[g+13],5,-1444681467);l=md5_gg(l,o,n,m,p[g+2],9,-51403784);m=md5_gg(m,l,o,n,p[g+7],14,1735328473);n=md5_gg(n,m,l,o,p[g+12],20,-1926607734);o=md5_hh(o,n,m,l,p[g+5],4,-378558);l=md5_hh(l,o,n,m,p[g+8],11,-2022574463);m=md5_hh(m,l,o,n,p[g+11],16,1839030562);n=md5_hh(n,m,l,o,p[g+14],23,-35309556);o=md5_hh(o,n,m,l,p[g+1],4,-1530992060);l=md5_hh(l,o,n,m,p[g+4],11,1272893353);m=md5_hh(m,l,o,n,p[g+7],16,-155497632);n=md5_hh(n,m,l,o,p[g+10],23,-1094730640);o=md5_hh(o,n,m,l,p[g+13],4,681279174);l=md5_hh(l,o,n,m,p[g+0],11,-358537222);m=md5_hh(m,l,o,n,p[g+3],16,-722521979);n=md5_hh(n,m,l,o,p[g+6],23,76029189);o=md5_hh(o,n,m,l,p[g+9],4,-640364487);l=md5_hh(l,o,n,m,p[g+12],11,-421815835);m=md5_hh(m,l,o,n,p[g+15],16,530742520);n=md5_hh(n,m,l,o,p[g+2],23,-995338651);o=md5_ii(o,n,m,l,p[g+0],6,-198630844);l=md5_ii(l,o,n,m,p[g+7],10,1126891415);m=md5_ii(m,l,o,n,p[g+14],15,-1416354905);n=md5_ii(n,m,l,o,p[g+5],21,-57434055);o=md5_ii(o,n,m,l,p[g+12],6,1700485571);l=md5_ii(l,o,n,m,p[g+3],10,-1894986606);m=md5_ii(m,l,o,n,p[g+10],15,-1051523);n=md5_ii(n,m,l,o,p[g+1],21,-2054922799);o=md5_ii(o,n,m,l,p[g+8],6,1873313359);l=md5_ii(l,o,n,m,p[g+15],10,-30611744);m=md5_ii(m,l,o,n,p[g+6],15,-1560198380);n=md5_ii(n,m,l,o,p[g+13],21,1309151649);o=md5_ii(o,n,m,l,p[g+4],6,-145523070);l=md5_ii(l,o,n,m,p[g+11],10,-1120210379);m=md5_ii(m,l,o,n,p[g+2],15,718787259);n=md5_ii(n,m,l,o,p[g+9],21,-343485551);o=safe_add(o,j);n=safe_add(n,h);m=safe_add(m,f);l=safe_add(l,e)}return Array(o,n,m,l)}function md5_cmn(h,e,d,c,g,f){return safe_add(bit_rol(safe_add(safe_add(e,h),safe_add(c,f)),g),d)}function md5_ff(g,f,k,j,e,i,h){return md5_cmn((f&k)|((~f)&j),g,f,e,i,h)}function md5_gg(g,f,k,j,e,i,h){return md5_cmn((f&j)|(k&(~j)),g,f,e,i,h)}function md5_hh(g,f,k,j,e,i,h){return md5_cmn(f^k^j,g,f,e,i,h)}function md5_ii(g,f,k,j,e,i,h){return md5_cmn(k^(f|(~j)),g,f,e,i,h)}function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}function bit_rol(a,b){return(a<<b)|(a>>>(32-b))};

Added modules/jshash/js/md5.js.

            1  +/*
            2  + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
            3  + * Digest Algorithm, as defined in RFC 1321.
            4  + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
            5  + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            6  + * Distributed under the BSD License
            7  + * See http://pajhome.org.uk/crypt/md5 for more info.
            8  + */
            9  +
           10  +/*
           11  + * Configurable variables. You may need to tweak these to be compatible with
           12  + * the server-side, but the defaults work in most cases.
           13  + */
           14  +var hexcase = 0;   /* hex output format. 0 - lowercase; 1 - uppercase        */
           15  +var b64pad  = "";  /* base-64 pad character. "=" for strict RFC compliance   */
           16  +
           17  +/*
           18  + * These are the functions you'll usually want to call
           19  + * They take string arguments and return either hex or base-64 encoded strings
           20  + */
           21  +function hex_md5(s)    { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
           22  +function b64_md5(s)    { return rstr2b64(rstr_md5(str2rstr_utf8(s))); }
           23  +function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); }
           24  +function hex_hmac_md5(k, d)
           25  +  { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
           26  +function b64_hmac_md5(k, d)
           27  +  { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
           28  +function any_hmac_md5(k, d, e)
           29  +  { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
           30  +
           31  +/*
           32  + * Perform a simple self-test to see if the VM is working
           33  + */
           34  +function md5_vm_test()
           35  +{
           36  +  return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72";
           37  +}
           38  +
           39  +/*
           40  + * Calculate the MD5 of a raw string
           41  + */
           42  +function rstr_md5(s)
           43  +{
           44  +  return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
           45  +}
           46  +
           47  +/*
           48  + * Calculate the HMAC-MD5, of a key and some data (raw strings)
           49  + */
           50  +function rstr_hmac_md5(key, data)
           51  +{
           52  +  var bkey = rstr2binl(key);
           53  +  if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8);
           54  +
           55  +  var ipad = Array(16), opad = Array(16);
           56  +  for(var i = 0; i < 16; i++)
           57  +  {
           58  +    ipad[i] = bkey[i] ^ 0x36363636;
           59  +    opad[i] = bkey[i] ^ 0x5C5C5C5C;
           60  +  }
           61  +
           62  +  var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
           63  +  return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
           64  +}
           65  +
           66  +/*
           67  + * Convert a raw string to a hex string
           68  + */
           69  +function rstr2hex(input)
           70  +{
           71  +  try { hexcase } catch(e) { hexcase=0; }
           72  +  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
           73  +  var output = "";
           74  +  var x;
           75  +  for(var i = 0; i < input.length; i++)
           76  +  {
           77  +    x = input.charCodeAt(i);
           78  +    output += hex_tab.charAt((x >>> 4) & 0x0F)
           79  +           +  hex_tab.charAt( x        & 0x0F);
           80  +  }
           81  +  return output;
           82  +}
           83  +
           84  +/*
           85  + * Convert a raw string to a base-64 string
           86  + */
           87  +function rstr2b64(input)
           88  +{
           89  +  try { b64pad } catch(e) { b64pad=''; }
           90  +  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
           91  +  var output = "";
           92  +  var len = input.length;
           93  +  for(var i = 0; i < len; i += 3)
           94  +  {
           95  +    var triplet = (input.charCodeAt(i) << 16)
           96  +                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
           97  +                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
           98  +    for(var j = 0; j < 4; j++)
           99  +    {
          100  +      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
          101  +      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
          102  +    }
          103  +  }
          104  +  return output;
          105  +}
          106  +
          107  +/*
          108  + * Convert a raw string to an arbitrary string encoding
          109  + */
          110  +function rstr2any(input, encoding)
          111  +{
          112  +  var divisor = encoding.length;
          113  +  var i, j, q, x, quotient;
          114  +
          115  +  /* Convert to an array of 16-bit big-endian values, forming the dividend */
          116  +  var dividend = Array(Math.ceil(input.length / 2));
          117  +  for(i = 0; i < dividend.length; i++)
          118  +  {
          119  +    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
          120  +  }
          121  +
          122  +  /*
          123  +   * Repeatedly perform a long division. The binary array forms the dividend,
          124  +   * the length of the encoding is the divisor. Once computed, the quotient
          125  +   * forms the dividend for the next step. All remainders are stored for later
          126  +   * use.
          127  +   */
          128  +  var full_length = Math.ceil(input.length * 8 /
          129  +                                    (Math.log(encoding.length) / Math.log(2)));
          130  +  var remainders = Array(full_length);
          131  +  for(j = 0; j < full_length; j++)
          132  +  {
          133  +    quotient = Array();
          134  +    x = 0;
          135  +    for(i = 0; i < dividend.length; i++)
          136  +    {
          137  +      x = (x << 16) + dividend[i];
          138  +      q = Math.floor(x / divisor);
          139  +      x -= q * divisor;
          140  +      if(quotient.length > 0 || q > 0)
          141  +        quotient[quotient.length] = q;
          142  +    }
          143  +    remainders[j] = x;
          144  +    dividend = quotient;
          145  +  }
          146  +
          147  +  /* Convert the remainders to the output string */
          148  +  var output = "";
          149  +  for(i = remainders.length - 1; i >= 0; i--)
          150  +    output += encoding.charAt(remainders[i]);
          151  +
          152  +  return output;
          153  +}
          154  +
          155  +/*
          156  + * Encode a string as utf-8.
          157  + * For efficiency, this assumes the input is valid utf-16.
          158  + */
          159  +function str2rstr_utf8(input)
          160  +{
          161  +  var output = "";
          162  +  var i = -1;
          163  +  var x, y;
          164  +
          165  +  while(++i < input.length)
          166  +  {
          167  +    /* Decode utf-16 surrogate pairs */
          168  +    x = input.charCodeAt(i);
          169  +    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
          170  +    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
          171  +    {
          172  +      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
          173  +      i++;
          174  +    }
          175  +
          176  +    /* Encode output as utf-8 */
          177  +    if(x <= 0x7F)
          178  +      output += String.fromCharCode(x);
          179  +    else if(x <= 0x7FF)
          180  +      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
          181  +                                    0x80 | ( x         & 0x3F));
          182  +    else if(x <= 0xFFFF)
          183  +      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
          184  +                                    0x80 | ((x >>> 6 ) & 0x3F),
          185  +                                    0x80 | ( x         & 0x3F));
          186  +    else if(x <= 0x1FFFFF)
          187  +      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
          188  +                                    0x80 | ((x >>> 12) & 0x3F),
          189  +                                    0x80 | ((x >>> 6 ) & 0x3F),
          190  +                                    0x80 | ( x         & 0x3F));
          191  +  }
          192  +  return output;
          193  +}
          194  +
          195  +/*
          196  + * Encode a string as utf-16
          197  + */
          198  +function str2rstr_utf16le(input)
          199  +{
          200  +  var output = "";
          201  +  for(var i = 0; i < input.length; i++)
          202  +    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
          203  +                                  (input.charCodeAt(i) >>> 8) & 0xFF);
          204  +  return output;
          205  +}
          206  +
          207  +function str2rstr_utf16be(input)
          208  +{
          209  +  var output = "";
          210  +  for(var i = 0; i < input.length; i++)
          211  +    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
          212  +                                   input.charCodeAt(i)        & 0xFF);
          213  +  return output;
          214  +}
          215  +
          216  +/*
          217  + * Convert a raw string to an array of little-endian words
          218  + * Characters >255 have their high-byte silently ignored.
          219  + */
          220  +function rstr2binl(input)
          221  +{
          222  +  var output = Array(input.length >> 2);
          223  +  for(var i = 0; i < output.length; i++)
          224  +    output[i] = 0;
          225  +  for(var i = 0; i < input.length * 8; i += 8)
          226  +    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
          227  +  return output;
          228  +}
          229  +
          230  +/*
          231  + * Convert an array of little-endian words to a string
          232  + */
          233  +function binl2rstr(input)
          234  +{
          235  +  var output = "";
          236  +  for(var i = 0; i < input.length * 32; i += 8)
          237  +    output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
          238  +  return output;
          239  +}
          240  +
          241  +/*
          242  + * Calculate the MD5 of an array of little-endian words, and a bit length.
          243  + */
          244  +function binl_md5(x, len)
          245  +{
          246  +  /* append padding */
          247  +  x[len >> 5] |= 0x80 << ((len) % 32);
          248  +  x[(((len + 64) >>> 9) << 4) + 14] = len;
          249  +
          250  +  var a =  1732584193;
          251  +  var b = -271733879;
          252  +  var c = -1732584194;
          253  +  var d =  271733878;
          254  +
          255  +  for(var i = 0; i < x.length; i += 16)
          256  +  {
          257  +    var olda = a;
          258  +    var oldb = b;
          259  +    var oldc = c;
          260  +    var oldd = d;
          261  +
          262  +    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
          263  +    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
          264  +    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
          265  +    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
          266  +    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
          267  +    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
          268  +    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
          269  +    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
          270  +    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
          271  +    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
          272  +    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
          273  +    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
          274  +    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
          275  +    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
          276  +    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
          277  +    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
          278  +
          279  +    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
          280  +    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
          281  +    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
          282  +    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
          283  +    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
          284  +    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
          285  +    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
          286  +    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
          287  +    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
          288  +    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
          289  +    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
          290  +    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
          291  +    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
          292  +    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
          293  +    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
          294  +    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
          295  +
          296  +    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
          297  +    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
          298  +    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
          299  +    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
          300  +    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
          301  +    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
          302  +    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
          303  +    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
          304  +    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
          305  +    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
          306  +    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
          307  +    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
          308  +    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
          309  +    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
          310  +    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
          311  +    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
          312  +
          313  +    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
          314  +    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
          315  +    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
          316  +    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
          317  +    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
          318  +    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
          319  +    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
          320  +    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
          321  +    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
          322  +    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
          323  +    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
          324  +    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
          325  +    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
          326  +    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
          327  +    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
          328  +    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
          329  +
          330  +    a = safe_add(a, olda);
          331  +    b = safe_add(b, oldb);
          332  +    c = safe_add(c, oldc);
          333  +    d = safe_add(d, oldd);
          334  +  }
          335  +  return Array(a, b, c, d);
          336  +}
          337  +
          338  +/*
          339  + * These functions implement the four basic operations the algorithm uses.
          340  + */
          341  +function md5_cmn(q, a, b, x, s, t)
          342  +{
          343  +  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
          344  +}
          345  +function md5_ff(a, b, c, d, x, s, t)
          346  +{
          347  +  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
          348  +}
          349  +function md5_gg(a, b, c, d, x, s, t)
          350  +{
          351  +  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
          352  +}
          353  +function md5_hh(a, b, c, d, x, s, t)
          354  +{
          355  +  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
          356  +}
          357  +function md5_ii(a, b, c, d, x, s, t)
          358  +{
          359  +  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
          360  +}
          361  +
          362  +/*
          363  + * Add integers, wrapping at 2^32. This uses 16-bit operations internally
          364  + * to work around bugs in some JS interpreters.
          365  + */
          366  +function safe_add(x, y)
          367  +{
          368  +  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
          369  +  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
          370  +  return (msw << 16) | (lsw & 0xFFFF);
          371  +}
          372  +
          373  +/*
          374  + * Bitwise rotate a 32-bit number to the left.
          375  + */
          376  +function bit_rol(num, cnt)
          377  +{
          378  +  return (num << cnt) | (num >>> (32 - cnt));
          379  +}

Added modules/jshash/js/ripemd160-min.js.

            1  +/*
            2  + * A JavaScript implementation of the RIPEMD-160 Algorithm
            3  + * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
            4  + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            5  + * Distributed under the BSD License
            6  + * See http://pajhome.org.uk/crypt/md5 for details.
            7  + * Also http://www.esat.kuleuven.ac.be/~cosicart/pdf/AB-9601/
            8  + */
            9  +var hexcase=0;function hex_rmd160(a){return rstr2hex(rstr_rmd160(str2rstr_utf8(a)))}function hex_hmac_rmd160(a,b){return rstr2hex(rstr_hmac_rmd160(str2rstr_utf8(a),str2rstr_utf8(b)))}function rmd160_vm_test(){return hex_rmd160("abc").toLowerCase()=="8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"}function rstr_rmd160(a){return binl2rstr(binl_rmd160(rstr2binl(a),a.length*8))}function rstr_hmac_rmd160(c,f){var e=rstr2binl(c);if(e.length>16){e=binl_rmd160(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binl_rmd160(a.concat(rstr2binl(f)),512+f.length*8);return binl2rstr(binl_rmd160(d.concat(g),512+160))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binl(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(c%32)}return a}function binl2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(c%32))&255)}return a}function binl_rmd160(q,v){q[v>>5]|=128<<(v%32);q[(((v+64)>>>9)<<4)+14]=v;var l=1732584193;var k=4023233417;var h=2562383102;var g=271733878;var f=3285377520;for(var u=0;u<q.length;u+=16){var e;var c=l,o=k,t=h,d=g,p=f;var a=l,m=k,s=h,b=g,n=f;for(var r=0;r<=79;++r){e=safe_add(c,rmd160_f(r,o,t,d));e=safe_add(e,q[u+rmd160_r1[r]]);e=safe_add(e,rmd160_K1(r));e=safe_add(bit_rol(e,rmd160_s1[r]),p);c=p;p=d;d=bit_rol(t,10);t=o;o=e;e=safe_add(a,rmd160_f(79-r,m,s,b));e=safe_add(e,q[u+rmd160_r2[r]]);e=safe_add(e,rmd160_K2(r));e=safe_add(bit_rol(e,rmd160_s2[r]),n);a=n;n=b;b=bit_rol(s,10);s=m;m=e}e=safe_add(k,safe_add(t,b));k=safe_add(h,safe_add(d,n));h=safe_add(g,safe_add(p,a));g=safe_add(f,safe_add(c,m));f=safe_add(l,safe_add(o,s));l=e}return[l,k,h,g,f]}function rmd160_f(b,a,d,c){return(0<=b&&b<=15)?(a^d^c):(16<=b&&b<=31)?(a&d)|(~a&c):(32<=b&&b<=47)?(a|~d)^c:(48<=b&&b<=63)?(a&c)|(d&~c):(64<=b&&b<=79)?a^(d|~c):"rmd160_f: j out of range"}function rmd160_K1(a){return(0<=a&&a<=15)?0:(16<=a&&a<=31)?1518500249:(32<=a&&a<=47)?1859775393:(48<=a&&a<=63)?2400959708:(64<=a&&a<=79)?2840853838:"rmd160_K1: j out of range"}function rmd160_K2(a){return(0<=a&&a<=15)?1352829926:(16<=a&&a<=31)?1548603684:(32<=a&&a<=47)?1836072691:(48<=a&&a<=63)?2053994217:(64<=a&&a<=79)?0:"rmd160_K2: j out of range"}var rmd160_r1=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13];var rmd160_r2=[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11];var rmd160_s1=[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6];var rmd160_s2=[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11];function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}function bit_rol(a,b){return(a<<b)|(a>>>(32-b))};

Added modules/jshash/js/ripemd160.js.

            1  +/*
            2  + * A JavaScript implementation of the RIPEMD-160 Algorithm
            3  + * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
            4  + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            5  + * Distributed under the BSD License
            6  + * See http://pajhome.org.uk/crypt/md5 for details.
            7  + * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
            8  + */
            9  +
           10  +/*
           11  + * Configurable variables. You may need to tweak these to be compatible with
           12  + * the server-side, but the defaults work in most cases.
           13  + */
           14  +var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
           15  +var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
           16  +
           17  +/*
           18  + * These are the functions you'll usually want to call
           19  + * They take string arguments and return either hex or base-64 encoded strings
           20  + */
           21  +function hex_rmd160(s)    { return rstr2hex(rstr_rmd160(str2rstr_utf8(s))); }
           22  +function b64_rmd160(s)    { return rstr2b64(rstr_rmd160(str2rstr_utf8(s))); }
           23  +function any_rmd160(s, e) { return rstr2any(rstr_rmd160(str2rstr_utf8(s)), e); }
           24  +function hex_hmac_rmd160(k, d)
           25  +  { return rstr2hex(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d))); }
           26  +function b64_hmac_rmd160(k, d)
           27  +  { return rstr2b64(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d))); }
           28  +function any_hmac_rmd160(k, d, e)
           29  +  { return rstr2any(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
           30  +
           31  +/*
           32  + * Perform a simple self-test to see if the VM is working
           33  + */
           34  +function rmd160_vm_test()
           35  +{
           36  +  return hex_rmd160("abc").toLowerCase() == "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc";
           37  +}
           38  +
           39  +/*
           40  + * Calculate the rmd160 of a raw string
           41  + */
           42  +function rstr_rmd160(s)
           43  +{
           44  +  return binl2rstr(binl_rmd160(rstr2binl(s), s.length * 8));
           45  +}
           46  +
           47  +/*
           48  + * Calculate the HMAC-rmd160 of a key and some data (raw strings)
           49  + */
           50  +function rstr_hmac_rmd160(key, data)
           51  +{
           52  +  var bkey = rstr2binl(key);
           53  +  if(bkey.length > 16) bkey = binl_rmd160(bkey, key.length * 8);
           54  +
           55  +  var ipad = Array(16), opad = Array(16);
           56  +  for(var i = 0; i < 16; i++)
           57  +  {
           58  +    ipad[i] = bkey[i] ^ 0x36363636;
           59  +    opad[i] = bkey[i] ^ 0x5C5C5C5C;
           60  +  }
           61  +
           62  +  var hash = binl_rmd160(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
           63  +  return binl2rstr(binl_rmd160(opad.concat(hash), 512 + 160));
           64  +}
           65  +
           66  +/*
           67  + * Convert a raw string to a hex string
           68  + */
           69  +function rstr2hex(input)
           70  +{
           71  +  try { hexcase } catch(e) { hexcase=0; }
           72  +  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
           73  +  var output = "";
           74  +  var x;
           75  +  for(var i = 0; i < input.length; i++)
           76  +  {
           77  +    x = input.charCodeAt(i);
           78  +    output += hex_tab.charAt((x >>> 4) & 0x0F)
           79  +           +  hex_tab.charAt( x        & 0x0F);
           80  +  }
           81  +  return output;
           82  +}
           83  +
           84  +/*
           85  + * Convert a raw string to a base-64 string
           86  + */
           87  +function rstr2b64(input)
           88  +{
           89  +  try { b64pad } catch(e) { b64pad=''; }
           90  +  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
           91  +  var output = "";
           92  +  var len = input.length;
           93  +  for(var i = 0; i < len; i += 3)
           94  +  {
           95  +    var triplet = (input.charCodeAt(i) << 16)
           96  +                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
           97  +                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
           98  +    for(var j = 0; j < 4; j++)
           99  +    {
          100  +      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
          101  +      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
          102  +    }
          103  +  }
          104  +  return output;
          105  +}
          106  +
          107  +/*
          108  + * Convert a raw string to an arbitrary string encoding
          109  + */
          110  +function rstr2any(input, encoding)
          111  +{
          112  +  var divisor = encoding.length;
          113  +  var remainders = Array();
          114  +  var i, q, x, quotient;
          115  +
          116  +  /* Convert to an array of 16-bit big-endian values, forming the dividend */
          117  +  var dividend = Array(Math.ceil(input.length / 2));
          118  +  for(i = 0; i < dividend.length; i++)
          119  +  {
          120  +    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
          121  +  }
          122  +
          123  +  /*
          124  +   * Repeatedly perform a long division. The binary array forms the dividend,
          125  +   * the length of the encoding is the divisor. Once computed, the quotient
          126  +   * forms the dividend for the next step. We stop when the dividend is zero.
          127  +   * All remainders are stored for later use.
          128  +   */
          129  +  while(dividend.length > 0)
          130  +  {
          131  +    quotient = Array();
          132  +    x = 0;
          133  +    for(i = 0; i < dividend.length; i++)
          134  +    {
          135  +      x = (x << 16) + dividend[i];
          136  +      q = Math.floor(x / divisor);
          137  +      x -= q * divisor;
          138  +      if(quotient.length > 0 || q > 0)
          139  +        quotient[quotient.length] = q;
          140  +    }
          141  +    remainders[remainders.length] = x;
          142  +    dividend = quotient;
          143  +  }
          144  +
          145  +  /* Convert the remainders to the output string */
          146  +  var output = "";
          147  +  for(i = remainders.length - 1; i >= 0; i--)
          148  +    output += encoding.charAt(remainders[i]);
          149  +
          150  +  /* Append leading zero equivalents */
          151  +  var full_length = Math.ceil(input.length * 8 /
          152  +                                    (Math.log(encoding.length) / Math.log(2)))
          153  +  for(i = output.length; i < full_length; i++)
          154  +    output = encoding[0] + output;
          155  +
          156  +  return output;
          157  +}
          158  +
          159  +/*
          160  + * Encode a string as utf-8.
          161  + * For efficiency, this assumes the input is valid utf-16.
          162  + */
          163  +function str2rstr_utf8(input)
          164  +{
          165  +  var output = "";
          166  +  var i = -1;
          167  +  var x, y;
          168  +
          169  +  while(++i < input.length)
          170  +  {
          171  +    /* Decode utf-16 surrogate pairs */
          172  +    x = input.charCodeAt(i);
          173  +    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
          174  +    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
          175  +    {
          176  +      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
          177  +      i++;
          178  +    }
          179  +
          180  +    /* Encode output as utf-8 */
          181  +    if(x <= 0x7F)
          182  +      output += String.fromCharCode(x);
          183  +    else if(x <= 0x7FF)
          184  +      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
          185  +                                    0x80 | ( x         & 0x3F));
          186  +    else if(x <= 0xFFFF)
          187  +      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
          188  +                                    0x80 | ((x >>> 6 ) & 0x3F),
          189  +                                    0x80 | ( x         & 0x3F));
          190  +    else if(x <= 0x1FFFFF)
          191  +      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
          192  +                                    0x80 | ((x >>> 12) & 0x3F),
          193  +                                    0x80 | ((x >>> 6 ) & 0x3F),
          194  +                                    0x80 | ( x         & 0x3F));
          195  +  }
          196  +  return output;
          197  +}
          198  +
          199  +/*
          200  + * Encode a string as utf-16
          201  + */
          202  +function str2rstr_utf16le(input)
          203  +{
          204  +  var output = "";
          205  +  for(var i = 0; i < input.length; i++)
          206  +    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
          207  +                                  (input.charCodeAt(i) >>> 8) & 0xFF);
          208  +  return output;
          209  +}
          210  +
          211  +function str2rstr_utf16be(input)
          212  +{
          213  +  var output = "";
          214  +  for(var i = 0; i < input.length; i++)
          215  +    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
          216  +                                   input.charCodeAt(i)        & 0xFF);
          217  +  return output;
          218  +}
          219  +
          220  +/*
          221  + * Convert a raw string to an array of little-endian words
          222  + * Characters >255 have their high-byte silently ignored.
          223  + */
          224  +function rstr2binl(input)
          225  +{
          226  +  var output = Array(input.length >> 2);
          227  +  for(var i = 0; i < output.length; i++)
          228  +    output[i] = 0;
          229  +  for(var i = 0; i < input.length * 8; i += 8)
          230  +    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
          231  +  return output;
          232  +}
          233  +
          234  +/*
          235  + * Convert an array of little-endian words to a string
          236  + */
          237  +function binl2rstr(input)
          238  +{
          239  +  var output = "";
          240  +  for(var i = 0; i < input.length * 32; i += 8)
          241  +    output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
          242  +  return output;
          243  +}
          244  +
          245  +/*
          246  + * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
          247  + */
          248  +function binl_rmd160(x, len)
          249  +{
          250  +  /* append padding */
          251  +  x[len >> 5] |= 0x80 << (len % 32);
          252  +  x[(((len + 64) >>> 9) << 4) + 14] = len;
          253  +
          254  +  var h0 = 0x67452301;
          255  +  var h1 = 0xefcdab89;
          256  +  var h2 = 0x98badcfe;
          257  +  var h3 = 0x10325476;
          258  +  var h4 = 0xc3d2e1f0;
          259  +
          260  +  for (var i = 0; i < x.length; i += 16) {
          261  +    var T;
          262  +    var A1 = h0, B1 = h1, C1 = h2, D1 = h3, E1 = h4;
          263  +    var A2 = h0, B2 = h1, C2 = h2, D2 = h3, E2 = h4;
          264  +    for (var j = 0; j <= 79; ++j) {
          265  +      T = safe_add(A1, rmd160_f(j, B1, C1, D1));
          266  +      T = safe_add(T, x[i + rmd160_r1[j]]);
          267  +      T = safe_add(T, rmd160_K1(j));
          268  +      T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
          269  +      A1 = E1; E1 = D1; D1 = bit_rol(C1, 10); C1 = B1; B1 = T;
          270  +      T = safe_add(A2, rmd160_f(79-j, B2, C2, D2));
          271  +      T = safe_add(T, x[i + rmd160_r2[j]]);
          272  +      T = safe_add(T, rmd160_K2(j));
          273  +      T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
          274  +      A2 = E2; E2 = D2; D2 = bit_rol(C2, 10); C2 = B2; B2 = T;
          275  +    }
          276  +    T = safe_add(h1, safe_add(C1, D2));
          277  +    h1 = safe_add(h2, safe_add(D1, E2));
          278  +    h2 = safe_add(h3, safe_add(E1, A2));
          279  +    h3 = safe_add(h4, safe_add(A1, B2));
          280  +    h4 = safe_add(h0, safe_add(B1, C2));
          281  +    h0 = T;
          282  +  }
          283  +  return [h0, h1, h2, h3, h4];
          284  +}
          285  +
          286  +function rmd160_f(j, x, y, z)
          287  +{
          288  +  return ( 0 <= j && j <= 15) ? (x ^ y ^ z) :
          289  +         (16 <= j && j <= 31) ? (x & y) | (~x & z) :
          290  +         (32 <= j && j <= 47) ? (x | ~y) ^ z :
          291  +         (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
          292  +         (64 <= j && j <= 79) ? x ^ (y | ~z) :
          293  +         "rmd160_f: j out of range";
          294  +}
          295  +function rmd160_K1(j)
          296  +{
          297  +  return ( 0 <= j && j <= 15) ? 0x00000000 :
          298  +         (16 <= j && j <= 31) ? 0x5a827999 :
          299  +         (32 <= j && j <= 47) ? 0x6ed9eba1 :
          300  +         (48 <= j && j <= 63) ? 0x8f1bbcdc :
          301  +         (64 <= j && j <= 79) ? 0xa953fd4e :
          302  +         "rmd160_K1: j out of range";
          303  +}
          304  +function rmd160_K2(j)
          305  +{
          306  +  return ( 0 <= j && j <= 15) ? 0x50a28be6 :
          307  +         (16 <= j && j <= 31) ? 0x5c4dd124 :
          308  +         (32 <= j && j <= 47) ? 0x6d703ef3 :
          309  +         (48 <= j && j <= 63) ? 0x7a6d76e9 :
          310  +         (64 <= j && j <= 79) ? 0x00000000 :
          311  +         "rmd160_K2: j out of range";
          312  +}
          313  +var rmd160_r1 = [
          314  +   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
          315  +   7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,
          316  +   3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,
          317  +   1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,
          318  +   4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13
          319  +];
          320  +var rmd160_r2 = [
          321  +   5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,
          322  +   6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,
          323  +  15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,
          324  +   8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,
          325  +  12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11
          326  +];
          327  +var rmd160_s1 = [
          328  +  11, 14, 15, 12,  5,  8,  7,  9, 11, 13, 14, 15,  6,  7,  9,  8,
          329  +   7,  6,  8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,
          330  +  11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,
          331  +  11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,
          332  +   9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6
          333  +];
          334  +var rmd160_s2 = [
          335  +   8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,
          336  +   9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,
          337  +   9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,
          338  +  15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,
          339  +   8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11
          340  +];
          341  +
          342  +/*
          343  + * Add integers, wrapping at 2^32. This uses 16-bit operations internally
          344  + * to work around bugs in some JS interpreters.
          345  + */
          346  +function safe_add(x, y)
          347  +{
          348  +  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
          349  +  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
          350  +  return (msw << 16) | (lsw & 0xFFFF);
          351  +}
          352  +
          353  +/*
          354  + * Bitwise rotate a 32-bit number to the left.
          355  + */
          356  +function bit_rol(num, cnt)
          357  +{
          358  +  return (num << cnt) | (num >>> (32 - cnt));
          359  +}

Added modules/jshash/js/sha1-min.js.

            1  +/*
            2  + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
            3  + * in FIPS 180-1
            4  + * Version 2.2 Copyright Paul Johnston 2000 - 2009.
            5  + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            6  + * Distributed under the BSD License
            7  + * See http://pajhome.org.uk/crypt/md5 for details.
            8  + */
            9  +var hexcase=0;var b64pad="";function hex_sha1(a){return rstr2hex(rstr_sha1(str2rstr_utf8(a)))}function hex_hmac_sha1(a,b){return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(a),str2rstr_utf8(b)))}function sha1_vm_test(){return hex_sha1("abc").toLowerCase()=="a9993e364706816aba3e25717850c26c9cd0d89d"}function rstr_sha1(a){return binb2rstr(binb_sha1(rstr2binb(a),a.length*8))}function rstr_hmac_sha1(c,f){var e=rstr2binb(c);if(e.length>16){e=binb_sha1(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binb_sha1(a.concat(rstr2binb(f)),512+f.length*8);return binb2rstr(binb_sha1(d.concat(g),512+160))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binb(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(24-c%32)}return a}function binb2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(24-c%32))&255)}return a}function binb_sha1(v,o){v[o>>5]|=128<<(24-o%32);v[((o+64>>9)<<4)+15]=o;var y=Array(80);var u=1732584193;var s=-271733879;var r=-1732584194;var q=271733878;var p=-1009589776;for(var l=0;l<v.length;l+=16){var n=u;var m=s;var k=r;var h=q;var f=p;for(var g=0;g<80;g++){if(g<16){y[g]=v[l+g]}else{y[g]=bit_rol(y[g-3]^y[g-8]^y[g-14]^y[g-16],1)}var z=safe_add(safe_add(bit_rol(u,5),sha1_ft(g,s,r,q)),safe_add(safe_add(p,y[g]),sha1_kt(g)));p=q;q=r;r=bit_rol(s,30);s=u;u=z}u=safe_add(u,n);s=safe_add(s,m);r=safe_add(r,k);q=safe_add(q,h);p=safe_add(p,f)}return Array(u,s,r,q,p)}function sha1_ft(e,a,g,f){if(e<20){return(a&g)|((~a)&f)}if(e<40){return a^g^f}if(e<60){return(a&g)|(a&f)|(g&f)}return a^g^f}function sha1_kt(a){return(a<20)?1518500249:(a<40)?1859775393:(a<60)?-1894007588:-899497514}function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}function bit_rol(a,b){return(a<<b)|(a>>>(32-b))};

Added modules/jshash/js/sha1.js.

            1  +/*
            2  + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
            3  + * in FIPS 180-1
            4  + * Version 2.2 Copyright Paul Johnston 2000 - 2009.
            5  + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            6  + * Distributed under the BSD License
            7  + * See http://pajhome.org.uk/crypt/md5 for details.
            8  + */
            9  +
           10  +/*
           11  + * Configurable variables. You may need to tweak these to be compatible with
           12  + * the server-side, but the defaults work in most cases.
           13  + */
           14  +var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
           15  +var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
           16  +
           17  +/*
           18  + * These are the functions you'll usually want to call
           19  + * They take string arguments and return either hex or base-64 encoded strings
           20  + */
           21  +function hex_sha1(s)    { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
           22  +function b64_sha1(s)    { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
           23  +function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
           24  +function hex_hmac_sha1(k, d)
           25  +  { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
           26  +function b64_hmac_sha1(k, d)
           27  +  { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
           28  +function any_hmac_sha1(k, d, e)
           29  +  { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
           30  +
           31  +/*
           32  + * Perform a simple self-test to see if the VM is working
           33  + */
           34  +function sha1_vm_test()
           35  +{
           36  +  return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
           37  +}
           38  +
           39  +/*
           40  + * Calculate the SHA1 of a raw string
           41  + */
           42  +function rstr_sha1(s)
           43  +{
           44  +  return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
           45  +}
           46  +
           47  +/*
           48  + * Calculate the HMAC-SHA1 of a key and some data (raw strings)
           49  + */
           50  +function rstr_hmac_sha1(key, data)
           51  +{
           52  +  var bkey = rstr2binb(key);
           53  +  if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
           54  +
           55  +  var ipad = Array(16), opad = Array(16);
           56  +  for(var i = 0; i < 16; i++)
           57  +  {
           58  +    ipad[i] = bkey[i] ^ 0x36363636;
           59  +    opad[i] = bkey[i] ^ 0x5C5C5C5C;
           60  +  }
           61  +
           62  +  var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
           63  +  return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
           64  +}
           65  +
           66  +/*
           67  + * Convert a raw string to a hex string
           68  + */
           69  +function rstr2hex(input)
           70  +{
           71  +  try { hexcase } catch(e) { hexcase=0; }
           72  +  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
           73  +  var output = "";
           74  +  var x;
           75  +  for(var i = 0; i < input.length; i++)
           76  +  {
           77  +    x = input.charCodeAt(i);
           78  +    output += hex_tab.charAt((x >>> 4) & 0x0F)
           79  +           +  hex_tab.charAt( x        & 0x0F);
           80  +  }
           81  +  return output;
           82  +}
           83  +
           84  +/*
           85  + * Convert a raw string to a base-64 string
           86  + */
           87  +function rstr2b64(input)
           88  +{
           89  +  try { b64pad } catch(e) { b64pad=''; }
           90  +  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
           91  +  var output = "";
           92  +  var len = input.length;
           93  +  for(var i = 0; i < len; i += 3)
           94  +  {
           95  +    var triplet = (input.charCodeAt(i) << 16)
           96  +                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
           97  +                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
           98  +    for(var j = 0; j < 4; j++)
           99  +    {
          100  +      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
          101  +      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
          102  +    }
          103  +  }
          104  +  return output;
          105  +}
          106  +
          107  +/*
          108  + * Convert a raw string to an arbitrary string encoding
          109  + */
          110  +function rstr2any(input, encoding)
          111  +{
          112  +  var divisor = encoding.length;
          113  +  var remainders = Array();
          114  +  var i, q, x, quotient;
          115  +
          116  +  /* Convert to an array of 16-bit big-endian values, forming the dividend */
          117  +  var dividend = Array(Math.ceil(input.length / 2));
          118  +  for(i = 0; i < dividend.length; i++)
          119  +  {
          120  +    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
          121  +  }
          122  +
          123  +  /*
          124  +   * Repeatedly perform a long division. The binary array forms the dividend,
          125  +   * the length of the encoding is the divisor. Once computed, the quotient
          126  +   * forms the dividend for the next step. We stop when the dividend is zero.
          127  +   * All remainders are stored for later use.
          128  +   */
          129  +  while(dividend.length > 0)
          130  +  {
          131  +    quotient = Array();
          132  +    x = 0;
          133  +    for(i = 0; i < dividend.length; i++)
          134  +    {
          135  +      x = (x << 16) + dividend[i];
          136  +      q = Math.floor(x / divisor);
          137  +      x -= q * divisor;
          138  +      if(quotient.length > 0 || q > 0)
          139  +        quotient[quotient.length] = q;
          140  +    }
          141  +    remainders[remainders.length] = x;
          142  +    dividend = quotient;
          143  +  }
          144  +
          145  +  /* Convert the remainders to the output string */
          146  +  var output = "";
          147  +  for(i = remainders.length - 1; i >= 0; i--)
          148  +    output += encoding.charAt(remainders[i]);
          149  +
          150  +  /* Append leading zero equivalents */
          151  +  var full_length = Math.ceil(input.length * 8 /
          152  +                                    (Math.log(encoding.length) / Math.log(2)))
          153  +  for(i = output.length; i < full_length; i++)
          154  +    output = encoding[0] + output;
          155  +
          156  +  return output;
          157  +}
          158  +
          159  +/*
          160  + * Encode a string as utf-8.
          161  + * For efficiency, this assumes the input is valid utf-16.
          162  + */
          163  +function str2rstr_utf8(input)
          164  +{
          165  +  var output = "";
          166  +  var i = -1;
          167  +  var x, y;
          168  +
          169  +  while(++i < input.length)
          170  +  {
          171  +    /* Decode utf-16 surrogate pairs */
          172  +    x = input.charCodeAt(i);
          173  +    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
          174  +    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
          175  +    {
          176  +      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
          177  +      i++;
          178  +    }
          179  +
          180  +    /* Encode output as utf-8 */
          181  +    if(x <= 0x7F)
          182  +      output += String.fromCharCode(x);
          183  +    else if(x <= 0x7FF)
          184  +      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
          185  +                                    0x80 | ( x         & 0x3F));
          186  +    else if(x <= 0xFFFF)
          187  +      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
          188  +                                    0x80 | ((x >>> 6 ) & 0x3F),
          189  +                                    0x80 | ( x         & 0x3F));
          190  +    else if(x <= 0x1FFFFF)
          191  +      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
          192  +                                    0x80 | ((x >>> 12) & 0x3F),
          193  +                                    0x80 | ((x >>> 6 ) & 0x3F),
          194  +                                    0x80 | ( x         & 0x3F));
          195  +  }
          196  +  return output;
          197  +}
          198  +
          199  +/*
          200  + * Encode a string as utf-16
          201  + */
          202  +function str2rstr_utf16le(input)
          203  +{
          204  +  var output = "";
          205  +  for(var i = 0; i < input.length; i++)
          206  +    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
          207  +                                  (input.charCodeAt(i) >>> 8) & 0xFF);
          208  +  return output;
          209  +}
          210  +
          211  +function str2rstr_utf16be(input)
          212  +{
          213  +  var output = "";
          214  +  for(var i = 0; i < input.length; i++)
          215  +    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
          216  +                                   input.charCodeAt(i)        & 0xFF);
          217  +  return output;
          218  +}
          219  +
          220  +/*
          221  + * Convert a raw string to an array of big-endian words
          222  + * Characters >255 have their high-byte silently ignored.
          223  + */
          224  +function rstr2binb(input)
          225  +{
          226  +  var output = Array(input.length >> 2);
          227  +  for(var i = 0; i < output.length; i++)
          228  +    output[i] = 0;
          229  +  for(var i = 0; i < input.length * 8; i += 8)
          230  +    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
          231  +  return output;
          232  +}
          233  +
          234  +/*
          235  + * Convert an array of big-endian words to a string
          236  + */
          237  +function binb2rstr(input)
          238  +{
          239  +  var output = "";
          240  +  for(var i = 0; i < input.length * 32; i += 8)
          241  +    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
          242  +  return output;
          243  +}
          244  +
          245  +/*
          246  + * Calculate the SHA-1 of an array of big-endian words, and a bit length
          247  + */
          248  +function binb_sha1(x, len)
          249  +{
          250  +  /* append padding */
          251  +  x[len >> 5] |= 0x80 << (24 - len % 32);
          252  +  x[((len + 64 >> 9) << 4) + 15] = len;
          253  +
          254  +  var w = Array(80);
          255  +  var a =  1732584193;
          256  +  var b = -271733879;
          257  +  var c = -1732584194;
          258  +  var d =  271733878;
          259  +  var e = -1009589776;
          260  +
          261  +  for(var i = 0; i < x.length; i += 16)
          262  +  {
          263  +    var olda = a;
          264  +    var oldb = b;
          265  +    var oldc = c;
          266  +    var oldd = d;
          267  +    var olde = e;
          268  +
          269  +    for(var j = 0; j < 80; j++)
          270  +    {
          271  +      if(j < 16) w[j] = x[i + j];
          272  +      else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
          273  +      var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
          274  +                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
          275  +      e = d;
          276  +      d = c;
          277  +      c = bit_rol(b, 30);
          278  +      b = a;
          279  +      a = t;
          280  +    }
          281  +
          282  +    a = safe_add(a, olda);
          283  +    b = safe_add(b, oldb);
          284  +    c = safe_add(c, oldc);
          285  +    d = safe_add(d, oldd);
          286  +    e = safe_add(e, olde);
          287  +  }
          288  +  return Array(a, b, c, d, e);
          289  +
          290  +}
          291  +
          292  +/*
          293  + * Perform the appropriate triplet combination function for the current
          294  + * iteration
          295  + */
          296  +function sha1_ft(t, b, c, d)
          297  +{
          298  +  if(t < 20) return (b & c) | ((~b) & d);
          299  +  if(t < 40) return b ^ c ^ d;
          300  +  if(t < 60) return (b & c) | (b & d) | (c & d);
          301  +  return b ^ c ^ d;
          302  +}
          303  +
          304  +/*
          305  + * Determine the appropriate additive constant for the current iteration
          306  + */
          307  +function sha1_kt(t)
          308  +{
          309  +  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
          310  +         (t < 60) ? -1894007588 : -899497514;
          311  +}
          312  +
          313  +/*
          314  + * Add integers, wrapping at 2^32. This uses 16-bit operations internally
          315  + * to work around bugs in some JS interpreters.
          316  + */
          317  +function safe_add(x, y)
          318  +{
          319  +  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
          320  +  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
          321  +  return (msw << 16) | (lsw & 0xFFFF);
          322  +}
          323  +
          324  +/*
          325  + * Bitwise rotate a 32-bit number to the left.
          326  + */
          327  +function bit_rol(num, cnt)
          328  +{
          329  +  return (num << cnt) | (num >>> (32 - cnt));
          330  +}

Added modules/jshash/js/sha256-min.js.

            1  +/*
            2  + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
            3  + * in FIPS 180-2
            4  + * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
            5  + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            6  + * Distributed under the BSD License
            7  + * See http://pajhome.org.uk/crypt/md5 for details.
            8  + * Also http://anmar.eu.org/projects/jssha2/
            9  + */
           10  +var hexcase=0;function hex_sha256(a){return rstr2hex(rstr_sha256(str2rstr_utf8(a)))}function hex_hmac_sha256(a,b){return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}function sha256_vm_test(){return hex_sha256("abc").toLowerCase()=="ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"}function rstr_sha256(a){return binb2rstr(binb_sha256(rstr2binb(a),a.length*8))}function rstr_hmac_sha256(c,f){var e=rstr2binb(c);if(e.length>16){e=binb_sha256(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binb_sha256(a.concat(rstr2binb(f)),512+f.length*8);return binb2rstr(binb_sha256(d.concat(g),512+256))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binb(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(24-c%32)}return a}function binb2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(24-c%32))&255)}return a}function sha256_S(b,a){return(b>>>a)|(b<<(32-a))}function sha256_R(b,a){return(b>>>a)}function sha256_Ch(a,c,b){return((a&c)^((~a)&b))}function sha256_Maj(a,c,b){return((a&c)^(a&b)^(c&b))}function sha256_Sigma0256(a){return(sha256_S(a,2)^sha256_S(a,13)^sha256_S(a,22))}function sha256_Sigma1256(a){return(sha256_S(a,6)^sha256_S(a,11)^sha256_S(a,25))}function sha256_Gamma0256(a){return(sha256_S(a,7)^sha256_S(a,18)^sha256_R(a,3))}function sha256_Gamma1256(a){return(sha256_S(a,17)^sha256_S(a,19)^sha256_R(a,10))}function sha256_Sigma0512(a){return(sha256_S(a,28)^sha256_S(a,34)^sha256_S(a,39))}function sha256_Sigma1512(a){return(sha256_S(a,14)^sha256_S(a,18)^sha256_S(a,41))}function sha256_Gamma0512(a){return(sha256_S(a,1)^sha256_S(a,8)^sha256_R(a,7))}function sha256_Gamma1512(a){return(sha256_S(a,19)^sha256_S(a,61)^sha256_R(a,6))}var sha256_K=new Array(1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,-778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998);function binb_sha256(n,o){var p=new Array(1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225);var k=new Array(64);var B,A,z,y,w,u,t,s;var r,q,x,v;n[o>>5]|=128<<(24-o%32);n[((o+64>>9)<<4)+15]=o;for(r=0;r<n.length;r+=16){B=p[0];A=p[1];z=p[2];y=p[3];w=p[4];u=p[5];t=p[6];s=p[7];for(q=0;q<64;q++){if(q<16){k[q]=n[q+r]}else{k[q]=safe_add(safe_add(safe_add(sha256_Gamma1256(k[q-2]),k[q-7]),sha256_Gamma0256(k[q-15])),k[q-16])}x=safe_add(safe_add(safe_add(safe_add(s,sha256_Sigma1256(w)),sha256_Ch(w,u,t)),sha256_K[q]),k[q]);v=safe_add(sha256_Sigma0256(B),sha256_Maj(B,A,z));s=t;t=u;u=w;w=safe_add(y,x);y=z;z=A;A=B;B=safe_add(x,v)}p[0]=safe_add(B,p[0]);p[1]=safe_add(A,p[1]);p[2]=safe_add(z,p[2]);p[3]=safe_add(y,p[3]);p[4]=safe_add(w,p[4]);p[5]=safe_add(u,p[5]);p[6]=safe_add(t,p[6]);p[7]=safe_add(s,p[7])}return p}function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)};

Added modules/jshash/js/sha256.js.

            1  +/*
            2  + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
            3  + * in FIPS 180-2
            4  + * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
            5  + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            6  + * Distributed under the BSD License
            7  + * See http://pajhome.org.uk/crypt/md5 for details.
            8  + * Also http://anmar.eu.org/projects/jssha2/
            9  + */
           10  +
           11  +/*
           12  + * Configurable variables. You may need to tweak these to be compatible with
           13  + * the server-side, but the defaults work in most cases.
           14  + */
           15  +var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
           16  +var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
           17  +
           18  +/*
           19  + * These are the functions you'll usually want to call
           20  + * They take string arguments and return either hex or base-64 encoded strings
           21  + */
           22  +function hex_sha256(s)    { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); }
           23  +function b64_sha256(s)    { return rstr2b64(rstr_sha256(str2rstr_utf8(s))); }
           24  +function any_sha256(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); }
           25  +function hex_hmac_sha256(k, d)
           26  +  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
           27  +function b64_hmac_sha256(k, d)
           28  +  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
           29  +function any_hmac_sha256(k, d, e)
           30  +  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
           31  +
           32  +/*
           33  + * Perform a simple self-test to see if the VM is working
           34  + */
           35  +function sha256_vm_test()
           36  +{
           37  +  return hex_sha256("abc").toLowerCase() ==
           38  +            "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
           39  +}
           40  +
           41  +/*
           42  + * Calculate the sha256 of a raw string
           43  + */
           44  +function rstr_sha256(s)
           45  +{
           46  +  return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
           47  +}
           48  +
           49  +/*
           50  + * Calculate the HMAC-sha256 of a key and some data (raw strings)
           51  + */
           52  +function rstr_hmac_sha256(key, data)
           53  +{
           54  +  var bkey = rstr2binb(key);
           55  +  if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8);
           56  +
           57  +  var ipad = Array(16), opad = Array(16);
           58  +  for(var i = 0; i < 16; i++)
           59  +  {
           60  +    ipad[i] = bkey[i] ^ 0x36363636;
           61  +    opad[i] = bkey[i] ^ 0x5C5C5C5C;
           62  +  }
           63  +
           64  +  var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
           65  +  return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256));
           66  +}
           67  +
           68  +/*
           69  + * Convert a raw string to a hex string
           70  + */
           71  +function rstr2hex(input)
           72  +{
           73  +  try { hexcase } catch(e) { hexcase=0; }
           74  +  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
           75  +  var output = "";
           76  +  var x;
           77  +  for(var i = 0; i < input.length; i++)
           78  +  {
           79  +    x = input.charCodeAt(i);
           80  +    output += hex_tab.charAt((x >>> 4) & 0x0F)
           81  +           +  hex_tab.charAt( x        & 0x0F);
           82  +  }
           83  +  return output;
           84  +}
           85  +
           86  +/*
           87  + * Convert a raw string to a base-64 string
           88  + */
           89  +function rstr2b64(input)
           90  +{
           91  +  try { b64pad } catch(e) { b64pad=''; }
           92  +  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
           93  +  var output = "";
           94  +  var len = input.length;
           95  +  for(var i = 0; i < len; i += 3)
           96  +  {
           97  +    var triplet = (input.charCodeAt(i) << 16)
           98  +                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
           99  +                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
          100  +    for(var j = 0; j < 4; j++)
          101  +    {
          102  +      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
          103  +      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
          104  +    }
          105  +  }
          106  +  return output;
          107  +}
          108  +
          109  +/*
          110  + * Convert a raw string to an arbitrary string encoding
          111  + */
          112  +function rstr2any(input, encoding)
          113  +{
          114  +  var divisor = encoding.length;
          115  +  var remainders = Array();
          116  +  var i, q, x, quotient;
          117  +
          118  +  /* Convert to an array of 16-bit big-endian values, forming the dividend */
          119  +  var dividend = Array(Math.ceil(input.length / 2));
          120  +  for(i = 0; i < dividend.length; i++)
          121  +  {
          122  +    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
          123  +  }
          124  +
          125  +  /*
          126  +   * Repeatedly perform a long division. The binary array forms the dividend,
          127  +   * the length of the encoding is the divisor. Once computed, the quotient
          128  +   * forms the dividend for the next step. We stop when the dividend is zero.
          129  +   * All remainders are stored for later use.
          130  +   */
          131  +  while(dividend.length > 0)
          132  +  {
          133  +    quotient = Array();
          134  +    x = 0;
          135  +    for(i = 0; i < dividend.length; i++)
          136  +    {
          137  +      x = (x << 16) + dividend[i];
          138  +      q = Math.floor(x / divisor);
          139  +      x -= q * divisor;
          140  +      if(quotient.length > 0 || q > 0)
          141  +        quotient[quotient.length] = q;
          142  +    }
          143  +    remainders[remainders.length] = x;
          144  +    dividend = quotient;
          145  +  }
          146  +
          147  +  /* Convert the remainders to the output string */
          148  +  var output = "";
          149  +  for(i = remainders.length - 1; i >= 0; i--)
          150  +    output += encoding.charAt(remainders[i]);
          151  +
          152  +  /* Append leading zero equivalents */
          153  +  var full_length = Math.ceil(input.length * 8 /
          154  +                                    (Math.log(encoding.length) / Math.log(2)))
          155  +  for(i = output.length; i < full_length; i++)
          156  +    output = encoding[0] + output;
          157  +
          158  +  return output;
          159  +}
          160  +
          161  +/*
          162  + * Encode a string as utf-8.
          163  + * For efficiency, this assumes the input is valid utf-16.
          164  + */
          165  +function str2rstr_utf8(input)
          166  +{
          167  +  var output = "";
          168  +  var i = -1;
          169  +  var x, y;
          170  +
          171  +  while(++i < input.length)
          172  +  {
          173  +    /* Decode utf-16 surrogate pairs */
          174  +    x = input.charCodeAt(i);
          175  +    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
          176  +    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
          177  +    {
          178  +      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
          179  +      i++;
          180  +    }
          181  +
          182  +    /* Encode output as utf-8 */
          183  +    if(x <= 0x7F)
          184  +      output += String.fromCharCode(x);
          185  +    else if(x <= 0x7FF)
          186  +      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
          187  +                                    0x80 | ( x         & 0x3F));
          188  +    else if(x <= 0xFFFF)
          189  +      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
          190  +                                    0x80 | ((x >>> 6 ) & 0x3F),
          191  +                                    0x80 | ( x         & 0x3F));
          192  +    else if(x <= 0x1FFFFF)
          193  +      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
          194  +                                    0x80 | ((x >>> 12) & 0x3F),
          195  +                                    0x80 | ((x >>> 6 ) & 0x3F),
          196  +                                    0x80 | ( x         & 0x3F));
          197  +  }
          198  +  return output;
          199  +}
          200  +
          201  +/*
          202  + * Encode a string as utf-16
          203  + */
          204  +function str2rstr_utf16le(input)
          205  +{
          206  +  var output = "";
          207  +  for(var i = 0; i < input.length; i++)
          208  +    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
          209  +                                  (input.charCodeAt(i) >>> 8) & 0xFF);
          210  +  return output;
          211  +}
          212  +
          213  +function str2rstr_utf16be(input)
          214  +{
          215  +  var output = "";
          216  +  for(var i = 0; i < input.length; i++)
          217  +    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
          218  +                                   input.charCodeAt(i)        & 0xFF);
          219  +  return output;
          220  +}
          221  +
          222  +/*
          223  + * Convert a raw string to an array of big-endian words
          224  + * Characters >255 have their high-byte silently ignored.
          225  + */
          226  +function rstr2binb(input)
          227  +{
          228  +  var output = Array(input.length >> 2);
          229  +  for(var i = 0; i < output.length; i++)
          230  +    output[i] = 0;
          231  +  for(var i = 0; i < input.length * 8; i += 8)
          232  +    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
          233  +  return output;
          234  +}
          235  +
          236  +/*
          237  + * Convert an array of big-endian words to a string
          238  + */
          239  +function binb2rstr(input)
          240  +{
          241  +  var output = "";
          242  +  for(var i = 0; i < input.length * 32; i += 8)
          243  +    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
          244  +  return output;
          245  +}
          246  +
          247  +/*
          248  + * Main sha256 function, with its support functions
          249  + */
          250  +function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));}
          251  +function sha256_R (X, n) {return ( X >>> n );}
          252  +function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
          253  +function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
          254  +function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));}
          255  +function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));}
          256  +function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));}
          257  +function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));}
          258  +function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));}
          259  +function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));}
          260  +function sha256_Gamma0512(x) {return (sha256_S(x, 1)  ^ sha256_S(x, 8) ^ sha256_R(x, 7));}
          261  +function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));}
          262  +
          263  +var sha256_K = new Array
          264  +(
          265  +  1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993,
          266  +  -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
          267  +  1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
          268  +  264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
          269  +  -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
          270  +  113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
          271  +  1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885,
          272  +  -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
          273  +  430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
          274  +  1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872,
          275  +  -1866530822, -1538233109, -1090935817, -965641998
          276  +);
          277  +
          278  +function binb_sha256(m, l)
          279  +{
          280  +  var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534,
          281  +                       1359893119, -1694144372, 528734635, 1541459225);
          282  +  var W = new Array(64);
          283  +  var a, b, c, d, e, f, g, h;
          284  +  var i, j, T1, T2;
          285  +
          286  +  /* append padding */
          287  +  m[l >> 5] |= 0x80 << (24 - l % 32);
          288  +  m[((l + 64 >> 9) << 4) + 15] = l;
          289  +
          290  +  for(i = 0; i < m.length; i += 16)
          291  +  {
          292  +    a = HASH[0];
          293  +    b = HASH[1];
          294  +    c = HASH[2];
          295  +    d = HASH[3];
          296  +    e = HASH[4];
          297  +    f = HASH[5];
          298  +    g = HASH[6];
          299  +    h = HASH[7];
          300  +
          301  +    for(j = 0; j < 64; j++)
          302  +    {
          303  +      if (j < 16) W[j] = m[j + i];
          304  +      else W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
          305  +                                            sha256_Gamma0256(W[j - 15])), W[j - 16]);
          306  +
          307  +      T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
          308  +                                                          sha256_K[j]), W[j]);
          309  +      T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
          310  +      h = g;
          311  +      g = f;
          312  +      f = e;
          313  +      e = safe_add(d, T1);
          314  +      d = c;
          315  +      c = b;
          316  +      b = a;
          317  +      a = safe_add(T1, T2);
          318  +    }
          319  +
          320  +    HASH[0] = safe_add(a, HASH[0]);
          321  +    HASH[1] = safe_add(b, HASH[1]);
          322  +    HASH[2] = safe_add(c, HASH[2]);
          323  +    HASH[3] = safe_add(d, HASH[3]);
          324  +    HASH[4] = safe_add(e, HASH[4]);
          325  +    HASH[5] = safe_add(f, HASH[5]);
          326  +    HASH[6] = safe_add(g, HASH[6]);
          327  +    HASH[7] = safe_add(h, HASH[7]);
          328  +  }
          329  +  return HASH;
          330  +}
          331  +
          332  +function safe_add (x, y)
          333  +{
          334  +  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
          335  +  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
          336  +  return (msw << 16) | (lsw & 0xFFFF);
          337  +}

Added modules/jshash/js/sha512-min.js.

            1  +/*
            2  + * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined
            3  + * in FIPS 180-2
            4  + * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
            5  + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            6  + * Distributed under the BSD License
            7  + * See http://pajhome.org.uk/crypt/md5 for details.
            8  + */
            9  +var hexcase=0;function hex_sha512(a){return rstr2hex(rstr_sha512(str2rstr_utf8(a)))}function hex_hmac_sha512(a,b){return rstr2hex(rstr_hmac_sha512(str2rstr_utf8(a),str2rstr_utf8(b)))}function sha512_vm_test(){return hex_sha512("abc").toLowerCase()=="ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"}function rstr_sha512(a){return binb2rstr(binb_sha512(rstr2binb(a),a.length*8))}function rstr_hmac_sha512(c,f){var e=rstr2binb(c);if(e.length>32){e=binb_sha512(e,c.length*8)}var a=Array(32),d=Array(32);for(var b=0;b<32;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binb_sha512(a.concat(rstr2binb(f)),1024+f.length*8);return binb2rstr(binb_sha512(d.concat(g),1024+512))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binb(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(24-c%32)}return a}function binb2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(24-c%32))&255)}return a}var sha512_k;function binb_sha512(p,A){if(sha512_k==undefined){sha512_k=new Array(new int64(1116352408,-685199838),new int64(1899447441,602891725),new int64(-1245643825,-330482897),new int64(-373957723,-2121671748),new int64(961987163,-213338824),new int64(1508970993,-1241133031),new int64(-1841331548,-1357295717),new int64(-1424204075,-630357736),new int64(-670586216,-1560083902),new int64(310598401,1164996542),new int64(607225278,1323610764),new int64(1426881987,-704662302),new int64(1925078388,-226784913),new int64(-2132889090,991336113),new int64(-1680079193,633803317),new int64(-1046744716,-815192428),new int64(-459576895,-1628353838),new int64(-272742522,944711139),new int64(264347078,-1953704523),new int64(604807628,2007800933),new int64(770255983,1495990901),new int64(1249150122,1856431235),new int64(1555081692,-1119749164),new int64(1996064986,-2096016459),new int64(-1740746414,-295247957),new int64(-1473132947,766784016),new int64(-1341970488,-1728372417),new int64(-1084653625,-1091629340),new int64(-958395405,1034457026),new int64(-710438585,-1828018395),new int64(113926993,-536640913),new int64(338241895,168717936),new int64(666307205,1188179964),new int64(773529912,1546045734),new int64(1294757372,1522805485),new int64(1396182291,-1651133473),new int64(1695183700,-1951439906),new int64(1986661051,1014477480),new int64(-2117940946,1206759142),new int64(-1838011259,344077627),new int64(-1564481375,1290863460),new int64(-1474664885,-1136513023),new int64(-1035236496,-789014639),new int64(-949202525,106217008),new int64(-778901479,-688958952),new int64(-694614492,1432725776),new int64(-200395387,1467031594),new int64(275423344,851169720),new int64(430227734,-1194143544),new int64(506948616,1363258195),new int64(659060556,-544281703),new int64(883997877,-509917016),new int64(958139571,-976659869),new int64(1322822218,-482243893),new int64(1537002063,2003034995),new int64(1747873779,-692930397),new int64(1955562222,1575990012),new int64(2024104815,1125592928),new int64(-2067236844,-1578062990),new int64(-1933114872,442776044),new int64(-1866530822,593698344),new int64(-1538233109,-561857047),new int64(-1090935817,-1295615723),new int64(-965641998,-479046869),new int64(-903397682,-366583396),new int64(-779700025,566280711),new int64(-354779690,-840897762),new int64(-176337025,-294727304),new int64(116418474,1914138554),new int64(174292421,-1563912026),new int64(289380356,-1090974290),new int64(460393269,320620315),new int64(685471733,587496836),new int64(852142971,1086792851),new int64(1017036298,365543100),new int64(1126000580,-1676669620),new int64(1288033470,-885112138),new int64(1501505948,-60457430),new int64(1607167915,987167468),new int64(1816402316,1246189591))}var q=new Array(new int64(1779033703,-205731576),new int64(-1150833019,-2067093701),new int64(1013904242,-23791573),new int64(-1521486534,1595750129),new int64(1359893119,-1377402159),new int64(-1694144372,725511199),new int64(528734635,-79577749),new int64(1541459225,327033209));var s=new int64(0,0),r=new int64(0,0),J=new int64(0,0),I=new int64(0,0),G=new int64(0,0),F=new int64(0,0),E=new int64(0,0),D=new int64(0,0),C=new int64(0,0),B=new int64(0,0),m=new int64(0,0),l=new int64(0,0),t=new int64(0,0),o=new int64(0,0),z=new int64(0,0),w=new int64(0,0),u=new int64(0,0);var v,y;var n=new Array(80);for(y=0;y<80;y++){n[y]=new int64(0,0)}p[A>>5]|=128<<(24-(A&31));p[((A+128>>10)<<5)+31]=A;for(y=0;y<p.length;y+=32){int64copy(J,q[0]);int64copy(I,q[1]);int64copy(G,q[2]);int64copy(F,q[3]);int64copy(E,q[4]);int64copy(D,q[5]);int64copy(C,q[6]);int64copy(B,q[7]);for(v=0;v<16;v++){n[v].h=p[y+2*v];n[v].l=p[y+2*v+1]}for(v=16;v<80;v++){int64rrot(z,n[v-2],19);int64revrrot(w,n[v-2],29);int64shr(u,n[v-2],6);l.l=z.l^w.l^u.l;l.h=z.h^w.h^u.h;int64rrot(z,n[v-15],1);int64rrot(w,n[v-15],8);int64shr(u,n[v-15],7);m.l=z.l^w.l^u.l;m.h=z.h^w.h^u.h;int64add4(n[v],l,n[v-7],m,n[v-16])}for(v=0;v<80;v++){t.l=(E.l&D.l)^(~E.l&C.l);t.h=(E.h&D.h)^(~E.h&C.h);int64rrot(z,E,14);int64rrot(w,E,18);int64revrrot(u,E,9);l.l=z.l^w.l^u.l;l.h=z.h^w.h^u.h;int64rrot(z,J,28);int64revrrot(w,J,2);int64revrrot(u,J,7);m.l=z.l^w.l^u.l;m.h=z.h^w.h^u.h;o.l=(J.l&I.l)^(J.l&G.l)^(I.l&G.l);o.h=(J.h&I.h)^(J.h&G.h)^(I.h&G.h);int64add5(s,B,l,t,sha512_k[v],n[v]);int64add(r,m,o);int64copy(B,C);int64copy(C,D);int64copy(D,E);int64add(E,F,s);int64copy(F,G);int64copy(G,I);int64copy(I,J);int64add(J,s,r)}int64add(q[0],q[0],J);int64add(q[1],q[1],I);int64add(q[2],q[2],G);int64add(q[3],q[3],F);int64add(q[4],q[4],E);int64add(q[5],q[5],D);int64add(q[6],q[6],C);int64add(q[7],q[7],B)}var k=new Array(16);for(y=0;y<8;y++){k[2*y]=q[y].h;k[2*y+1]=q[y].l}return k}function int64(b,a){this.h=b;this.l=a}function int64copy(b,a){b.h=a.h;b.l=a.l}function int64rrot(c,a,b){c.l=(a.l>>>b)|(a.h<<(32-b));c.h=(a.h>>>b)|(a.l<<(32-b))}function int64revrrot(c,a,b){c.l=(a.h>>>b)|(a.l<<(32-b));c.h=(a.l>>>b)|(a.h<<(32-b))}function int64shr(c,a,b){c.l=(a.l>>>b)|(a.h<<(32-b));c.h=(a.h>>>b)}function int64add(g,b,f){var d=(b.l&65535)+(f.l&65535);var c=(b.l>>>16)+(f.l>>>16)+(d>>>16);var a=(b.h&65535)+(f.h&65535)+(c>>>16);var e=(b.h>>>16)+(f.h>>>16)+(a>>>16);g.l=(d&65535)|(c<<16);g.h=(a&65535)|(e<<16)}function int64add4(j,m,l,k,i){var h=(m.l&65535)+(l.l&65535)+(k.l&65535)+(i.l&65535);var g=(m.l>>>16)+(l.l>>>16)+(k.l>>>16)+(i.l>>>16)+(h>>>16);var f=(m.h&65535)+(l.h&65535)+(k.h&65535)+(i.h&65535)+(g>>>16);var e=(m.h>>>16)+(l.h>>>16)+(k.h>>>16)+(i.h>>>16)+(f>>>16);j.l=(h&65535)|(g<<16);j.h=(f&65535)|(e<<16)}function int64add5(l,o,n,m,k,j){var i=(o.l&65535)+(n.l&65535)+(m.l&65535)+(k.l&65535)+(j.l&65535);var h=(o.l>>>16)+(n.l>>>16)+(m.l>>>16)+(k.l>>>16)+(j.l>>>16)+(i>>>16);var g=(o.h&65535)+(n.h&65535)+(m.h&65535)+(k.h&65535)+(j.h&65535)+(h>>>16);var f=(o.h>>>16)+(n.h>>>16)+(m.h>>>16)+(k.h>>>16)+(j.h>>>16)+(g>>>16);l.l=(i&65535)|(h<<16);l.h=(g&65535)|(f<<16)};

Added modules/jshash/js/sha512.js.

            1  +/*
            2  + * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined
            3  + * in FIPS 180-2
            4  + * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
            5  + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            6  + * Distributed under the BSD License
            7  + * See http://pajhome.org.uk/crypt/md5 for details.
            8  + */
            9  +
           10  +/*
           11  + * Configurable variables. You may need to tweak these to be compatible with
           12  + * the server-side, but the defaults work in most cases.
           13  + */
           14  +var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
           15  +var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
           16  +
           17  +/*
           18  + * These are the functions you'll usually want to call
           19  + * They take string arguments and return either hex or base-64 encoded strings
           20  + */
           21  +function hex_sha512(s)    { return rstr2hex(rstr_sha512(str2rstr_utf8(s))); }
           22  +function b64_sha512(s)    { return rstr2b64(rstr_sha512(str2rstr_utf8(s))); }
           23  +function any_sha512(s, e) { return rstr2any(rstr_sha512(str2rstr_utf8(s)), e);}
           24  +function hex_hmac_sha512(k, d)
           25  +  { return rstr2hex(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); }
           26  +function b64_hmac_sha512(k, d)
           27  +  { return rstr2b64(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); }
           28  +function any_hmac_sha512(k, d, e)
           29  +  { return rstr2any(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d)), e);}
           30  +
           31  +/*
           32  + * Perform a simple self-test to see if the VM is working
           33  + */
           34  +function sha512_vm_test()
           35  +{
           36  +  return hex_sha512("abc").toLowerCase() ==
           37  +    "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
           38  +    "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
           39  +}
           40  +
           41  +/*
           42  + * Calculate the SHA-512 of a raw string
           43  + */
           44  +function rstr_sha512(s)
           45  +{
           46  +  return binb2rstr(binb_sha512(rstr2binb(s), s.length * 8));
           47  +}
           48  +
           49  +/*
           50  + * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
           51  + */
           52  +function rstr_hmac_sha512(key, data)
           53  +{
           54  +  var bkey = rstr2binb(key);
           55  +  if(bkey.length > 32) bkey = binb_sha512(bkey, key.length * 8);
           56  +
           57  +  var ipad = Array(32), opad = Array(32);
           58  +  for(var i = 0; i < 32; i++)
           59  +  {
           60  +    ipad[i] = bkey[i] ^ 0x36363636;
           61  +    opad[i] = bkey[i] ^ 0x5C5C5C5C;
           62  +  }
           63  +
           64  +  var hash = binb_sha512(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
           65  +  return binb2rstr(binb_sha512(opad.concat(hash), 1024 + 512));
           66  +}
           67  +
           68  +/*
           69  + * Convert a raw string to a hex string
           70  + */
           71  +function rstr2hex(input)
           72  +{
           73  +  try { hexcase } catch(e) { hexcase=0; }
           74  +  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
           75  +  var output = "";
           76  +  var x;
           77  +  for(var i = 0; i < input.length; i++)
           78  +  {
           79  +    x = input.charCodeAt(i);
           80  +    output += hex_tab.charAt((x >>> 4) & 0x0F)
           81  +           +  hex_tab.charAt( x        & 0x0F);
           82  +  }
           83  +  return output;
           84  +}
           85  +
           86  +/*
           87  + * Convert a raw string to a base-64 string
           88  + */
           89  +function rstr2b64(input)
           90  +{
           91  +  try { b64pad } catch(e) { b64pad=''; }
           92  +  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
           93  +  var output = "";
           94  +  var len = input.length;
           95  +  for(var i = 0; i < len; i += 3)
           96  +  {
           97  +    var triplet = (input.charCodeAt(i) << 16)
           98  +                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
           99  +                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
          100  +    for(var j = 0; j < 4; j++)
          101  +    {
          102  +      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
          103  +      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
          104  +    }
          105  +  }
          106  +  return output;
          107  +}
          108  +
          109  +/*
          110  + * Convert a raw string to an arbitrary string encoding
          111  + */
          112  +function rstr2any(input, encoding)
          113  +{
          114  +  var divisor = encoding.length;
          115  +  var i, j, q, x, quotient;
          116  +
          117  +  /* Convert to an array of 16-bit big-endian values, forming the dividend */
          118  +  var dividend = Array(Math.ceil(input.length / 2));
          119  +  for(i = 0; i < dividend.length; i++)
          120  +  {
          121  +    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
          122  +  }
          123  +
          124  +  /*
          125  +   * Repeatedly perform a long division. The binary array forms the dividend,
          126  +   * the length of the encoding is the divisor. Once computed, the quotient
          127  +   * forms the dividend for the next step. All remainders are stored for later
          128  +   * use.
          129  +   */
          130  +  var full_length = Math.ceil(input.length * 8 /
          131  +                                    (Math.log(encoding.length) / Math.log(2)));
          132  +  var remainders = Array(full_length);
          133  +  for(j = 0; j < full_length; j++)
          134  +  {
          135  +    quotient = Array();
          136  +    x = 0;
          137  +    for(i = 0; i < dividend.length; i++)
          138  +    {
          139  +      x = (x << 16) + dividend[i];
          140  +      q = Math.floor(x / divisor);
          141  +      x -= q * divisor;
          142  +      if(quotient.length > 0 || q > 0)
          143  +        quotient[quotient.length] = q;
          144  +    }
          145  +    remainders[j] = x;
          146  +    dividend = quotient;
          147  +  }
          148  +
          149  +  /* Convert the remainders to the output string */
          150  +  var output = "";
          151  +  for(i = remainders.length - 1; i >= 0; i--)
          152  +    output += encoding.charAt(remainders[i]);
          153  +
          154  +  return output;
          155  +}
          156  +
          157  +/*
          158  + * Encode a string as utf-8.
          159  + * For efficiency, this assumes the input is valid utf-16.
          160  + */
          161  +function str2rstr_utf8(input)
          162  +{
          163  +  var output = "";
          164  +  var i = -1;
          165  +  var x, y;
          166  +
          167  +  while(++i < input.length)
          168  +  {
          169  +    /* Decode utf-16 surrogate pairs */
          170  +    x = input.charCodeAt(i);
          171  +    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
          172  +    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
          173  +    {
          174  +      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
          175  +      i++;
          176  +    }
          177  +
          178  +    /* Encode output as utf-8 */
          179  +    if(x <= 0x7F)
          180  +      output += String.fromCharCode(x);
          181  +    else if(x <= 0x7FF)
          182  +      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
          183  +                                    0x80 | ( x         & 0x3F));
          184  +    else if(x <= 0xFFFF)
          185  +      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
          186  +                                    0x80 | ((x >>> 6 ) & 0x3F),
          187  +                                    0x80 | ( x         & 0x3F));
          188  +    else if(x <= 0x1FFFFF)
          189  +      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
          190  +                                    0x80 | ((x >>> 12) & 0x3F),
          191  +                                    0x80 | ((x >>> 6 ) & 0x3F),
          192  +                                    0x80 | ( x         & 0x3F));
          193  +  }
          194  +  return output;
          195  +}
          196  +
          197  +/*
          198  + * Encode a string as utf-16
          199  + */
          200  +function str2rstr_utf16le(input)
          201  +{
          202  +  var output = "";
          203  +  for(var i = 0; i < input.length; i++)
          204  +    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
          205  +                                  (input.charCodeAt(i) >>> 8) & 0xFF);
          206  +  return output;
          207  +}
          208  +
          209  +function str2rstr_utf16be(input)
          210  +{
          211  +  var output = "";
          212  +  for(var i = 0; i < input.length; i++)
          213  +    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
          214  +                                   input.charCodeAt(i)        & 0xFF);
          215  +  return output;
          216  +}
          217  +
          218  +/*
          219  + * Convert a raw string to an array of big-endian words
          220  + * Characters >255 have their high-byte silently ignored.
          221  + */
          222  +function rstr2binb(input)
          223  +{
          224  +  var output = Array(input.length >> 2);
          225  +  for(var i = 0; i < output.length; i++)
          226  +    output[i] = 0;
          227  +  for(var i = 0; i < input.length * 8; i += 8)
          228  +    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
          229  +  return output;
          230  +}
          231  +
          232  +/*
          233  + * Convert an array of big-endian words to a string
          234  + */
          235  +function binb2rstr(input)
          236  +{
          237  +  var output = "";
          238  +  for(var i = 0; i < input.length * 32; i += 8)
          239  +    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
          240  +  return output;
          241  +}
          242  +
          243  +/*
          244  + * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
          245  + */
          246  +var sha512_k;
          247  +function binb_sha512(x, len)
          248  +{
          249  +  if(sha512_k == undefined)
          250  +  {
          251  +    //SHA512 constants
          252  +    sha512_k = new Array(
          253  +new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
          254  +new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
          255  +new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
          256  +new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
          257  +new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
          258  +new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
          259  +new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
          260  +new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
          261  +new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
          262  +new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
          263  +new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
          264  +new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
          265  +new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
          266  +new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
          267  +new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
          268  +new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
          269  +new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
          270  +new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
          271  +new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
          272  +new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
          273  +new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
          274  +new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
          275  +new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
          276  +new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
          277  +new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
          278  +new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
          279  +new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
          280  +new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
          281  +new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
          282  +new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
          283  +new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
          284  +new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
          285  +new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
          286  +new int64(-354779690, -840897762), new int64(-176337025, -294727304),
          287  +new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
          288  +new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
          289  +new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
          290  +new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
          291  +new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
          292  +new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817));
          293  +  }
          294  +
          295  +  //Initial hash values
          296  +  var H = new Array(
          297  +new int64(0x6a09e667, -205731576),
          298  +new int64(-1150833019, -2067093701),
          299  +new int64(0x3c6ef372, -23791573),
          300  +new int64(-1521486534, 0x5f1d36f1),
          301  +new int64(0x510e527f, -1377402159),
          302  +new int64(-1694144372, 0x2b3e6c1f),
          303  +new int64(0x1f83d9ab, -79577749),
          304  +new int64(0x5be0cd19, 0x137e2179));
          305  +
          306  +  var T1 = new int64(0, 0),
          307  +    T2 = new int64(0, 0),
          308  +    a = new int64(0,0),
          309  +    b = new int64(0,0),
          310  +    c = new int64(0,0),
          311  +    d = new int64(0,0),
          312  +    e = new int64(0,0),
          313  +    f = new int64(0,0),
          314  +    g = new int64(0,0),
          315  +    h = new int64(0,0),
          316  +    //Temporary variables not specified by the document
          317  +    s0 = new int64(0, 0),
          318  +    s1 = new int64(0, 0),
          319  +    Ch = new int64(0, 0),
          320  +    Maj = new int64(0, 0),
          321  +    r1 = new int64(0, 0),
          322  +    r2 = new int64(0, 0),
          323  +    r3 = new int64(0, 0);
          324  +  var j, i;
          325  +  var W = new Array(80);
          326  +  for(i=0; i<80; i++)
          327  +    W[i] = new int64(0, 0);
          328  +
          329  +  // append padding to the source string. The format is described in the FIPS.
          330  +  x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
          331  +  x[((len + 128 >> 10)<< 5) + 31] = len;
          332  +
          333  +  for(i = 0; i<x.length; i+=32) //32 dwords is the block size
          334  +  {
          335  +    int64copy(a, H[0]);
          336  +    int64copy(b, H[1]);
          337  +    int64copy(c, H[2]);
          338  +    int64copy(d, H[3]);
          339  +    int64copy(e, H[4]);
          340  +    int64copy(f, H[5]);
          341  +    int64copy(g, H[6]);
          342  +    int64copy(h, H[7]);
          343  +
          344  +    for(j=0; j<16; j++)
          345  +    {
          346  +        W[j].h = x[i + 2*j];
          347  +        W[j].l = x[i + 2*j + 1];
          348  +    }
          349  +
          350  +    for(j=16; j<80; j++)
          351  +    {
          352  +      //sigma1
          353  +      int64rrot(r1, W[j-2], 19);
          354  +      int64revrrot(r2, W[j-2], 29);
          355  +      int64shr(r3, W[j-2], 6);
          356  +      s1.l = r1.l ^ r2.l ^ r3.l;
          357  +      s1.h = r1.h ^ r2.h ^ r3.h;
          358  +      //sigma0
          359  +      int64rrot(r1, W[j-15], 1);
          360  +      int64rrot(r2, W[j-15], 8);
          361  +      int64shr(r3, W[j-15], 7);
          362  +      s0.l = r1.l ^ r2.l ^ r3.l;
          363  +      s0.h = r1.h ^ r2.h ^ r3.h;
          364  +
          365  +      int64add4(W[j], s1, W[j-7], s0, W[j-16]);
          366  +    }
          367  +
          368  +    for(j = 0; j < 80; j++)
          369  +    {
          370  +      //Ch
          371  +      Ch.l = (e.l & f.l) ^ (~e.l & g.l);
          372  +      Ch.h = (e.h & f.h) ^ (~e.h & g.h);
          373  +
          374  +      //Sigma1
          375  +      int64rrot(r1, e, 14);
          376  +      int64rrot(r2, e, 18);
          377  +      int64revrrot(r3, e, 9);
          378  +      s1.l = r1.l ^ r2.l ^ r3.l;
          379  +      s1.h = r1.h ^ r2.h ^ r3.h;
          380  +
          381  +      //Sigma0
          382  +      int64rrot(r1, a, 28);
          383  +      int64revrrot(r2, a, 2);
          384  +      int64revrrot(r3, a, 7);
          385  +      s0.l = r1.l ^ r2.l ^ r3.l;
          386  +      s0.h = r1.h ^ r2.h ^ r3.h;
          387  +
          388  +      //Maj
          389  +      Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
          390  +      Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
          391  +
          392  +      int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
          393  +      int64add(T2, s0, Maj);
          394  +
          395  +      int64copy(h, g);
          396  +      int64copy(g, f);
          397  +      int64copy(f, e);
          398  +      int64add(e, d, T1);
          399  +      int64copy(d, c);
          400  +      int64copy(c, b);
          401  +      int64copy(b, a);
          402  +      int64add(a, T1, T2);
          403  +    }
          404  +    int64add(H[0], H[0], a);
          405  +    int64add(H[1], H[1], b);
          406  +    int64add(H[2], H[2], c);
          407  +    int64add(H[3], H[3], d);
          408  +    int64add(H[4], H[4], e);
          409  +    int64add(H[5], H[5], f);
          410  +    int64add(H[6], H[6], g);
          411  +    int64add(H[7], H[7], h);
          412  +  }
          413  +
          414  +  //represent the hash as an array of 32-bit dwords
          415  +  var hash = new Array(16);
          416  +  for(i=0; i<8; i++)
          417  +  {
          418  +    hash[2*i] = H[i].h;
          419  +    hash[2*i + 1] = H[i].l;
          420  +  }
          421  +  return hash;
          422  +}
          423  +
          424  +//A constructor for 64-bit numbers
          425  +function int64(h, l)
          426  +{
          427  +  this.h = h;
          428  +  this.l = l;
          429  +  //this.toString = int64toString;
          430  +}
          431  +
          432  +//Copies src into dst, assuming both are 64-bit numbers
          433  +function int64copy(dst, src)
          434  +{
          435  +  dst.h = src.h;
          436  +  dst.l = src.l;
          437  +}
          438  +
          439  +//Right-rotates a 64-bit number by shift
          440  +//Won't handle cases of shift>=32
          441  +//The function revrrot() is for that
          442  +function int64rrot(dst, x, shift)
          443  +{
          444  +    dst.l = (x.l >>> shift) | (x.h << (32-shift));
          445  +    dst.h = (x.h >>> shift) | (x.l << (32-shift));
          446  +}
          447  +
          448  +//Reverses the dwords of the source and then rotates right by shift.
          449  +//This is equivalent to rotation by 32+shift
          450  +function int64revrrot(dst, x, shift)
          451  +{
          452  +    dst.l = (x.h >>> shift) | (x.l << (32-shift));
          453  +    dst.h = (x.l >>> shift) | (x.h << (32-shift));
          454  +}
          455  +
          456  +//Bitwise-shifts right a 64-bit number by shift
          457  +//Won't handle shift>=32, but it's never needed in SHA512
          458  +function int64shr(dst, x, shift)
          459  +{
          460  +    dst.l = (x.l >>> shift) | (x.h << (32-shift));
          461  +    dst.h = (x.h >>> shift);
          462  +}
          463  +
          464  +//Adds two 64-bit numbers
          465  +//Like the original implementation, does not rely on 32-bit operations
          466  +function int64add(dst, x, y)
          467  +{
          468  +   var w0 = (x.l & 0xffff) + (y.l & 0xffff);
          469  +   var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
          470  +   var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
          471  +   var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
          472  +   dst.l = (w0 & 0xffff) | (w1 << 16);
          473  +   dst.h = (w2 & 0xffff) | (w3 << 16);
          474  +}
          475  +
          476  +//Same, except with 4 addends. Works faster than adding them one by one.
          477  +function int64add4(dst, a, b, c, d)
          478  +{
          479  +   var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
          480  +   var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
          481  +   var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
          482  +   var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
          483  +   dst.l = (w0 & 0xffff) | (w1 << 16);
          484  +   dst.h = (w2 & 0xffff) | (w3 << 16);
          485  +}
          486  +
          487  +//Same, except with 5 addends
          488  +function int64add5(dst, a, b, c, d, e)
          489  +{
          490  +   var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff);
          491  +   var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16);
          492  +   var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16);
          493  +   var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
          494  +   dst.l = (w0 & 0xffff) | (w1 << 16);
          495  +   dst.h = (w2 & 0xffff) | (w3 << 16);
          496  +}

Added modules/jshash/js/test-min.py.

            1  +#--
            2  +# Script to test the JavaScript hash algorithms
            3  +# This produces an HTML file, that you load in a browser to run the tests
            4  +#--
            5  +import hashlib, base64, hmac
            6  +
            7  +all_algs = ['md5', 'sha1', 'ripemd160', 'sha256', 'sha512']
            8  +short = {'ripemd160': 'rmd160'}
            9  +test_strings = ['hello', 'world', u'fred\u1234'.encode('utf-8'), 'this is a longer test message to confirm that multiple blocks are handled correctly by the hashing algorithm']
           10  +
           11  +print """<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/></head><body>"""
           12  +
           13  +for alg in all_algs:
           14  +    algs = short.get(alg, alg)
           15  +
           16  +    print """<script src="%s-min.js"></script>
           17  +<script>
           18  +var pass = 0; fail = 0;
           19  +function check(a, b)
           20  +{
           21  +    if(a != b)
           22  +    {
           23  +        document.write('Test fail: ' + a + ' != ' + b + '<br/>');
           24  +        fail += 1;
           25  +    }
           26  +    else pass += 1;
           27  +}
           28  +document.write("Testing %s...<br/>");
           29  +""" % (alg, alg)
           30  +
           31  +    for t in test_strings:
           32  +        h = hashlib.new(alg)
           33  +        h.update(t)
           34  +        print "check(hex_%s('%s'), '%s');" % (algs, t, h.hexdigest())
           35  +        h = hmac.new('key', t, lambda: hashlib.new(alg))
           36  +        print "check(hex_hmac_%s('key', '%s'), '%s');" % (algs, t, h.hexdigest())
           37  +
           38  +    print """
           39  +document.write('Tests competed - ' + pass + ' passed; ' + fail + ' failed.<br/><br/>');
           40  +</script>
           41  +"""
           42  +
           43  +print "</body></html>"

Added modules/jshash/js/test.py.

            1  +#--
            2  +# Script to test the JavaScript hash algorithms
            3  +# This produces an HTML file, that you load in a browser to run the tests
            4  +#--
            5  +import hashlib, base64, hmac
            6  +
            7  +all_algs = ['md5', 'sha1', 'ripemd160', 'sha256', 'sha512']
            8  +short = {'ripemd160': 'rmd160'}
            9  +test_strings = ['hello', 'world', u'fred\u1234'.encode('utf-8'), 'this is a longer test message to confirm that multiple blocks are handled correctly by the hashing algorithm']
           10  +
           11  +print """<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/></head><body>"""
           12  +
           13  +for alg in all_algs:
           14  +    algs = short.get(alg, alg)
           15  +
           16  +    print """<script src="%s.js"></script>
           17  +<script>
           18  +var pass = 0; fail = 0;
           19  +function check(a, b)
           20  +{
           21  +    if(a != b)
           22  +    {
           23  +        document.write('Test fail: ' + a + ' != ' + b + '<br/>');
           24  +        fail += 1;
           25  +    }
           26  +    else pass += 1;
           27  +}
           28  +document.write("Testing %s...<br/>");
           29  +""" % (alg, alg)
           30  +
           31  +    for t in test_strings:
           32  +        h = hashlib.new(alg)
           33  +        h.update(t)
           34  +        print "check(hex_%s('%s'), '%s');" % (algs, t, h.hexdigest())
           35  +        print "check(b64_%s('%s'), '%s');" % (algs, t, base64.b64encode(h.digest()).rstrip('='))
           36  +        h = hmac.new('key', t, lambda: hashlib.new(alg))
           37  +        print "check(hex_hmac_%s('key', '%s'), '%s');" % (algs, t, h.hexdigest())
           38  +        print "check(b64_hmac_%s('key', '%s'), '%s');" % (algs, t, base64.b64encode(h.digest()).rstrip('='))
           39  +
           40  +    print """
           41  +document.write('Tests competed - ' + pass + ' passed; ' + fail + ' failed.<br/><br/>');
           42  +</script>
           43  +"""
           44  +
           45  +print "</body></html>"

Added modules/jshash/jshash.md.

            1  +A JavaScript implementation of the Secure Hash Algorithm
            2  +
            3  +Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
            4  +
            5  +Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
            6  +
            7  +Distributed under the BSD License
            8  +See <http://pajhome.org.uk/crypt/md5> for details.
            9  +
           10  +This package adds javascripts capable of performing md5 and
           11  +sha1 hashes, and makes them available at /jshash on the local
           12  +webserver.
           13  +
           14  +To use them add the following block of code to your pages:
           15  +
           16  +    <script type="text/javascript" src="/jshash/sha1.js"></script>  

Added modules/jshash/jshash.tcl.

            1  +###
            2  +# Add hooks for jshash
            3  +###
            4  +
            5  +package require httpd::doc	;# Httpd_Redirect Httpd_ReturnData
            6  +
            7  +set PWD [file dirname [file normalize [info script]]]
            8  +
            9  +Doc_AddRoot /jshash $PWD/js
           10  +
           11  +package provide httpd::jshash 0.1

Added modules/jshash/pkgIndex.tcl.

            1  +# Tcl package index file, version 1.1
            2  +# This file is generated by the "pkg_mkIndex" command
            3  +# and sourced either when an application starts up or
            4  +# by a "package unknown" script.  It invokes the
            5  +# "package ifneeded" command to set up package-related
            6  +# information so that packages will be loaded automatically
            7  +# in response to "package require" commands.  When this
            8  +# script is sourced, the variable $dir must contain the
            9  +# full path name of this file's directory.
           10  +
           11  +package ifneeded httpd::jshash 0.1 [list source [file join $dir jshash.tcl]]

Changes to modules/tao-sqlite/tao-sqlite.md.

            1  +Back to [tao](../tao.md)
            2  +
            3  +tao-sqlite is a module of related classes which act as ambassadors to **sqlte** database connections.
            4  +
            5  +# Sub-Modules
            6  +
            7  +[yggdrasil](yggdrasil.md)
            8  +
            9  +# Core Classes
           10  +
           11  +## class taodb::connection
           12  +
           13  +Implements a generic wrapper around a database connection. (Note: at this
           14  +point only sqlite has been developed.)
           15  +
           16  +Ancestors: [tao.onion](../tao/onions.md)
           17  +
           18  +### Methods
           19  +
           20  +#### method active_layers
           21  +
           22  +Return a list of database layers to act as ambassodors for various
           23  +collections of tables. See [onions](../tao/onions.md)
           24  +
           25  +#### method Database_Create
           26  +
           27  +Commands to invoke when the interface attempts to connect to a virgin
           28  +database. This method should build the database schema and populate any
           29  +starter data.
           30  +
           31  +#### method Database_Functions
           32  +
           33  +Inject functions into the database interface. For sqlite, this method
           34  +invokes the interface's native *function* method to map an sqlite function
           35  +to a Tcl command.
           36  +
           37  +#### Ensemble schema
           38  +
           39  +Ensemble to manage database schemas.
           40  +
           41  +##### method schema create_sql
           42  +
           43  +Return fully formed SQL code to implement the schema
           44  +
           45  +The default implementation
           46  +is to interrogate the object layers for a *schema create_sql* property.
           47  +
           48  +##### method schema tables
           49  +
           50  +Return a list of tables specified by the schema. The default implementation
           51  +is to interrogate the object layers for a *schema table* property.
           52  +
           53  +

Changes to modules/tao/lutils.tcl.

   413    413       foreach item $value {
   414    414           if {[lsearch $list $item] >= 0} {
   415    415               return true
   416    416           }
   417    417       }
   418    418       return false
   419    419   }
          420  +
          421  +makeproc cat filename {
          422  +  set fin [open $filename r]
          423  +  set dat [read $fin]
          424  +  close $fin
          425  +  return $dat
          426  +}
   420    427   

Added modules/tao/onions.md.

            1  +Onions have layers. Like ogres. Or parfaits.
            2  +
            3  +# Class tao::layer
            4  +
            5  +## Options
            6  +
            7  +* prefix - A letter code for this layer
            8  +* layer\_name - A plaintext name for this layer.
            9  +* layer\_index\_order - Integer which expresses what order this layer should be index. (0 first -> infinity)
           10  +
           11  +## Methods
           12  +
           13  +### method node\_is\_managed *unit*
           14  +
           15  +Returns true if an object or record described by *unit* is managed by this object.
           16  +
           17  +### method type\_is\_managed *unit*
           18  +
           19  +Returns true if an type, class or family of records described by *unit* is managed by this object.
           20  +
           21  +# Class tao::onion
           22  +
           23  +## Variables
           24  +
           25  +* layers - A dict containing a mapping of layer names and the objects which implement them.
           26  +
           27  +## Properties
           28  +
           29  +* shared_organs - A list of stubs which are also connected to any node or layer spawned by this object.
           30  +
           31  +## Methods
           32  +
           33  +### method action activate_layers
           34  +
           35  +Action to perform after all of the layer objects have been connected.
           36  +
           37  +### method activate_layers ?1|0?
           38  +
           39  +Using the output of *active_layers*, build a nest of layers. If a *1* is
           40  +given as the first argument, all existing layers are unmapped and destroyed
           41  +before mapping new layers. Otherwise layers that were previously mapped
           42  +and not present in the current incarnation of the object are destroyed. Layers
           43  +which exist in the current incarnation, but which arent't mapped are created.
           44  +Layers that are mapped, and present in the *active_layers*, but which
           45  +have a different class implementation morph into the new class.
           46  +
           47  +### method active_layers
           48  +
           49  +Return a dict describing the layers that should be mapped to this object.
           50  +
           51  +Example:
           52  +
           53  +    method active_layers {} {
           54  +      set result {
           55  +        xtype     {prefix y class sde.layer.xtype}
           56  +        eqpt      {prefix e class sde.layer.eqpt}
           57  +        portal    {prefix p class sde.layer.portal}
           58  +      }
           59  +      return $result
           60  +    }
           61  +    
           62  +### method layer *layerid* ?*method*? ?*args...*?
           63  +
           64  +With only the *layerid* argument, return the object which implements
           65  +the layer described by *layerid*. If the layer does not exist, ::noop (a command which takes any argument
           66  +and does nothing) is returned.
           67  +
           68  +If more arguments are specified, the command will exercise the *method* of the
           69  +layer object using any additional *args*.
           70  +
           71  +Example:
           72  +
           73  +    set obj [::db layer users]
           74  +    set username [$obj record_exists $userid]
           75  +    
           76  +    OR
           77  +    
           78  +    set exists [::db layer users record_exists $userid]
           79  +
           80  +### method layers
           81  +
           82  +Return a dict describing the layers currently mapped to this object.
           83  +
           84  +### method Shared_Organs
           85  +
           86  +Return a list of organs for this object which should also be grafted to
           87  +any layers or other nodes spawned by it. The default implementation is to
           88  +return the contents of the value of *property shared_organs*
           89  +
           90  +### Method SubObject layer *name*
           91  +
           92  +Return the fully qualified name of the object which will implement this layer.
           93  +
           94  +The default implementation return \[namespace current\]::SubObject\_Layer\_\$name

Added modules/tao/property.md.