Changeset 481 for trunk/src/sh_socket.c
- Timestamp:
- Jul 18, 2015, 5:06:52 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/sh_socket.c
r421 r481 33 33 #include <string.h> 34 34 35 #if TIME_WITH_SYS_TIME 36 #include <sys/time.h> 37 #include <time.h> 38 #else 39 #if HAVE_SYS_TIME_H 40 #include <sys/time.h> 41 #else 42 #include <time.h> 43 #endif 44 #endif 45 35 46 #include "samhain.h" 36 47 #include "sh_socket.h" … … 38 49 #include "sh_unix.h" 39 50 #include "sh_calls.h" 51 #include "sh_guid.h" 52 #include "sh_fifo.h" 53 #include "sh_utils.h" 40 54 41 55 #undef FIL__ … … 46 60 #include <signal.h> 47 61 62 typedef struct delta_tofetch { 63 char uuid[SH_UUID_BUF]; 64 time_t last_time; 65 unsigned int count; 66 } SH_DELTA_DB; 67 68 static SH_DELTA_DB * parse_entry(SH_DELTA_DB * db, const char * str) 69 { 70 long last_time; 71 unsigned int count; 72 char buf[SH_UUID_BUF]; 73 int res = sscanf(str, _("%u:%ld:%36s"), &count, &last_time, buf); 74 if (res == 3) 75 { 76 db->count = count; 77 db->last_time = (time_t) last_time; 78 sl_strlcpy(db->uuid, buf, SH_UUID_BUF); 79 return db; 80 } 81 return NULL; 82 } 83 84 static char * unparse_entry(const SH_DELTA_DB * db, char * str, size_t len) 85 { 86 int nbytes = sl_snprintf(str, len, _("%u:%ld:%s"), 87 db->count, (long) db->last_time, db->uuid); 88 if (nbytes < 0 || nbytes >= (int) len) 89 return NULL; 90 return str; 91 } 92 93 static SH_FIFO xfifo = SH_FIFO_INITIALIZER; 94 95 int sh_socket_store_uuid(const char * cmd) 96 { 97 char * p = sh_util_strdup(cmd); 98 char * q = strchr(cmd, ':'); 99 char entry[SH_BUFSIZE]; 100 SH_DELTA_DB db; 101 102 if (!q) { SH_FREE(p); return -1; } 103 104 ++q; 105 106 if (0 != sh_uuid_check(q)) { SH_FREE(p); return -1; } 107 108 db.count = 0; 109 db.last_time = (time_t) 0; 110 sl_strlcpy(db.uuid, q, SH_UUID_BUF); 111 SH_FREE(p); 112 113 if (NULL != unparse_entry(&db, entry, sizeof(entry))) 114 { 115 sh_fifo_push(&xfifo, entry); 116 return 0; 117 } 118 return -1; 119 } 120 121 static unsigned int try_interval = 60; 122 static unsigned int try_max = 2; 123 124 int set_delta_retry_interval(const char * str) 125 { 126 long val = strtol (str, (char **)NULL, 10); 127 128 if (val < 0 || val > INT_MAX) 129 return -1; 130 try_interval = (unsigned int) val; 131 return 0; 132 } 133 int set_delta_retry_count(const char * str) 134 { 135 long val = strtol (str, (char **)NULL, 10); 136 137 if (val < 0 || val > INT_MAX) 138 return -1; 139 try_max = (unsigned int) val; 140 return 0; 141 } 142 143 char * sh_socket_get_uuid(int * errflag, unsigned int * count, time_t * last) 144 { 145 char * entry = sh_fifo_pop(&xfifo); 146 char * uuid = NULL; 147 148 if (entry) 149 { 150 SH_DELTA_DB db; 151 time_t now; 152 153 if (NULL == parse_entry(&db, entry)) 154 { 155 SH_FREE(entry); 156 sh_error_handle(SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_SUBGEN, 157 _("Bad entry in fifo"), 158 _("sh_socket_get_uuid")); 159 *errflag = -1; 160 return NULL; 161 } 162 163 now = time(NULL); 164 165 if ( (db.count > 0) && ((unsigned long)(now - db.last_time) < try_interval) ) 166 { 167 sh_fifo_push_tail(&xfifo, entry); 168 SH_FREE(entry); 169 *errflag = -1; 170 return NULL; 171 } 172 173 SH_FREE(entry); 174 uuid = sh_util_strdup(db.uuid); 175 *count = db.count; 176 *last = db.last_time; 177 } 178 179 *errflag = 0; 180 return uuid; 181 } 182 183 int sh_socket_return_uuid (const char * uuid, unsigned int count, time_t last) 184 { 185 (void) last; 186 187 if (count < try_max) 188 { 189 char entry[SH_BUFSIZE]; 190 SH_DELTA_DB db; 191 time_t now = time(NULL); 192 193 db.count = count + 1; 194 db.last_time = now; 195 sl_strlcpy(db.uuid, uuid, SH_UUID_BUF); 196 197 if (NULL != unparse_entry(&db, entry, sizeof(entry))) 198 return sh_fifo_push_tail(&xfifo, entry); /* >0 for success */ 199 } 200 return -1; 201 } 202 48 203 void sh_socket_server_cmd(const char * srvcmd) 49 204 { … … 54 209 SL_RET0(_("sh_socket_server_cmd")); 55 210 } 56 if ((srvcmd[0] == 'S') && (srvcmd[1] == 'T') && 57 (srvcmd[2] == 'O') && (srvcmd[3] == 'P'))211 212 if (0 == strncmp(srvcmd, _("STOP"), 4)) 58 213 { 59 214 TPT((0, FIL__, __LINE__, _("msg=<stop command from server>\n"))); … … 65 220 #endif 66 221 } 67 else if ((srvcmd[0] == 'R') && (srvcmd[1] == 'E') && 68 (srvcmd[2] == 'L') && (srvcmd[3] == 'O') && 69 (srvcmd[4] == 'A') && (srvcmd[5] == 'D')) 222 223 else if (0 == strncmp(srvcmd, _("RELOAD"), 6)) 70 224 { 71 225 TPT((0, FIL__, __LINE__, _("msg=<reload command from server>\n"))); … … 77 231 #endif 78 232 } 79 else if ((srvcmd[0] == 'S') && (srvcmd[1] == 'C') && 80 (srvcmd[2] == 'A') && (srvcmd[3] == 'N')) 233 234 else if (0 == strncmp(srvcmd, _("DELTA:"), 6)) 235 { 236 TPT((0, FIL__, __LINE__, _("msg=<delta load command from server>\n"))); 237 238 if (sh_socket_store_uuid(srvcmd) == 0) 239 { 240 ++sh_load_delta_flag; 241 ++sig_raised; 242 } 243 } 244 245 else if (0 == strncmp(srvcmd, _("SCAN"), 4)) 81 246 { 82 247 TPT((0, FIL__, __LINE__, _("msg=<scan command from server>\n"))); 83 if (sh.flag.isdaemon == ON)248 if (sh.flag.isdaemon == S_TRUE) 84 249 { 85 250 #ifdef SIGTTOU … … 96 261 } 97 262 } 263 264 /* Unknown command 265 */ 98 266 else 99 267 { 100 sh_error_handle(SH_ERR_ INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN,268 sh_error_handle(SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_SUBGEN, 101 269 srvcmd, 102 270 _("sh_socket_server_cmd")); … … 104 272 SL_RET0(_("sh_socket_server_cmd")); 105 273 } 106 /* #if defined (SH_WITH_CLIENT) 107 */ 108 #endif 274 #endif /* #if defined (SH_WITH_CLIENT) */ 109 275 110 276 #if defined(SH_WITH_SERVER) … … 225 391 struct stat buf; 226 392 227 #ifdef SH_DEBUG_SOCKET228 fprintf(stderr, "PROBE\n");229 #endif230 231 393 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item; 232 394 item = (client_t *) zAVLNext(&avlcursor)) 233 395 { 234 #ifdef SH_DEBUG_SOCKET235 fprintf(stderr, "%s %d\n", item->hostname, (int)item->status_now);236 #endif237 238 396 if (item->status_now != CLT_INACTIVE) 239 397 { … … 242 400 file = get_client_conf_file (item->hostname, &dummy); 243 401 244 #ifdef SH_DEBUG_SOCKET245 fprintf(stderr, "%s\n", file);246 #endif247 402 if (0 == stat (file, &buf)) 248 403 { … … 250 405 while (new) 251 406 { 252 #ifdef SH_DEBUG_SOCKET253 fprintf(stderr, "%s <> %s\n", new->clt, item->hostname);254 #endif255 407 if (0 == sl_strcmp(new->clt, item->hostname)) 256 408 { 257 409 flag = 1; /* Client is in list already */ 258 410 259 #ifdef SH_DEBUG_SOCKET260 fprintf(stderr, "%lu <> %lu\n",261 (unsigned long) buf.st_mtime,262 (unsigned long)new->cti);263 #endif264 411 if (buf.st_mtime > new->cti) 265 412 { … … 368 515 369 516 #define NEED_PASSWORD_AUTH 370 371 517 #endif 372 518 … … 540 686 SL_RETURN( (0), _("sh_socket_open_int")); 541 687 } 542 /* #if !defined(HAVE_CMSGCRED) || !defined(SO_PEERCRED) */ 543 /* #endif */ 544 545 /* 546 #if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && !defined(HAVE_STRUCT_CMSGCRED) && !defined(HAVE_STRUCT_FCRED) && !(defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS)) 547 static 548 int sh_socket_read (struct socket_cmd * srvcmd) 549 { 550 srvcmd->cmd[0] = '\0'; 551 srvcmd->clt[0] = '\0'; 552 return 0; 553 } 554 #else 555 */ 688 556 689 557 690 /* … … 582 715 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 583 716 */ 584 static 585 int sh_socket_read (struct socket_cmd * srvcmd) 586 { 587 struct socket_cmd * list_cmd; 588 char message[SH_MAXMSG]; 589 struct sockaddr_un name; 590 ACCEPT_TYPE_ARG3 size = sizeof(name); 591 717 718 static int receive_message(int talkfd, struct msghdr * msg, size_t message_size) 719 { 720 unsigned int retry = 0; 592 721 int nbytes; 593 int talkfd; 594 int retry = 0; 595 596 char * cmd = NULL; 597 char * clt = NULL; 598 599 int client_uid = -1; 722 char * message = msg->msg_iov->iov_base; 600 723 char errbuf[SH_ERRBUF_SIZE]; 601 724 602 603 struct msghdr msg;604 struct iovec iov;605 606 #if defined(NEED_PASSWORD_AUTH)607 char * eopw = NULL;608 char * goodpassword = NULL;609 #endif610 611 #if defined(HAVE_GETPEEREID)612 uid_t peer_uid;613 gid_t peer_gid;614 #elif defined(SO_PEERCRED)615 struct ucred cr;616 #ifdef HAVE_SOCKLEN_T617 socklen_t cl = sizeof(cr);618 #else619 int cl = sizeof(cr);620 #endif621 622 #elif defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))623 624 #ifdef HAVE_STRUCT_CMSGCRED625 typedef struct cmsgcred Cred;626 #define CRED_UID cmcred_uid627 628 #elif HAVE_STRUCT_FCRED629 typedef struct fcred Cred;630 #define CRED_UID fc_uid631 632 #elif HAVE_STRUCT_SOCKCRED633 typedef struct sockcred Cred;634 #define CRED_UID sc_uid635 636 #endif637 Cred *cred;638 639 /* Compute size without padding */640 char cmsgmem[ALIGN(sizeof(struct cmsghdr)) + ALIGN(sizeof(Cred))];641 /* for NetBSD */642 643 /* Point to start of first structure */644 struct cmsghdr *cmsg = (struct cmsghdr *) cmsgmem;645 #endif646 647 if (pf_unix_fd < 0)648 {649 return 0;650 }651 652 iov.iov_base = (char *) &message;653 iov.iov_len = sizeof(message);654 655 memset (&msg, 0, sizeof (msg));656 msg.msg_iov = &iov;657 msg.msg_iovlen = 1;658 659 #if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID)660 #if defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))661 msg.msg_control = (char *) cmsg;662 msg.msg_controllen = sizeof (cmsgmem);663 memset (cmsg, 0, sizeof (cmsgmem));664 #endif665 #endif666 667 /* the socket is non-blocking668 * 'name' is the address of the sender socket669 */670 725 do { 671 talkfd = accept(pf_unix_fd, (struct sockaddr *) &name, &size); 672 } while (talkfd < 0 && errno == EINTR); 673 674 if ((talkfd < 0) && (errno == EAGAIN)) 675 { 676 return 0; 677 } 678 else if (talkfd < 0) 679 { 680 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, 681 sh_error_message (errno, errbuf, sizeof(errbuf)), 682 _("sh_socket_read: accept")); 683 return -1; 684 } 685 686 687 #if defined(LOCAL_CREDS) && !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) 688 /* Set the socket to receive credentials on the next message 689 */ 690 { 691 int on = 1; 692 if (setsockopt (talkfd, 0, LOCAL_CREDS, &on, sizeof (on)) < 0) 693 { 694 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, 695 sh_error_message (errno, errbuf, sizeof(errbuf)), 696 _("sh_socket_read: setsockopt")); 697 sl_close_fd(FIL__, __LINE__, talkfd); 698 return -1; 699 } 700 } 701 #endif 702 703 do { 704 nbytes = recvmsg (talkfd, &msg, 0); 726 nbytes = recvmsg (talkfd, msg, 0); 705 727 if ((nbytes < 0) && (errno != EAGAIN)) 706 728 { … … 718 740 } while ((nbytes < 0) && (retry < 3)); 719 741 720 #ifdef SH_DEBUG_SOCKET721 fprintf(stderr, "%d bytes received\n", nbytes);722 #endif723 724 742 /* msg.msg_iov.iov_base, filled by recvmsg 725 743 */ 726 message[ sizeof(message)-1] = '\0';744 message[message_size-1] = '\0'; 727 745 728 746 if (nbytes < 0) … … 731 749 { 732 750 /* no data */ 751 sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, errno, MSG_E_SUBGEN, 752 sh_error_message (errno, errbuf, sizeof(errbuf)), 753 _("sh_socket_read: recvfrom")); 733 754 sl_close_fd(FIL__, __LINE__, talkfd); 734 755 return 0; … … 740 761 return -1; 741 762 } 763 return 0; 764 } 742 765 743 766 #if defined(HAVE_GETPEEREID) 767 768 static int get_peer_uid(int talkfd) 769 { 770 uid_t peer_uid; 771 gid_t peer_gid; 772 char errbuf[SH_ERRBUF_SIZE]; 773 744 774 if (0 != getpeereid(talkfd, &peer_uid, &peer_gid)) 745 775 { … … 750 780 return -1; 751 781 } 752 client_uid = peer_uid; 753 cmd = message; 754 #elif defined(SO_PEERCRED) 782 return peer_uid; 783 } 784 785 #elif defined(SO_PEERCRED) 786 787 static int get_peer_uid(int talkfd) 788 { 789 char errbuf[SH_ERRBUF_SIZE]; 790 struct ucred cr; 791 #ifdef HAVE_SOCKLEN_T 792 socklen_t cl = sizeof(cr); 793 #else 794 int cl = sizeof(cr); 795 #endif 796 755 797 if (0 != getsockopt(talkfd, SOL_SOCKET, SO_PEERCRED, &cr, &cl)) 756 798 { … … 761 803 return -1; 762 804 } 763 client_uid = cr.uid; 764 cmd = message; 765 #elif defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS)) 766 if (cmsg->cmsg_len < sizeof (cmsgmem) || cmsg->cmsg_type != SCM_CREDS) 767 { 768 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, 769 _("Message from recvmsg() was not SCM_CREDS"), 770 _("sh_socket_read")); 771 772 /* Check for file descriptors sent using SCM_RIGHTS, and 773 * close them. If MSG_CTRUNC is set, the buffer was too small, 774 * and no fds are duped. 775 */ 776 if (msg.msg_controllen >= sizeof(struct cmsghdr) && 777 (msg.msg_flags & MSG_CTRUNC) == 0) 778 { 779 unsigned int data_size; 780 unsigned int data_i; 781 int fdcount, fdmax; 782 struct cmsghdr * cmptr; 783 int fdsbuf[1 + (sizeof(cmsgmem)/sizeof(int))]; 784 785 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL; 786 cmptr = CMSG_NXTHDR(&msg, cmptr)) 787 { 788 if (cmptr->cmsg_len > sizeof (cmsgmem) || 789 cmptr->cmsg_level != SOL_SOCKET || 790 cmptr->cmsg_type != SCM_RIGHTS) 791 continue; 792 793 /* Crappy way of finding the data length. 794 * cmptr->cmsg_len includes both header and padding, 795 * how are you supposed to find the data length? 796 * cmptr->cmsg_len - ALIGN(sizeof(struct cmsghdr)) ? 797 */ 798 data_size = 0; 799 800 for (data_i = 0; data_i < cmptr->cmsg_len; ++data_i) 801 { 802 if (CMSG_LEN(data_i) == cmptr->cmsg_len) 803 { 804 data_size = data_i; 805 break; 806 } 807 } 808 memcpy(fdsbuf, CMSG_DATA(cmptr), data_size); 809 fdmax = data_size / sizeof(int); 810 for (fdcount = 0; fdcount < fdmax; ++fdcount) 811 (void) sl_close_fd(FIL__, __LINE__, fdsbuf[fdcount]); 812 } 813 } 814 815 sl_close_fd(FIL__, __LINE__, talkfd); 816 return -1; 817 } 818 cred = (Cred *) CMSG_DATA (cmsg); 819 client_uid = cred->CRED_UID; 820 cmd = message; 821 #elif defined(NEED_PASSWORD_AUTH) 805 return cr.uid; 806 } 807 808 #endif 809 810 #if defined(NEED_PASSWORD_AUTH) 811 char * check_password(char * message, int * client_uid, int talkfd) 812 { 813 char * cmd = NULL; 814 char * eopw = NULL; 815 char * goodpassword = NULL; 816 822 817 goodpassword = sh_get_sockpass(); 823 818 eopw = strchr(message, '@'); … … 830 825 strlen(goodpassword) < (sizeof(message)/2)) 831 826 { 832 client_uid = sh_socket_flaguid;827 *client_uid = sh_socket_flaguid; 833 828 cmd = &message[strlen(goodpassword)+1]; 834 829 sh_set_sockpass(); … … 841 836 sh_set_sockpass(); 842 837 sl_close_fd(FIL__, __LINE__, talkfd); 838 return NULL; 839 } 840 return cmd; 841 } 842 #endif 843 844 static int list_all (int talkfd, char * cmd); 845 static int process_message(int talkfd, char * cmd, struct socket_cmd * srvcmd); 846 847 static 848 int sh_socket_read (struct socket_cmd * srvcmd) 849 { 850 char message[SH_MAXMSG]; 851 struct sockaddr_un name; 852 ACCEPT_TYPE_ARG3 size = sizeof(name); 853 int talkfd; 854 char * cmd = NULL; 855 int client_uid = -1; 856 char errbuf[SH_ERRBUF_SIZE]; 857 struct msghdr msg; 858 struct iovec iov; 859 int status; 860 861 if (pf_unix_fd < 0) 862 return 0; 863 864 iov.iov_base = (char *) &message; 865 iov.iov_len = sizeof(message); 866 867 memset (&msg, 0, sizeof (msg)); 868 msg.msg_iov = &iov; 869 msg.msg_iovlen = 1; 870 871 /* the socket is non-blocking 872 * 'name' is the address of the sender socket 873 */ 874 do { 875 talkfd = accept(pf_unix_fd, (struct sockaddr *) &name, &size); 876 } while (talkfd < 0 && errno == EINTR); 877 878 if ((talkfd < 0) && (errno == EAGAIN)) 879 { 880 return 0; 881 } 882 else if (talkfd < 0) 883 { 884 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, 885 sh_error_message (errno, errbuf, sizeof(errbuf)), 886 _("sh_socket_read: accept")); 843 887 return -1; 844 888 } 889 890 if (receive_message(talkfd, &msg, sizeof(message)) < 0) 891 return -1; 892 893 /* Authenticate request by peer uid or password. 894 */ 895 #if defined(HAVE_GETPEEREID) 896 client_uid = get_peer_uid(talkfd); 897 cmd = message; 898 899 #elif defined(SO_PEERCRED) 900 client_uid = get_peer_uid(talkfd); 901 cmd = message; 902 903 #elif defined(NEED_PASSWORD_AUTH) 904 cmd = check_password(message, &client_uid, talkfd); 905 845 906 #else 846 907 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, … … 851 912 #endif 852 913 853 #ifdef SH_DEBUG_SOCKET854 fprintf(stderr, "Peer uid=%d, required=%d\n",855 client_uid, sh_socket_flaguid);856 #endif857 858 914 if (client_uid != sh_socket_flaguid) 859 915 { … … 865 921 } 866 922 867 868 /* Give a diagnostic message. 869 */ 870 #ifdef SH_DEBUG_SOCKET 871 fprintf (stderr, "Server: got message: %s\n", cmd); 872 #endif 873 874 clt = strchr(cmd, ':'); 923 status = process_message(talkfd, cmd, srvcmd); 924 925 sl_close_fd(FIL__, __LINE__, talkfd); 926 return status; 927 } 928 929 static int check_valid_command(const char * str) 930 { 931 unsigned int i = 0; 932 char * commands[] = { N_("DELTA"), N_("RELOAD"), N_("STOP"), N_("SCAN"), 933 N_("CANCEL"), N_("LISTALL"), N_("LIST"), N_("PROBE"), NULL }; 934 935 while (commands[i]) 936 { 937 if (0 == strcmp(_(commands[i]), str)) 938 { 939 return 0; 940 } 941 ++i; 942 } 943 return -1; 944 } 945 946 static int send_reply (int fd, char * msg) 947 { 948 int nbytes = send (fd, msg, strlen(msg) + 1, 0); 949 950 if (nbytes < 0) 951 { 952 char errbuf[SH_ERRBUF_SIZE]; 953 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, 954 sh_error_message (errno, errbuf, sizeof(errbuf)), 955 _("send_reply")); 956 return -1; 957 } 958 959 return nbytes; 960 } 961 962 static int process_message(int talkfd, char * cmd, struct socket_cmd * srvcmd) 963 { 964 int nbytes; 965 char error_type[SH_ERRBUF_SIZE] = { '\0' }; 966 char * clt = (cmd) ? strchr(cmd, ':') : NULL; 967 968 if (clt && 0 == strncmp(cmd, _("DELTA:"), 6)) 969 { 970 /* DELTA:uuid:hostname 971 */ 972 char * uuid = clt; 973 974 *uuid = '\0'; ++uuid; 975 clt = strchr(uuid, ':'); 976 if (clt) { *clt = '\0'; ++clt; } 977 978 if (sh_uuid_check(uuid) < 0) 979 { 980 sl_strlcpy(error_type, _("!E:uuid-format:"), sizeof(error_type)); 981 sl_strlcat(error_type, uuid, sizeof(error_type)); 982 clt = NULL; 983 } 984 985 --uuid; *uuid = ':'; 986 } 987 else if (clt && *clt == ':') 988 { 989 *clt = '\0'; ++clt; 990 if (check_valid_command(cmd) < 0) 991 { 992 sl_strlcpy(error_type, _("!E:cmd-invalid:"), sizeof(error_type)); 993 sl_strlcat(error_type, cmd, sizeof(error_type)); 994 clt = NULL; 995 } 996 } 997 875 998 if (clt != NULL) 876 999 { 877 *clt = '\0'; ++clt;878 1000 if (sl_strlen(cmd) >= SH_MAXMSGLEN) 879 1001 { 880 #ifdef SH_DEBUG_SOCKET881 fprintf (stderr, "Server: command too long: %s\n", cmd);882 #endif883 1002 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, 884 1003 _("Bad message format: command too long"), 885 1004 _("sh_socket_read")); 886 sl_close_fd(FIL__, __LINE__, talkfd); 1005 sl_strlcpy(error_type, _("!E:cmd-toolong"), sizeof(error_type)); 1006 send_reply(talkfd, error_type); 887 1007 return -1; 888 1008 } 889 1009 else if (sl_strlen(clt) >= SH_MAXMSGLEN) 890 1010 { 891 #ifdef SH_DEBUG_SOCKET892 fprintf (stderr, "Server: hostname too long: %s\n", clt);893 #endif894 1011 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, 895 1012 _("Bad message format: hostname too long"), 896 1013 _("sh_socket_read")); 897 sl_close_fd(FIL__, __LINE__, talkfd); 1014 sl_strlcpy(error_type, _("!E:hostname-toolong"), sizeof(error_type)); 1015 send_reply(talkfd, error_type); 898 1016 return -1; 899 1017 } 900 if (cmd[0] == 'L' && cmd[1] == 'I' && 901 cmd[2] == 'S' && cmd[3] == 'T') 902 { 903 #ifdef SH_DEBUG_SOCKET 904 fprintf (stderr, "Server: list %s\n", clt); 905 #endif 906 goto list_all; 907 } 908 else if (cmd[0] == 'P' && cmd[1] == 'R' && 909 cmd[2] == 'O' && cmd[3] == 'B' && cmd[4] == 'E') 910 { 911 #ifdef SH_DEBUG_SOCKET 912 fprintf (stderr, "Server: probe start %s\n", clt); 913 #endif 1018 1019 if (0 == strncmp(cmd, _("LIST"), 4)) 1020 return list_all(talkfd, cmd); 1021 else if (0 == strncmp(cmd, _("PROBE"), 4)) 1022 { 914 1023 sh_socket_probe4reload(); 915 #ifdef SH_DEBUG_SOCKET 916 fprintf (stderr, "Server: probe done %s\n", clt); 917 #endif 918 cmd[0] = 'L'; cmd[1] = 'I'; cmd[2] = 'S'; cmd[3] = 'T';cmd[4] = '\0'; 919 goto list_all; 920 } 1024 sl_strlcpy(cmd, _("LIST"), 5); 1025 return list_all(talkfd, cmd); 1026 } 1027 921 1028 sl_strlcpy (srvcmd->cmd, cmd, SH_MAXMSGLEN); 922 1029 sl_strlcpy (srvcmd->clt, clt, SH_MAXMSGLEN); … … 925 1032 else 926 1033 { 927 #ifdef SH_DEBUG_SOCKET928 fprintf (stderr, "Server: bad message\n");929 #endif930 1034 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, 931 1035 _("Bad message format"), 932 1036 _("sh_socket_read")); 933 sl_close_fd(FIL__, __LINE__, talkfd); 1037 if (error_type[0] == '\0') 1038 sl_strlcpy(error_type, _("!E:message-format"), sizeof(error_type)); 1039 send_reply(talkfd, error_type); 934 1040 return -1; 935 1041 } 936 1042 937 1043 /* Bounce the message back to the sender. 938 * 'name' is the receiver address; it has been been filled939 * with the sender address in the recvfrom call940 1044 */ 941 #ifdef SH_DEBUG_SOCKET 942 fprintf (stderr, "Server: send message: %s to %s\n", 943 cmd, name.sun_path); 944 #endif 945 /* 946 nbytes = sendto (pf_unix_fd, message, nbytes, 0, 947 (struct sockaddr *) & name, size); 948 */ 949 nbytes = send (talkfd, cmd, strlen(cmd) + 1, 0); 950 sl_close_fd(FIL__, __LINE__, talkfd); 951 if (nbytes < 0) 952 { 953 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN, 954 sh_error_message (errno, errbuf, sizeof(errbuf)), 955 _("sh_socket_read: send")); 956 return -1; 957 } 958 #ifdef SH_DEBUG_SOCKET 959 fprintf (stderr, "Server: message is out\n"); 960 #endif 1045 nbytes = send_reply(talkfd, cmd); 1046 961 1047 return nbytes; 962 963 list_all: 964 #ifdef SH_DEBUG_SOCKET 965 fprintf (stderr, "Server: list all\n"); 966 #endif 967 if (cmd[4] == 'A' && cmd[5] == 'L' && cmd[6] == 'L') 1048 } 1049 1050 static int list_all (int talkfd, char * cmd) 1051 { 1052 int nbytes; 1053 struct socket_cmd * list_cmd; 1054 char message[SH_MAXMSG]; 1055 char errbuf[SH_ERRBUF_SIZE]; 1056 1057 if (0 == strncmp(cmd, _("LISTALL"), 7)) 968 1058 { 969 1059 list_cmd = runlist; 970 1060 while (list_cmd) 971 1061 { 972 sl_snprintf(message, sizeof(message), _("SENT % 8s %32s %s"),1062 sl_snprintf(message, sizeof(message), _("SENT %42s %32s %s"), 973 1063 list_cmd->cmd, list_cmd->clt, list_cmd->cti); 974 /* 975 sl_strlcpy(message, _("DONE"), SH_MAXMSG); 976 sl_strlcat(message, " ", SH_MAXMSG); 977 sl_strlcat(message, list_cmd->cmd, SH_MAXMSG); 978 sl_strlcat(message, " ", SH_MAXMSG); 979 sl_strlcat(message, list_cmd->clt, SH_MAXMSG); 980 sl_strlcat(message, " ", SH_MAXMSG); 981 sl_strlcat(message, list_cmd->cti, SH_MAXMSG); 982 */ 1064 983 1065 nbytes = send (talkfd, message, sl_strlen(message) + 1, 0); 984 1066 if (nbytes < 0) … … 987 1069 sh_error_message (errno, errbuf, sizeof(errbuf)), 988 1070 _("sh_socket_read: sendto")); 989 sl_close_fd(FIL__, __LINE__, talkfd);990 1071 return -1; 991 1072 } … … 997 1078 while (list_cmd) 998 1079 { 999 sl_snprintf(message, sizeof(message), _(">>>> % 8s %32s %s"),1080 sl_snprintf(message, sizeof(message), _(">>>> %42s %32s %s"), 1000 1081 list_cmd->cmd, list_cmd->clt, list_cmd->cti); 1001 /* 1002 sl_strlcpy(message, _(">>>>"), SH_MAXMSG); 1003 sl_strlcat(message, " ", SH_MAXMSG); 1004 sl_strlcat(message, list_cmd->cmd, SH_MAXMSG); 1005 sl_strlcat(message, " ", SH_MAXMSG); 1006 sl_strlcat(message, list_cmd->clt, SH_MAXMSG); 1007 sl_strlcat(message, " ", SH_MAXMSG); 1008 sl_strlcat(message, list_cmd->cti, SH_MAXMSG); 1009 */ 1010 /* 1011 nbytes = sendto (pf_unix_fd, message, sl_strlen(message) + 1, 0, 1012 (struct sockaddr *) & name, size); 1013 */ 1082 1014 1083 nbytes = send (talkfd, message, sl_strlen(message) + 1, 0); 1015 1084 if (nbytes < 0) … … 1018 1087 sh_error_message (errno, errbuf, sizeof(errbuf)), 1019 1088 _("sh_socket_read: sendto")); 1020 sl_close_fd(FIL__, __LINE__, talkfd);1021 1089 return -1; 1022 1090 } … … 1024 1092 } 1025 1093 1026 /* 1027 nbytes = sendto (pf_unix_fd, _("END"), 4, 0, 1028 (struct sockaddr *) & name, size); 1029 */ 1030 /* nbytes = *//* never read */ send (talkfd, _("END"), 4, 0); 1031 sl_close_fd(FIL__, __LINE__, talkfd); 1094 send (talkfd, _("END"), 4, 0); 1032 1095 return 0; 1033 1096 } 1034 /* #if !defined(HAVE_CMSGCRED) || !defined(SO_PEERCRED) */1035 /* #endif */1036 1097 1037 1098 static void sh_socket_add2list (struct socket_cmd * in) 1038 1099 { 1039 struct socket_cmd * new; 1040 1041 new = SH_ALLOC(sizeof(struct socket_cmd)); 1042 sl_strlcpy (new->cmd, in->cmd, sizeof(new->cmd)); 1043 sl_strlcpy (new->clt, in->clt, sizeof(new->clt)); 1044 #ifdef SH_DEBUG_SOCKET 1045 fprintf(stderr, "add2list: time set for %s\n", new->clt); 1046 #endif 1047 (void) sh_unix_time(0, new->cti, sizeof(new->cti)); 1048 new->next = cmdlist; 1049 cmdlist = new; 1050 1051 return; 1052 } 1053 1054 static void sh_socket_add2run (struct socket_cmd * in) 1055 { 1056 struct socket_cmd * new = runlist; 1057 char * client_name = in->clt; 1100 struct socket_cmd * new = cmdlist; 1101 struct socket_cmd * last = cmdlist; 1058 1102 1059 1103 while (new) 1060 1104 { 1061 if (0 == sl_strcmp(new->clt, client_name)) 1062 { 1063 sl_strlcpy (new->cmd, in->cmd, sizeof(new->cmd)); 1064 sl_strlcpy (new->clt, in->clt, sizeof(new->clt)); 1065 #ifdef SH_DEBUG_SOCKET 1066 fprintf(stderr, "add2run: time reset for %s\n", new->clt); 1067 #endif 1105 /* Only skip identical commands. 1106 */ 1107 if (0 == sl_strcmp(new->clt, in->clt) && 1108 0 == sl_strcmp(new->cmd, in->cmd)) 1109 { 1068 1110 (void) sh_unix_time(0, new->cti, sizeof(new->cti)); 1069 1111 return; … … 1073 1115 1074 1116 new = SH_ALLOC(sizeof(struct socket_cmd)); 1075 sl_strlcpy (new->cmd, in->cmd, sizeof(new->cmd)); 1076 sl_strlcpy (new->clt, in->clt, sizeof(new->clt)); 1117 sl_strlcpy (new->cmd, in->cmd, sizeof(new->cmd)); 1118 sl_strlcpy (new->clt, in->clt, sizeof(new->clt)); 1119 (void) sh_unix_time(0, new->cti, sizeof(new->cti)); 1120 new->next = NULL; 1121 1122 if (last) 1123 { 1124 while (last->next) { last = last->next; } 1125 last->next = new; 1126 } 1127 else 1128 { 1129 cmdlist = new; 1130 } 1131 return; 1132 } 1133 1134 static void sh_socket_add2run (struct socket_cmd * in) 1135 { 1136 struct socket_cmd * new = runlist; 1137 struct socket_cmd * last = runlist; 1138 1139 while (new) 1140 { 1141 /* Only skip identical commands. First 5 will 1142 * make all 'DELTA' identical. 1143 */ 1144 if (0 == sl_strcmp(new->clt, in->clt) && 1145 0 == sl_strncmp(new->cmd, in->cmd, 5)) 1146 { 1147 sl_strlcpy (new->cmd, in->cmd, sizeof(new->cmd)); 1148 (void) sh_unix_time(0, new->cti, sizeof(new->cti)); 1149 return; 1150 } 1151 new = new->next; 1152 } 1153 1154 new = SH_ALLOC(sizeof(struct socket_cmd)); 1155 sl_strlcpy (new->cmd, in->cmd, sizeof(new->cmd)); 1156 sl_strlcpy (new->clt, in->clt, sizeof(new->clt)); 1077 1157 #ifdef SH_DEBUG_SOCKET 1078 1158 fprintf(stderr, "add2run: time set for %s\n", new->clt); 1079 1159 #endif 1080 1160 (void) sh_unix_time(0, new->cti, sizeof(new->cti)); 1081 new->next = runlist; 1082 runlist = new; 1083 1161 new->next = NULL; 1162 1163 if (last) 1164 { 1165 while (last->next) { last = last->next; } 1166 last->next = new; 1167 } 1168 else 1169 { 1170 runlist = new; 1171 } 1084 1172 return; 1085 1173 } … … 1087 1175 1088 1176 1089 static void sh_socket_rm2list (const char * client_name )1177 static void sh_socket_rm2list (const char * client_name, int remove_all) 1090 1178 { 1091 1179 struct socket_cmd * old = cmdlist; … … 1098 1186 if ((new == cmdlist) && (new->next == NULL)) 1099 1187 { 1188 /* There is only one entry */ 1100 1189 cmdlist = NULL; 1101 1190 SH_FREE(new); … … 1104 1193 else if (new == cmdlist) 1105 1194 { 1195 /* first entry: new = old = cmdlist */ 1106 1196 cmdlist = new->next; 1107 1197 SH_FREE(new); 1108 return; 1198 if (remove_all == S_FALSE) 1199 return; 1200 old = cmdlist; 1201 new = cmdlist; 1202 continue; 1109 1203 } 1110 1204 else … … 1112 1206 old->next = new->next; 1113 1207 SH_FREE(new); 1114 return; 1208 if (remove_all == S_FALSE) 1209 return; 1210 new = old; 1115 1211 } 1116 1212 } … … 1131 1227 1132 1228 if (pf_unix_fd < 0) 1133 { 1134 return 0; 1135 } 1229 return 0; 1136 1230 1137 1231 sl_strlcpy(cancel_cmd, _("CANCEL"), sizeof(cancel_cmd)); … … 1140 1234 { 1141 1235 if (0 == sl_strcmp(cmd.cmd, cancel_cmd)) 1142 { 1143 sh_socket_rm2list (cmd.clt); 1144 } 1236 sh_socket_rm2list (cmd.clt, S_TRUE); 1145 1237 else 1146 { 1147 sh_socket_rm2list (cmd.clt); 1148 sh_socket_add2list (&cmd); 1149 } 1238 sh_socket_add2list (&cmd); 1150 1239 } 1151 1240 return 0; … … 1164 1253 if (0 == sl_strcmp(new->clt, client_name)) 1165 1254 { 1166 sl_strlcpy(out, new->cmd,sizeof(out));1255 sl_strlcpy(out, new->cmd, sizeof(out)); 1167 1256 sh_socket_add2run (new); 1168 sh_socket_rm2list (client_name);1257 sh_socket_rm2list (client_name, S_FALSE); 1169 1258 return out; 1170 1259 } … … 1173 1262 return NULL; 1174 1263 } 1175 1176 1264 /* #if defined (SH_WITH_SERVER) 1177 1265 */ 1178 1266 #endif 1179 1267 1268 1269 #ifdef SH_CUTEST 1270 #include "CuTest.h" 1271 1272 void Test_cmdlist (CuTest *tc) { 1273 1274 #if defined (SH_WITH_SERVER) 1275 struct socket_cmd cmd; 1276 char * p; 1277 1278 sl_strlcpy(cmd.clt, "one", sizeof(cmd.clt)); 1279 sl_strlcpy(cmd.cmd, "RELOAD", sizeof(cmd.cmd)); 1280 1281 sh_socket_add2list (&cmd); 1282 p = sh_socket_check("one"); 1283 CuAssertPtrNotNull(tc, p); 1284 CuAssertStrEquals(tc, "RELOAD", p); 1285 1286 p = sh_socket_check("one"); 1287 CuAssertPtrEquals(tc, NULL, p); 1288 1289 sh_socket_add2list (&cmd); 1290 sl_strlcpy(cmd.cmd, "STOP", sizeof(cmd.cmd)); 1291 sh_socket_add2list (&cmd); 1292 1293 sl_strlcpy(cmd.clt, "two", sizeof(cmd.clt)); 1294 sl_strlcpy(cmd.cmd, "STOP", sizeof(cmd.cmd)); 1295 sh_socket_add2list (&cmd); 1296 sl_strlcpy(cmd.clt, "three", sizeof(cmd.clt)); 1297 sl_strlcpy(cmd.cmd, "STOP", sizeof(cmd.cmd)); 1298 sh_socket_add2list (&cmd); 1299 1300 sl_strlcpy(cmd.clt, "one", sizeof(cmd.clt)); 1301 sl_strlcpy(cmd.cmd, "DELTA", sizeof(cmd.cmd)); 1302 sh_socket_add2list (&cmd); 1303 1304 p = sh_socket_check("one"); 1305 CuAssertPtrNotNull(tc, p); 1306 CuAssertStrEquals(tc, "RELOAD", p); 1307 1308 sl_strlcpy(cmd.clt, "two", sizeof(cmd.clt)); 1309 sl_strlcpy(cmd.cmd, "RELOAD", sizeof(cmd.cmd)); 1310 sh_socket_add2list (&cmd); 1311 sl_strlcpy(cmd.clt, "three", sizeof(cmd.clt)); 1312 sl_strlcpy(cmd.cmd, "RELOAD", sizeof(cmd.cmd)); 1313 sh_socket_add2list (&cmd); 1314 1315 p = sh_socket_check("one"); 1316 CuAssertPtrNotNull(tc, p); 1317 CuAssertStrEquals(tc, "STOP", p); 1318 p = sh_socket_check("one"); 1319 CuAssertPtrNotNull(tc, p); 1320 CuAssertStrEquals(tc, "DELTA", p); 1321 p = sh_socket_check("one"); 1322 CuAssertPtrEquals(tc, NULL, p); 1323 1324 /* Test removal in correct order */ 1325 sl_strlcpy(cmd.clt, "one", sizeof(cmd.clt)); 1326 sl_strlcpy(cmd.cmd, "RELOAD", sizeof(cmd.cmd)); 1327 sh_socket_add2list (&cmd); 1328 sl_strlcpy(cmd.cmd, "STOP", sizeof(cmd.cmd)); 1329 sh_socket_add2list (&cmd); 1330 sl_strlcpy(cmd.cmd, "DELTA", sizeof(cmd.cmd)); 1331 sh_socket_add2list (&cmd); 1332 sl_strlcpy(cmd.cmd, "FOOBAR", sizeof(cmd.cmd)); 1333 sh_socket_add2list (&cmd); 1334 1335 sh_socket_rm2list ("one", S_FALSE); 1336 1337 p = sh_socket_check("one"); 1338 CuAssertPtrNotNull(tc, p); 1339 CuAssertStrEquals(tc, "STOP", p); 1340 1341 sh_socket_rm2list ("one", S_FALSE); 1342 1343 p = sh_socket_check("one"); 1344 CuAssertPtrNotNull(tc, p); 1345 CuAssertStrEquals(tc, "FOOBAR", p); 1346 1347 p = sh_socket_check("one"); 1348 CuAssertPtrEquals(tc, NULL, p); 1349 1350 sl_strlcpy(cmd.clt, "one", sizeof(cmd.clt)); 1351 sl_strlcpy(cmd.cmd, "RELOAD", sizeof(cmd.cmd)); 1352 sh_socket_add2list (&cmd); 1353 sl_strlcpy(cmd.cmd, "STOP", sizeof(cmd.cmd)); 1354 sh_socket_add2list (&cmd); 1355 1356 sl_strlcpy(cmd.clt, "two", sizeof(cmd.clt)); 1357 sl_strlcpy(cmd.cmd, "RELOAD", sizeof(cmd.cmd)); 1358 sh_socket_add2list (&cmd); 1359 sl_strlcpy(cmd.clt, "three", sizeof(cmd.clt)); 1360 sl_strlcpy(cmd.cmd, "RELOAD", sizeof(cmd.cmd)); 1361 sh_socket_add2list (&cmd); 1362 1363 sl_strlcpy(cmd.clt, "one", sizeof(cmd.clt)); 1364 sl_strlcpy(cmd.cmd, "DELTA", sizeof(cmd.cmd)); 1365 sh_socket_add2list (&cmd); 1366 sl_strlcpy(cmd.cmd, "FOOBAR", sizeof(cmd.cmd)); 1367 sh_socket_add2list (&cmd); 1368 1369 sh_socket_rm2list ("one", S_TRUE); 1370 p = sh_socket_check("one"); 1371 CuAssertPtrEquals(tc, NULL, p); 1372 1373 p = sh_socket_check("two"); 1374 CuAssertPtrNotNull(tc, p); 1375 CuAssertStrEquals(tc, "STOP", p); 1376 p = sh_socket_check("two"); 1377 CuAssertPtrNotNull(tc, p); 1378 CuAssertStrEquals(tc, "RELOAD", p); 1379 p = sh_socket_check("two"); 1380 CuAssertPtrEquals(tc, NULL, p); 1381 1382 p = sh_socket_check("three"); 1383 CuAssertPtrNotNull(tc, p); 1384 CuAssertStrEquals(tc, "STOP", p); 1385 p = sh_socket_check("three"); 1386 CuAssertPtrNotNull(tc, p); 1387 CuAssertStrEquals(tc, "RELOAD", p); 1388 p = sh_socket_check("three"); 1389 CuAssertPtrEquals(tc, NULL, p); 1390 1391 p = sh_socket_check("four"); 1392 CuAssertPtrEquals(tc, NULL, p); 1393 #else 1394 (void) tc; 1395 #endif 1396 } 1397 1398 #endif /* #ifdef SH_CUTEST */ 1399 1400 1401
Note:
See TracChangeset
for help on using the changeset viewer.