i am use openvpn 2.0.7,and use *auth-user-pass-verify to auth userlogin.*
*but i have a problems!*
**
*if openvpn server "use auth-user-pass-verify ",can't disable a user
name duplicate
login in same time.*
**
*my auth plugin src is below:*
**
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define _XOPEN_SOURCE
#include <unistd.h>
#include <crypt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "openvpn-plugin.h"
#define MAX_USER_LEN 15
#define MAX_PASS_LEN 47
#define MAX_USERS 100
struct user
{
char name[MAX_USER_LEN + 1];
char pass[MAX_PASS_LEN + 1];
int online;
};
/*
* Our context, where we keep our state.
*/
struct plugin_context
{
const char *file_path;
time_t mtime;
int num_users;
struct user users[MAX_USERS];
int fs;
};
/**
* 检验客户端输入的用户名和密码是否正确
*
* @return 非 0 正确;0 错误
*/
static int valid_login(struct plugin_context *ct,const char *user,const char
*pass)
{
int i;
FILE *fp;
struct user *users = ct->users;
if ( user == NULL || pass == NULL )
{
return 0;
}
for (i=0; i < ct->num_users; i++)
{
if ( strcmp(user,users[i].name) == 0 ) // && ( users[i].online ==
0))
{
//char *result = crypt(pass,users[i].pass);
//return (strcmp(result,users[i].pass) == 0);
//users[i].online =1;
fp = fopen("/home/wsgtrsys/openvpn/log/login","a");
if (ct->fs == 0)
{
fclose(fp);
fp = fopen("/home/wsgtrsys/openvpn/log/login","w");
ct->fs = 1;
}
fprintf(fp,user name is:%s\n,user);
fclose(fp);
return 1;
}
}
return 0;
}
/*
* Given an environmental variable name, search
* the envp array for its value, returning it
* if found or NULL otherwise.
*/
static const char *
get_env (const char *name, const char *envp[])
{
if (envp)
{
int i;
const int namelen = strlen (name);
for (i = 0; envp[i]; ++i)
{
if (!strncmp (envp[i], name, namelen))
{
const char *cp = envp[i] + namelen;
if (*cp == '=')
return cp + 1;
}
}
}
return NULL;
}
/**
* 读入帐号文件中的帐号
*/
static int read_users(struct plugin_context *ct)
{
int num;
FILE *fp;
struct stat st;
char buf[256];
if (ct == NULL || ct->file_path == NULL)
{
fprintf(stderr,"Arg check failed\n");
return -1;
}
if ( stat(ct->file_path,&st) < 0 )
{
perror("stat");
return -1;
}
if ( st.st_mtime <= ct->mtime )
{
return 0;
}
fp = fopen(ct->file_path,"r");
if (fp == NULL)
{
perror("fopen");
return -1;
}
num = 0;
while( fgets(buf,sizeof(buf),fp) )
{
char *p = strchr(buf,':');
if (p == NULL)
continue;
*p++ = '\0';
if ( strlen(buf) > MAX_USER_LEN )
{
fprintf(stderr,"Too long user: %s\n",buf);
continue;
}
if ( strlen(p) > MAX_PASS_LEN )
{
fprintf(stderr,"Too long pass: %s\n",p);
continue;
}
strcpy(ct->users[num].name,buf);
strcpy(ct->users[num].pass,p);
while ( (p = strrchr(ct->users[num].pass,'\n')) )
*p = '\0';
num++;
if (num >= MAX_USERS)
break;
}
fclose(fp);
ct->mtime = st.st_mtime;
ct->num_users = num;
return num;
}
OPENVPN_EXPORT openvpn_plugin_handle_t
openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const
char *envp[])
{
struct plugin_context *context;
if ( argv[1] == NULL )
{
fprintf(stderr,"Need u/p file argument\n");
return NULL;
}
/*
* Allocate our context
*/
context = (struct plugin_context *) calloc (1, sizeof (struct
plugin_context));
memset(context,0,sizeof(struct plugin_context));
context->file_path = argv[1];
if ( read_users(context) < 0 )
{
free(context);
fprintf(stderr,"Get users failed\n");
return NULL;
}
context->file_path = strdup(argv[1]);
/*
* We are only interested in intercepting the
* --auth-user-pass-verify callback.
*/
*type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY);
return (openvpn_plugin_handle_t) context;
}
OPENVPN_EXPORT int
openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type,
const char *argv[], const char *envp[])
{
struct plugin_context *context = (struct plugin_context *) handle;
/* get username/password from envp string array */
const char *username = get_env ("username", envp);
const char *password = get_env ("password", envp);
read_users(context);
/* check entered username/password against what we require */
if ( valid_login(context,username,password) )
return OPENVPN_PLUGIN_FUNC_SUCCESS;
else
return OPENVPN_PLUGIN_FUNC_ERROR;
}
OPENVPN_EXPORT void
openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle)
{
struct plugin_context *context = (struct plugin_context *) handle;
free((void*)context->file_path);
free (context);
}
#ifdef TEST
int main(int argc,const char **argv,const char **envp)
{
unsigned int type = 0;
openvpn_plugin_handle_t h;
h = openvpn_plugin_open_v1(&type,&argv[1],envp);
if (h == NULL)
{
fprintf(stderr,"openvpn_plugin_open_v1\n");
return -1;
}
if ( openvpn_plugin_func_v1(h,type,NULL,envp) ==
OPENVPN_PLUGIN_FUNC_SUCCESS )
{
puts("OK");
}
openvpn_plugin_close_v1(h);
return 0;
}
#endif