Esempio n. 1
0
int
heim_digest_parse_response(heim_digest_t context, const char *response)
{
    struct md5_value *val = NULL;
    char *nonce;
    int ret;

    ret = parse_values(response, &val);
    if (ret)
	goto out;

    ret = 1;

    if (context->type == HEIM_DIGEST_TYPE_AUTO)
	goto out;

    context->clientUsername = values_find(&val, "username");
    if (context->clientUsername == NULL) goto out;

    context->clientRealm = values_find(&val, "realm");
    
    context->clientResponse = values_find(&val, "response");
    if (context->clientResponse == NULL) goto out;

    nonce = values_find(&val, "nonce");
    if (nonce == NULL) goto out;

    if (strcmp(nonce, context->serverNonce) != 0) {
	free(nonce);
	goto out;
    }
    free(nonce);

    context->clientQOP = values_find(&val, "qop");
    if (context->clientQOP == NULL)
	context->clientQOP = strdup("auth");
    if (context->clientQOP == NULL) goto out;


    if (context->type != HEIM_DIGEST_TYPE_RFC2069) {
	context->clientNC = values_find(&val, "nc");
	if (context->clientNC == NULL) goto out;

	context->clientNonce = values_find(&val, "cnonce");
	if (context->clientNonce == NULL) goto out;
    }

    if (context->type == HEIM_DIGEST_TYPE_RFC2069)
	context->clientURI = values_find(&val, "uri");
    else
	context->clientURI = values_find(&val, "digest-uri");
    if (context->clientURI == NULL) goto out;

    ret = 0;
 out:
    free_values(val);
    return ret;
}
int
heim_digest_parse_challenge(heim_digest_t context, const char *challenge)
{
    struct md5_value *val = NULL;
    int ret, type;
    
    challenge = check_prefix(context, challenge);

    ret = parse_values(challenge, &val);
    if (ret)
	goto out;

    ret = 1;

    context->serverNonce = values_find(&val, "nonce");
    if (context->serverNonce == NULL) goto out;

    context->serverRealm = values_find(&val, "realm");
    if (context->serverRealm == NULL) goto out;

    /* check alg */

    context->serverAlgorithm = values_find(&val, "algorithm");
    if (context->serverAlgorithm == NULL || strcasecmp(context->serverAlgorithm, "md5") == 0) {
	type = HEIM_DIGEST_TYPE_RFC2617_MD5;
    } else if (strcasecmp(context->serverAlgorithm, "md5-sess") == 0) {
	type = HEIM_DIGEST_TYPE_RFC2617_OR_RFC2831;
    } else {
	goto out;
    }

    context->serverQOP = values_find(&val, "qop");
    if (context->serverQOP == NULL)
	type = HEIM_DIGEST_TYPE_RFC2069;
    
    context->serverOpaque = values_find(&val, "opaque");

    if (context->type != HEIM_DIGEST_TYPE_AUTO && (context->type & type) == 0)
	goto out;
    else if (context->type == HEIM_DIGEST_TYPE_AUTO)
	context->type = type;

    ret = 0;
 out:
    free_values(val);
    if (ret)
	clear_context(context);
    return ret;
}
Esempio n. 3
0
int
heim_digest_parse_challenge(heim_digest_t context, const char *challenge)
{
    struct md5_value *val = NULL;
    int ret, type;

    ret = parse_values(challenge, &val);
    if (ret)
	goto out;

    ret = 1;

    context->serverNonce = values_find(&val, "nonce");
    if (context->serverNonce == NULL) goto out;

    context->serverRealm = values_find(&val, "realm");
    if (context->serverRealm == NULL) goto out;

    context->serverQOP = values_find(&val, "qop");
    if (context->serverQOP == NULL)
	context->serverQOP = strdup("auth");
    if (context->serverQOP == NULL) goto out;

    /* check alg */

    context->serverAlgorithm = values_find(&val, "algorithm");
    if (context->serverAlgorithm == NULL || strcasecmp(context->serverAlgorithm, "md5") == 0) {
	type = HEIM_DIGEST_TYPE_RFC2069;
    } else if (strcasecmp(context->serverAlgorithm, "md5-sess") == 0) {
	type = HEIM_DIGEST_TYPE_MD5_SESS;
    } else {
	goto out;
    }

    if (context->type != HEIM_DIGEST_TYPE_AUTO && context->type != type)
	goto out;
    else
	context->type = type;



    ret = 0;
 out:
    free_values(val);
    if (ret)
	clear_context(context);
    return ret;
}
Esempio n. 4
0
/*
* Lookup in values we announce ourselves.
* Useful for networks of only one node, also faster.
*/
void kad_lookup_local_values( struct results_t *results ) {
	char addrbuf[FULL_ADDSTRLEN+1];
	struct value_t* value;
	IP addr;

	/* 127.0.0.1 */
	unsigned int inaddr_loopback = htonl( INADDR_LOOPBACK );

	value = values_find( results->id );
	if( value ) {
		if( gconf->af == AF_INET6 ) {
			to_addr( &addr, &in6addr_loopback, 16, htons( value->port ) ); // ::1
		} else {
			to_addr( &addr, &inaddr_loopback, 4, htons( value->port ) ); // 127.0.0.1
		}
		log_debug( "KAD: Address found in local values: %s\n", str_addr( &addr, addrbuf ) );
		results_add_addr( results, &addr );
	}
}
int
heim_digest_parse_response(heim_digest_t context, const char *response)
{
    struct md5_value *val = NULL;
    char *nonce;
    int ret;

    response = check_prefix(context, response);

    ret = parse_values(response, &val);
    if (ret)
	goto out;

    ret = 1;

    if (context->type == HEIM_DIGEST_TYPE_AUTO) {
	goto out;
    } else if (context->type == HEIM_DIGEST_TYPE_RFC2617_OR_RFC2831) {
	context->clientURI = values_find(&val, "uri");
	if (context->clientURI) {
	    context->type = HEIM_DIGEST_TYPE_RFC2617_MD5_SESS;
	} else {
	    context->clientURI = values_find(&val, "digest-uri");
	    context->type = HEIM_DIGEST_TYPE_RFC2831;
	}
    } else if (context->type == HEIM_DIGEST_TYPE_RFC2831) {
	context->clientURI = values_find(&val, "digest-uri");
    } else {
	context->clientURI = values_find(&val, "uri");
    }

    if (context->clientURI == NULL)
        goto out;

    context->clientUsername = values_find(&val, "username");
    if (context->clientUsername == NULL) goto out;

    /* if client sent realm, make sure its the same of serverRealm if its set */
    context->clientRealm = values_find(&val, "realm");
    if (context->clientRealm && context->serverRealm && strcmp(context->clientRealm, context->serverRealm) != 0)
	goto out;
    
    context->clientResponse = values_find(&val, "response");
    if (context->clientResponse == NULL) goto out;

    nonce = values_find(&val, "nonce");
    if (nonce == NULL) goto out;

    if (strcmp(nonce, context->serverNonce) != 0) {
	free(nonce);
	goto out;
    }
    free(nonce);

    if (context->type != HEIM_DIGEST_TYPE_RFC2069) {

	context->clientQOP = values_find(&val, "qop");
	if (context->clientQOP == NULL) goto out;
	
	/*
	 * If we have serverQOP, lets check that clientQOP exists
	 * in the list of server entries.
	 */
	
	if (context->serverQOP) {
	    Boolean found = false;
	    char *b, *e;
	    size_t len, clen = strlen(context->clientQOP);
	    
	    b = context->serverQOP;
	    while (b && !found) {
		e = strchr(b, ',');
		if (e == NULL)
		    len = strlen(b);
		else {
		    len = e - b;
		    e += 1;
		}
		if (clen == len && strncmp(b, context->clientQOP, len) == 0)
		    found = true;
		b = e;
	    }
	    if (!found)
		goto out;
	}

	context->clientNC = values_find(&val, "nc");
	if (context->clientNC == NULL) goto out;

	context->clientNonce = values_find(&val, "cnonce");
	if (context->clientNonce == NULL) goto out;
    }

    set_auth_method(context);

    ret = 0;
 out:
    free_values(val);
    return ret;
}