Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
John McEleney
/
mailutils
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit
09b35a6e
...
09b35a6eb4eb31497bd7dc1495b6178a26d832df
authored
2002-08-13 13:25:44 +0000
by
Sergey Poznyakoff
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
New file. Basic authentication/authorization functions.
1 parent
cc9ac172
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
455 additions
and
0 deletions
mailbox/mu_auth.c
mailbox/mu_auth.c
0 → 100644
View file @
09b35a6
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 2002 Free Software Foundation, Inc.
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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#ifdef HAVE_SHADOW_H
# include <shadow.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_SECURITY_PAM_APPL_H
# include <security/pam_appl.h>
#endif
#ifdef HAVE_CRYPT_H
# include <crypt.h>
#endif
#include <mailutils/list.h>
#include <mailutils/iterator.h>
#include <mailutils/mailbox.h>
#include <mailutils/argp.h>
#include <mailutils/mu_auth.h>
#include <mailutils/error.h>
#define DEBUG(c) do { printf c; printf("\n"); } while (0)
/* memory allocation */
int
mu_auth_data_alloc
(
struct
mu_auth_data
**
ptr
,
const
char
*
name
,
const
char
*
passwd
,
uid_t
uid
,
gid_t
gid
,
const
char
*
gecos
,
const
char
*
dir
,
const
char
*
shell
,
const
char
*
mailbox
,
int
change_uid
)
{
size_t
size
=
sizeof
(
**
ptr
)
+
strlen
(
name
)
+
1
+
strlen
(
passwd
)
+
1
+
strlen
(
gecos
)
+
1
+
strlen
(
dir
)
+
1
+
strlen
(
shell
)
+
1
+
strlen
(
mailbox
)
+
1
;
char
*
p
;
*
ptr
=
malloc
(
size
);
if
(
!*
ptr
)
return
1
;
p
=
(
char
*
)(
*
ptr
+
1
);
#define COPY(f) \
(*ptr)->##f = p; \
strcpy (p, ##f); \
p += strlen (##f) + 1
COPY
(
name
);
COPY
(
passwd
);
COPY
(
gecos
);
COPY
(
dir
);
COPY
(
shell
);
COPY
(
mailbox
);
(
*
ptr
)
->
uid
=
uid
;
(
*
ptr
)
->
gid
=
gid
;
(
*
ptr
)
->
change_uid
=
change_uid
;
return
0
;
}
void
mu_auth_data_free
(
struct
mu_auth_data
*
ptr
)
{
free
(
ptr
);
}
/* Generic functions */
struct
auth_stack_entry
{
char
*
name
;
/* for diagnostics purposes */
mu_auth_fp
fun
;
void
*
func_data
;
};
void
mu_insert_stack_entry
(
list_t
*
pflist
,
struct
auth_stack_entry
*
entry
)
{
if
(
!*
pflist
&&
list_create
(
pflist
))
return
;
list_append
(
*
pflist
,
entry
);
}
int
mu_auth_runlist
(
list_t
flist
,
void
*
return_data
,
void
*
key
,
void
*
data
)
{
int
rc
=
1
;
iterator_t
itr
;
if
(
iterator_create
(
&
itr
,
flist
)
==
0
)
{
struct
auth_stack_entry
*
ep
;
for
(
iterator_first
(
itr
);
rc
&&
!
iterator_is_done
(
itr
);
iterator_next
(
itr
))
{
iterator_current
(
itr
,
(
void
**
)
&
ep
);
DEBUG
((
"trying %s"
,
ep
->
name
));
rc
=
ep
->
fun
(
return_data
,
key
,
ep
->
func_data
,
data
);
DEBUG
((
"Result: %d"
,
rc
));
}
iterator_destroy
(
&
itr
);
}
return
rc
;
}
int
mu_auth_nosupport
(
void
*
usused_return_data
,
void
*
unused_key
,
void
*
unused_func_data
,
void
*
unused_call_data
)
{
errno
=
ENOSYS
;
return
1
;
}
/* II. Authorization: retrieving information about user */
static
list_t
mu_auth_by_name_list
;
static
list_t
mu_auth_by_uid_list
;
struct
mu_auth_data
*
mu_get_auth_by_name
(
const
char
*
username
)
{
struct
mu_auth_data
*
auth
=
NULL
;
DEBUG
((
"mu_get_auth_by_name"
));
mu_auth_runlist
(
mu_auth_by_name_list
,
&
auth
,
username
,
NULL
);
return
auth
;
}
struct
mu_auth_data
*
mu_get_auth_by_uid
(
uid_t
uid
)
{
struct
mu_auth_data
*
auth
=
NULL
;
DEBUG
((
"mu_get_auth_by_uid"
));
mu_auth_runlist
(
mu_auth_by_uid_list
,
&
auth
,
&
uid
,
NULL
);
return
auth
;
}
/* III. Authentication: determining the authenticity of a user */
static
list_t
mu_authenticate_list
;
int
mu_authenticate
(
struct
mu_auth_data
*
auth_data
,
char
*
pass
)
{
DEBUG
((
"mu_authenticate"
));
return
mu_auth_runlist
(
mu_authenticate_list
,
NULL
,
auth_data
,
pass
);
}
/* IV. Implementation functions */
/* IV a. Authorization */
/* Modules & configuration */
#define ARG_AUTHORIZATION 1
#define ARG_AUTHENTICATION 2
static
error_t
mu_auth_argp_parser
__P
((
int
key
,
char
*
arg
,
struct
argp_state
*
state
));
/* Options used by programs that use extended authentication mechanisms. */
static
struct
argp_option
mu_auth_argp_option
[]
=
{
{
"authentication"
,
ARG_AUTHENTICATION
,
"MODLIST"
,
0
,
"Set list of modules to be used for authentication"
,
0
},
{
"authorization"
,
ARG_AUTHORIZATION
,
"MODLIST"
,
0
,
"Set list of modules to be used for authorization"
,
0
},
{
NULL
,
0
,
NULL
,
0
,
NULL
,
0
}
};
struct
argp
mu_auth_argp
=
{
mu_auth_argp_option
,
mu_auth_argp_parser
,
};
struct
argp_child
mu_auth_argp_child
=
{
&
mu_auth_argp
,
0
,
"Authentication options"
,
0
};
static
void
mu_auth_finish_setup
__P
((
void
));
static
error_t
mu_auth_argp_parser
(
int
key
,
char
*
arg
,
struct
argp_state
*
state
)
{
switch
(
key
)
{
/* authentication */
case
ARG_AUTHORIZATION
:
mu_authorization_add_module_list
(
arg
);
break
;
case
ARG_AUTHENTICATION
:
mu_authentication_add_module_list
(
arg
);
break
;
case
ARGP_KEY_FINI
:
mu_auth_finish_setup
();
break
;
default:
return
ARGP_ERR_UNKNOWN
;
}
return
0
;
}
struct
_module_handler
{
struct
auth_stack_entry
authenticate
;
struct
auth_stack_entry
auth_by_name
;
struct
auth_stack_entry
auth_by_uid
;
};
static
list_t
module_handler_list
;
void
mu_auth_register_module
(
struct
mu_auth_module
*
mod
)
{
struct
_module_handler
*
entry
;
if
(
mod
->
argp
)
{
int
i
;
struct
argp_child
*
cp
;
if
(
mu_auth_argp
.
children
)
{
struct
argp_child
*
tmp
;
for
(
i
=
0
;
mu_auth_argp
.
children
[
i
].
argp
;
i
++
)
;
tmp
=
realloc
((
void
*
)
mu_auth_argp
.
children
,
(
i
+
1
)
*
sizeof
(
mu_auth_argp
.
children
[
0
]));
mu_auth_argp
.
children
=
tmp
;
}
else
{
mu_auth_argp
.
children
=
calloc
(
2
,
sizeof
(
mu_auth_argp
.
children
[
0
]));
i
=
0
;
}
if
(
!
mu_auth_argp
.
children
)
{
mu_error
(
"not enough memory"
);
exit
(
1
);
}
cp
=
(
struct
argp_child
*
)
&
mu_auth_argp
.
children
[
i
];
cp
->
argp
=
mod
->
argp
;
cp
->
flags
=
0
;
cp
->
header
=
NULL
;
cp
->
group
=
0
;
/* FIXME */
cp
++
;
cp
->
argp
=
NULL
;
}
if
(
!
module_handler_list
&&
list_create
(
&
module_handler_list
))
abort
();
entry
=
malloc
(
sizeof
(
*
entry
));
if
(
!
entry
)
{
mu_error
(
"not enough memory"
);
exit
(
1
);
}
entry
->
authenticate
.
name
=
mod
->
name
;
entry
->
authenticate
.
fun
=
mod
->
authenticate
;
entry
->
authenticate
.
func_data
=
mod
->
authenticate_data
;
entry
->
auth_by_name
.
name
=
mod
->
name
;
entry
->
auth_by_name
.
fun
=
mod
->
auth_by_name
;
entry
->
auth_by_name
.
func_data
=
mod
->
auth_by_name_data
;
entry
->
auth_by_uid
.
name
=
mod
->
name
;
entry
->
auth_by_uid
.
fun
=
mod
->
auth_by_uid
;
entry
->
auth_by_uid
.
func_data
=
mod
->
auth_by_uid_data
;
list_append
(
module_handler_list
,
entry
);
}
static
struct
_module_handler
*
_locate
(
const
char
*
name
)
{
struct
_module_handler
*
rp
=
NULL
;
iterator_t
itr
;
if
(
iterator_create
(
&
itr
,
module_handler_list
)
==
0
)
{
struct
_module_handler
*
p
;
for
(
iterator_first
(
itr
);
!
rp
&&
!
iterator_is_done
(
itr
);
iterator_next
(
itr
))
{
iterator_current
(
itr
,
(
void
**
)
&
p
);
if
(
strcmp
(
p
->
authenticate
.
name
,
name
)
==
0
)
rp
=
p
;
}
iterator_destroy
(
&
itr
);
}
return
rp
;
}
static
void
_add_module_list
(
const
char
*
modlist
,
int
(
*
fun
)(
const
char
*
name
))
{
char
*
sp
,
*
name
;
for
(
name
=
strtok_r
((
char
*
)
modlist
,
":"
,
&
sp
);
name
;
name
=
strtok_r
(
NULL
,
":"
,
&
sp
))
{
if
(
fun
(
name
))
{
if
(
errno
==
ENOENT
)
mu_error
(
"no such module: %s"
,
name
);
else
mu_error
(
"failed to add module %s: %s"
,
strerror
(
errno
));
exit
(
1
);
}
}
}
int
mu_authorization_add_module
(
const
char
*
name
)
{
struct
_module_handler
*
mod
=
_locate
(
name
);
if
(
!
mod
)
{
errno
=
ENOENT
;
return
1
;
}
mu_insert_stack_entry
(
&
mu_auth_by_name_list
,
&
mod
->
auth_by_name
);
mu_insert_stack_entry
(
&
mu_auth_by_uid_list
,
&
mod
->
auth_by_uid
);
return
0
;
}
void
mu_authorization_add_module_list
(
const
char
*
modlist
)
{
_add_module_list
(
modlist
,
mu_authorization_add_module
);
}
int
mu_authentication_add_module
(
const
char
*
name
)
{
struct
_module_handler
*
mod
=
_locate
(
name
);
if
(
!
mod
)
{
errno
=
ENOENT
;
return
1
;
}
mu_insert_stack_entry
(
&
mu_authenticate_list
,
&
mod
->
authenticate
);
return
0
;
}
void
mu_authentication_add_module_list
(
const
char
*
modlist
)
{
_add_module_list
(
modlist
,
mu_authentication_add_module
);
}
/* ************************************************************************ */
void
mu_auth_finish_setup
()
{
iterator_t
itr
;
if
(
!
mu_authenticate_list
)
{
if
(
iterator_create
(
&
itr
,
module_handler_list
)
==
0
)
{
struct
_module_handler
*
mod
;
for
(
iterator_first
(
itr
);
!
iterator_is_done
(
itr
);
iterator_next
(
itr
))
{
iterator_current
(
itr
,
(
void
**
)
&
mod
);
mu_insert_stack_entry
(
&
mu_authenticate_list
,
&
mod
->
authenticate
);
}
iterator_destroy
(
&
itr
);
}
}
if
(
!
mu_auth_by_name_list
)
{
if
(
iterator_create
(
&
itr
,
module_handler_list
)
==
0
)
{
struct
_module_handler
*
mod
;
for
(
iterator_first
(
itr
);
!
iterator_is_done
(
itr
);
iterator_next
(
itr
))
{
iterator_current
(
itr
,
(
void
**
)
&
mod
);
mu_insert_stack_entry
(
&
mu_auth_by_name_list
,
&
mod
->
auth_by_name
);
mu_insert_stack_entry
(
&
mu_auth_by_uid_list
,
&
mod
->
auth_by_uid
);
}
iterator_destroy
(
&
itr
);
}
}
}
void
mu_auth_init
()
{
if
(
mu_register_capa
(
"auth"
,
&
mu_auth_argp_child
))
{
mu_error
(
"INTERNAL ERROR: cannot register argp capability auth"
);
abort
();
}
}
Please
register
or
sign in
to post a comment