?? userdb.c
字號:
/* * Copyright (C) 2006 Takeharu KATO * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include <stdio.h>#include <string.h>#include <errno.h>#include <gnome.h>#include <glib.h>#include "callbacks.h"#include "common.h"static GList *users=NULL;static GList *waiter_windows=NULL;GStaticMutex userdb_mutex = G_STATIC_MUTEX_INIT;GStaticMutex win_mutex = G_STATIC_MUTEX_INIT;static gint userdb_find_element(gconstpointer a,gconstpointer b) { int rc=-EINVAL; userdb_t *user_a,*user_b; if ( (!a) || (!b) ) goto out; user_a=(userdb_t *)a; user_b=(userdb_t *)b; if ( (!strncmp(user_a->user,user_b->user,NAME_LEN)) && (!strcmp(user_a->ipaddr,user_b->ipaddr)) ) { rc=0; goto out; /* found */ } rc=1; out: return rc; /* Not found */}static gint userdb_find_by_ipaddr(gconstpointer a,gconstpointer b) { int rc=-EINVAL; userdb_t *user_a,*user_b; if ( (!a) || (!b) ) goto out; user_a=(userdb_t *)a; user_b=(userdb_t *)b; if (!strcmp(user_a->ipaddr,user_b->ipaddr)) return 0; rc=-ESRCH; out: return rc; /* Not found */}static voidprint_one_user_entry(gpointer data,gpointer user_data) { userdb_t *current_user; unsigned long skey,akey,sign; if (!data) return; current_user=(userdb_t *)data; dbg_out("NickName: %s\n",current_user->nickname); dbg_out("Group: %s\n",current_user->group); dbg_out("User: %s\n",current_user->user); dbg_out("Host: %s\n",current_user->host); dbg_out("IP Addr: %s\n",current_user->ipaddr); dbg_out("Capability: %x\n",(unsigned int)current_user->cap); if (current_user->cap & IPMSG_DIALUPOPT) dbg_out("\t Dialup host\n"); if (current_user->cap & IPMSG_FILEATTACHOPT) dbg_out("\t File Attach\n"); if (current_user->cap & IPMSG_ENCRYPTOPT) dbg_out("\t Encryption\n"); if (current_user->cap & IPMSG_UTF8OPT) dbg_out("\t UTF-8\n"); if (current_user->cap & IPMSG_ENCRYPTOPT) {#if defined(USE_OPENSSL) dbg_out("\t Crypt capability\n"); if (current_user->crypt_cap) { if (current_user->crypt_cap) { skey=get_symkey_part(current_user->crypt_cap); if (skey & IPMSG_RC2_40) dbg_out("\t RC2 40 bits\n"); if (skey & IPMSG_RC2_128) dbg_out("\t RC2 128 bits\n"); if (skey & IPMSG_RC2_256) dbg_out("\t RC2 256 bits\n"); if (skey & IPMSG_BLOWFISH_128) dbg_out("\t Blowfish 128 bits\n"); if (skey & IPMSG_BLOWFISH_256) dbg_out("\t Blowfish 256 bits\n"); akey=get_asymkey_part(current_user->crypt_cap); if (akey & IPMSG_RSA_512) dbg_out("\t RSA 512 bits\n"); if (akey & IPMSG_RSA_1024) dbg_out("\t RSA 1024 bits\n"); if (akey & IPMSG_RSA_2048) dbg_out("\t RSA 2048 bits\n"); g_assert(current_user->pub_key_e); g_assert(current_user->pub_key_n); dbg_out("\tPublic key:\n"); dbg_out("\te=%s\n",current_user->pub_key_e); dbg_out("\tn=%s\n",current_user->pub_key_n); sign=get_sign_part(current_user->crypt_cap); if (sign) { if (sign&IPMSG_SIGN_MD5) dbg_out("\t handle MD5 sign\n"); if (sign&IPMSG_SIGN_SHA1) dbg_out("\t handle SHA1 sign\n"); }else{ dbg_out("\t No sign\n"); } } }else{ dbg_out("\t\t Unknown\n"); }#else dbg_out("\t\t Unknown\n");#endif } return;}static intalloc_user_info(userdb_t **entry){ userdb_t *new_user; if (!entry) return -EINVAL; new_user=g_slice_new(userdb_t); if (!new_user) return -ENOMEM; memset(new_user,0,sizeof(userdb_t)); *entry=new_user; return 0;}static intdestroy_user_info_contents(userdb_t *entry){ if (!entry) return -EINVAL; if (entry->user) g_free(entry->user); if (entry->host) g_free(entry->host); if (entry->group) g_free(entry->group); if (entry->nickname) g_free(entry->nickname); if (entry->ipaddr) g_free(entry->ipaddr); if (entry->pub_key_e) g_free(entry->pub_key_e); if (entry->pub_key_n) g_free(entry->pub_key_n); memset(entry,0,sizeof(userdb_t)); return 0;}static voiddo_notify_change(gpointer data,gpointer user_data) { GtkWidget *window; if (!data) return; window=GTK_WIDGET(data); update_users_on_message_window(window,FALSE); return;}static intnotify_userdb_changed(void){ g_static_mutex_lock(&win_mutex); g_list_foreach(waiter_windows, do_notify_change, NULL); g_static_mutex_unlock(&win_mutex);}#define strdup_with_check(dest,src,member,err_label) \ ((dest)->member)=g_strdup((src)->member); \ if (!((dest)->member)) \ goto err_label ; static intcopy_user_info(userdb_t *dest,userdb_t *src) { int rc=-ENOMEM; if ( (!dest) || (!src) ) return -EINVAL; g_assert(!(dest->user)); g_assert(!(dest->host)); g_assert(!(dest->group)); g_assert(!(dest->nickname)); g_assert(!(dest->ipaddr)); g_assert(!(dest->pub_key_e)); g_assert(!(dest->pub_key_n)); dest->prio=src->prio; dest->cap=src->cap; dest->crypt_cap=src->crypt_cap; /* 下記はマクロであることに注意 */ strdup_with_check(dest,src,user,err_out) strdup_with_check(dest,src,host,err_out) strdup_with_check(dest,src,group,err_out) strdup_with_check(dest,src,nickname,err_out) strdup_with_check(dest,src,ipaddr,err_out) if (src->pub_key_e) { strdup_with_check(dest,src,pub_key_e,err_out) } if (src->pub_key_n) { strdup_with_check(dest,src,pub_key_n,err_out) } return 0; err_out: destroy_user_info_contents(dest); return rc;}static intfill_user_info_with_message(const char *peer_addr,const msg_data_t *msg,userdb_t *new_user){ int rc; int default_prio; if ( (!new_user) || (!msg) ) return -EINVAL; memset(new_user,0,sizeof(userdb_t)); rc=-ENOMEM; convert_string_internal(refer_user_name_from_msg(msg),(const gchar **)&(new_user->user)); if (new_user->user == NULL) { ipmsg_err_dialog(_("Can not convert message from %s into ineternal representation"), peer_addr); goto memclear_out; } convert_string_internal(refer_host_name_from_msg(msg),(const gchar **)&(new_user->host)); if (new_user->host == NULL) { ipmsg_err_dialog(_("Can not convert message from %s into ineternal representation"), peer_addr); goto free_user_out; } convert_string_internal(refer_group_name_from_msg(msg),(const gchar **)&(new_user->group)); if (new_user->group == NULL) { ipmsg_err_dialog(_("Can not convert message from %s into ineternal representation"), peer_addr); goto free_host_out; } convert_string_internal(refer_nick_name_from_msg(msg),(const gchar **)&(new_user->nickname)); if (new_user->nickname == NULL) { ipmsg_err_dialog(_("Can not convert message from %s into ineternal representation"), peer_addr); goto free_group_out; } convert_string_internal(peer_addr,(const gchar **)&(new_user->ipaddr)); if (new_user->ipaddr == NULL) { ipmsg_err_dialog(_("Can not convert message from %s into ineternal representation"), peer_addr); goto free_nickname_out; } rc=hostinfo_get_ipmsg_ipaddr_prio(new_user->ipaddr,&default_prio); if (rc<0) default_prio=0; new_user->cap=msg->command_opts; new_user->prio=default_prio; dbg_out("Fill: %s %s %s %s %d %x\n", new_user->user, new_user->host, new_user->group, new_user->ipaddr, new_user->prio, (unsigned int)new_user->cap); return 0; free_ipaddr_out: g_free(new_user->ipaddr); free_nickname_out: g_free(new_user->nickname); free_group_out: g_free(new_user->group); free_host_out: g_free(new_user->host); free_user_out: g_free(new_user->user); memclear_out: memset(new_user,0,sizeof(userdb_t)); return rc;}static intadd_with_userdb_entry(userdb_t *new_user){ int rc; GList *new_entry; GList *current_entry=NULL; if (!new_user) return -EINVAL; dbg_out("Add: %s %s %s %s %x\n", new_user->user, new_user->host, new_user->group, new_user->ipaddr, (unsigned int)new_user->cap); g_static_mutex_lock(&userdb_mutex); current_entry=g_list_find_custom (users,new_user,userdb_find_element); if (!current_entry){ users=g_list_append(users,new_user); } else { rc=-EEXIST; goto error_out; } /* * 健全性チェック */ new_entry=g_list_find_custom(users,new_user,userdb_find_element); g_assert(new_entry); g_assert(new_entry->data == new_user); g_static_mutex_unlock(&userdb_mutex); notify_userdb_changed(); return 0; error_out: g_static_mutex_unlock(&userdb_mutex); destroy_user_info(new_user); return rc;}/* *start:length:ユーザ名:ホスト名:コマンド番號:IP アドレス: *ポート番號(リトルエンディアン):ニックネーム:グループ名 */static intuserdb_add_hostlist_entry(userdb_t *entry,const char **entry_string_p, int *is_last){ int rc; char *buffer=NULL; char *sp,*ep; long remains; int intval; size_t len; char *user=NULL; char *host=NULL; char *ipaddr=NULL; int port; char *nickname=NULL; char *group=NULL; const char *entry_string; if ( (!entry) || (!entry_string_p) || (!is_last) ) return -EINVAL; entry_string=*entry_string_p; rc=-ENOMEM; buffer=g_strdup(entry_string); if (!buffer) goto free_buffer_out; rc=-ENOENT; *is_last=1; len=strlen(buffer); remains=len; dbg_out("Buffer:%s\n",buffer); /* * username */ sp=buffer; ep=memchr(sp, HOSTLIST_SEPARATOR, remains); if (!ep) goto free_buffer_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_buffer_out; *ep='\0'; user=g_strdup(make_entry_canonical(sp)); if (!user) goto free_buffer_out; ++ep; sp=ep; dbg_out("user:%s\n",user); /* * host */ ep=memchr(sp, HOSTLIST_SEPARATOR, remains); if (!ep) goto free_user_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_user_out; *ep='\0'; host=g_strdup(make_entry_canonical(sp)); if (!host) goto free_user_out; ++ep; sp=ep; dbg_out("host:%s\n",host); /* * skip command */ ep=memchr(sp, HOSTLIST_SEPARATOR , remains); if (!ep) goto free_host_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_host_out; *ep='\0'; ++ep; sp=ep; /* * ipaddr */ ep=memchr(sp, HOSTLIST_SEPARATOR, remains); if (!ep) goto free_host_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_host_out; *ep='\0'; ipaddr=g_strdup(make_entry_canonical(sp)); if (!ipaddr) goto free_host_out; ++ep; sp=ep; dbg_out("ipaddr:%s\n",ipaddr); /* * port */ ep=memchr(sp, HOSTLIST_SEPARATOR , remains); if (!ep) goto free_ipaddr_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_ipaddr_out; *ep='\0'; intval=strtol(sp, (char **)NULL, 10); ++ep; sp=ep; dbg_out("port:%d\n",intval); /* * nick name */ ep=memchr(sp, HOSTLIST_SEPARATOR , remains); if (!ep) goto free_ipaddr_out; remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_ipaddr_out; *ep='\0'; nickname=g_strdup(make_entry_canonical(sp)); if (!nickname) goto free_ipaddr_out; ++ep; sp=ep; dbg_out("nickname:%s\n",nickname); /* * group */ ep=memchr(sp, HOSTLIST_SEPARATOR , remains); if (!ep) { ep=memchr(sp, '\0' , remains); if (!ep) goto free_nickname_out; }else{ *is_last=0; } remains =len - ((unsigned long)ep-(unsigned long)sp); if (remains<0) goto free_nickname_out; *ep='\0'; group=g_strdup(make_entry_canonical(sp)); if (!nickname) goto free_nickname_out; ++ep; dbg_out("group:%s\n",group); entry->user=user;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -