PageRenderTime 24ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/client-agent/start_agent.c

https://bitbucket.org/dcid/ossec-hids/
C | 283 lines | 184 code | 59 blank | 40 comment | 25 complexity | 773ce3541dab64b7c4ce04c02e813f4d MD5 | raw file
Possible License(s): GPL-2.0
  1. /* @(#) $Id: ./src/client-agent/start_agent.c, 2011/09/08 dcid Exp $
  2. */
  3. /* Copyright (C) 2009 Trend Micro Inc.
  4. * All right reserved.
  5. *
  6. * This program is a free software; you can redistribute it
  7. * and/or modify it under the terms of the GNU General Public
  8. * License (version 2) as published by the FSF - Free Software
  9. * Foundation
  10. */
  11. #include "shared.h"
  12. #include "agentd.h"
  13. #include "os_net/os_net.h"
  14. /** void connect_server()
  15. * Attempts to connect to all configured servers.
  16. */
  17. int connect_server(int initial_id)
  18. {
  19. int attempts = 2;
  20. int rc = initial_id;
  21. /* Checking if the initial is zero, meaning we have to rotate to the
  22. * beginning.
  23. */
  24. if(logr->rip[initial_id] == NULL)
  25. {
  26. rc = 0;
  27. initial_id = 0;
  28. }
  29. /* Closing socket if available. */
  30. if(logr->sock >= 0)
  31. {
  32. sleep(1);
  33. CloseSocket(logr->sock);
  34. logr->sock = -1;
  35. if(logr->rip[1])
  36. {
  37. verbose("%s: INFO: Closing connection to server (%s:%d).",
  38. ARGV0,
  39. logr->rip[rc],
  40. logr->port);
  41. }
  42. }
  43. while(logr->rip[rc])
  44. {
  45. char *tmp_str;
  46. /* Checking if we have a hostname. */
  47. tmp_str = strchr(logr->rip[rc], '/');
  48. if(tmp_str)
  49. {
  50. char *f_ip;
  51. *tmp_str = '\0';
  52. f_ip = OS_GetHost(logr->rip[rc], 5);
  53. if(f_ip)
  54. {
  55. char ip_str[128];
  56. ip_str[127] = '\0';
  57. snprintf(ip_str, 127, "%s/%s", logr->rip[rc], f_ip);
  58. free(f_ip);
  59. free(logr->rip[rc]);
  60. os_strdup(ip_str, logr->rip[rc]);
  61. tmp_str = strchr(logr->rip[rc], '/');
  62. tmp_str++;
  63. }
  64. else
  65. {
  66. merror("%s: WARN: Unable to get hostname for '%s'.",
  67. ARGV0, logr->rip[rc]);
  68. *tmp_str = '/';
  69. tmp_str++;
  70. }
  71. }
  72. else
  73. {
  74. tmp_str = logr->rip[rc];
  75. }
  76. verbose("%s: INFO: Trying to connect to server (%s:%d).", ARGV0,
  77. logr->rip[rc],
  78. logr->port);
  79. /* IPv6 address: */
  80. if(strchr(tmp_str,':') != NULL)
  81. {
  82. verbose("%s: INFO: Using IPv6 for: %s .", ARGV0, tmp_str);
  83. logr->sock = OS_ConnectUDP(logr->port, tmp_str, 1);
  84. }
  85. else
  86. {
  87. verbose("%s: INFO: Using IPv4 for: %s .", ARGV0, tmp_str);
  88. logr->sock = OS_ConnectUDP(logr->port, tmp_str, 0);
  89. }
  90. if(logr->sock < 0)
  91. {
  92. logr->sock = -1;
  93. merror(CONNS_ERROR, ARGV0, tmp_str);
  94. rc++;
  95. if(logr->rip[rc] == NULL)
  96. {
  97. attempts += 10;
  98. /* Only log that if we have more than 1 server configured. */
  99. if(logr->rip[1])
  100. merror("%s: ERROR: Unable to connect to any server.",ARGV0);
  101. sleep(attempts);
  102. rc = 0;
  103. }
  104. }
  105. else
  106. {
  107. /* Setting socket non-blocking on HPUX */
  108. #ifdef HPUX
  109. //fcntl(logr->sock, O_NONBLOCK);
  110. #endif
  111. #ifdef WIN32
  112. int bmode = 1;
  113. /* Setting socket to non-blocking */
  114. ioctlsocket(logr->sock, FIONBIO, (u_long FAR*) &bmode);
  115. #endif
  116. logr->rip_id = rc;
  117. return(1);
  118. }
  119. }
  120. return(0);
  121. }
  122. /* start_agent: Sends the synchronization message to
  123. * the server and waits for the ack.
  124. */
  125. void start_agent(int is_startup)
  126. {
  127. int recv_b = 0, attempts = 0, g_attempts = 1;
  128. char *tmp_msg;
  129. char msg[OS_MAXSTR +2];
  130. char buffer[OS_MAXSTR +1];
  131. char cleartext[OS_MAXSTR +1];
  132. char fmsg[OS_MAXSTR +1];
  133. memset(msg, '\0', OS_MAXSTR +2);
  134. memset(buffer, '\0', OS_MAXSTR +1);
  135. memset(cleartext, '\0', OS_MAXSTR +1);
  136. memset(fmsg, '\0', OS_MAXSTR +1);
  137. snprintf(msg, OS_MAXSTR, "%s%s", CONTROL_HEADER, HC_STARTUP);
  138. #ifdef ONEWAY
  139. return;
  140. #endif
  141. /* Sending start message and waiting for the ack */
  142. while(1)
  143. {
  144. /* Sending start up message */
  145. send_msg(0, msg);
  146. attempts = 0;
  147. /* Read until our reply comes back */
  148. while(((recv_b = recv(logr->sock, buffer, OS_MAXSTR,
  149. MSG_DONTWAIT)) >= 0) || (attempts <= 5))
  150. {
  151. if(recv_b <= 0)
  152. {
  153. /* Sleep five seconds before trying to get the reply from
  154. * the server again.
  155. */
  156. attempts++;
  157. sleep(attempts);
  158. /* Sending message again (after three attempts) */
  159. if(attempts >= 3)
  160. {
  161. send_msg(0, msg);
  162. }
  163. continue;
  164. }
  165. /* Id of zero -- only one key allowed */
  166. tmp_msg = ReadSecMSG(&keys, buffer, cleartext, 0, recv_b -1);
  167. if(tmp_msg == NULL)
  168. {
  169. merror(MSG_ERROR, ARGV0, logr->rip[logr->rip_id]);
  170. continue;
  171. }
  172. /* Check for commands */
  173. if(IsValidHeader(tmp_msg))
  174. {
  175. /* If it is an ack reply */
  176. if(strcmp(tmp_msg, HC_ACK) == 0)
  177. {
  178. available_server = time(0);
  179. verbose(AG_CONNECTED, ARGV0, logr->rip[logr->rip_id],
  180. logr->port);
  181. if(is_startup)
  182. {
  183. /* Send log message about start up */
  184. snprintf(msg, OS_MAXSTR, OS_AG_STARTED,
  185. keys.keyentries[0]->name,
  186. keys.keyentries[0]->ip->ip);
  187. snprintf(fmsg, OS_MAXSTR, "%c:%s:%s", LOCALFILE_MQ,
  188. "ossec", msg);
  189. send_msg(0, fmsg);
  190. }
  191. return;
  192. }
  193. }
  194. }
  195. /* Waiting for servers reply */
  196. merror(AG_WAIT_SERVER, ARGV0, logr->rip[logr->rip_id]);
  197. /* If we have more than one server, try all. */
  198. if(logr->rip[1])
  199. {
  200. int curr_rip = logr->rip_id;
  201. merror("%s: INFO: Trying next server ip in the line: '%s'.", ARGV0,
  202. logr->rip[logr->rip_id + 1] != NULL?logr->rip[logr->rip_id + 1]:logr->rip[0]);
  203. connect_server(logr->rip_id +1);
  204. if(logr->rip_id == curr_rip)
  205. {
  206. sleep(g_attempts);
  207. g_attempts+=(attempts * 3);
  208. }
  209. else
  210. {
  211. g_attempts+=5;
  212. sleep(g_attempts);
  213. }
  214. }
  215. else
  216. {
  217. sleep(g_attempts);
  218. g_attempts+=(attempts * 3);
  219. connect_server(0);
  220. }
  221. }
  222. return;
  223. }
  224. /* EOF */