Index: bin/gnump3d2 =================================================================== RCS file: /sources/gnump3d/gnump3d/bin/gnump3d2,v retrieving revision 1.152 diff -r1.152 gnump3d2 197a198 > our $AUTHORIZATION_TYPE= ""; 779c780 < if ( $request =~ /Authorization: Basic ([^\r\n]+)/ ) --- > if ( $request =~ /Authorization: (Basic|Digest) ([^\r\n]+)/ ) 781c782 < $AUTHORIZATION = $1; --- > $AUTHORIZATION = $2; 1422c1423,1433 < $header .= "WWW-Authenticate: Basic realm=\"GNUMP3d\"\r\n"; --- > if ($AUTHORIZATION_TYPE eq 'Digest') > { > my $md5_handle = gnump3d::MD5->new(); > $md5_handle->add(rand() + time()); > my $nonce = $md5_handle->hexdigest; > $header .= "WWW-Authenticate: Digest realm=\"GNUMP3d\", nonce=\"" . $nonce . "\", algorithm=MD5, domain=\"" . $REQUEST . "\", qop=\"auth\"\r\n"; > } > elsif ($AUTHORIZATION_TYPE eq 'Basic') > { > $header .= "WWW-Authenticate: Basic realm=\"GNUMP3d\"\r\n"; > } 3017,3018c3028,3029 < while ( $directory ne $ROOT ) < { --- > while ( $directory ne $ROOT ) > { 3020,3098c3031,3141 < if ( -e $directory . "/.password" ) < { < $DEBUG && print "Password file found\n"; < if ( not length( $AUTHORIZATION ) ) < { < # Send auth required header. < my $header = getHTTPHeader( 401, "text/html" ); < &sendData( $data, $header ); < < my $text = &getErrorPage( $ARGUMENTS{'theme'}, < "Access has been denied to $connected_address" ); < &sendData( $data, $text ); < close( $data ); < exit; < } < else < { < my $decoder = gnump3d::base64->new( ); < my $decoded = $decoder->decode( $AUTHORIZATION ); < my $user = ""; < my $pass = ""; < < if ( $decoded =~ /(.*):(.*)/ ) < { < $user = $1; < $pass = $2; < } < < if ( ( not length( $pass ) ) or < ( not length( $user ) ) ) < { < # < # Null usernames/passwords are invalid. < # < my $header = getHTTPHeader( 401, "text/html" ); < &sendData( $data, $header ); < < my $text = &getErrorPage( $ARGUMENTS{'theme'}, < $literals->get( "ACCESS_DENIED" ) ); < &sendData( $data, $text ); < close( $data ); < return; < } < < # < # Find a match. < # < open( PASSWORD, "<$directory/.password" ) < or warn "Can't open: password file : $!"; < my @valid = ; < close( PASSWORD ); < foreach my $line ( @valid ) < { < chomp($line); < if ( $line eq "$user:$pass" ) < { < # Successful login - saved logged in username < $LOGGED_IN_USER = $user; < return; < } < } < < # < # Record failed login attempts < # < $DEBUG && print "Error : invalid login for user : $user\n"; < < # < # No match found < # < my $header = getHTTPHeader( 401, "text/html" ); < &sendData( $data, $header ); < < my $text = &getErrorPage( $ARGUMENTS{'theme'}, < $literals->get( "ACCESS_DENIED" ) ); < &sendData( $data, $text ); < close( $data ); < } < } --- > if ( -e $directory . "/.password" ) > { > $DEBUG && print "Password file found\n"; > if ( not length( $AUTHORIZATION ) ) > { > # Send auth required header. > my $header = getHTTPHeader( 401, "text/html" ); > &sendData( $data, $header ); > > my $text = &getErrorPage( $ARGUMENTS{'theme'}, > "Access has been denied to $connected_address" ); > &sendData( $data, $text ); > close( $data ); > exit; > } > else > { > my $user = ""; > my $pass = ""; > my $digestRequest = ""; > > if ($AUTHORIZATION_TYPE eq 'Digest') > { > my $md5_handle = gnump3d::MD5->new(); > if ($AUTHORIZATION =~ /username=\"(.*)\", realm=\"(.*)\", nonce=\"(.*)\", uri=\"(.*)\", algorithm=(.*), response=\"(.*)\", qop=(.*), nc=(.*), cnonce=\"(.*)\"/) > { > my ($username, $realm, $nonce, $uri, $algorithm, $response, $qop, $nc, $cnonce) = ($1, $2, $3, $4, $5, $6, $7, $8, $9); > $md5_handle->add('GET:' . $REQUEST); > my $A2 = $md5_handle->hexdigest; > $user = $username; > $pass = $nonce . ':' . $nc . ':' . $cnonce . ':' . $qop . ':' . $A2; > $digestRequest = $response; > } > } > elsif ($AUTHORIZATION_TYPE eq 'Basic') > { > my $decoder = gnump3d::base64->new( ); > my $decoded = $decoder->decode( $AUTHORIZATION ); > > if ( $decoded =~ /(.*):(.*)/ ) > { > $user = $1; > $pass = $2; > } > } > > if ( ( not length( $pass ) ) or > ( not length( $user ) ) ) > { > # > # Null usernames/passwords are invalid. > # > my $header = getHTTPHeader( 401, "text/html" ); > &sendData( $data, $header ); > > my $text = &getErrorPage( $ARGUMENTS{'theme'}, > $literals->get( "ACCESS_DENIED" ) ); > &sendData( $data, $text ); > close( $data ); > return; > } > # > # Find a match. > # > open( PASSWORD, "<$directory/.password" ) > or warn "Can't open: password file : $!"; > my @valid = ; > close( PASSWORD ); > foreach my $line ( @valid ) > { > chomp($line); > if ($AUTHORIZATION_TYPE eq 'Digest') > { > if ($line =~ /(.*):(.*)/) > { > my $md5_handle = gnump3d::MD5->new(); > $md5_handle->add($2 . ':' . $pass); > my $digest = $md5_handle->hexdigest; > if (($user eq $1) and ($digest eq $digestRequest)) > { > # Successful login - saved logged in username > $LOGGED_IN_USER = $user; > return; > } > } > } > elsif ( $line eq "$user:$pass" ) > { > # Successful login - saved logged in username > $LOGGED_IN_USER = $user; > return; > } > } > > # > # Record failed login attempts > # > $DEBUG && print "Error : invalid login for user : $user\n"; > > # > # No match found > # > my $header = getHTTPHeader( 401, "text/html" ); > &sendData( $data, $header ); > > my $text = &getErrorPage( $ARGUMENTS{'theme'}, > $literals->get( "ACCESS_DENIED" ) ); > &sendData( $data, $text ); > close( $data ); > } > } 3429a3473 > $AUTHORIZATION_TYPE = getConfig( 'authentication_type', 'Basic' ); Index: etc/gnump3d.conf =================================================================== RCS file: /sources/gnump3d/gnump3d/etc/gnump3d.conf,v retrieving revision 1.23 diff -r1.23 gnump3d.conf 309a310,318 > # OR, for Digest authentification, the password file should be of > # the following format: > # > # username:hash > # username2:hash2 > # > # hash or hash2 represent MD5(login:GNUMP3d:password) > # To generate an hash string, type: > # $> echo -n 'username:GNUMP3d:password' | md5sum 318a328 > # authentication_type = Basic # Basic or Digest