Beispiel #1
0
/* 
 * Whatever the manuals might say, you cannot get IPV6 interface
 * configuration from the ioctls. This seems to be implemented in a non
 * standard way across OSes BSDi has done getifaddrs(), solaris 8 has a
 * new ioctl, Stevens book shows the suggestion which has not been
 * implemented...
 */
void
GetV6InterfaceInfo(void)
{
    FILE *pp;
    char buffer[CF_BUFSIZE];

    Verbose("Trying to locate my IPv6 address\n");

    switch (g_vsystemhardclass) {
    case cfnt:
        /* NT cannot do this */
        break;
    default:
        if ((pp = cfpopen("/sbin/ifconfig -a", "r")) == NULL) {
            Verbose("Could not find interface info\n");
            return;
        }

        while (!feof(pp)) {
            fgets(buffer, CF_BUFSIZE, pp);

            if (StrStr(buffer, "inet6")) {
                struct Item *ip,*list = NULL;
                char *sp;

                list = SplitStringAsItemList(buffer, ' ');

                for (ip = list; ip != NULL; ip=ip->next) {
                    for (sp = ip->name; *sp != '\0'; sp++) {

                        /* Remove CIDR mask */
                        if (*sp == '/')  {
                            *sp = '\0';
                        }
                    }

                    if (IsIPV6Address(ip->name) &&
                            (strcmp(ip->name, "::1") != 0)) {

                        Verbose("Found IPv6 address %s\n", ip->name);
                        AppendItem(&g_ipaddresses, ip->name, "");
                        AddClassToHeap(CanonifyName(ip->name));

                    }
                }
                DeleteItemList(list);
            }
        }
        fclose(pp);
        break;
    }
}
Beispiel #2
0
int IsIPV6NetworkAddress(char *name)
{
    char *sp;
    if (!IsIPV6Address(name))
    {
        return false;
    }

    if ((sp = strchr(name, '/')))
    {
        if (strncmp(sp-2, "::", 2) == 0)
        {
            return true;
        }
    }

    return false;
}
Beispiel #3
0
static void ShowState(char *type)
{
    struct stat statbuf;
    char buffer[CF_BUFSIZE], vbuff[CF_BUFSIZE], assemble[CF_BUFSIZE];
    Item *addresses = NULL, *saddresses = NULL, *ip;
    int i = 0, tot = 0, min_signal_diversity = 1, conns = 1;
    int maxlen = 0, count;
    double *dist = NULL, S = 0.0;
    char *offset = NULL;
    FILE *fp;

    CfDebug("ShowState(%s)\n", type);

    snprintf(buffer, CF_BUFSIZE - 1, "%s/state/cf_%s", CFWORKDIR, type);

    if (cfstat(buffer, &statbuf) == 0)
    {
        if ((fp = fopen(buffer, "r")) == NULL)
        {
            CfOut(cf_inform, "fopen", "Could not open state memory %s\n", buffer);
            return;
        }

        while (!feof(fp))
        {
            char local[CF_BUFSIZE], remote[CF_BUFSIZE];

            buffer[0] = local[0] = remote[0] = '\0';

            memset(vbuff, 0, CF_BUFSIZE);
            fgets(buffer, CF_BUFSIZE, fp);

            if (strlen(buffer) > 0)
            {
                CfOut(cf_verbose, "", "(%2d) %s", conns, buffer);

                if (IsSocketType(type))
                {
                    if (strncmp(type, "incoming", 8) == 0 || strncmp(type, "outgoing", 8) == 0)
                    {
                        if (strncmp(buffer, "tcp", 3) == 0)
                        {
                            sscanf(buffer, "%*s %*s %*s %s %s", local, remote); /* linux-like */
                        }
                        else
                        {
                            sscanf(buffer, "%s %s", local, remote);     /* solaris-like */
                        }

                        strncpy(vbuff, remote, CF_BUFSIZE - 1);
                        DePort(vbuff);
                    }
                }
                else if (IsTCPType(type))
                {
                    count = 1;
                    sscanf(buffer, "%d %[^\n]", &count, remote);
                    AppendItem(&addresses, remote, "");
                    SetItemListCounter(addresses, remote, count);
                    conns += count;
                    continue;
                }
                else
                {
                    /* If we get here this is a process thing */
                    if (offset == NULL)
                    {
                        if ((offset = strstr(buffer, "CMD")))
                        {
                        }
                        else if ((offset = strstr(buffer, "COMMAND")))
                        {
                        }

                        if (offset == NULL)
                        {
                            continue;
                        }
                    }

                    strncpy(vbuff, offset, CF_BUFSIZE - 1);
                    Chop(vbuff);
                }

                if (!IsItemIn(addresses, vbuff))
                {
                    conns++;
                    AppendItem(&addresses, vbuff, "");
                    IncrementItemListCounter(addresses, vbuff);
                }
                else
                {
                    conns++;
                    IncrementItemListCounter(addresses, vbuff);
                }
            }
        }

        fclose(fp);
        conns--;

        CfOut(cf_error, "", "\n");
        CfOut(cf_error, "", "R: The peak measured state was q = %d:\n", conns);

        if (IsSocketType(type) || IsTCPType(type))
        {
            for (ip = addresses; ip != NULL; ip = ip->next)
            {
                tot += ip->counter;

                buffer[0] = '\0';
                sscanf(ip->name, "%s", buffer);

                if (!IsIPV4Address(buffer) && !IsIPV6Address(buffer))
                {
                    CfOut(cf_verbose, "", "Rejecting address %s\n", ip->name);
                    continue;
                }

                CfOut(cf_error, "", "R: DNS key: %s = %s (%d/%d)\n", buffer, IPString2Hostname(buffer), ip->counter,
                      conns);

                if (strlen(ip->name) > maxlen)
                {
                    maxlen = strlen(ip->name);
                }
            }

            if (addresses != NULL)
            {
                printf("R: -\n");
            }
        }
        else
        {
            for (ip = addresses; ip != NULL; ip = ip->next)
            {
                tot += ip->counter;
            }
        }

        addresses = SortItemListCounters(addresses);
        saddresses = addresses;

        for (ip = saddresses; ip != NULL; ip = ip->next)
        {
            int s;

            if (maxlen > 17)    /* ipv6 */
            {
                snprintf(assemble, CF_BUFSIZE, "Frequency: %-40s|", ip->name);
            }
            else
            {
                snprintf(assemble, CF_BUFSIZE, "Frequency: %-17s|", ip->name);
            }

            for (s = 0; (s < ip->counter) && (s < 50); s++)
            {
                if (s < 48)
                {
                    strcat(assemble, "*");
                }
                else
                {
                    strcat(assemble, "+");
                }
            }

            CfOut(cf_error, "", "R: %s \t(%d/%d)\n", assemble, ip->counter, conns);
        }

        dist = xmalloc((tot + 1) * sizeof(double));

        if (conns > min_signal_diversity)
        {
            for (i = 0, ip = addresses; ip != NULL; i++, ip = ip->next)
            {
                dist[i] = ((double) (ip->counter)) / ((double) tot);

                S -= dist[i] * log(dist[i]);
            }

            CfOut(cf_error, "", "R: Variability/entropy of addresses = %.1f %%\n", S / log((double) tot) * 100.0);
            CfOut(cf_error, "", "R: (Entropy = 0 for single source, 100 for flatly distributed source)\n -\n");
        }

        CfOut(cf_error, "", "\n");
        CfOut(cf_error, "", "R: State of %s peaked at %s\n", type, cf_ctime(&statbuf.st_mtime));
    }
    else
    {
        CfOut(cf_inform, "", "R: State parameter %s is not known or recorded\n", type);
    }

    DeleteItemList(addresses);

    if (dist)
    {
        free((char *) dist);
    }
}
Beispiel #4
0
static void FindV6InterfacesInfo(void)
{
    FILE *pp = NULL;
    char buffer[CF_BUFSIZE];

/* Whatever the manuals might say, you cannot get IPV6
   interface configuration from the ioctls. This seems
   to be implemented in a non standard way across OSes
   BSDi has done getifaddrs(), solaris 8 has a new ioctl, Stevens
   book shows the suggestion which has not been implemented...
*/

    CfOut(OUTPUT_LEVEL_VERBOSE, "", "Trying to locate my IPv6 address\n");

#if defined(__CYGWIN__)
    /* NT cannot do this */
    return;
#elif defined(__hpux)
    if ((pp = cf_popen("/usr/sbin/ifconfig -a", "r")) == NULL)
    {
        CfOut(OUTPUT_LEVEL_VERBOSE, "", "Could not find interface info\n");
        return;
    }
#elif defined(_AIX)
    if ((pp = cf_popen("/etc/ifconfig -a", "r")) == NULL)
    {
        CfOut(OUTPUT_LEVEL_VERBOSE, "", "Could not find interface info\n");
        return;
    }
#else
    if ((pp = cf_popen("/sbin/ifconfig -a", "r")) == NULL)
    {
        CfOut(OUTPUT_LEVEL_VERBOSE, "", "Could not find interface info\n");
        return;
    }
#endif

/* Don't know the output format of ifconfig on all these .. hope for the best*/

    while (!feof(pp))
    {
        buffer[0] = '\0';
        if (fgets(buffer, CF_BUFSIZE, pp) == NULL)
        {
            if (strlen(buffer))
            {
                UnexpectedError("Failed to read line from stream");
            }
        }

        if (ferror(pp))         /* abortable */
        {
            break;
        }

        if (strcasestr(buffer, "inet6"))
        {
            Item *ip, *list = NULL;
            char *sp;

            list = SplitStringAsItemList(buffer, ' ');

            for (ip = list; ip != NULL; ip = ip->next)
            {
                for (sp = ip->name; *sp != '\0'; sp++)
                {
                    if (*sp == '/')     /* Remove CIDR mask */
                    {
                        *sp = '\0';
                    }
                }

                if ((IsIPV6Address(ip->name)) && ((strcmp(ip->name, "::1") != 0)))
                {
                    CfOut(OUTPUT_LEVEL_VERBOSE, "", "Found IPv6 address %s\n", ip->name);
                    AppendItem(&IPADDRESSES, ip->name, "");
                    HardClass(ip->name);
                }
            }

            DeleteItemList(list);
        }
    }

    cf_pclose(pp);
}
Beispiel #5
0
void Unix_FindV6InterfaceInfo(void)
{
    FILE *pp = NULL;
    char buffer[CF_BUFSIZE];

/* Whatever the manuals might say, you cannot get IPV6
   interface configuration from the ioctls. This seems
   to be implemented in a non standard way across OSes
   BSDi has done getifaddrs(), solaris 8 has a new ioctl, Stevens
   book shows the suggestion which has not been implemented...
*/

    CfOut(cf_verbose, "", "Trying to locate my IPv6 address\n");

    switch (VSYSTEMHARDCLASS)
    {
    case cfnt:
        /* NT cannot do this */
        return;

    case irix:
    case irix4:
    case irix64:

        if ((pp = cf_popen("/usr/etc/ifconfig -a", "r")) == NULL)
        {
            CfOut(cf_verbose, "", "Could not find interface info\n");
            return;
        }

        break;

    case hp:

        if ((pp = cf_popen("/usr/sbin/ifconfig -a", "r")) == NULL)
        {
            CfOut(cf_verbose, "", "Could not find interface info\n");
            return;
        }

        break;

    case aix:

        if ((pp = cf_popen("/etc/ifconfig -a", "r")) == NULL)
        {
            CfOut(cf_verbose, "", "Could not find interface info\n");
            return;
        }

        break;

    default:

        if ((pp = cf_popen("/sbin/ifconfig -a", "r")) == NULL)
        {
            CfOut(cf_verbose, "", "Could not find interface info\n");
            return;
        }

    }

/* Don't know the output format of ifconfig on all these .. hope for the best*/

    while (!feof(pp))
    {
        fgets(buffer, CF_BUFSIZE - 1, pp);

        if (ferror(pp))         /* abortable */
        {
            break;
        }

        if (strcasestr(buffer, "inet6"))
        {
            Item *ip, *list = NULL;
            char *sp;

            list = SplitStringAsItemList(buffer, ' ');

            for (ip = list; ip != NULL; ip = ip->next)
            {
                for (sp = ip->name; *sp != '\0'; sp++)
                {
                    if (*sp == '/')     /* Remove CIDR mask */
                    {
                        *sp = '\0';
                    }
                }

                if (IsIPV6Address(ip->name) && (strcmp(ip->name, "::1") != 0))
                {
                    CfOut(cf_verbose, "", "Found IPv6 address %s\n", ip->name);
                    AppendItem(&IPADDRESSES, ip->name, "");
                    NewClass(ip->name);
                }
            }

            DeleteItemList(list);
        }
    }

    cf_pclose(pp);
}
Beispiel #6
0
int IdentifyAgent(ConnectionInfo *conn_info)
{
    char uname[CF_BUFSIZE], sendbuff[CF_BUFSIZE];
    char dnsname[CF_MAXVARSIZE], localip[CF_MAX_IP_LEN];
    int ret;

    if ((!SKIPIDENTIFY) && (strcmp(VDOMAIN, CF_START_DOMAIN) == 0))
    {
        Log(LOG_LEVEL_ERR, "Undefined domain name");
        return false;
    }

    if (!SKIPIDENTIFY)
    {
        /* First we need to find out the IP address and DNS name of the socket
           we are sending from. This is not necessarily the same as VFQNAME if
           the machine has a different uname from its IP name (!) This can
           happen on poorly set up machines or on hosts with multiple
           interfaces, with different names on each interface ... */
        struct sockaddr_storage myaddr = {0};
        socklen_t myaddr_len = sizeof(myaddr);

        if (getsockname(conn_info->sd, (struct sockaddr *) &myaddr, &myaddr_len) == -1)
        {
            Log(LOG_LEVEL_ERR, "Couldn't get socket address. (getsockname: %s)", GetErrorStr());
            return false;
        }

        /* No lookup, just convert the bound address to string. */
        ret = getnameinfo((struct sockaddr *) &myaddr, myaddr_len,
                          localip, sizeof(localip),
                          NULL, 0, NI_NUMERICHOST);
        if (ret != 0)
        {
            Log(LOG_LEVEL_ERR,
                "During agent identification. (getnameinfo: %s)",
                  gai_strerror(ret));
            return false;
        }

        /* dnsname: Reverse lookup of the bound IP address. */
        ret = getnameinfo((struct sockaddr *) &myaddr, myaddr_len,
                          dnsname, sizeof(dnsname), NULL, 0, 0);
        if (ret != 0)
        {
            /* getnameinfo doesn't fail on resolution failure, it just prints
             * the IP, so here something else is wrong. */
            Log(LOG_LEVEL_ERR,
                "During agent identification for '%s'. (getnameinfo: %s)",
                  localip, gai_strerror(ret));
            return false;
        }

        /* getnameinfo() should always return FQDN. Some resolvers will not
         * return FQNAME and missing PTR will give numerical result */
        if ((strlen(VDOMAIN) > 0)                      /* TODO true always? */
            && (!IsIPV6Address(dnsname)) && (!strchr(dnsname, '.')))
        {
            strcat(dnsname, ".");
            strncat(dnsname, VDOMAIN, CF_MAXVARSIZE / 2);
        }

        /* Seems to be a bug in some resolvers that adds garbage, when it just
         * returns the input. */
        if (strncmp(dnsname, localip, strlen(localip)) == 0
            && dnsname[strlen(localip)] != '\0')
        {
            dnsname[strlen(localip)] = '\0';
            Log(LOG_LEVEL_WARNING,
                "getnameinfo() seems to append garbage to unresolvable IPs, bug mitigated by CFEngine but please report your platform!");
        }
    }
    else
    {
        assert(sizeof(localip) >= sizeof(VIPADDRESS));
        strcpy(localip, VIPADDRESS);

        Log(LOG_LEVEL_VERBOSE,
            "skipidentify was promised, so we are trusting and simply announcing the identity as '%s' for this host",
            strlen(VFQNAME) > 0 ? VFQNAME : "skipident");
        if (strlen(VFQNAME) > 0)
        {
            strcpy(dnsname, VFQNAME);
        }
        else
        {
            strcpy(dnsname, "skipident");
        }
    }

/* client always identifies as root on windows */
#ifdef __MINGW32__
    snprintf(uname, sizeof(uname), "%s", "root");
#else
    GetCurrentUserName(uname, sizeof(uname));
#endif

    snprintf(sendbuff, sizeof(sendbuff), "CAUTH %s %s %s %d",
             localip, dnsname, uname, 0);

    if (SendTransaction(conn_info, sendbuff, 0, CF_DONE) == -1)
    {
        Log(LOG_LEVEL_ERR,
              "During identify agent, could not send auth response. (SendTransaction: %s)", GetErrorStr());
        return false;
    }

    return true;
}
Beispiel #7
0
int IdentifyForVerification(int sd,char *localip,int family)

