//functions
UtlBoolean
SubscribeServerThread::handleMessage(OsMsg& eventMessage)
{

    // Only handle SIP messages
    if (eventMessage.getMsgType() != OsMsg::PHONE_APP ||
        eventMessage.getMsgSubType() != SipMessage::NET_SIP_MESSAGE)
    {
       return FALSE ;
    }

    const SipMessage* message =
        ((SipMessageEvent&)eventMessage).getMessage();

    UtlString userKey;
    UtlString uri;
    SipMessage finalResponse;

    // Test for request/response processing code path
    if (!message->isResponse())
    {
        // this is a request, so authenticate and authorize the request
        if ( isValidDomain( message, &finalResponse ) )
        {
            UtlString eventPackage;
            UtlString id;
            UtlHashMap otherParams;

            message->getEventField(&eventPackage, &id, &otherParams);

            StatusPluginReference* pluginContainer =
                mPluginTable->getPlugin( eventPackage );

            if( pluginContainer )
            {
               //check in credential database if authentication needed
               UtlString authenticatedUser, authenticatedRealm;
               if( isAuthenticated ( message, &finalResponse, authenticatedUser, authenticatedRealm ) )
               {
                  if ( isAuthorized ( message, &finalResponse, pluginContainer ) )
                  {
                     // fetch the plugin
                     SubscribeServerPluginBase* plugin =
                        pluginContainer->getPlugin();

                     if (plugin)
                     {
                        int timeNow = (int)OsDateTime::getSecsSinceEpoch();
                        int grantedExpiration;
                        UtlString newToTag;

                        // add the subscription to the IMDB
                        SubscribeStatus isSubscriptionAdded
                           = addSubscription(timeNow,
                                             message,
                                             mDefaultDomain,
                                             eventPackage,
                                             id,
                                             otherParams,
                                             newToTag,
                                             grantedExpiration);

                        otherParams.destroyAll();

                        switch ( isSubscriptionAdded )
                        {
                        case STATUS_SUCCESS:
                           // create response - 202 Accepted Response
                           finalResponse.setResponseData( message,
                                                          SIP_ACCEPTED_CODE,
                                                          SIP_ACCEPTED_TEXT);
                           // Set the granted subscription time.
                           finalResponse.setExpiresField(grantedExpiration);

                           plugin->handleSubscribeRequest( *message,
                                                           finalResponse,
                                                           authenticatedUser.data(),
                                                           authenticatedRealm.data(),
                                                           mDefaultDomain.data());

                           // ensure that the contact returned will route back to here
                           // (the default supplied by SipUserAgent will not).
                           {
                              UtlString requestUri;
                              message->getRequestUri(&requestUri);
                              finalResponse.setContactField(requestUri);
                           }
                           break;

                        case STATUS_TO_BE_REMOVED:
                           // create response - 202 Accepted Response
                           finalResponse.setResponseData( message,
                                                          SIP_ACCEPTED_CODE,
                                                          SIP_ACCEPTED_TEXT);
                           // Set the granted subscription time.
                           finalResponse.setExpiresField(grantedExpiration);

                           plugin->handleSubscribeRequest( *message,
                                                           finalResponse,
                                                           authenticatedUser.data(),
                                                           authenticatedRealm.data(),
                                                           mDefaultDomain.data());

                           // ensure that the contact returned will route back to here
                           // (the default supplied by SipUserAgent will not).
                           {
                              UtlString requestUri;
                              message->getRequestUri(&requestUri);
                              finalResponse.setContactField(requestUri);
                           }
                           // Now that final NOTIFY has been sent, remove row
                           removeSubscription(message);

                           break;

                        case STATUS_LESS_THAN_MINEXPIRES:
                           // (already logged in addSubscription)

                           // send 423 Subscription Too Brief response
                           finalResponse.setResponseData(
                              message,
                              SIP_TOO_BRIEF_CODE,
                              SIP_TOO_BRIEF_TEXT );

                           finalResponse.setHeaderValue(
                              SIP_MIN_EXPIRES_FIELD,
                              mMinExpiresTimeStr,
                              0 );
                           break;

                        case STATUS_INVALID_REQUEST:
                           OsSysLog::add(FAC_SIP, PRI_ERR,
                                         "SubscribeServerThread::handleMessage()"
                                         "Subscription Could Not Be Added "
                                         SIP_BAD_REQUEST_TEXT
                              );

                           finalResponse.setResponseData(
                              message,
                              SIP_BAD_REQUEST_CODE,
                              SIP_BAD_REQUEST_TEXT );
                           break;

                        case STATUS_FORBIDDEN:
                           OsSysLog::add(FAC_SIP, PRI_ERR,
                                         "SubscribeServerThread::handleMessage()"
                                         "Subscription Could Not Be Added "
                                         SIP_FORBIDDEN_TEXT
                              );

                           finalResponse.setResponseData(
                              message,
                              SIP_FORBIDDEN_CODE,
                              SIP_FORBIDDEN_TEXT);
                           break;

                        case STATUS_NOT_FOUND:
                           OsSysLog::add(FAC_SIP, PRI_ERR,
                                         "SubscribeServerThread::handleMessage()"
                                         "Subscription Could Not Be Added "
                                         SIP_NOT_FOUND_TEXT
                              );
                           finalResponse.setResponseData(
                              message,
                              SIP_NOT_FOUND_CODE,
                              SIP_NOT_FOUND_TEXT );
                           break;

                        case STATUS_BAD_SUBSCRIPTION:
                           // send 481 Subscription Does Not Exist response
                           OsSysLog::add(FAC_SIP, PRI_DEBUG,
                                         "SubscribeServerThread::handleMessage()"
                                         "Subscription to be renewed does not exist "
                                         SIP_BAD_SUBSCRIPTION_TEXT
                              );
                           finalResponse.setResponseData(
                              message,
                              SIP_BAD_SUBSCRIPTION_CODE,
                              SIP_BAD_SUBSCRIPTION_TEXT );
                           break;

                        case STATUS_INTERNAL_ERROR:
                        default:
                           OsSysLog::add(FAC_SIP, PRI_ERR,
                                         "SubscribeServerThread::handleMessage()"
                                         "Subscription Could Not Be Added "
                                         "Status %d from addSubscription",
                                         isSubscriptionAdded
                              );
                           finalResponse.setResponseData(
                              message,
                              SIP_SERVER_INTERNAL_ERROR_CODE,
                              "Subscription database error" );
                        }

                        // Apply the new to-tag, if any, to the response.
                        if (!newToTag.isNull())
                        {
                           finalResponse.setToFieldTag(newToTag);
                        }
                     }
                     else
                     {
                        OsSysLog::add(FAC_SIP, PRI_CRIT,
                                      "SubscribeServerThread::handleMessage()"
                                      " container->getPlugin failed for '%s'",
                                      eventPackage.data()
                           );
                        finalResponse.setResponseData(
                           message,
                           SIP_SERVER_INTERNAL_ERROR_CODE,
                           SIP_SERVER_INTERNAL_ERROR_TEXT );
                     }
                  }
                  else
                  {
                     // not authorized - the response was created in isAuthorized
                  }
               }
               else
               {
                  // not authenticated - the response was created in isAuthenticated
               }
            }
            else // no plugin found for this event type
            {
               OsSysLog::add(FAC_SIP, PRI_WARNING,
                             "SubscribeServerThread::handleMessage()"
                             " Request denied - "
                             SIP_BAD_EVENT_TEXT
                  );
               finalResponse.setResponseData( message,
                                              SIP_BAD_EVENT_CODE,
                                              "Event type not supported" );
            }

            // send final response
            UtlString finalMessageStr;
            ssize_t finalMessageLen;
            finalResponse.getBytes(&finalMessageStr, &finalMessageLen);
            OsSysLog::add(FAC_SIP, PRI_DEBUG, "\n----------------------------------\n"
                "Sending final response\n%s",finalMessageStr.data());
            mpSipUserAgent->setUserAgentHeader( finalResponse );
            mpSipUserAgent->send( finalResponse );
        }
        else // Invalid domain
        {
           const char* notFoundMsg = SIP_NOT_FOUND_TEXT " Invalid Domain";
           finalResponse.setResponseData(message,
                                         SIP_NOT_FOUND_CODE,
                                         notFoundMsg
                                         );
           mpSipUserAgent->setUserAgentHeader( finalResponse );
           mpSipUserAgent->send( finalResponse );
        }
    }
    else // response
    {
       // The server may send us back a "481" response, if it does we need
       // to remove the subscription from the SubscriptionDB as the callid
       // that it corresponds to is stale (probably the phone was rebooted)
       // In the above case, RFC 3265 says we MUST remove the subscription.
       // It also says (essentially) that any error that does not imply a retry
       // SHOULD remove the subscription.  We will interpret this to be any
       // 4xx code _except_ 408 timeout (because that may be a transient error).
       int responseCode = message->getResponseStatusCode();
       if (   responseCode >= SIP_4XX_CLASS_CODE
           && responseCode != SIP_REQUEST_TIMEOUT_CODE )
       {
          // remove the subscription
          removeErrorSubscription ( *message );
       }
    }
    return TRUE;
}
Example #2
0
int main(int argc, char *argv[]) {
  unsigned short wordlist = FALSE, threads = 8, dumpit = 0, showdns = 0;
  unsigned long int wcount = 0;
  int i = 0, j, k, ignore_ns_error = 0;
  char dom[MAXSTRSIZE] = "", *wordlistFilename = NULL;
  FILE *fpWords;
  char typ = 't', **sub_orig;
  pthread_t thread[MAX_THREADS];

  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);

  if (getenv("THC_IPV6_PPPOE") != NULL || getenv("THC_IPV6_6IN4") != NULL) printf("WARNING: %s is not working with injection!\n", argv[0]);

  do4 = 1;
  do6 = 1;
  if (argv[0] != NULL && argv[0][0] != 0)
    i = argv[0][strlen(argv[0]) - 1];
  if (i == '4')
    do6 = 0;
  if (i == '6')
    do4 = 0;

  if (argc < 2 || strncmp(argv[1], "-h", 2) == 0 || strncmp(argv[1], "--h", 3) == 0)
    help(argv[0]);

  while ((i = getopt(argc, argv, "det:smlxuSD46")) >= 0) {
    switch (i) {
    case '4':
      do4 = 1;
      break;
    case '6':
      do6 = 0;
      break;
    case 'd':
      showdns = 1;
      break;
    case 'e':
      ignore_ns_error = 1;
      break;
    case 't':
      threads = atoi(optarg);
      break;
    case 's':
      sub = (char **) sub_small;
      break;
    case 'm':
      sub = (char **) sub_medium;
      break;
    case 'l':
      sub = (char **) sub_large;
      break;
    case 'x':
      sub = (char **) sub_xtreme;
      break;
    case 'u':
      sub = (char **) sub_uber;
      break;
    case 'D':
      dumpit = 1;
      break;
    case 'S':
      dosrv = 1;
      break;
    default:
      fprintf(stderr, "Error: unknown option -%c\n", i);
      exit(-1);
    }
  }

  if (do4 && do6)
    dof = 0;
  else if (do4 && do6 == 0)
    dof = AF_INET;
  else
    dof = AF_INET6;

  if (threads > MAX_THREADS) {
    threads = MAX_THREADS;
    fprintf(stderr, "Warning: setting threats to maximum of %d\n", threads);
  }
  if (threads < 1)
    threads = 1;

  if (dumpit) {
    i = 0;
    while (sub[i] != NULL && sub[i][0] != 0)
      printf("%s\n", sub[i++]);
    exit(0);
  }

  if (argc == optind || argc > optind + 2) {
    fprintf(stderr, "Error: invalid options, try \"-h\" for help!\n");
    exit(-1);
  }

  if (argc > (optind + 1)) {
    wordlist = TRUE;
    wordlistFilename = argv[optind + 1];
  }

  for (i = 0; argv[optind][i]; ++i)     // convert domain to lower case
    argv[optind][i] = (tolower(argv[optind][i]));
  strcpy(domain, argv[optind]);
  if (domain[strlen(domain) - 1] == '.')
    domain[strlen(domain) - 1] = 0;
