Esempio n. 1
0
// haystack is \0 (space if leading upper) (lowercase string), ends with two \0
// needles are a NULL terminated list of lowercase strings, with a leading space if upper
int text_search(char* haystack, char** needles, int exact, int* results)
{
    // information about the needles
    int n = count_pointers(needles);
    int uppers[n];        // is this needle uppercase prefix
    int lengths[n];       // length of this needle
    char* strings[n];     // actual text of this needle

    for (int i = 0; i < n; i++)
    {
        uppers[i] = needles[i][0] == ' ';
        strings[i] = uppers[i] ? &needles[i][1] : needles[i];
        lengths[i] = strlen(strings[i]);
    }

    int index = 0;          // Number of \n's I've already seen in haystack
    int found = 0;          // Number I've written to results

    for (index = 0; ; index++)
    {
        int upper = haystack[0] == ' ';
        if (upper) haystack++;
        int length = strlen(haystack);
        if (length == 0) break;
        char* string = haystack;
        haystack = &haystack[length+1];

        int score = 4;
        for (int i = 0; i < n; i++)
        {
            char* pos = strstr(string, strings[i]); // length, strings[i], lengths[i]);
            if (pos == NULL)
            {
                score = -1;
                break;
            }
            else if (pos == string)
            {
                int complete = lengths[i] == length;
                int cased = uppers[i] == upper;
                score = min_int(score, (!complete ? 2 : 0) + (!cased ? 1 : 0));
            }
        }
        if (score >= 0 && (!exact || score == 0))
            results[found++] = (score << 24) | index;
    }
    qsort(results, found, sizeof(int), compare_int);
    for (int i = 0; i < found; i++)
        results[i] = results[i] & 0xffffff;
    return found;
}
Esempio n. 2
0
void socket_thread_handle(socket_thread_data_t *td)
{
	char *buf;
	char errbuf[ERRBUFLEN + 1];
	apr_size_t bufsize = 1024;
	apr_size_t readsize = bufsize;
	char **argv;
	apr_status_t res;
	dynalogin_result_t dynalogin_res;

	apr_pool_t *query_pool;

	int ntokens;

	char *selected_mode;
	dynalogin_userid_t userid;
	dynalogin_scheme_t scheme;
	dynalogin_code_t code;

	char *digest_realm;
	char *digest_response;
	char *digest_suffix;

	if((res=apr_pool_create(&query_pool, td->pool))!=APR_SUCCESS)
	{
		syslog(LOG_ERR, "failed to create query pool: %s",
						apr_strerror(res, errbuf, ERRBUFLEN));
		return;
	}

	if(send_result(td, 220)!=APR_SUCCESS)
	{
		syslog(LOG_ERR, "failed to send greeting");
		return;
	}

	readsize = bufsize;
	res = read_line(query_pool, td, &buf, bufsize);
	while(res == APR_SUCCESS || res == APR_EOF)
	{
		if((res=apr_tokenize_to_argv(buf, &argv, query_pool))
				!=APR_SUCCESS)
		{
			syslog(LOG_ERR, "failed to tokenize query: %s",
							apr_strerror(res, errbuf, ERRBUFLEN));
			return;
		}
		ntokens = count_pointers(argv);

		/* Examine the command sent by the client */
		if(ntokens < 1)
		{
			syslog(LOG_WARNING, "insufficient tokens in query");
                        res = send_result(td, 500);
		}
		else if(strcasecmp(argv[0], "QUIT")==0)
		{
			send_result(td, 221);
			return;
		}
                else if(strcasecmp(argv[0], "UDATA")==0)
		{
			/* User sending user ID and response value */
			selected_mode=argv[1];
			if(ntokens < 1)
			{
                                /* Command too short */
                                syslog(LOG_WARNING, "insufficient tokens in query");
                                res = send_result(td, 500);
			}
			else if(strcasecmp(selected_mode, "HOTP") == 0 ||
					strcasecmp(selected_mode, "TOTP") == 0)
			{
				userid=argv[2];
				scheme = selected_mode[0] == 'H' ? HOTP : TOTP;
				code=argv[3];
				if(ntokens < 4)
				{
					/* Command too short */
					syslog(LOG_WARNING, "insufficient tokens in query");
					res = send_result(td, 500);
				}
				else
				{
					syslog(LOG_DEBUG, "attempting DYNALOGIN auth for user=%s", userid);
					dynalogin_res = dynalogin_authenticate(td->dynalogin_session,
						userid, scheme, code);

					switch(dynalogin_res)
					{
					case DYNALOGIN_SUCCESS:
						syslog(LOG_DEBUG, "DYNALOGIN success for user=%s", userid);
						res = send_result(td, 250);
						break;
					case DYNALOGIN_DENY:
						/* User unknown or bad password */
						syslog(LOG_DEBUG, "DYNALOGIN denied for user=%s", userid);
						res = send_result(td, 401);
						break;
					case DYNALOGIN_ERROR:
						/* Error connecting to DB, etc */
						syslog(LOG_DEBUG, "DYNALOGIN error for user=%s", userid);
						res = send_result(td, 500);
						break;
					default:
						syslog(LOG_DEBUG, "DYNALOGIN unexpected result for user=%s", userid);
						res = send_result(td, 500);
					}
				}
			} else if (strcasecmp(selected_mode, "HOTP-DIGEST") == 0 ||
					strcasecmp(selected_mode, "TOTP-DIGEST") == 0)
			{
				/* HOTP Digest mode */
				userid = argv[2];
				scheme = selected_mode[0] == 'H' ? HOTP : TOTP;
				digest_realm = argv[3];
				digest_response = argv[4];
				digest_suffix = argv[5];
				if(ntokens < 6)
				{
					/* Command too short */
					syslog(LOG_WARNING, "insufficient tokens in query");
					res = send_result(td, 500);
				}
				else
				{
					syslog(LOG_DEBUG, "attempting DYNALOGIN digest auth for user=%s", userid);
					dynalogin_res = dynalogin_authenticate_digest(td->dynalogin_session, 
						userid, scheme, digest_response, digest_realm, digest_suffix);

					switch(dynalogin_res)
					{
					case DYNALOGIN_SUCCESS:
						syslog(LOG_DEBUG, "DYNALOGIN success for user=%s", userid);
						res = send_result(td, 250);
						break;
					case DYNALOGIN_DENY:
						/* User unknown or bad password */
						syslog(LOG_DEBUG, "DYNALOGIN denied for user=%s", userid);
						res = send_result(td, 401);
						break;
					case DYNALOGIN_ERROR:
						/* Error connecting to DB, etc */
						syslog(LOG_DEBUG, "DYNALOGIN error for user=%s", userid);
						res = send_result(td, 500);
						break;
					default:
						syslog(LOG_DEBUG, "DYNALOGIN unexpected result for user=%s", userid);
						res = send_result(td, 500);
					}
				}
			} else {
				syslog(LOG_WARNING, "unsupported mode requested");
                        	res = send_result(td, 500);
			}
		}
		else
		{
			/* Unrecognised command */
			res = send_result(td, 500);
		}
	
		if(res != APR_SUCCESS)
		{
			syslog(LOG_ERR, "failed to send response: %s",
					apr_strerror(res, errbuf, ERRBUFLEN));
			return;
		}

		apr_pool_destroy(query_pool);
		if((res=apr_pool_create(&query_pool, td->pool))!=APR_SUCCESS)
		{
			syslog(LOG_ERR, "failed to create query pool: %s",
							apr_strerror(res, errbuf, ERRBUFLEN));
			return;
		}
		res = read_line(query_pool, td, &buf, bufsize);
	}
	syslog(LOG_ERR, "failed to read input from socket: %s",
					apr_strerror(res, errbuf, ERRBUFLEN));
}