//-----------------------------------------------------------------------------
// Copyright © 2003 - Philip Howard - All rights reserved
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//-----------------------------------------------------------------------------
// package	libh/http
// homepage	http://libh.slashusr.org/
//-----------------------------------------------------------------------------
// author	Philip Howard
// email	phil at ipal dot org
//-----------------------------------------------------------------------------
// This file is best viewed using a fixed spaced font such as Courier
// and in a display at least 112 columns wide.
//-----------------------------------------------------------------------------

#include "http_lib.h"

__PROTO_BEGIN__
//-----------------------------------------------------------------------------
// function	http_auth_get
//
// purpose	Extract and decode the username and the password from the
//		HTTP_AUTHORIZATION environment variable, which represents
//		The HTTP Authorization header.
//
// notice	This requires the SECURITY_HOLE_PASS_AUTHORIZATION option
//		to be enabled in Apache at compile time in order to get
//		the HTTP Authorization header in the HTTP_AUTHORIZATION
//		environment variable.  Otherwise Apache suppresses that
//		environment variable for security purposes.
//
// arguments	1 (const char *) NULL or alternate HTTP authorization string
//		2 (char *) where to store the username
//		3 (size_t) maximum length for username
//		4 (char *) where to store the password
//		5 (size_t) maximum length for password
//
// returns	(int) -1 : error
//		(int)  0 : OK (username and password are both OK)
//		+1 = username is truncated
//		+2 = password is truncated
//		+4 = password is absent
//-----------------------------------------------------------------------------
int
http_auth_get (
    const char *	arg_authstr
    ,
    char *		arg_ptr_username
    ,
    size_t		arg_len_username
    ,
    char *		arg_ptr_password
    ,
    size_t		arg_len_password
    )
__PROTO_END__
{
    char *	auth_ptr	;
    int		rc		;
    char	auth_decoded	[256];


    //------------------------------------------
    // Get the HTTP authorization header string.
    //------------------------------------------
    if ( ! arg_authstr && ! ( arg_authstr = getenv( "HTTP_AUTHORIZATION" ) ) ) return -1;

    //--------------------------------------------------
    // Make sure the HTTP authorization type is "Basic".
    //--------------------------------------------------
    if ( tolower( arg_authstr[0] ) != 'b' ||
	 tolower( arg_authstr[1] ) != 'a' ||
	 tolower( arg_authstr[2] ) != 's' ||
	 tolower( arg_authstr[3] ) != 'i' ||
	 tolower( arg_authstr[4] ) != 'c' ||
	 ! isspace( arg_authstr[5] ) ) {
	return -1;
    }

    //----------------------------------
    // Find the data part and decode it.
    //----------------------------------
    arg_authstr += 6;
    while ( * arg_authstr && * arg_authstr == ' ' ) ++ arg_authstr;
    str_cpy_decode_base64( auth_decoded, 256, arg_authstr );
    auth_ptr = auth_decoded;
    rc = 0;

    //---------------------------------------
    // Skip to the beginning of the username.
    //---------------------------------------
    while ( isspace( * auth_ptr ) ) ++ auth_ptr;
    if ( ! * auth_ptr ) return -1;

    //------------------------------------------
    // Copy the username to the caller location.
    //------------------------------------------
    while ( * auth_ptr && * auth_ptr != ':' ) {
	if ( arg_ptr_username ) {
	    if ( arg_len_username > 0 ) {
		* arg_ptr_username = * auth_ptr;
		++ arg_ptr_username;
		-- arg_len_username;
	    } else {
		arg_ptr_username = NULL;
		rc |= 1;
	    }
	}
	++ auth_ptr;
    }
    if ( arg_ptr_username ) * arg_ptr_username = 0;

    //---------------------------------------
    // Skip to the beginning of the password.
    //---------------------------------------
    if ( * auth_ptr != ':' ) return ( rc | 4 );
    ++ auth_ptr;

    //------------------------------------------
    // Copy the password to the caller location.
    //------------------------------------------
    while ( * auth_ptr ) {
	if ( arg_ptr_password ) {
	    if ( arg_len_password > 0 ) {
		* arg_ptr_password = * auth_ptr;
		++ arg_ptr_password;
		-- arg_len_password;
	    } else {
		arg_ptr_password = NULL;
		rc |= 2;
	    }
	}
	++ auth_ptr;
    }
    if ( arg_ptr_password ) * arg_ptr_password = 0;

    //-------------------------
    // Return the final status.
    //-------------------------
    return rc;
}

