[En-Nut-Discussion] HTTP password protection - better solution
Peter Sodermanns
peter.sodermanns at aixcon.de
Tue Aug 29 13:23:32 CEST 2006
Hi all,
as Edwin pointed out, my first routine was buggy because of access to
already freed objects.
Now - after several tests - I come up with a hopefully better solution.
In httpd.h I changed the declaration of AUTHINFO into fixed size in
order to free allocated memory in NutClearAuth(). A directory name can
have up to 255 characters, for username and password I provided 20 char,
each.
httpd.h:
---------------------------------------------------------------------
/*
* Authorization
*/
typedef struct _AUTHINFO AUTHINFO;
/*!
* \struct _AUTHINFO httpd.h pro/httpd.h
* \brief HTTP authorization information structure.
*/
struct _AUTHINFO {
AUTHINFO *auth_next; /*!< \brief Link to next AUTHINFO
structure */
char auth_dirname[256]; /*!< \brief Pathname of protected
directory */
char auth_login[42]; /*!< \brief Login user and password,
separated by a colon. 20 characters each. */
};
__BEGIN_DECLS
extern int NutHttpAuthValidate(REQUEST * req);
extern int NutRegisterAuth(CONST char *dirname, CONST char *login);
extern int NutClearAuth(void);
extern int NutChangeAuth(CONST char *dirname, CONST char *oldlogin,
CONST char *newlogin);
__END_DECLS
---------------------------------------------------------------------
The clearing function now walks through the list of authorization
entries to the end and starts from there with freeing, since new entries
are added at begin of the list. I tested that with as much entries as
the heap could provide (23) and even more (113) with reduced string length.
Also I added another function NutChangeAuth() to change an existing
entry. It takes directory, old name/password and new name/password as
input and replaces name/password if the entry is found.
To complete user management, a function to remove a single entry would
be useful, but that's a future task.
auth.c:
---------------------------------------------------------------------
/*!
* \brief Clear all authorization entries.
*/
int NutClearAuth(void)
{
AUTHINFO *idx;
u_char n, m, count;
/*
* any entries at all?
*/
if (authList) {
count = 0;
idx = authList;
/*
* count entries
*/
while (idx) {
count++;
idx = idx->auth_next;
}
/*
* delete counted number of entries
*/
for (n=count; n>0;n--) {
idx = authList;
/*
* walk to end of list
*/
for (m=1; m<n;m++) {
idx = idx->auth_next;
}
/*
* free last item
*/
NutHeapFree(idx);
idx = 0;
}
/*
* indicate empty list
*/
authList = 0;
}
return 0;
}
/*!
* \brief Change name and/or password for an existing authorization entry.
*
* \param dirname Name of the directory to protect.
* \param oldlogin Current login (name:password).
* \param newlogin Changed login (name:password).
*
* \return 0 on success, -1 otherwise.
*/
int NutChangeAuth(CONST char *dirname, CONST char *oldlogin, CONST char
*newlogin)
{
AUTHINFO *auth;
auth = (NutHttpAuthLookup(dirname, oldlogin));
/*
* found that entry?
*/
if (auth) {
strncpy(auth->auth_login, newlogin, 41);
return 0;
} else {
return -1;
}
}
/*!
* \brief Register an authorization entry.
*
* Protect a specified directory from unauthorized access.
*
* \warning Directories not registered by this function are
* accessible by anyone.
*
* \param dirname Name of the directory to protect.
* Max length of dirname is 255 characters.
* \param login Required login to access this directory. This
* string must contain a user name, followed by
* a colon followed by an uncrypted password.
* Max length of login is 41 characters.
*
* \return 0 on success, -1 otherwise.
*/
int NutRegisterAuth(CONST char *dirname, CONST char *login)
{
AUTHINFO *auth;
if ((auth = NutHeapAlloc(sizeof(AUTHINFO))) == 0)
return -1;
auth->auth_next = authList;
strncpy(auth->auth_dirname, dirname, 255);
strncpy(auth->auth_login, login, 41);
authList = auth;
return 0;
}
------------------------------------------------------------------
In my application this works without problem.
If you think it's ok now, too, the modification can be put into CVS.
Kind regards
Peter
More information about the En-Nut-Discussion
mailing list