From 3616b334bc6426e973e08b612a5e8fd30ad80a5f Mon Sep 17 00:00:00 2001 From: fredrik Date: Wed, 11 Apr 2007 13:58:55 +0000 Subject: [PATCH] Add Unix authentication method. git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/doldaconnect@897 959494ce-11ee-0310-bf91-de5d638817bd --- daemon/Makefile.am | 1 + daemon/auth-krb5.c | 2 +- daemon/auth-pam.c | 2 +- daemon/auth-unix.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++ daemon/auth.c | 13 +++++-- daemon/auth.h | 8 +++-- daemon/ui.c | 6 ++-- lib/uimisc.c | 6 ++++ 8 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 daemon/auth-unix.c diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 306df3d..e4f0ea2 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -14,6 +14,7 @@ doldacond_SOURCES= main.c \ auth.h \ auth-pam.c \ auth-krb5.c \ + auth-unix.c \ client.c \ client.h \ net.c \ diff --git a/daemon/auth-krb5.c b/daemon/auth-krb5.c index 4a05e66..8f19956 100644 --- a/daemon/auth-krb5.c +++ b/daemon/auth-krb5.c @@ -266,7 +266,7 @@ static void setrenew(struct krb5data *data) data->renewtimer = timercallback(good, (void (*)(int, void *))renewcreds, data); } -static int krbauth(struct authhandle *auth, char *passdata) +static int krbauth(struct authhandle *auth, struct socket *sk, char *passdata) { int ret; struct krb5data *data; diff --git a/daemon/auth-pam.c b/daemon/auth-pam.c index b11825a..38aa7cf 100644 --- a/daemon/auth-pam.c +++ b/daemon/auth-pam.c @@ -197,7 +197,7 @@ static void pamauththread(struct authhandle *auth) data->validctxt = 0; } -static int pamauth(struct authhandle *auth, char *passdata) +static int pamauth(struct authhandle *auth, struct socket *sk, char *passdata) { struct pamdata *data; diff --git a/daemon/auth-unix.c b/daemon/auth-unix.c new file mode 100644 index 0000000..c90aba8 --- /dev/null +++ b/daemon/auth-unix.c @@ -0,0 +1,101 @@ +/* + * Dolda Connect - Modular multiuser Direct Connect-style client + * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com) + * + * 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 +*/ + +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "auth.h" +#include "utils.h" +#include "module.h" +#include "conf.h" + +struct unixdata { + char *username; +}; + +static int inithandle(struct authhandle *auth, char *username) +{ + struct unixdata *data; + + data = smalloc(sizeof(*data)); + memset(data, 0, sizeof(*data)); + data->username = sstrdup(username); + auth->mechdata = data; + return(0); +} + +static void release(struct authhandle *auth) +{ + struct unixdata *data; + + data = auth->mechdata; + free(data->username); + free(data); +} + +static int unixauth(struct authhandle *auth, struct socket *sk, char *passdata) +{ + struct passwd *pwd; + struct unixdata *data; + + data = auth->mechdata; + if((pwd = getpwnam(data->username)) == NULL) + return(AUTH_ERR); + if(sk->ucred.pid == 0) { + errno = EBADE; + return(AUTH_ERR); + } + if(pwd->pw_uid == sk->ucred.uid) + return(AUTH_SUCCESS); + auth->text = swcsdup(L"Unix credentials do not match supplied user name"); + return(AUTH_DENIED); +} + +static int available(struct socket *sk) +{ + return((sk->family == PF_UNIX) && (sk->ucred.pid != 0)); +} + +static struct authmech mechdesc = { + .inithandle = inithandle, + .release = release, + .authenticate = unixauth, + .available = available, + .name = L"unix", + .enabled = 1 +}; + +static int init(int hup) +{ + if(!hup) + regmech(&mechdesc); + return(0); +} + +static struct module me = { + .init = init, + .name = "auth-unix" +}; +MODULE(me) diff --git a/daemon/auth.c b/daemon/auth.c index c5aace0..83fc5aa 100644 --- a/daemon/auth.c +++ b/daemon/auth.c @@ -38,7 +38,7 @@ static void authless_release(struct authhandle *auth) { } -static int authless_authenticate(struct authhandle *auth, char *data) +static int authless_authenticate(struct authhandle *auth, struct socket *sk, char *data) { return(AUTH_SUCCESS); } @@ -112,11 +112,18 @@ struct authhandle *initauth(wchar_t *mechname, char *username) return(auth); } -int authenticate(struct authhandle *handle, char *data) +int authenticate(struct authhandle *handle, struct socket *sk, char *data) { if(handle->mech == NULL) return(AUTH_ERR); - return(handle->mech->authenticate(handle, data)); + return(handle->mech->authenticate(handle, sk, data)); +} + +int authavailable(struct authmech *mech, struct socket *sk) +{ + if(mech->available == NULL) + return(1); + return(mech->available(sk)); } int authrenewcred(struct authhandle *handle) diff --git a/daemon/auth.h b/daemon/auth.h index 0763841..27a828b 100644 --- a/daemon/auth.h +++ b/daemon/auth.h @@ -21,6 +21,8 @@ #include +#include "net.h" + #define AUTH_SUCCESS 0 /* Authentication successful and done */ #define AUTH_DENIED 1 /* Ultimately failed - reason in handle->text */ #define AUTH_PASS 2 /* Pass data - look in handle->prompt */ @@ -41,10 +43,11 @@ struct authmech wchar_t *name; int (*inithandle)(struct authhandle *handle, char *username); void (*release)(struct authhandle *handle); - int (*authenticate)(struct authhandle *handle, char *data); + int (*authenticate)(struct authhandle *handle, struct socket *sk, char *data); int (*renewcred)(struct authhandle *handle); int (*opensess)(struct authhandle *handle); int (*closesess)(struct authhandle *handle); + int (*available)(struct socket *sk); }; struct authhandle @@ -56,7 +59,7 @@ struct authhandle void *mechdata; }; -int authenticate(struct authhandle *handle, char *data); +int authenticate(struct authhandle *handle, struct socket *sk, char *data); struct authhandle *initauth(wchar_t *mechname, char *username); void authgethandle(struct authhandle *auth); void authputhandle(struct authhandle *auth); @@ -64,6 +67,7 @@ int authrenewcred(struct authhandle *handle); int authopensess(struct authhandle *handle); int authclosesess(struct authhandle *handle); void regmech(struct authmech *mech); +int authavailable(struct authmech *mech, struct socket *sk); extern struct authmech *mechs; diff --git a/daemon/ui.c b/daemon/ui.c index d77efa7..34eebc1 100644 --- a/daemon/ui.c +++ b/daemon/ui.c @@ -389,7 +389,7 @@ static void cmd_lsauth(struct socket *sk, struct uidata *data, int argc, wchar_t prev = NULL; for(mech = mechs; mech != NULL; mech = mech->next) { - if(mech->enabled) + if(mech->enabled && authavailable(mech, sk)) { if(prev != NULL) sq(sk, 1, L"200", prev->name, NULL); @@ -438,7 +438,7 @@ static void cmd_login(struct socket *sk, struct uidata *data, int argc, wchar_t return; } free(buf); - switch(authenticate(data->auth, NULL)) + switch(authenticate(data->auth, sk, NULL)) { case AUTH_SUCCESS: data->userinfo = finduser(data->username); @@ -512,7 +512,7 @@ static void cmd_pass(struct socket *sk, struct uidata *data, int argc, wchar_t * sq(sk, 0, L"507", L"Data not expected", NULL); return; } - switch(authenticate(data->auth, buf)) + switch(authenticate(data->auth, sk, buf)) { case AUTH_SUCCESS: data->userinfo = finduser(data->username); diff --git a/lib/uimisc.c b/lib/uimisc.c index 9cef69f..8252a7e 100644 --- a/lib/uimisc.c +++ b/lib/uimisc.c @@ -414,6 +414,12 @@ static struct authmech authmechs[] = }, #endif { + .name = L"unix", + .process = process_authless, + .init = NULL, + .release = NULL + }, + { .name = L"authless", .process = process_authless, .init = NULL, -- 2.11.0