README.auth_mysql010064400022410000017000000026130635421355200141550ustar00yjjusers00002430000003 This package is an NSAPI plugin function to authenticate users against an MYSQL table. It is for HTTP "Basic" authentication and gets the user/password information from the "Authorization:" header. This package does not include any tool for record input -- assuming you have other tools to do this. You may want to modify the code and Makefile to suit your system: 1) The code assumes a table structure create table USERS ( user char(32), password char(32), usergroup char(32), primary key(user) ) You may modify the auth_mysql.c to accomodate your own table structure. 2) The password is encrypted in Unix password style. If you have something different, you may want to change the auth_mysql.c code. 3) Modify the Makefile.mysql variables: CC=Your_C_Compiler NS_INCLUDE=Your_NSAPI_header_file_directory MYSQL=MySQL directory. After this, you can compile and install the function: 1) Compile % make -f Makefile.mysql 2) Modify your Netscape server configuration file: At the beginning of obj.conf add *Init fn=load-modules shlib=auth_mysql.so funcs=auth_mysql Inside an object in obj.conf: *AuthTrans fn=auth_mysql auth-type="basic" mysql_db=MYDB mysql_tb="user_records" \ mysql_host="localhost" [mysql_user=ME] [mysql_pw=PASSWORD] PathCheck realm="mysql" fn="require-auth" [auth-users=(USER1|USER2...)] \ auth-type="basic" 3) Save obj.conf and start your server. auth_mysql.c010064400022410000017000000222220634364704300134440ustar00yjjusers00002430000003/* * Copyright (c) 1997. Author: Yuan John Jiang */ /* * auth_mysql.c: NSAPI function to authenticate (BASIC) users * against MYSQL tables.. * V 0.8Alpha MySQL socket/connection is opened/closed for * each Request. Maybe enhanced to use a pool of * connections later on. */ /* ---------------------------- auth_mysql usage ------------------------ * * At the beginning of obj.conf: *Init fn=load-modules shlib=auth_mysql.so funcs=auth_mysql * * Inside an object in obj.conf: *AuthTrans fn=auth_mysql auth-type="basic" mysql_db=MYDB mysql_tb="user_records" \ * mysql_host="localhost" [mysql_user=ME] [mysql_pw=PASSWORD] * *PathCheck realm="mysql" fn="require-auth" [auth-users=(USER1|USER2...)] * auth-type="basic" * *---------------------------- User table ------------------------------- * You may modify this section according to your table * create table USERS ( user char(32), password char(32), usergroup char(32), primary key(user) ) */ #include "mysql.h" #define GET_USER "select password, usergroup from %s where user='%s'" /*------------------------------------------------------------------------*/ #include /* ------------------------------------------------------------------------ * * The following three are standard headers for SAFs. They're used to * get the data structures and prototypes needed to declare and use SAFs. */ #define net_read ns_net_read #define net_write ns_net_write #include "base/pblock.h" #include "base/session.h" #include "frame/req.h" #include "frame/protocol.h" #include "frame/log.h" #ifdef XP_WIN32 #define NSAPI_PUBLIC __declspec(dllexport) #else /* !XP_WIN32 */ #define NSAPI_PUBLIC #endif /* !XP_WIN32 */ /*************************************************************/ NSAPI_PUBLIC int auth_mysql(pblock *param, Session *sn, Request *rq) { int ret=REQ_NOACTION; /* Parameters given by obj.conf */ char *group = NULL; char *mysql_db = pblock_findval("mysql_db", param); char *mysql_tb = pblock_findval("mysql_tb", param); char *mysql_host = pblock_findval("mysql_host", param); char *mysql_user = pblock_findval("mysql_user", param); char *mysql_pw = pblock_findval("mysql_pw", param); /* Authentication input */ char *auth = pblock_findval("authorization", rq->headers); /* working variables */ char *auth_dec=NULL,*user,*pw,*pw_crypt,*pw_r,*t; int uudecode(char *, char * ); /* MYSQL variables */ MYSQL db_sock; MYSQL_RES *db_res; MYSQL_ROW db_row; int num_fields; char query[256]; /***** check configuration *****/ /* get user:pw */ if(auth!=NULL) { if( (t=strstr(auth,"Basic "))!=NULL ) { if(t!=auth) auth=t; /* skip spaces */ /* auth_dec holds the decoded authentication info */ auth_dec = (char *) MALLOC( sizeof(char *)*sizeof(auth) ); uudecode(auth+6,auth_dec); if( (t=strchr(auth_dec,':'))!=NULL ) { t[0]='\0'; pw=t+1; } else pw=auth_dec+strlen(auth_dec); user=auth_dec; ret=REQ_PROCEED; } } else return ret; if( (!mysql_db)||(strlen(mysql_db)==0) ) { log_error(LOG_MISCONFIG, "auth_mysql", sn, rq, "Configuration: fn=auth_pw mysql_db=DBNAME mysql_tb=TABLENAME mysql_host=HOST"); /* When we abort, the default status code is 500 Server Error */ return REQ_ABORTED; } /* Check against our passwd */ if( (ret==REQ_PROCEED)&&(mysql_tb!=NULL) ) { ret=REQ_NOACTION; /* set default */ if( mysql_connect(&db_sock, mysql_host, mysql_user, mysql_pw) ) { if( !mysql_select_db(&db_sock, mysql_db) ) { if(strlen(mysql_tb)+strlen(user) < 64 ) sprintf(query, GET_USER, mysql_tb, user ); else query[0]='\0'; if( (!mysql_query(&db_sock, query)) &&(db_res=mysql_store_result(&db_sock)) &&(num_fields=mysql_num_fields(db_res)) &&(db_row=mysql_fetch_row(db_res)) ) { pw_r=db_row[0]; pw_crypt = crypt(pw, pw_r); if( strcmp(pw_crypt, pw_r) == 0 ) { /* authenticated */ param_free(pblock_remove("auth-type", rq->vars)); pblock_nvinsert("auth-type", "basic", rq->vars); param_free(pblock_remove("auth-user", rq->vars)); pblock_nvinsert("auth-user", user, rq->vars); if(num_fields>1) { param_free(pblock_remove("auth-group", rq->vars)); pblock_nvinsert("auth-group", db_row[1], rq->vars); } ret=REQ_PROCEED; } /* pw correct */ } /* query ok */ else fprintf(stderr, "query error: %s\n", mysql_error(&db_sock)); mysql_free_result(db_res); } /* DB connect ok */ else fprintf(stderr, "query error: %s\n", mysql_error(&db_sock)); } else fprintf(stderr, "query error: %s\n", mysql_error(&db_sock)); mysql_close(&db_sock); } /* input ok */ return ret; } /* From Apache source code */ /* $Id: auth_mysql.c,v 1.1 1997/05/30 22:00:24 yjj Exp yjj $ * ==================================================================== * Copyright (c) 1995 The Apache Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. * * 5. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see . * */ /* aaaack but it's fast and const should make it shared text page. */ static const int pr2six[256]={ 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, 64,64,64,62,64,64,64,63,52,53,54,55,56,57,58,59,60,61,64,64, 64,64,64,64,64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 15,16,17,18,19,20,21,22,23,24,25,64,64,64,64,64,64,26,27,28, 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48, 49,50,51,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64 }; /* modified Apache code */ int uudecode(char *bufcoded,char *bufplain) /* bufout is created. Remember to free it! */ { int nbytesdecoded; unsigned char *bufin; unsigned char *bufout; int nprbytes; /* Strip leading whitespace. */ while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++; /* Figure out how many characters are in the input buffer. * Allocate this many from the per-transaction pool for the result. */ bufin = (unsigned char *)bufcoded; while(pr2six[*(bufin++)] <= 63) ; nprbytes = (char *)bufin - bufcoded - 1; nbytesdecoded = ((nprbytes+3)/4) * 3; bufout = (unsigned char *)bufplain; bufin = (unsigned char *)bufcoded; while (nprbytes > 0) { *(bufout++) = (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); *(bufout++) = (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); *(bufout++) = (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); bufin += 4; nprbytes -= 4; } if(nprbytes & 03) { if(pr2six[bufin[-2]] > 63) nbytesdecoded -= 2; else nbytesdecoded -= 1; } bufplain[nbytesdecoded] = '\0'; return nbytesdecoded; } 32 */ #define NSAPI_PUBLIC #endif /* !XP_WIN32 */ /*************************************************************/ NSAPI_PUBLIC int auth_mysql(pblock *param, Session *sn, Request *rq) { int ret=REQ_NOACTION; /* Parameters given by obj.conf */ char *group = NULL; char *mysql_db = pblock_findval("mysql_db", param); char *mysql_tb = pblock_findval("mysql_tb", parMakefile.mysql010075500022410000017000000024240634333524500137210ustar00yjjusers00002430000003# Defines for example NSAPI programs running under SOLARIS #MAKE = make CC="$(CC)" AS="$(AS)" LD="$(LD)" AR="$(AR)" CPP="$(CPP)" CPP=/lib/cpp AR=/bin/ar CC=gcc CC_CMD=gcc LD_SHAREDCMD=ld -G INC_LOC = . SRC = auth_mysql.c OBJS = auth_mysql.o TARGET = auth_mysql.so ############################## # NS stuff ############################## INCLUDEDIR=../include NS_INCS=-I$(INCLUDEDIR) -I$(INCLUDEDIR)/base -I$(INCLUDEDIR)/frame NS_DEFS=-DMCC_HTTPD -DXP_UNIX -DSOLARIS NS_CFLAGS = $(NS_INCS) $(NS_DEFS) NS_LDFLAGS = ############################## # MYSQL stuff ############################## # # MYSQL related includes and libraries # # MYSQL_LIBPATH = $(MYSQL)/lib MYSQL_LIBS = -B static -lmysqlclient -lgcc # # The source and include files # MYSQL_INC = $(MYSQL)/include MYSQL_INCS = -I$(MYSQL_INC) #GCCFLAGS = -ansi -pedantic -Wall -Wtraditional -Wshadow -Wpointer-arith -pipe MYSQL_CFLAGS = $(MYSQL_INCS) $(DEFS) MYSQL_LDFLAGS = -L$(MYSQL_LIBPATH) # # ALL CFLAGS = $(NS_CFLAGS) $(MYSQL_CFLAGS) LIBS = -lsocket -lnsl -lc $(NS_LIBS) $(MYSQL_LIBS) LDFLAGS = -G -B symbolic $(NS_LDFLAGS) $(MYSQL_LDFLAGS) all: $(TARGET) $(TARGET): $(OBJS) $(LD) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) .c.o: $(CC) $(CFLAGS) -c -g $< clean: rm $(OBJS) $(SO_DIR)/$(TARGET) sccs_clean: sccs clean