⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 userdb.c

📁 Linux下的飞鸽传书
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  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 + -