Hello,

I posted few days ago a patch to add digest auth feature to gnump3d. I
didn't receive any answer, maybe devel mailing list is not used
anymore, so I repost it here.

--
samuel alba

---------- Forwarded message ----------
From: samuel alba <[EMAIL PROTECTED]>
Date: Mar 31, 2007 6:09 PM
Subject: [gnump3d] feature added : HTTP Authentication Digest
To: [email protected], [EMAIL PROTECTED]


Hello,

I've just finished to implement HTTP auth digest on the last CVS revision.
I think it's important to add this feature on the next release because
of security reason.

This code is in accordance with rfc 2617, I've tested it with
mozilla-firefox successfully.

I've attached the patch.

samuel "shad" alba
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 = <PASSWORD>;
< 	       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 = <PASSWORD>;
> 				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
_______________________________________________
Gnump3d-users mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/gnump3d-users

Reply via email to