//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; }
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; }