static AgentConnection *ServerConnection(const char *server, FileCopy fc, int *err) { AgentConnection *conn; *err = 0; #if !defined(__MINGW32__) signal(SIGPIPE, SIG_IGN); #endif /* !__MINGW32__ */ #if !defined(__MINGW32__) static sigset_t signal_mask; sigemptyset(&signal_mask); sigaddset(&signal_mask, SIGPIPE); pthread_sigmask(SIG_BLOCK, &signal_mask, NULL); #endif conn = NewAgentConn(server); if (strcmp(server, "localhost") == 0) { conn->authenticated = true; return conn; } conn->authenticated = false; conn->encryption_type = CfEnterpriseOptions(); /* username of the client - say root from Windows */ #ifdef __MINGW32__ snprintf(conn->username, CF_SMALLBUF, "root"); #else GetCurrentUserName(conn->username, CF_SMALLBUF); #endif /* !__MINGW32__ */ if (conn->sd == SOCKET_INVALID) { if (!ServerConnect(conn, server, fc)) { Log(LOG_LEVEL_INFO, "No server is responding on this port"); DisconnectServer(conn); *err = -1; return NULL; } if (conn->sd < 0) /* INVALID or OFFLINE socket */ { UnexpectedError("ServerConnect() succeeded but socket descriptor is %d!", conn->sd); *err = -1; return NULL; } if (!IdentifyAgent(conn->sd)) { Log(LOG_LEVEL_ERR, "Id-authentication for '%s' failed", VFQNAME); errno = EPERM; DisconnectServer(conn); *err = -2; // auth err return NULL; } if (!AuthenticateAgent(conn, fc.trustkey)) { Log(LOG_LEVEL_ERR, "Authentication dialogue with '%s' failed", server); errno = EPERM; DisconnectServer(conn); *err = -2; // auth err return NULL; } conn->authenticated = true; return conn; } return conn; }
/** * @NOTE if #flags.protocol_version is CF_PROTOCOL_UNDEFINED, then classic * protocol is used by default. */ AgentConnection *ServerConnection(const char *server, const char *port, unsigned int connect_timeout, ConnectionFlags flags, int *err) { AgentConnection *conn = NULL; int ret; *err = 0; conn = NewAgentConn(server, port, flags); #if !defined(__MINGW32__) signal(SIGPIPE, SIG_IGN); sigset_t signal_mask; sigemptyset(&signal_mask); sigaddset(&signal_mask, SIGPIPE); pthread_sigmask(SIG_BLOCK, &signal_mask, NULL); /* FIXME: username is local */ GetCurrentUserName(conn->username, sizeof(conn->username)); #else /* Always say "root" as username from windows. */ strlcpy(conn->username, "root", sizeof(conn->username)); #endif if (port == NULL || *port == '\0') { port = CFENGINE_PORT_STR; } char txtaddr[CF_MAX_IP_LEN] = ""; conn->conn_info->sd = SocketConnect(server, port, connect_timeout, flags.force_ipv4, txtaddr, sizeof(txtaddr)); if (conn->conn_info->sd == -1) { Log(LOG_LEVEL_INFO, "No server is responding on port: %s", port); DisconnectServer(conn); *err = -1; return NULL; } assert(sizeof(conn->remoteip) >= sizeof(txtaddr)); strcpy(conn->remoteip, txtaddr); switch (flags.protocol_version) { case CF_PROTOCOL_UNDEFINED: case CF_PROTOCOL_TLS: /* Set the version to request during protocol negotiation. After * TLSConnect() it will have the version we finally ended up with. */ conn->conn_info->protocol = CF_PROTOCOL_LATEST; ret = TLSConnect(conn->conn_info, flags.trust_server, conn->remoteip, conn->username); if (ret == -1) /* Error */ { DisconnectServer(conn); *err = -1; return NULL; } else if (ret == 0) /* Auth/ID error */ { DisconnectServer(conn); errno = EPERM; *err = -2; return NULL; } assert(ret == 1); conn->conn_info->status = CONNECTIONINFO_STATUS_ESTABLISHED; LastSaw1(conn->remoteip, KeyPrintableHash(conn->conn_info->remote_key), LAST_SEEN_ROLE_CONNECT); break; case CF_PROTOCOL_CLASSIC: conn->conn_info->protocol = CF_PROTOCOL_CLASSIC; conn->encryption_type = CfEnterpriseOptions(); if (!IdentifyAgent(conn->conn_info)) { Log(LOG_LEVEL_ERR, "Id-authentication for '%s' failed", VFQNAME); errno = EPERM; DisconnectServer(conn); *err = -2; // auth err return NULL; } if (!AuthenticateAgent(conn, flags.trust_server)) { Log(LOG_LEVEL_ERR, "Authentication dialogue with '%s' failed", server); errno = EPERM; DisconnectServer(conn); *err = -2; // auth err return NULL; } conn->conn_info->status = CONNECTIONINFO_STATUS_ESTABLISHED; break; default: ProgrammingError("ServerConnection: ProtocolVersion %d!", flags.protocol_version); } conn->authenticated = true; return conn; }