add openvpn username/password auth
[tomato.git] / release / src / router / openvpn_plugin_auth_nvram / openvpn_plugin_auth_nvram.c
blob360c80e8703510a8b142de458e049cdec9bdbae3
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <openvpn-plugin.h>
5 #include <bcmnvram.h>
6 #define NVRAM_KEY_MAX_LEN 32
8 struct nvram_context {
9 char nvarm_key[NVRAM_KEY_MAX_LEN + 1];
11 static const char *get_env(const char *key, const char *env[]) {
12 int i;
14 if (!env)
15 return (NULL);
17 for (i = 0; env[i]; i++) {
18 int keylen = strlen(key);
20 if (keylen > strlen(env[i]))
21 continue;
23 if (!strncmp(key, env[i], keylen)) {
24 const char *p = env[i] + keylen;
25 if (*p == '=')
26 return (p + 1);
30 return (NULL);
32 /**
33 find password ptr of username.
35 static int nv_verify_pass(const char *nv_key,const char *username,const char *password) {
36 int i;
37 if(!nv_key || !username || !password)
38 return 0;
39 const char *nv = nvram_safe_get(nv_key);
40 const char *start = nv;
41 int to_verify_len = strlen(username) + strlen(password) + 3; // 1<username<password, add 3 bytes:'1 < <'
42 char *to_verify = malloc(to_verify_len + 1);
43 sprintf(to_verify,"1<%s<%s",username,password);//snprintf is not necessary.
44 for(i = 0 ; ;i++){
45 if(nv[i] == '>'){
46 if(to_verify_len == nv + i - start && !memcmp(to_verify,start,to_verify_len)){
47 free(to_verify);
48 return 1;
50 start = nv + i + 1;
52 else if(nv[i] == 0){
53 free(to_verify);
54 return 0;
57 free(to_verify);
58 return 0;
60 int string_array_len (const char *array[])
62 int i = 0;
63 if (array)
65 while (array[i])
66 ++i;
68 return i;
70 OPENVPN_EXPORT openvpn_plugin_handle_t openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[]) {
71 struct nvram_context *context = calloc(1,sizeof(struct nvram_context));
72 *type_mask = OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY);
73 if (string_array_len (argv) < 2) {
74 fprintf (stderr, "AUTH-NVRAM: need NVRAM KEY parameter\n");
75 goto error;
77 else {
78 strncpy(context->nvarm_key,argv[1],NVRAM_KEY_MAX_LEN);
80 return (openvpn_plugin_handle_t) context;
81 error:
82 if(context) free(context);
83 return NULL;
85 OPENVPN_EXPORT void openvpn_plugin_close_v1(openvpn_plugin_handle_t handle)
87 free (handle);
89 OPENVPN_EXPORT int openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]) {
90 struct nvram_context *context = (struct nvram_context *)handle;
91 if (type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY){
92 const char *username = get_env ("username", envp);
93 const char *password = get_env ("password", envp);
94 if(username && password && nv_verify_pass(context->nvarm_key,username,password)){
95 return OPENVPN_PLUGIN_FUNC_SUCCESS;
98 return OPENVPN_PLUGIN_FUNC_ERROR;