pgpool2.git / summary / log / commit / refs

commit    5bc8c654bd774020f1cdc8f097ff36d78f72e1c2
Author:   Yugo Nagata <nagata@sraoss.co.jp>
Date:     Fri Apr 19 08:14:20 2013 +0000

    Add authentication mechanism for watchdog packet communication
    
    Watchdog packets from pgpool having wrong authentication key are
    rejected. All pgpools must have the same key, which is specified
    option wd_authkey in pgpool.conf. pgpool with wrong authkey can't
    even start watchdog, because the startup packet is rejected by other
    pgpools.


pgpool.conf.sample | 44 +++++++++++--------- pool_config.c | 6 +-- pool_config.h | 2 +- pool_config.l | 6 +-- watchdog/watchdog.c | 6 ++- watchdog/watchdog.h | 7 +++- watchdog/wd_child.c | 25 ++++++++++-- watchdog/wd_ext.h | 4 ++ watchdog/wd_interlock.c | 2 +- watchdog/wd_packet.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++ watchdog/wd_udp.c | 54 +++++++++---------------- 11 files changed, 191 insertions(+), 70 deletions(-) diff --git a/pgpool.conf.sample b/pgpool.conf.sample index 2c47ddbf6..c22c86733 100644 --- a/pgpool.conf.sample +++ b/pgpool.conf.sample @@ -427,6 +427,9 @@ client_idle_limit_in_recovery = 0 #------------------------------------------------------------------------------ use_watchdog = off # Activates watchdog + +watchdog_mode='udp' + # Mode of watchdog lifecheck ('udp' or 'query') # (change requires restart) trusted_servers = '' # trusted server list which are used @@ -445,6 +448,9 @@ wd_port = 9000 wd_interval = 10 # lifecheck interval (sec) > 0 # (change requires restart) +wd_authkey = '' + # Authentication key for watchdog communication + ping_path = '/bin' # ping command path # (change requires restart) @@ -464,6 +470,22 @@ arping_path = '/usr/sbin' # arping command path arping_cmd = 'arping -U $_IP_$ -w 1' # arping command # (change requires restart) +wd_udp_port = 9694 + # Port number for UDP heartbeat lifecheck +wd_udp_keepalive = 2; + # Interval time of sending UDP heartbeat signal (sec) +wd_udp_deadtime = 30 + # Deadtime interval for UDP heartbeat signal (sec) +udp_device0 = 'eth0' + # Name of NIC device 0 using for + # sending/receiving heartbeat signal +udp_destination0 = 'host0_ip1' + # Destination host name or IP address + # for sending heartbeat signal using NIC device 0. + +#udp_device1 = 'eth1' +#udp_destination1 = 'host0_ip2' + wd_life_point = 3 # lifecheck retry times # (change requires restart) @@ -476,6 +498,8 @@ wd_lifecheck_user = 'nobody' # watchdog user monitoring pgpools in lifecheck wd_lifecheck_password = '' # Password for watchdog user in lifecheck + + # Other pgpool Connection Settings #other_pgpool_hostname0 = 'host0' @@ -488,26 +512,6 @@ wd_lifecheck_password = '' #other_pgpool_port1 = 5432 #other_wd_port1 = 9000 -watchdog_mode='udp' - # Mode of watchdog lifecheck ('udp' or 'query') -wd_udp_port = 9694 - # Port number for UDP heartbeat lifecheck -wd_udp_keepalive = 2; - # Interval time of sending UDP heartbeat signal (sec) -wd_udp_deadtime = 30 - # Deadtime interval for UDP heartbeat signal (sec) -wd_udp_authkey = '' - # Authentication key for UDP heartbeat signal (sec) - -udp_device0 = 'eth0' - # Name of NIC device 0 using for - # sending/receiving heartbeat signal -udp_destination0 = 'host0_ip1' - # Destination host name or IP address - # for sending heartbeat signal using NIC device 0. - -#udp_device1 = 'eth1' -#udp_destination1 = 'host0_ip2' #------------------------------------------------------------------------------ # OTHERS diff --git a/pool_config.c b/pool_config.c index 55ebc5744..783622071 100644 --- a/pool_config.c +++ b/pool_config.c @@ -1808,7 +1808,7 @@ int pool_init_config(void) pool_config->wd_udp_keepalive = 2; pool_config->wd_udp_deadtime = 30; pool_config->wd_udp_port = 9694; - pool_config->wd_udp_authkey = ""; + pool_config->wd_authkey = ""; pool_config->memory_cache_enabled = 0; pool_config->memqcache_method = "shmem"; @@ -3853,7 +3853,7 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context) } pool_config->wd_udp_deadtime = v; } - else if (!strcmp(key, "wd_udp_authkey") && + else if (!strcmp(key, "wd_authkey") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; @@ -3870,7 +3870,7 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context) fclose(fd); return(-1); } - pool_config->wd_udp_authkey = str; + pool_config->wd_authkey = str; } else if (!strncmp(key, "udp_device", 10) && diff --git a/pool_config.h b/pool_config.h index fb36dec7e..c8060de03 100644 --- a/pool_config.h +++ b/pool_config.h @@ -245,7 +245,7 @@ typedef struct { int wd_udp_keepalive; int wd_udp_deadtime; int wd_udp_port; - char *wd_udp_authkey; + char *wd_authkey; } POOL_CONFIG; typedef enum { diff --git a/pool_config.l b/pool_config.l index aa8331855..38ae80d31 100644 --- a/pool_config.l +++ b/pool_config.l @@ -261,7 +261,7 @@ int pool_init_config(void) pool_config->wd_udp_keepalive = 2; pool_config->wd_udp_deadtime = 30; pool_config->wd_udp_port = 9694; - pool_config->wd_udp_authkey = ""; + pool_config->wd_authkey = ""; pool_config->memory_cache_enabled = 0; pool_config->memqcache_method = "shmem"; @@ -2306,7 +2306,7 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context) } pool_config->wd_udp_deadtime = v; } - else if (!strcmp(key, "wd_udp_authkey") && + else if (!strcmp(key, "wd_authkey") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; @@ -2323,7 +2323,7 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context) fclose(fd); return(-1); } - pool_config->wd_udp_authkey = str; + pool_config->wd_authkey = str; } else if (!strncmp(key, "udp_device", 10) && diff --git a/watchdog/watchdog.c b/watchdog/watchdog.c index d46a1a7b1..1a14b0c4f 100644 --- a/watchdog/watchdog.c +++ b/watchdog/watchdog.c @@ -50,6 +50,8 @@ static pid_t writer_pid[WD_MAX_IF_NUM]; pid_t wd_main(int fork_wait_time); void wd_kill_watchdog(int sig); int wd_reaper_watchdog(pid_t pid, int status); +int wd_chk_setuid(void); + static pid_t fork_a_lifecheck(int fork_wait_time); static void wd_exit(int exit_status); static int wd_check_config(void); @@ -105,9 +107,9 @@ wd_check_config(void) pool_error("wd_check_config: delegate_IP is empty"); status = WD_NG; } - if (strlen(pool_config->wd_udp_authkey) > MAX_PASSWORD_SIZE) + if (strlen(pool_config->wd_authkey) > MAX_PASSWORD_SIZE) { - pool_error("wd_check_config: wd_udp_authkey length can't be larger than %d", + pool_error("wd_check_config: wd_authkey length can't be larger than %d", MAX_PASSWORD_SIZE); status = WD_NG; } diff --git a/watchdog/watchdog.h b/watchdog/watchdog.h index 34c79bf3a..2379667bd 100644 --- a/watchdog/watchdog.h +++ b/watchdog/watchdog.h @@ -46,7 +46,7 @@ #define WD_NG (0) #define WD_OK (1) -#define WD_MAX_SALT (256) +#define WD_MAX_PACKET_STRING (256) #define WD_TIME_INIT(tv) ((tv).tv_sec = (tv).tv_usec = 0) #define WD_TIME_ISSET(tv) ((tv).tv_sec || (tv).tv_usec) @@ -77,6 +77,7 @@ typedef enum { WD_START_INTERLOCK, /* announce to start interlocking */ WD_END_INTERLOCK, /* annnouce to end interlocking */ WD_SERVER_DOWN, /* announce server down */ + WD_AUTH_FAILED, /* fail anwser to authentication */ WD_READY, /* answer to the announce */ /* node packet */ @@ -130,7 +131,7 @@ typedef struct { int life; /* life point */ char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ int delegate_ip_flag; /* delegate IP flag */ - struct timeval udp_send_time; /*send time */ + struct timeval udp_send_time; /* send time */ struct timeval udp_last_recv_time; /* recv time */ bool is_lock_holder; /* lock holder flag */ bool in_interlocking; /* failover or failback is in progress */ @@ -170,6 +171,8 @@ typedef struct { typedef struct { WD_PACKET_NO packet_no; /* packet number */ WD_PACKET_BODY wd_body; /* watchdog information */ + struct timeval send_time; + char hash[(MD5_PASSWD_LEN+1)*2]; } WdPacket; /* diff --git a/watchdog/wd_child.c b/watchdog/wd_child.c index 83349295b..102192136 100644 --- a/watchdog/wd_child.c +++ b/watchdog/wd_child.c @@ -32,11 +32,12 @@ #include <sys/time.h> #include "pool.h" #include "watchdog.h" +#include "pool_config.h" #include "wd_ext.h" pid_t wd_child(int fork_wait_time); static void wd_child_exit(int exit_signo); -static int send_response(int sock, WdPacket * recv_pack); +static int wd_send_response(int sock, WdPacket * recv_pack); pid_t wd_child(int fork_wait_time) @@ -104,7 +105,7 @@ wd_child(int fork_wait_time) rtn = wd_recv_packet(fd, &buf); if (rtn == WD_OK) { - send_response(fd, &buf); + wd_send_response(fd, &buf); } close(fd); } @@ -127,7 +128,7 @@ wd_child_exit(int exit_signo) } static int -send_response(int sock, WdPacket * recv_pack) +wd_send_response(int sock, WdPacket * recv_pack) { int rtn = WD_NG; WdInfo * p, *q; @@ -135,6 +136,9 @@ send_response(int sock, WdPacket * recv_pack) WdLockInfo * lock; WdPacket send_packet; struct timeval tv; + char pack_str[WD_MAX_PACKET_STRING]; + int pack_str_len; + char hash[(MD5_PASSWD_LEN+1)*2]; if (recv_pack == NULL) { @@ -143,6 +147,21 @@ send_response(int sock, WdPacket * recv_pack) memset(&send_packet, 0, sizeof(WdPacket)); p = &(recv_pack->wd_body.wd_info); + /* auhtentication */ + if (strlen(pool_config->wd_authkey)) + { + /* calculate hash from packet */ + pack_str_len = wd_packet_to_string(*recv_pack, pack_str, sizeof(pack_str)); + wd_calc_hash(pack_str, pack_str_len, hash); + + if (strcmp(recv_pack->hash, hash)) + { + pool_log("wd_send_response: watchdog authentication failed"); + rtn = wd_authentication_failed(sock); + return rtn; + } + } + /* set response packet no */ switch (recv_pack->packet_no) { diff --git a/watchdog/wd_ext.h b/watchdog/wd_ext.h index 4a5fe8c16..786b0b903 100644 --- a/watchdog/wd_ext.h +++ b/watchdog/wd_ext.h @@ -32,6 +32,7 @@ extern pid_t wd_main(int fork_wait_time); extern int wd_chk_sticky(void); extern int wd_is_watchdog_pid(pid_t pid); extern int wd_reaper_watchdog(pid_t pid, int status); +extern int wd_chk_setuid(void); extern void wd_kill_watchdog(int sig); /* wd_child.c */ @@ -59,6 +60,7 @@ extern int wd_startup(void); extern int wd_declare(void); extern int wd_stand_for_master(void); extern int wd_notice_server_down(void); +extern int wd_authentication_failed(int sock); extern int wd_create_send_socket(char * hostname, int port); extern int wd_create_recv_socket(int port); extern int wd_accept(int sock); @@ -73,6 +75,8 @@ extern int wd_promote_backend(int node_id); extern int wd_set_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count); extern int wd_send_packet_no(WD_PACKET_NO packet_no ); extern int wd_send_lock_packet(WD_PACKET_NO packet_no, WD_LOCK_ID lock_id); +extern void wd_calc_hash(const char *str, int len, char *buf); +int wd_packet_to_string(WdPacket pkt, char *str, int maxlen); /* wd_ping.c */ extern int wd_is_upper_ok(char * server_list); diff --git a/watchdog/wd_interlock.c b/watchdog/wd_interlock.c index 7c817a631..e00fcc0e9 100644 --- a/watchdog/wd_interlock.c +++ b/watchdog/wd_interlock.c @@ -61,7 +61,7 @@ wd_init_interlock(void) pool_error("wd_init_interlock: failed to allocate WD_Locks"); return WD_NG; } - memset(WD_Locks, 0, sizeof(WD_Locks)); + memset((void *)WD_Locks, 0, sizeof(WD_Locks) * WD_MAX_LOCK_NUM); } return WD_OK; diff --git a/watchdog/wd_packet.c b/watchdog/wd_packet.c index f6e38ae3a..7efd3d666 100644 --- a/watchdog/wd_packet.c +++ b/watchdog/wd_packet.c @@ -55,6 +55,7 @@ int wd_startup(void); int wd_declare(void); int wd_stand_for_master(void); int wd_notice_server_down(void); +int wd_authentication_failed(int sock); int wd_create_send_socket(char * hostname, int port); int wd_create_recv_socket(int port); int wd_accept(int sock); @@ -73,6 +74,9 @@ int wd_send_lock_packet(WD_PACKET_NO packet_no, WD_LOCK_ID lock_id); static int wd_send_node_packet(WD_PACKET_NO packet_no, int *node_id_set, int count); static int wd_chk_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count); +void wd_calc_hash(const char *str, int len, char *buf); +int wd_packet_to_string(WdPacket pkt, char *str, int maxlen); + static void * wd_thread_negotiation(void * arg); static int send_packet_4_nodes(WdPacket *packet, WD_SEND_TYPE type); static int hton_wd_packet(WdPacket * to, WdPacket * from); @@ -126,6 +130,23 @@ wd_notice_server_down(void) return rtn; } +/* send authenticaiont failed packet */ +int +wd_authentication_failed(int sock) +{ + int rtn; + WdPacket send_packet; + + memset(&send_packet, 0, sizeof(WdPacket)); + + send_packet.packet_no = WD_AUTH_FAILED; + memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); + + rtn = wd_send_packet(sock, &send_packet); + + return rtn; +} + int wd_send_packet_no(WD_PACKET_NO packet_no ) { @@ -509,6 +530,7 @@ wd_recv_packet(int sock, WdPacket * recv_pack) { ntoh_wd_lock_packet(recv_pack,&buf); } + return WD_OK; } } @@ -528,10 +550,21 @@ wd_thread_negotiation(void * arg) uintptr_t rtn; WdPacket recv_packet; WdInfo * p; + char pack_str[WD_MAX_PACKET_STRING]; + int pack_str_len; thread_arg = (WdPacketThreadArg *)arg; sock = thread_arg->sock; + gettimeofday(&(thread_arg->packet->send_time), NULL); + + if (strlen(pool_config->wd_authkey)) + { + /* calculate hash from packet */ + pack_str_len = wd_packet_to_string(*(thread_arg->packet), pack_str, sizeof(pack_str)); + wd_calc_hash(pack_str, pack_str_len, thread_arg->packet->hash); + } + /* packet send to target watchdog */ rtn = (uintptr_t)wd_send_packet(sock, thread_arg->packet); if (rtn != WD_OK) @@ -549,6 +582,7 @@ wd_thread_negotiation(void * arg) pthread_exit((void *)rtn); } rtn = WD_OK; + switch (thread_arg->packet->packet_no) { case WD_ADD_REQ: @@ -592,6 +626,10 @@ wd_thread_negotiation(void * arg) case WD_UNLOCK_REQUEST: rtn = (recv_packet.packet_no == WD_LOCK_FAILED) ? WD_NG : WD_OK; break; + case WD_AUTH_FAILED: + pool_log("wd_thread_negotiation: watchdog authentication failed"); + rtn = WD_NG; + break; default: break; } @@ -733,6 +771,11 @@ hton_wd_packet(WdPacket * to, WdPacket * from) from_info = &(from->wd_body.wd_info); to->packet_no = htonl(from->packet_no); + to->send_time.tv_sec = htonl(from->send_time.tv_sec); + to->send_time.tv_usec = htonl(from->send_time.tv_usec); + + memcpy(to->hash, from->hash, sizeof(to->hash)); + to_info->status = htonl(from_info->status); to_info->tv.tv_sec = htonl(from_info->tv.tv_sec); to_info->tv.tv_usec = htonl(from_info->tv.tv_usec); @@ -760,6 +803,11 @@ ntoh_wd_packet(WdPacket * to, WdPacket * from) from_info = &(from->wd_body.wd_info); to->packet_no = ntohl(from->packet_no); + to->send_time.tv_sec = ntohl(from->send_time.tv_sec); + to->send_time.tv_usec = ntohl(from->send_time.tv_usec); + + memcpy(to->hash, from->hash, sizeof(to->hash)); + to_info->status = ntohl(from_info->status); to_info->tv.tv_sec = ntohl(from_info->tv.tv_sec); to_info->tv.tv_usec = ntohl(from_info->tv.tv_usec); @@ -788,6 +836,11 @@ hton_wd_node_packet(WdPacket * to, WdPacket * from) from_info = &(from->wd_body.wd_node_info); to->packet_no = htonl(from->packet_no); + to->send_time.tv_sec = htonl(from->send_time.tv_sec); + to->send_time.tv_usec = htonl(from->send_time.tv_usec); + + memcpy(to->hash, from->hash, sizeof(to->hash)); + to_info->node_num = htonl(from_info->node_num); for (i = 0 ; i < from_info->node_num ; i ++) @@ -814,6 +867,11 @@ ntoh_wd_node_packet(WdPacket * to, WdPacket * from) from_info = &(from->wd_body.wd_node_info); to->packet_no = ntohl(from->packet_no); + to->send_time.tv_sec = ntohl(from->send_time.tv_sec); + to->send_time.tv_usec = ntohl(from->send_time.tv_usec); + + memcpy(to->hash, from->hash, sizeof(to->hash)); + to_info->node_num = ntohl(from_info->node_num); for (i = 0 ; i < to_info->node_num ; i ++) @@ -839,6 +897,11 @@ hton_wd_lock_packet(WdPacket * to, WdPacket * from) from_info = &(from->wd_body.wd_lock_info); to->packet_no = htonl(from->packet_no); + to->send_time.tv_sec = htonl(from->send_time.tv_sec); + to->send_time.tv_usec = htonl(from->send_time.tv_usec); + + memcpy(to->hash, from->hash, sizeof(to->hash)); + to_info->lock_id = htonl(from_info->lock_id); return WD_OK; @@ -859,6 +922,11 @@ ntoh_wd_lock_packet(WdPacket * to, WdPacket * from) from_info = &(from->wd_body.wd_lock_info); to->packet_no = ntohl(from->packet_no); + to->send_time.tv_sec = ntohl(from->send_time.tv_sec); + to->send_time.tv_usec = ntohl(from->send_time.tv_usec); + + memcpy(to->hash, from->hash, sizeof(to->hash)); + to_info->lock_id = ntohl(from_info->lock_id); return WD_OK; @@ -1030,3 +1098,40 @@ wd_set_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count) } return rtn; } + +/* calculate hash for authentiction using packet contents */ +void +wd_calc_hash(const char *str, int len, char *buf) +{ + char pass[(MAX_PASSWORD_SIZE + 1) / 2]; + char username[(MAX_PASSWORD_SIZE + 1) / 2]; + size_t pass_len; + size_t username_len; + size_t authkey_len; + + /* use first half of authkey as username, last half as password */ + authkey_len = strlen(pool_config->wd_authkey); + + username_len = authkey_len / 2; + pass_len = authkey_len - username_len; + snprintf(username, username_len + 1, pool_config->wd_authkey); + snprintf(pass, pass_len + 1, pool_config->wd_authkey + username_len); + + /* calculate hash using md5 encrypt */ + pool_md5_encrypt(pass, username, strlen(username), buf + MD5_PASSWD_LEN + 1); + buf[(MD5_PASSWD_LEN+1)*2-1] = '\0'; + + pool_md5_encrypt(buf+MD5_PASSWD_LEN+1, str, len, buf); + buf[MD5_PASSWD_LEN] = '\0'; +} + +int +wd_packet_to_string(WdPacket pkt, char *str, int maxlen) +{ + int len; + + len = snprintf(str, maxlen, "no=%d tv_sec=%ld tv_usec=%ld", + pkt.packet_no, pkt.send_time.tv_sec, pkt.send_time.tv_usec); + + return len; +} diff --git a/watchdog/wd_udp.c b/watchdog/wd_udp.c index e741a382d..f82fa6930 100644 --- a/watchdog/wd_udp.c +++ b/watchdog/wd_udp.c @@ -56,7 +56,7 @@ static RETSIGTYPE writer_exit(int sig); static RETSIGTYPE reader_exit(int sig); static int hton_wd_udp_packet(WdUdpPacket * to, WdUdpPacket * from); static int ntoh_wd_udp_packet(WdUdpPacket * to, WdUdpPacket * from); -static void calc_hash(WdUdpPacket pkt, char *buf); +static int packet_to_string_udp(WdUdpPacket pkt, char *str, int maxlen); int wd_create_udp_send_socket(WdUdpIf udp_if) @@ -295,6 +295,8 @@ pid_t wd_reader(int fork_wait_time, WdUdpIf udp_if) struct timeval tv; char from[WD_MAX_HOST_NAMELEN]; char buf[(MD5_PASSWD_LEN+1)*2]; + char pack_str[WD_MAX_PACKET_STRING]; + int pack_str_len; WdInfo * p; @@ -341,10 +343,11 @@ pid_t wd_reader(int fork_wait_time, WdUdpIf udp_if) if (wd_udp_read(sock, &pkt) == WD_OK) { /* auhtentication */ - if (strlen(pool_config->wd_udp_authkey)) + if (strlen(pool_config->wd_authkey)) { /* calculate hash from packet */ - calc_hash(pkt, buf); + pack_str_len = packet_to_string_udp(pkt, pack_str, sizeof(pack_str)); + wd_calc_hash(pack_str, pack_str_len, buf); if (strcmp(pkt.hash, buf)) { @@ -388,6 +391,8 @@ pid_t wd_writer(int fork_wait_time, WdUdpIf udp_if) pid_t pid = 0; WdUdpPacket pkt; WdInfo * p = WD_List; + char pack_str[WD_MAX_PACKET_STRING]; + int pack_str_len; pid = fork(); if (pid != 0) @@ -434,13 +439,14 @@ pid_t wd_writer(int fork_wait_time, WdUdpIf udp_if) pkt.status = p->status; - if (strlen(pool_config->wd_udp_authkey)) + if (strlen(pool_config->wd_authkey)) { /* calculate hash from packet */ - calc_hash(pkt, pkt.hash); + pack_str_len = packet_to_string_udp(pkt, pack_str, sizeof(pack_str)); + wd_calc_hash(pack_str, pack_str_len, pkt.hash); } - wd_udp_write(sock, &pkt, sizeof(pkt), udp_if.addr); + wd_udp_write(sock, &pkt, sizeof(pkt), udp_if.addr); pool_debug("wd_writer: send heartbeat signal to %s", udp_if.addr); sleep(pool_config->wd_udp_keepalive); } @@ -516,34 +522,12 @@ ntoh_wd_udp_packet(WdUdpPacket * to, WdUdpPacket * from) return WD_OK; } -/* calculate hash for authentiction using packet contents */ -static void -calc_hash(WdUdpPacket pkt, char *buf) +/* convert pakcet to string and return length of the string */ +static int packet_to_string_udp(WdUdpPacket pkt, char *str, int maxlen) { - char pass[(MAX_PASSWORD_SIZE + 1) / 2]; - char username[(MAX_PASSWORD_SIZE + 1) / 2]; - char salt[WD_MAX_SALT]; - size_t pass_len; - size_t username_len; - size_t salt_len; - size_t authkey_len; - - /* use first half of authkey as username, last half as password */ - authkey_len = strlen(pool_config->wd_udp_authkey); - - username_len = authkey_len / 2; - pass_len = authkey_len - username_len; - snprintf(username, username_len + 1, pool_config->wd_udp_authkey); - snprintf(pass, pass_len + 1, pool_config->wd_udp_authkey + username_len); - - /* convert pakcet to string and use this as salt */ - salt_len = snprintf(salt, sizeof(salt), "status=%d tv_sec=%ld tv_usec=%ld from=%s", - pkt.status, pkt.send_time.tv_sec, pkt.send_time.tv_usec, pkt.from); - - /* calculate hash using md5 encrypt */ - pool_md5_encrypt(pass, username, strlen(username), buf + MD5_PASSWD_LEN + 1); - buf[(MD5_PASSWD_LEN+1)*2-1] = '\0'; - - pool_md5_encrypt(buf+MD5_PASSWD_LEN+1, salt, salt_len, buf); - buf[MD5_PASSWD_LEN] = '\0'; + int len; + len = snprintf(str, maxlen, "status=%d tv_sec=%ld tv_usec=%ld from=%s", + pkt.status, pkt.send_time.tv_sec, pkt.send_time.tv_usec, pkt.from); + + return len; } [parent: 0ab7ef476eae]