auth.h \
auth-pam.c \
auth-krb5.c \
+ auth-unix.c \
client.c \
client.h \
net.c \
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;
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;
--- /dev/null
+/*
+ * 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 <pwd.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <string.h>
+#include <wchar.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#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)
{
}
-static int authless_authenticate(struct authhandle *auth, char *data)
+static int authless_authenticate(struct authhandle *auth, struct socket *sk, char *data)
{
return(AUTH_SUCCESS);
}
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)
#include <wchar.h>
+#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 */
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
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);
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;
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);
return;
}
free(buf);
- switch(authenticate(data->auth, NULL))
+ switch(authenticate(data->auth, sk, NULL))
{
case AUTH_SUCCESS:
data->userinfo = finduser(data->username);
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);
},
#endif
{
+ .name = L"unix",
+ .process = process_authless,
+ .init = NULL,
+ .release = NULL
+ },
+ {
.name = L"authless",
.process = process_authless,
.init = NULL,