[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] CGIs and authentication



At 3:18 PM 1/30/96, yeah wrote:
>I'm prototyping an access-restriction CGI in my favorite
>scripting language -- that is, MacPerl -- and I'm having
>trouble getting a hold of the password passed by the
>HTTP client.
>...
>
>REMOTE_USER          SNARF
>HTTP_AUTHORIZATION   Basic em9tYm11OnNub3Q=
>
>The questions are:
>1. Is that really SNARF's password?
>2. If so, how do I encrypt a known password in order to match it to
>   what's in HTTP_AUTHORIZATION?
>3. If MacCrypt.pl is the answer to #2, what is the "salt" value I need?

1.  The string labelled HTTP_AUTHORIZATION is actually a base64 encoding
    of a string that would look like

        SNARF:foo

    where "foo" is the password for "SNARF".  Base64 it TOTALLY NOT SECURE;
    its only purpose is to transform a arbitrary bitstring into printable
    ASCII for transmission (without fear of having any control characters
    embedded in the original bitstring mangle your comm).

2.  The spec for base64 is in RFC 1521 "MIME".  My quick-and-dirty MacPerl
    hack at it is contained below.

3.  No crypt.  No salt.

==========================================================================

The script below is a test implementation of string-to-base64 and
base64-to-string conversions.  I played with it enough to be satisfied
for my purposes (including reproducing the example in RFC1521), but your
mileage may vary.  NO WARRANTIES OF ANY KIND, etc. etc. etc.

Type a line containing an operation character, immediately followed by
the string you want translated.

An operation character of ">" translates the string into base64.
An operation character of "<" translates the string back from base64.

Have fun!

==========================================================================
#!/usr/local/bin/perl

$s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

while (length ($in = <>) > 1) {
        chop $in;
        ($verb,$obj) = (substr ($in, 0, 1), substr ($in, 1));
        if ($verb eq ">") {
                $out = &str2b64 ($obj);
        } elsif ($verb eq "<") {
                $out = &b642str ($obj);
        } else {
                $out = "please prefix line with > or <";
        }
        print " $out\n";
}

1;

sub str2b64 {
        local ($arg) = @_;
        local ($b, $w, $r, $d, $c) = (0, 0, "", 0, 0);
        foreach $c (unpack ("c" x length ($arg), $arg)) {
                ($b,$w) = (($b << 8) + $c, $w + 8);
                while ($w >= 6) {
                        $b -= ($d = $b >> ($w -= 6)) << $w;
                        $r .= substr ($s, $d, 1);
                }
        }
        $r .= substr ($s, $b << (6 - $w), 1) if ($w);
        return ($r .= substr ("====", 0, (4 - length ($r) % 4) % 4));
}

sub b642str {
        local ($arg) = @_;
        local ($c, $d, $r, $b, $w) = ("", 0, "", 0, 0);
        if ($arg =~ m!([A-Za-z0-9+/]+)=*!) {
                foreach $d (unpack ("a" x length ($1), $1)) {
                        ($b, $w) = (($b << 6) + index ($s, $d), $w + 6);
                        while ($w >= 8) {
                                $b -= ($d = $b >> ($w -= 8)) << $w;
                                $r .= pack ("c", $d);
                        }
                }
        }
        return $r;
}

--------------------------------------------------------------------
-jn- (my two cats have accepted full responsibility for my opinions)
--------------------------------------------------------------------