diff --git a/Common/uthash/uthash.h b/Common/uthash/uthash.h index 76bdca641..6da43b4a2 100644 --- a/Common/uthash/uthash.h +++ b/Common/uthash/uthash.h @@ -25,11 +25,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define UTHASH_H #define UTHASH_VERSION 2.1.0 - +#ifdef __KERNEL__ +#include +#include +#include +#else #include /* memcmp, memset, strlen */ #include /* ptrdiff_t */ #include /* exit */ - +#endif /* These macros use decltype or the earlier __typeof GNU extension. As decltype is only available in newer compilers (VS2010 or gcc 4.3+ when compiling c++ source) this code uses whatever method is needed @@ -63,6 +67,7 @@ do { #endif /* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#ifndef __KERNEL__ #if defined(_WIN32) #if defined(_MSC_VER) && _MSC_VER >= 1600 #include @@ -78,13 +83,23 @@ typedef unsigned char uint8_t; typedef unsigned int uint32_t; typedef unsigned char uint8_t; #endif +#endif +#ifdef __KERNEL__ +#ifndef uthash_malloc +#define uthash_malloc(sz) kmalloc(sz, GFP_KERNEL) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) kfree(ptr) /* free fcn */ +#endif +#else #ifndef uthash_malloc #define uthash_malloc(sz) malloc(sz) /* malloc fcn */ #endif #ifndef uthash_free #define uthash_free(ptr,sz) free(ptr) /* free fcn */ #endif +#endif #ifndef uthash_bzero #define uthash_bzero(a,n) memset(a,'\0',n) #endif @@ -128,8 +143,12 @@ typedef unsigned char uint8_t; /* malloc failures result in lost memory, hash tables are unusable */ #ifndef uthash_fatal +#ifdef __KERNEL__ +#define uthash_fatal(msg) BUG() /* fatal OOM error */ +#else #define uthash_fatal(msg) exit(-1) /* fatal OOM error */ #endif +#endif #define HASH_RECORD_OOM(oomed) uthash_fatal("out of memory") #define IF_HASH_NONFATAL_OOM(x) diff --git a/ControlPlatform/aaa/aaa-shiro/impl/pom.xml b/ControlPlatform/aaa/aaa-shiro/impl/pom.xml index 71e68b848..1caffd9d3 100644 --- a/ControlPlatform/aaa/aaa-shiro/impl/pom.xml +++ b/ControlPlatform/aaa/aaa-shiro/impl/pom.xml @@ -251,6 +251,15 @@ and is available at http://www.eclipse.org/legal/epl-v10.html + + org.jacoco + jacoco-maven-plugin + + + **/*UserHandler.class + + + diff --git a/ControlPlatform/aaa/aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/H2StoreTest.java b/ControlPlatform/aaa/aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/H2StoreTest.java index 16a7b53c6..ab07cc305 100644 --- a/ControlPlatform/aaa/aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/H2StoreTest.java +++ b/ControlPlatform/aaa/aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/H2StoreTest.java @@ -102,9 +102,25 @@ public class H2StoreTest { assertNotNull(h2Store.readUser(user.getUserid())); user.setEnabled(false); assertNotNull(h2Store.updateUser(user)); + try{ + user.setEmail(getExpectName()); + h2Store.updateUser(user); + fail("update user error"); + }catch (IDMStoreException e){ + assertThat(e.getMessage(),containsString("SQL Exception")); + } assertFalse(h2Store.readUser(user.getUserid()).isEnabled()); assertNotNull(h2Store.deleteUser(user.getUserid())); } + + private String getExpectName() { + return "1221r13r1rfdfsafsdfadfadfasfadsfdsfdaf" + + "dsfdsfafsdfadfasfsafdsafdfaadfdaffgdsfa" + + "safdsafafsafdasgfdsafdsafagadfadsfdsfdafda" + + "adfasdfdsafadsfsag4ef2313414r314313143113431" + + "1431413241231543143143154354321r3243fdsf3rfdr32f"; + } + @Test public void writeUserTest() throws IDMStoreException { User user = mockUser("test3"); @@ -136,6 +152,13 @@ public class H2StoreTest { } role.setName("changeRole"); assertNotNull(h2Store.updateRole(role)); + try{ + role.setDescription(getExpectName()); + h2Store.updateRole(role); + fail("update role error"); + }catch (IDMStoreException e){ + assertThat(e.getMessage(),containsString("SQL Exception")); + } assertNotNull(h2Store.readRole(role.getRoleid())); assertNotNull(h2Store.deleteRole(role.getRoleid())); } @@ -161,8 +184,14 @@ public class H2StoreTest { } domain.setName("changeDomain"); assertNotNull(h2Store.updateDomain(domain)); + try{ + domain.setName(getExpectName()); + h2Store.updateDomain(domain); + fail("update domain error"); + }catch (IDMStoreException e){ + assertThat(e.getMessage(),containsString("Error updating domain")); + } assertNotNull(h2Store.readDomain(domain.getDomainid())); - h2Store.readDomain("111"); assertNotNull(h2Store.deleteDomain(domain.getDomainid())); } diff --git a/ControlPlatform/aaa/aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/IdmLightConfigTest.java b/ControlPlatform/aaa/aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/IdmLightConfigTest.java index 02d22ffed..1cb52bc80 100644 --- a/ControlPlatform/aaa/aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/IdmLightConfigTest.java +++ b/ControlPlatform/aaa/aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/IdmLightConfigTest.java @@ -14,6 +14,9 @@ package org.opendaylight.aaa.datastore.h2; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.Test; import java.io.File; @@ -61,9 +64,35 @@ public class IdmLightConfigTest { public void testIdmBuilder() { IdmLightConfigBuilder builder = new IdmLightConfigBuilder().dbUser("foo").dbPwd("bar"); builder.dbName("idmlight.db"); + builder.dbDriver("org.h2.Driver"); + builder.dbValidTimeOut(3); + builder.dbConnectionStringPrefix("jdbc:h2:"); IdmLightConfig config = builder.build(); + IdmLightConfig config2 = builder.build(); + assertNotNull(config.toString()); + assertEquals(config.hashCode(),checkHashCode(config)); + assertEquals(config, config2); assertThat(config.getDbConnectionString()) .isEqualTo("jdbc:h2:./data" + File.separatorChar + "idmlight.db"); + assertThat(config.getDbDriver()) + .isEqualTo("org.h2.Driver"); + assertThat(config.getDbValidTimeOut()).isEqualTo(3); + assertThat(config.getDbConnectionStringPrefix()).isEqualTo("jdbc:h2:"); + + + } + + private int checkHashCode(IdmLightConfig config) { + int h = 5381; + h += (h << 5) + config.getDbName().hashCode(); + h += (h << 5) + config.getDbDirectory().hashCode(); + h += (h << 5) + config.getDbDriver().hashCode(); + h += (h << 5) + config.getDbUser().hashCode(); + h += (h << 5) + config.getDbPwd().hashCode(); + h += (h << 5) + config.getDbValidTimeOut(); + h += (h << 5) + config.getDbConnectionStringPrefix().hashCode(); + h += (h << 5) + config.getDbConnectionString().hashCode(); + return h; } } diff --git a/Product/build/user.web-auth.Makefile b/Product/build/user.web-auth.Makefile new file mode 100644 index 000000000..4f422bb95 --- /dev/null +++ b/Product/build/user.web-auth.Makefile @@ -0,0 +1,77 @@ +# target name, the target name must have the same name of c source file +TARGET_NAME=webauth + +# target +# for linux module driver: KO +# for application: EXE +# for dynamic library: DLL +TARGET_TYPE = EXE + +# target object +# for application: APP +# for device driver: DRV +TARGET_OBJ = APP + +# custom install dir +TARGET_BOX = + +#debug mode or release mode +DEBUG = TRUE + +PLAT_LINUX ?= TRUE +PLAT_ARM64 ?= FALSE + +VPATH = ../user/user_auth ../user/user_manager/usermanager-auth + +# source code + +# set the source file, don't used .o because of ... + +COMMON_SRCS = web_auth.c user_hashtable.c user_auth.c + +# MRS Board Source Files +PLAT_LINUX_SRCS = $(COMMON_SRCS) +PLAT_ARM64_SRCS = $(COMMON_SRCS) + +# gcc CFLAGS +PLAT_ARM64_CFLAGS := -I../../Common -I../../Platform/common -I../../Product/user -I../../Product/common +PLAT_LINUX_CFLAGS := $(PLAT_ARM64_CFLAGS) + + +PLAT_ARM64_LDFLAGS := +PLAT_LINUX_LDFLAGS := $(PLAT_ARM64_LDFLAGS) + + +#gcc libs +ARM64_LIBS := ./userauthapi-arm64.so +LINUX_LIBS := -lcjson ./userauthapi-linux.so + +ifeq ($(PLAT_ARM64), TRUE) +DEPEND_LIB += ./debug/userauthapi-arm64.so +USER_CLEAN_ITEMS += ./userauthapi-arm64.so +endif + +ifeq ($(PLAT_LINUX), TRUE) +DEPEND_LIB += ./debug/userauthapi-linux.so +USER_CLEAN_ITEMS += ./userauthapi-linux.so +endif + +# this line must be at below of thus, because of... +include ../../Common/common.Makefile + +ifneq ($(MAKECMDGOALS), clean) +ifneq ($(MAKECMDGOALS), cleanall) +ifneq ($(notdir $(DEPEND_LIB)), $(wildcard $(DEPEND_LIB))) +$(shell $(CP) $(DEPEND_LIB) ./) +endif +endif +endif + +ifeq ($(MAKECMDGOALS), ) +$(shell find ./ -name "$(TARGET)-*.ko" -delete) +else +ifeq ($(MAKECMDGOALS), all) +$(shell find ./ -name "$(TARGET)-*.ko" -delete) +endif +endif + diff --git a/Product/common/user_hashtable.c b/Product/common/user_hashtable.c deleted file mode 100644 index a76226ca1..000000000 --- a/Product/common/user_hashtable.c +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "hlist.h" -#include "user_hashtable.h" - -struct hlist_head *hash; -struct hlist_node *p = NULL, *n = NULL ; -int i = 0; -USER_INFO *pNode ; - -/*计算hash值 */ -struct hlist_head *call_hash(struct hlist_head *hash, uint32_t ip) -{ - unsigned int val = ip % 100; - return &hash[val]; -} - -/*初始化函数 */ -int Init_hash() -{ - hash = (struct hlist_head*)malloc(sizeof(*hash)*100); - if(NULL == hash) - { - printf("alloc error\n"); - return -1; - } - - for(i = 0; i < 100; i++) - INIT_HLIST_HEAD(&hash[i]); -} - - -/*查找用户信息*/ -struct user_info *ufind_user(uint32_t user_ip) -{ - hlist_for_each_safe(p,n,call_hash(hash,user_ip)) - { - pNode = hlist_entry(p, struct user_info ,hnode); - if(pNode != NULL) - printf("user_id :%d\n",pNode->id); - return pNode; - } -} - -/*增加用户信息*/ -int uadd_user(uint32_t user_ip, int user_id) -{ - USER_INFO *pNode =NULL; - hlist_for_each_safe(p,n,call_hash(hash, user_ip)) /*查找ip是否存在hash表中 */ - { - pNode = hlist_entry(p, struct user_info ,hnode); - if(pNode != NULL) - printf("IP ALEADY EXISTED\n"); - } - - if (pNode == NULL) - { - pNode = (struct user_info *)malloc(sizeof(struct user_info)); - if (NULL == pNode) - { - return -1; - } - memset(pNode,0,sizeof(struct user_info)); - INIT_HLIST_NODE(&pNode->hnode); - pNode->ip = user_ip; - hlist_add_head(&pNode->hnode, call_hash(hash, user_ip)); - } - pNode->id = user_id; - -} - -/*删除用户信息 */ -void udelete_user(int user_ip) -{ - hlist_for_each_safe(p,n,call_hash(hash,user_ip)) - { - pNode = hlist_entry(p, struct user_info ,hnode); - hlist_del(&pNode->hnode); - free(pNode); - } -} - -/*删除所有的hash节点 */ -void udelete_all() -{ - for(i = 0; i < 100; i++) - { - hlist_for_each_safe(p,n,&hash[i]) - { - pNode = hlist_entry(p, struct user_info ,hnode); - hlist_del(&pNode->hnode); - free(pNode); - } - } -} - -/*打印所有信息信息 */ -void uprintf_users() -{ - for(i = 0; i < 100; i++) - { - hlist_for_each_safe(p,n,&hash[i]) - { - char str[32]; - pNode = hlist_entry(p, struct user_info ,hnode); - if(pNode != NULL) - inet_ntop(AF_INET, (void *)&pNode->ip, str, 32); - printf("user_ip :%s user_id:%d\n", str, pNode->id); - } - } -} - diff --git a/Product/user/user_auth/user_hashtable.c b/Product/user/user_auth/user_hashtable.c new file mode 100644 index 000000000..97626ed30 --- /dev/null +++ b/Product/user/user_auth/user_hashtable.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include +#include +#include "hlist.h" +#include "user_hashtable.h" +#include "user_auth.h" + + +extern USER_AUTH_LIST g_user_auth_ret_table[] ; + +/*链表全局变量 */ +struct hlist_head *hash; +USER_INFO *pNode ; + + +/*计算hash值 */ +struct hlist_head * call_hash(struct hlist_head *hash, uint32_t ip) +{ + unsigned int val = ip % 100; + printf("val =%d\n", val); + return &hash[val]; +} + + +/*初始化函数 */ +int Init_hash() +{ + int i = 0; + + /*创建hash头 */ + hash = (struct hlist_head*)malloc(sizeof(*hash)*100); + if(NULL == hash) + { + printf("alloc error\n"); + return -1; + } + + /*初始化hash表头 */ + for(i = 0; i < 100; i++) + INIT_HLIST_HEAD(&hash[i]); + + + /*hsah桶普通节点分配内存 */ + pNode = (struct user_info *)malloc(sizeof(struct user_info)); + if (NULL == pNode) + { + printf("alloc error\n"); + return -1; + } + + /*初始化hash桶的普通结点 */ + memset(pNode,0,sizeof(struct user_info)); + INIT_HLIST_NODE(&pNode->hnode); +} + + + +/*查找用户信息*/ +USER_INFO * ufind_user(uint32_t user_ip) +{ + + struct hlist_node *p = NULL, *n = NULL ; + + /* 这个实际上就是一个for循环,从头到尾遍历链表。 + * pos:struct hlist_node类型的一个指针; + * n:struct hlist_node类型的一个指针; + * head:struct hlist_head类型的一个指针,表示hlist链表的头结点。 + */ + + hlist_for_each_safe(p,n,call_hash(hash,user_ip)) + { + + /* p:表示struct hlist_node类型的一个地址。 + * struct user_info:结构体名 + * hnode:type结构体中的hlist_node成员变量的名称 + * 表示得到p所指地址的这个结构体的首地址 + */ + pNode = hlist_entry(p, struct user_info ,hnode); + if(pNode != NULL) + printf("user_id :%d\n",pNode->id); + return pNode; + } +} + + +/*增加用户信息*/ +int uadd_user(uint32_t user_ip, int user_id) +{ + struct hlist_node *pos = NULL, *n = NULL ; + + pNode = NULL; + struct hlist_head* pVal = call_hash(hash, user_ip); + printf("pVal = %p, pVal->first = %p\n", pVal, pVal->first); + + //hlist_for_each_safe(p,n,call_hash(hash, user_ip)) /*查找ip是否存在hash表中 */ + for (pos = pVal->first; pos && ({ n = pos->next; 1; }); pos = n) + { + pNode = hlist_entry(pos, struct user_info ,hnode); + if(pNode != NULL) + printf("IP ALEADY EXISTED\n"); + } + + if (pNode == NULL) + { + pNode = (struct user_info *)malloc(sizeof(struct user_info)); + if (NULL == pNode) + { + return -1; + } + memset(pNode,0,sizeof(struct user_info)); + INIT_HLIST_NODE(&pNode->hnode); + pNode->ip = user_ip; + hlist_add_head(&pNode->hnode, call_hash(hash, user_ip)); + } + + pNode->id = user_id; + +} + +/*删除用户信息 */ +void udelete_user(int user_ip) +{ + + struct hlist_node *p = NULL, *n = NULL ; + int i = 0; + unsigned short check_id; + + hlist_for_each_safe(p,n,call_hash(hash,user_ip)) + { + pNode = hlist_entry(p, struct user_info ,hnode); + + /*查找用户ID,确认ID是否存在 */ + check_id = g_user_auth_ret_table[pNode->id].group_id; + if(check_id != NULL) + { + hlist_del(&pNode->hnode); + } + + free(pNode); + } +} + +/*删除所有的hash节点 */ +void udelete_all() +{ + struct hlist_node *p = NULL, *n = NULL ; + int i = 0; + + for(i = 0; i < 100; i++) + { + hlist_for_each_safe(p,n,&hash[i]) + { + pNode = hlist_entry(p, struct user_info ,hnode); + hlist_del(&pNode->hnode); + free(pNode); + } + } +} + +/*打印所有信息信息 */ +void uprintf_users() +{ + struct hlist_node *p = NULL, *n = NULL ; + int i = 0; + + for(i = 0; i < 100; i++) + { + hlist_for_each_safe(p,n,&hash[i]) + { + char str[32]; + pNode = hlist_entry(p, struct user_info ,hnode); + if(pNode != NULL) + inet_ntop(AF_INET, (void *)&pNode->ip, str, 32); + printf("user_ip :%s user_id:%d\n", str, pNode->id); + } + } +} + diff --git a/Product/user/user_auth/web_auth.c b/Product/user/user_auth/web_auth.c new file mode 100644 index 000000000..82b19946e --- /dev/null +++ b/Product/user/user_auth/web_auth.c @@ -0,0 +1,170 @@ +#include +#include +#include +#include "web_auth.h" +#include "user_hashtable.h" + + +/*输入参数:用户名、密码,json格式*/ +/*输出参数:resultcode、描述信息message、剩余锁定时间remain_lock_time(认证成功和失败的情况下,剩余锁定时间默认为0) */ +/*location:url location之后,get(方法判断是否是get方法) url的时候要判断下这个用户是否已经认证过*/ + + +/* 用户认证 */ +void user_auth_login(char* username, char* password, USER_AUTH_RET* auth_result); + +char * mes[]={"SUCCESS", "ErrorUsernameOrpassword", "NotInVaildTime", + "OutMaxOnlineNum", "UserIsLocked", "LackConfigInfo", + "OverMaxOnlineNum", "OtherErr"}; + + +/*content形式: {"username":"adimn", "password":"admin"} */ +ret_code user_auth(pointer content, RESULT *uresult) +{ + ret_code ret = RET_OK; + cJSON *cjson; + USER_AUTH_RET *resultinfo; + time_t time = 0; + + memset(uresult, 0, sizeof(RESULT)); + + /*创建内存地址 */ + resultinfo = (USER_AUTH_RET *)malloc(sizeof(USER_AUTH_RET)); + if (NULL == resultinfo) + { + ret = RET_NOMEM; + return ret; + } + + /*JSON字符串到JSON格式 */ + cjson = cJSON_Parse(content); + if(!cjson) + { + ret = RET_INPUTERR; + return ret; + } + + /*获取用户名 */ + char *uname = cJSON_GetObjectItem(cjson , "username")->valuestring; + printf("username :%s\n", uname); + + /*判断username长度是否正确*/ + if( strlen(uname) > USERNAME_MAXLEN ) + { + cJSON_Delete(cjson); + ret = RET_IPINVALID; + return ret; + } + + /*获取密码 */ + char *upwd = cJSON_GetObjectItem(cjson, "password")->valuestring; + printf("password :%s\n", upwd); + + /*判断password长度是否正确 */ + if( strlen(upwd) > PASSWORD_MAXLEN ) + { + cJSON_Delete(cjson); + ret = RET_IPINVALID; + return ret; + } + + + /*调用认证接口函数 */ + user_auth_login(uname, upwd, resultinfo); + printf("认证结束\n"); + + /*认证成功 */ + if (resultinfo->ret == 0) + { + printf("认证成功\n"); + uint32_t client_ip=10001; /*解析报文拿到用户IP */ + printf("client_ip :%d\n", client_ip); + Init_hash(); /*初始化hash表放在配置恢复处 */ + + + /*重定向到认证成功界面-调用web server提供的接口,发送url地址给接口,实现重定向 */ + + + /*客户端访问认证成功界面方法:GET */ + char method[10] = {"GET"}; + + + /*如果method是GET,判断这个用户是否认证过*/ + if(0 == strncmp(method, "GET",10)) + { + struct user_info * uinfo; + uinfo = (struct user_info *)malloc(sizeof(struct user_info)); + if (NULL == uinfo) + { + cJSON_Delete(cjson); + ret = RET_NOMEM; + return ret; + } + + /*用户认证过则跳出语句,不访问认证成功界面 */ + uinfo = ufind_user(client_ip); + + if ( NULL != uinfo ) + { + printf("用户已经认证过\n"); + free(uinfo); + cJSON_Delete(cjson); + ret = RET_ERR; + return ret ; + } + + uadd_user(client_ip,resultinfo->user_id); + uprintf_users(); + + uresult->resultcode = resultinfo->ret; + uresult->remain_lock_time = time; + uresult->message = mes[resultinfo->ret]; + printf("resultcode:%d remain_lock_time:%d message:%s\n",uresult->resultcode, + uresult->remain_lock_time, uresult->message ); + + + free(uinfo); + cJSON_Delete(cjson); + return ret; + } + } + + /*认证锁定*/ + if (resultinfo->ret == 4) + { + time = resultinfo->remain_lock_time; + + uresult->resultcode = resultinfo->ret; + uresult->remain_lock_time = time; + uresult->message = mes[resultinfo->ret]; + printf("resultcode:%d remain_lock_time:%d message:%s\n",uresult->resultcode, + uresult->remain_lock_time, uresult->message ); + + cJSON_Delete(cjson); + ret = RET_ERR; + return ret; + } + + /*认证失败*/ + if ( (resultinfo->ret != 4) && (resultinfo->ret != 0)) + { + printf("the value of resultcode is %d\n", resultinfo->ret); + uresult->resultcode = resultinfo->ret; + uresult->remain_lock_time = time; + uresult->message = mes[resultinfo->ret]; + printf("resultcode:%d remain_lock_time:%d message:%s\n",uresult->resultcode, + uresult->remain_lock_time, uresult->message ); + + cJSON_Delete(cjson); + ret = RET_ERR; + return ret; + } + + + cJSON_Delete(cjson); + return ret; +} + + + + diff --git a/Product/user/user_auth/web_auth.h b/Product/user/user_auth/web_auth.h new file mode 100644 index 000000000..3903547d5 --- /dev/null +++ b/Product/user/user_auth/web_auth.h @@ -0,0 +1,22 @@ +#ifndef USERAUTH_H_ +#define USERAUTH_H_ + +#define USERNAME_MAXLEN 65 +#define PASSWORD_MAXLEN 25 + +#include +#include "../../Product/common/user_auth.h" +#include "../../Platform/common/rpc/rpc_common.h" + +typedef void* pointer; + +/*输出函数结构体 */ +typedef struct result{ + auth_ret resultcode; + char *message; /*返回描述用指针表示数组 */ + time_t remain_lock_time; /*锁定剩余时间 */ +}RESULT; + +ret_code user_auth(pointer content, RESULT *uresult); + +#endif \ No newline at end of file