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]