{ char sendbuff[CF_BUFSIZE],dnsname[CF_BUFSIZE];
  struct in_addr *iaddr;
  struct hostent *hp;
  int len,err;
  struct passwd *user_ptr;
  char *uname;
#if defined(HAVE_GETADDRINFO)
  char myaddr[256]; /* Compilation trick for systems that don't know ipv6 */
#else
  struct sockaddr_in myaddr;
#endif
  
memset(sendbuff,0,CF_BUFSIZE);
memset(dnsname,0,CF_BUFSIZE);

if (!SKIPIDENTIFY && (strcmp(VDOMAIN,CF_START_DOMAIN) == 0))
   {
   CfLog(cferror,"Undefined domain name","");
   return false;
   }

if (!SKIPIDENTIFY)
   {
/* First we need to find out the IP address and DNS name of the socket
   we are sending from. This is not necessarily the same as VFQNAME if
   the machine has a different uname from its IP name (!) This can
   happen on stupidly set up machines or on hosts with multiple
   interfaces, with different names on each interface ... */ 
   
   switch (family)
      {
      case AF_INET: len = sizeof(struct sockaddr_in);
          break;
#if defined(HAVE_GETADDRINFO)
      case AF_INET6: len = sizeof(struct sockaddr_in6);
          break;
#endif
      default:
          CfLog(cferror,"Software error in IdentifyForVerification","");
      }
   
   if (getsockname(sd,(struct sockaddr *)&myaddr,&len) == -1)
      {
      CfLog(cferror,"Couldn't get socket address\n","getsockname");
      return false;
      }
   
   snprintf(localip,CF_MAX_IP_LEN-1,"%s",sockaddr_ntop((struct sockaddr *)&myaddr)); 
   
   Debug("Identifying this agent as %s i.e. %s, with signature %d\n",localip,VFQNAME,CFSIGNATURE);
   
#if defined(HAVE_GETADDRINFO)
   
   if ((err=getnameinfo((struct sockaddr *)&myaddr,len,dnsname,CF_MAXVARSIZE,NULL,0,0)) != 0)
      {
      snprintf(OUTPUT,CF_BUFSIZE,"Couldn't look up address v6 for %s: %s\n",dnsname,gai_strerror(err));
      CfLog(cferror,OUTPUT,"");
      return false;
      }
   
#else 
   
   iaddr = &(myaddr.sin_addr); 

   hp = gethostbyaddr((void *)iaddr,sizeof(myaddr.sin_addr),family);
   
   if ((hp == NULL) || (hp->h_name == NULL))
      {
      CfLog(cferror,"Couldn't lookup IP address\n","gethostbyaddr");
      return false;
      }
   
   strncpy(dnsname,hp->h_name,CF_MAXVARSIZE);
   
   if ((strstr(hp->h_name,".") == 0) && (strlen(VDOMAIN) > 0))
      {
      strcat(dnsname,".");
      strcat(dnsname,VDOMAIN);
      } 
#endif 
   }
else
   {
   strcpy(localip,VIPADDRESS);
   
   if (strlen(VFQNAME) > 0)
      {
      Verbose("SkipIdent was requested, so we are trusting and annoucning the identity as (%s) for this host\n",VFQNAME);
      strcat(dnsname,VFQNAME);
      }
   else
      {
      strcat(dnsname,"skipident");
      }
   }

user_ptr = getpwuid(getuid());
uname = user_ptr ? user_ptr->pw_name : "UNKNOWN";

/* Some resolvers will not return FQNAME and missing PTR will give numerical result */

if ((strlen(VDOMAIN) > 0) && !IsIPV6Address(dnsname) && !strchr(dnsname,'.'))
   {
   Debug("Appending domain %s to %s\n",VDOMAIN,dnsname);
   strcat(dnsname,".");
   strncat(dnsname,VDOMAIN,CF_MAXVARSIZE/2);
   }  

if (strncmp(dnsname,localip,strlen(localip)) == 0)
   {
   /* Seems to be a bug in some resolvers that adds garbage, when it just returns the input */
   strcpy(dnsname,localip);
   }

if (strlen(dnsname) == 0)
   {
   strcpy(dnsname,localip);
   }

snprintf(sendbuff,CF_BUFSIZE-1,"CAUTH %s %s %s %d",localip,dnsname,uname,CFSIGNATURE);

Debug("SENT:::%s\n",sendbuff);
 
SendTransaction(sd,sendbuff,0,CF_DONE);
return true;
}
Beispiel #8
0
int IdentifyAgent(int sd, char *localip)
{
    char uname[CF_BUFSIZE], sendbuff[CF_BUFSIZE], dnsname[CF_BUFSIZE];
    struct sockaddr_storage myaddr = {0};
    socklen_t myaddr_len = sizeof(myaddr);
    int ret;

    memset(sendbuff, 0, CF_BUFSIZE);
    memset(dnsname, 0, CF_BUFSIZE);

    if ((!SKIPIDENTIFY) && (strcmp(VDOMAIN, CF_START_DOMAIN) == 0))
    {
        Log(LOG_LEVEL_ERR, "Undefined domain name");
        return false;
    }

    if (!SKIPIDENTIFY)
    {
        /* First we need to find out the IP address and DNS name of the socket
           we are sending from. This is not necessarily the same as VFQNAME if
           the machine has a different uname from its IP name (!) This can
           happen on poorly set up machines or on hosts with multiple
           interfaces, with different names on each interface ... */

        if (getsockname(sd, (struct sockaddr *) &myaddr, &myaddr_len) == -1)
        {
            Log(LOG_LEVEL_ERR, "Couldn't get socket address: %s", GetErrorStr());
            return false;
        }

        /* No lookup, just convert the bound address to string. */
        getnameinfo((struct sockaddr *) &myaddr, myaddr_len,
                    localip, CF_MAX_IP_LEN,
                    NULL, 0, NI_NUMERICHOST);

        /* dnsname: Reverse lookup of the bound IP address. */
        ret = getnameinfo((struct sockaddr *) &myaddr, myaddr_len,
                          dnsname, CF_MAXVARSIZE, NULL, 0, 0);
        if (ret != 0)
        {
            Log(LOG_LEVEL_ERR,
                  "Couldn't look up address for %s: %s",
                  dnsname, gai_strerror(ret));
            return false;
        }
    }
    else
    {
        strcpy(localip, VIPADDRESS);

        if (strlen(VFQNAME) > 0)
        {
            Log(LOG_LEVEL_VERBOSE,
                  "skipidentify was promised, so we are trusting and simply announcing the identity as (%s) for this host",
                  VFQNAME);
            strcat(dnsname, VFQNAME);
        }
        else
        {
            strcat(dnsname, "skipident");
        }
    }

/* client always identifies as root on windows */
#ifdef __MINGW32__
    snprintf(uname, sizeof(uname), "%s", "root");
#else
    GetCurrentUserName(uname, sizeof(uname));
#endif

/* Some resolvers will not return FQNAME and missing PTR will give numerical result */

    if ((strlen(VDOMAIN) > 0) && (!IsIPV6Address(dnsname)) && (!strchr(dnsname, '.')))
    {
        strcat(dnsname, ".");
        strncat(dnsname, VDOMAIN, CF_MAXVARSIZE / 2);
    }

    if (strncmp(dnsname, localip, strlen(localip)) == 0)
    {
        /* Seems to be a bug in some resolvers that adds garbage, when it just
         * returns the input */
        strcpy(dnsname, localip);
    }

    if (strlen(dnsname) == 0)
    {
        strcpy(dnsname, localip);
    }

    snprintf(sendbuff, CF_BUFSIZE - 1, "CAUTH %s %s %s %d",
             localip, dnsname, uname, 0);

    if (SendTransaction(sd, sendbuff, 0, CF_DONE) == -1)
    {
        Log(LOG_LEVEL_ERR,
              "!! IdentifyAgent: Could not send auth response");
        return false;
    }

    return true;
}
int IdentifyAgent(int sd, char *localip, int family)
{
    char uname[CF_BUFSIZE], sendbuff[CF_BUFSIZE], dnsname[CF_BUFSIZE];
    socklen_t len;

#if defined(HAVE_GETADDRINFO)
    int err;
    char myaddr[256];           /* Compilation trick for systems that don't know ipv6 */
#else
    struct sockaddr_in myaddr;
    struct in_addr *iaddr;
    struct hostent *hp;
#endif

    memset(sendbuff, 0, CF_BUFSIZE);
    memset(dnsname, 0, CF_BUFSIZE);

    if ((!SKIPIDENTIFY) && (strcmp(VDOMAIN, CF_START_DOMAIN) == 0))
    {
        CfOut(cf_error, "", "Undefined domain name");
        return false;
    }

    if (!SKIPIDENTIFY)
    {
/* First we need to find out the IP address and DNS name of the socket
   we are sending from. This is not necessarily the same as VFQNAME if
   the machine has a different uname from its IP name (!) This can
   happen on poorly set up machines or on hosts with multiple
   interfaces, with different names on each interface ... */

        switch (family)
        {
        case AF_INET:
            len = sizeof(struct sockaddr_in);
            break;
#if defined(HAVE_GETADDRINFO)
        case AF_INET6:
            len = sizeof(struct sockaddr_in6);
            break;
#endif
        default:
            CfOut(cf_error, "", "Software error in IdentifyForVerification, family = %d", family);
        }

        if (getsockname(sd, (struct sockaddr *) &myaddr, &len) == -1)
        {
            CfOut(cf_error, "getsockname", "Couldn't get socket address\n");
            return false;
        }

        snprintf(localip, CF_MAX_IP_LEN - 1, "%s", sockaddr_ntop((struct sockaddr *) &myaddr));

        CfDebug("Identifying this agent as %s i.e. %s, with signature %d, family %d\n", localip, VFQNAME, CFSIGNATURE, family);

#if defined(HAVE_GETADDRINFO)

        if ((err = getnameinfo((struct sockaddr *) &myaddr, len, dnsname, CF_MAXVARSIZE, NULL, 0, 0)) != 0)
        {
            CfOut(cf_error, "", "Couldn't look up address v6 for %s: %s\n", dnsname, gai_strerror(err));
            return false;
        }

#else

        iaddr = &(myaddr.sin_addr);

        hp = gethostbyaddr((void *) iaddr, sizeof(myaddr.sin_addr), family);

        if ((hp == NULL) || (hp->h_name == NULL))
        {
            CfOut(cf_error, "gethostbyaddr", "Couldn't lookup IP address\n");
            return false;
        }

        strncpy(dnsname, hp->h_name, CF_MAXVARSIZE);

        if ((strstr(hp->h_name, ".") == 0) && (strlen(VDOMAIN) > 0))
        {
            strcat(dnsname, ".");
            strcat(dnsname, VDOMAIN);
        }
#endif
    }
    else
    {
        strcpy(localip, VIPADDRESS);

        if (strlen(VFQNAME) > 0)
        {
            CfOut(cf_verbose, "",
                  "skipidentify was promised, so we are trusting and simply announcing the identity as (%s) for this host\n",
                  VFQNAME);
            strcat(dnsname, VFQNAME);
        }
        else
        {
            strcat(dnsname, "skipident");
        }
    }

/* client always identifies as root on windows */
#ifdef MINGW
    snprintf(uname, sizeof(uname), "%s", "root");
#else
    GetCurrentUserName(uname, sizeof(uname));
#endif

/* Some resolvers will not return FQNAME and missing PTR will give numerical result */

    if ((strlen(VDOMAIN) > 0) && (!IsIPV6Address(dnsname)) && (!strchr(dnsname, '.')))
    {
        CfDebug("Appending domain %s to %s\n", VDOMAIN, dnsname);
        strcat(dnsname, ".");
        strncat(dnsname, VDOMAIN, CF_MAXVARSIZE / 2);
    }

    if (strncmp(dnsname, localip, strlen(localip)) == 0)
    {
        /* Seems to be a bug in some resolvers that adds garbage, when it just returns the input */
        strcpy(dnsname, localip);
    }

    if (strlen(dnsname) == 0)
    {
        strcpy(dnsname, localip);
    }

    snprintf(sendbuff, CF_BUFSIZE - 1, "CAUTH %s %s %s %d", localip, dnsname, uname, CFSIGNATURE);

    if (SendTransaction(sd, sendbuff, 0, CF_DONE) == -1)
    {
        CfOut(cf_error, "", "!! IdentifyAgent: Could not send auth response");
        return false;
    }

    CfDebug("SENT:::%s\n", sendbuff);

    return true;
}