#if DEBUG
  printf("domain: %s\n", domain);
#endif
  if (isValidDomain(domain) < 0) {
    fprintf(stderr, "Error: domain seems not to be valid: %s\n", domain);
    exit(-1);
  }

  strcat(domain, ".");
  if (verifyDomain(domain) != TRUE) {
    fprintf(stderr, "Error: no name server (NS) entry for domain %s exists\n", domain);
    if (ignore_ns_error == 0)
      exit(-1);
  }

  printf("Starting DNS enumeration work on %s ...\n", domain);

  if (showdns) {
    printf("Gathering NS and MX information...\n");
    dump_dns(domain, ns_t_ns);
    dump_dns(domain, ns_t_mx);
    printf("\n");
  }

  if (dosrv) {
    sub_orig = sub;
    sub = (char **) sub_srv;

    printf("Starting SRV service enumeration\n");
    printf("Estimated time to completion: 1 to 4 minutes\n");

    lists = malloc(threads * sizeof(void *));
    for (i = 0; i < threads; i++) {
      listptr[i] = 0;
      lists[i] = malloc(65536 * sizeof(int));
    }
    i = j = 0;
    while (sub[j] != NULL && sub[j][0] != 0) {
      lists[i][listptr[i]] = malloc(strlen(sub[j]) + 1);
      strcpy(lists[i][listptr[i]], sub[j]);
      listptr[i] += 1;
      i++;
      if (i >= threads)
        i = 0;
      wcount++;
      j++;
    }
    for (k = 0; k < threads; k++) {
      lists[k][listptr[k]] = malloc(2);
      lists[k][listptr[k]][0] = 0;
      lists[k][listptr[k] + 1] = NULL;
    }

    type = "_tcp";
    if (dnsquerycode(type, domain, ns_t_srv) == 0) {
      dosrv++;
      for (i = 0; i < threads; i++)
        pthread_create(&thread[i], NULL, (void *) threaded_resolve_srv, (void *) lists[i]);
      for (i = 0; i < threads; i++)
        pthread_join(thread[i], NULL);
    } else
      printf("No SRV entries for TCP\n");
    type = "_udp";
    if (dnsquerycode(type, domain, ns_t_srv) == 0) {
      dosrv++;
      for (i = 0; i < threads; i++)
        pthread_create(&thread[i], NULL, (void *) threaded_resolve_srv, (void *) lists[i]);
      for (i = 0; i < threads; i++)
        pthread_join(thread[i], NULL);
    } else
      printf("No SRV entries for UDP\n");

    if (dosrv > 1)
      printf("Found %d services with %d entries altogether\n\n", ucountsrv, ucountsrvs);
    sub = sub_orig;
    type = NULL;
  }

  lists = malloc(threads * sizeof(void *));
  for (i = 0; i < threads; i++) {
    listptr[i] = 0;
    lists[i] = malloc(65536 * sizeof(int));
  }

  wcount = 0;
  // split wordlist to thread lists
  if (wordlist == TRUE) {
    fpWords = fopen(wordlistFilename, "r");
    if (fpWords) {
      i = 0;
      while (!feof(fpWords)) {
        j = fscanf(fpWords, "%100s", dom);      // wordlist subdomain not allowed to be more than 100 chars
        // put in list here
        lists[i][listptr[i]] = malloc(strlen(dom) + 1);
        strcpy(lists[i][listptr[i]], dom);
        listptr[i] += 1;
        if (listptr[i] >= 65534) {
          fprintf(stderr, "Error: wordlist too large (max: %d)!\n", 65536 * threads);
          exit(-1);
        }
        i++;
        wcount++;
        if (i >= threads)
          i = 0;
      }
    } else {
      fprintf(stderr, "Error: could not open file %s\n", wordlistFilename);
      exit(-1);
    }
    fclose(fpWords);
  } else {
    i = j = 0;
    while (sub[j] != NULL && sub[j][0] != 0) {
      lists[i][listptr[i]] = malloc(strlen(sub[j]) + 1);
      strcpy(lists[i][listptr[i]], sub[j]);
      listptr[i] += 1;
      i++;
      if (i >= threads)
        i = 0;
      wcount++;
      j++;
    }
  }
  for (k = 0; k < threads; k++) {
    lists[k][listptr[k]] = malloc(2);
    lists[k][listptr[k]][0] = 0;
    lists[k][listptr[k] + 1] = NULL;
  }

  if (wcount < threads)
    threads = wcount;

  printf("Starting enumerating %s - creating %d threads for %d words...\n", domain, threads, (int) wcount);
  printf("Estimated time to completion: %d to %d minute%s\n", (int) ((wcount / 300) / threads) + 1, (int) ((wcount / 90) / threads) + 1,
         ((wcount / 60) / threads) + 1 > 1 ? "s" : "");
  // wildcard detection
  wildcarDetect(domain);
  for (i = 0; i < threads; i++)
    pthread_create(&thread[i], NULL, (void *) threaded_resolve, (void *) lists[i]);
  for (i = 0; i < threads; i++)
    pthread_join(thread[i], NULL);
  if (do4 && do6)
    printf("\nFound %d domain name%s, %d unique ipv4 and %d unique ipv6 addresses for %s\n", found, found == 1 ? "" : "s", ucount4 + wcard4, ucount + wcard, domain);
  else if (do4)
    printf("\nFound %d domain name%s and %d unique ipv4 address%s for %s\n", found, found == 1 ? "" : "s", ucount4 + wcard4, (ucount4 + wcard4) == 1 ? "" : "s", domain);
  else
    printf("\nFound %d domain name%s and %d unique ipv6 address%s for %s\n", found, found == 1 ? "" : "s", ucount + wcard, (ucount + wcard) == 1 ? "" : "s", domain);

  return 0;
}