예제 #1
0
int
heim_digest_set_key(heim_digest_t context, const char *key, const char *value)
{

    if (strcmp(key, "password") == 0) {
	FREE_AND_CLEAR(context->password);
	if ((context->password = strdup(value)) == NULL)
	    return ENOMEM;
	context->flags &= ~(F_HAVE_HASH|F_HAVE_HA1);
    } else if (strcmp(key, "userhash") == 0) {
	ssize_t ret;
	FREE_AND_CLEAR(context->password);

	ret = hex_decode(value, context->SecretHash, sizeof(context->SecretHash));
	if (ret != sizeof(context->SecretHash))
	    return EINVAL;
	context->flags &= ~F_HAVE_HA1;
	context->flags |= F_HAVE_HASH;
    } else if (strcmp(key, "H(A1)") == 0) {
	ssize_t ret;
	FREE_AND_CLEAR(context->password);
	
	ret = hex_decode(value, context->SecretHash, sizeof(context->SecretHash));
	if (ret != sizeof(context->SecretHash))
	    return EINVAL;
	context->flags &= ~F_HAVE_HASH;
	context->flags |= F_HAVE_HA1;
    } else if (strcmp(key, "method") == 0) {
	FREE_AND_CLEAR(context->serverMethod);
	if ((context->serverMethod = strdup(value)) == NULL)
	    return ENOMEM;
    } else {
	size_t n;

	for (n = 0; n < sizeof(keys) / sizeof(keys[0]); n++) {
	    if (strcasecmp(key, keys[n].name) == 0) {
		char **ptr = (char **)((((char *)context) + keys[n].offset));
		FREE_AND_CLEAR(*ptr);
		if (((*ptr) = strdup(value)) == NULL)
		    return ENOMEM;
		break;
	    }
	}
	if (n == sizeof(keys) / sizeof(keys[0]))
	    return ENOENT;
    }
    return 0;
}
예제 #2
0
int
heim_digest_set_key(heim_digest_t context, const char *key, const char *value)
{
    if (strcmp(key, "password") == 0) {
	FREE_AND_CLEAR(context->password);
	if ((context->password = strdup(value)) == NULL)
	    return ENOMEM;
    } else if (strcmp(key, "method") == 0) {
	FREE_AND_CLEAR(context->serverMethod);
	if ((context->serverMethod = strdup(value)) != NULL)
	    return ENOMEM;
    } else {
	return EINVAL;
    }
    return 0;
}
예제 #3
0
const char *
heim_digest_generate_challenge(heim_digest_t context)
{
    char *challenge = NULL;
    
    if (context->serverRealm == NULL)
	return NULL;
    
    if (context->serverNonce == NULL) {
	if ((context->serverNonce = generate_nonce()) == NULL)
	    return NULL;
    }
    
    if (context->serverQOP == NULL) {
	if ((context->serverQOP = strdup("auth")) == NULL)
	    return NULL;
    }
    
    if (context->serverMaxbuf == NULL) {
	if ((context->serverMaxbuf = strdup("65536")) == NULL)
	    return NULL;
    }

    switch(context->type) {
	case HEIM_DIGEST_TYPE_RFC2617_MD5:
	    asprintf(&challenge, "realm=\"%s\",nonce=\"%s\",algorithm=md5,qop=\"%s\"",
		     context->serverRealm, context->serverNonce,
		     context->serverQOP);
	    break;
	case HEIM_DIGEST_TYPE_RFC2617_MD5_SESS:
	    asprintf(&challenge, "realm=\"%s\",nonce=\"%s\",algorithm=md5-sess,qop=\"%s\"",
		     context->serverRealm, context->serverNonce, context->serverQOP);
	    break;
	case HEIM_DIGEST_TYPE_RFC2069:
	    asprintf(&challenge, "realm=\"%s\",nonce=\"%s\"",
		     context->serverRealm, context->serverNonce);
	    break;
	case HEIM_DIGEST_TYPE_AUTO:
	    context->type = HEIM_DIGEST_TYPE_RFC2831;
	    /* FALL THOUGH */
	case HEIM_DIGEST_TYPE_RFC2831:
	    asprintf(&challenge, "realm=\"%s\",nonce=\"%s\",qop=\"%s\",algorithm=md5-sess,charset=utf-8,maxbuf=%s",
		     context->serverRealm, context->serverNonce, context->serverQOP, context->serverMaxbuf);
	    break;
    }

    FREE_AND_CLEAR(context->serverChallenge);
    context->serverChallenge = challenge;
    
    return challenge;
}
예제 #4
0
static void
build_server_response(heim_digest_t context, char *a1, char **response)
{
    char *str;
    
    str = build_digest(context, a1, NULL);
    if (str == NULL)
	return;
    
    FREE_AND_CLEAR(context->serverReply);
    asprintf(&context->serverReply, "%srspauth=%s",
	     (context->flags & F_USE_PREFIX) ? digest_prefix : "",
	     str);
    free(str);
    if (response)
	*response = context->serverReply;
}
예제 #5
0
static void
clear_context(heim_digest_t context)
{
    MEMSET_FREE_AND_CLEAR(context->password);
    memset(context->SecretHash, 0, sizeof(context->SecretHash));
    context->flags &= ~(F_HAVE_HASH);
    FREE_AND_CLEAR(context->serverNonce);
    FREE_AND_CLEAR(context->serverRealm);
    FREE_AND_CLEAR(context->serverQOP);
    FREE_AND_CLEAR(context->serverMethod);
    FREE_AND_CLEAR(context->serverMaxbuf);
    FREE_AND_CLEAR(context->serverOpaque);
    FREE_AND_CLEAR(context->clientUsername);
    FREE_AND_CLEAR(context->clientResponse);
    FREE_AND_CLEAR(context->clientURI);
    FREE_AND_CLEAR(context->clientRealm);
    FREE_AND_CLEAR(context->clientNonce);
    FREE_AND_CLEAR(context->clientQOP);
    FREE_AND_CLEAR(context->clientNC);
    FREE_AND_CLEAR(context->serverAlgorithm);
    FREE_AND_CLEAR(context->auth_id);
    
    FREE_AND_CLEAR(context->serverChallenge);
    FREE_AND_CLEAR(context->clientReply);
    FREE_AND_CLEAR(context->serverReply);
}
예제 #6
0
const char *
heim_digest_create_response(heim_digest_t context, char **response)
{
    char *a1, *str, *cnonce = NULL, *opaque = NULL, *uri = NULL, *nc = NULL;
    
    if (response)
	*response = NULL;
    
    if (context->clientUsername == NULL || context->clientURI == NULL)
	return NULL;
    
    if (context->clientRealm == NULL) {
	if (context->serverRealm == NULL)
	    return NULL;
	if ((context->clientRealm = strdup(context->serverRealm)) == NULL)
	    return NULL;
    }
    
    if (context->type != HEIM_DIGEST_TYPE_RFC2069) {
	if (context->clientNC == NULL) {
	    if ((context->clientNC = strdup("00000001")) == NULL)
		return NULL;
	}
	if (context->clientNonce == NULL) {
	    if ((context->clientNonce = generate_nonce()) == NULL)
		return NULL;
	}

	/**
	 * If using non RFC2069, appropriate QOP should be set.
	 *
	 * Pick QOP from server if not given, if its a list, pick the first entry
	 */
	if (context->clientQOP == NULL) {
	    char *r;
	    if (context->serverQOP == NULL)
		return NULL;
	    r = strchr(context->serverQOP, ',');
	    if (r == NULL) {
		if ((context->clientQOP = strdup(context->serverQOP)) == NULL)
			return NULL;
	    } else {
		size_t len = (r - context->serverQOP) + 1;
		if ((context->clientQOP = malloc(len)) == NULL)
		    return NULL;
		strlcpy(context->clientQOP, context->serverQOP, len);
	    }
	}
    }
	    
    set_auth_method(context);
    
    a1 = build_A1_hash(context);
    if (a1 == NULL)
	return NULL;
    
    str = build_digest(context, a1, context->serverMethod);
    if (str == NULL) {
	MEMSET_FREE_AND_CLEAR(a1);
	return NULL;
    }
    
    MEMSET_FREE_AND_CLEAR(context->clientResponse);
    context->clientResponse = str;
    
    if (context->clientURI) {
	const char *name = "digest-uri";
	if (context->type != HEIM_DIGEST_TYPE_RFC2831)
	    name = "uri";
	asprintf(&uri, ",%s=\"%s\"", name, context->clientURI);
    }
    
    if (context->serverOpaque)
	asprintf(&opaque, ",opaque=\"%s\"", context->serverOpaque);
    
    if (context->clientNonce)
	asprintf(&cnonce, ",cnonce=\"%s\"", context->clientNonce);

    if (context->clientNC)
	asprintf(&nc, ",nc=%s", context->clientNC);
    
    asprintf(&context->clientReply,
	     "username=%s,realm=%s,nonce=\"%s\",qop=\"%s\"%s%s%s,response=\"%s\"%s",
	     context->clientUsername, context->clientRealm,
	     context->serverNonce,
	     context->clientQOP,
	     uri ? uri : "",
	     cnonce ? cnonce : "",
	     nc ? nc : "",
	     context->clientResponse,
	     opaque ? opaque : "");
    
    build_server_response(context, a1, response);
    MEMSET_FREE_AND_CLEAR(a1);
    FREE_AND_CLEAR(uri);
    FREE_AND_CLEAR(opaque);
    FREE_AND_CLEAR(cnonce);
    FREE_AND_CLEAR(nc);
    
    return context->clientReply;
}
예제 #7
0
static void
clear_context(heim_digest_t context)
{
    MEMSET_FREE_AND_CLEAR(context->password);
    memset(context->SecretHash, 0, sizeof(context->SecretHash));
    FREE_AND_CLEAR(context->serverNonce);
    FREE_AND_CLEAR(context->serverRealm);
    FREE_AND_CLEAR(context->serverQOP);
    FREE_AND_CLEAR(context->serverMethod);
    FREE_AND_CLEAR(context->clientUsername);
    FREE_AND_CLEAR(context->clientResponse);
    FREE_AND_CLEAR(context->clientURI);
    FREE_AND_CLEAR(context->clientRealm);
    FREE_AND_CLEAR(context->clientNonce);
    FREE_AND_CLEAR(context->clientQOP);
    FREE_AND_CLEAR(context->clientNC);
    FREE_AND_CLEAR(context->serverAlgorithm);
    FREE_AND_CLEAR(context->auth_id);
}
예제 #8
0
PRIVATE int net_ColorHTMLWrite (NET_StreamClass *stream, CONST char *s, int32 l)
{
	int32 i;
	int32 last_output_point;
	char *new_markup=0;
	char *tmp_markup=0;
	char  tiny_buf[4];
	CONST char *cp;
	int   status;
	DataObject *obj=stream->data_object;	

	last_output_point = 0;

	for(i = 0, cp = s; i < l; i++, cp++)
	  {
	    switch(obj->state)
	      {
		    case IN_CONTENT:
			    /* do nothing until you find a '<' "<!--" or '&' */
				if(*cp == '<')
				  {
					/* XXX we can miss a comment spanning a block boundary */
					if(i+4 <= l && !XP_STRNCMP(cp, "<!--", 4))
					  {
						StrAllocCopy(new_markup, BEGIN_COMMENT_MARKUP);
						StrAllocCat(new_markup, "&lt;");
						obj->state = IN_COMMENT;
					  }
					else
					  {
						new_markup = net_BeginColorHTMLTag(obj);
					  }
				  }
				else if(*cp == '&')
				  {
					StrAllocCopy(new_markup, BEGIN_AMPERSAND_THINGY_MARKUP);
					StrAllocCat(new_markup, "&amp;");
					obj->state = IN_AMPERSAND_THINGY;
				  }
			    break;
			case IN_SCRIPT:
				/* do nothing until you find '</SCRIPT>' */
				if(*cp == '<')
				  {
					/* XXX we can miss a </SCRIPT> spanning a block boundary */
					if(i+8 <= l && !XP_STRNCASECMP(cp, "</SCRIPT", 8))
					  {
						new_markup = net_BeginColorHTMLTag(obj);
					  }
				  }
				break;
		    case ABOUT_TO_BEGIN_TAG:
				/* we have seen the first '<'
				 * once we see a non-whitespace character
				 * we will be in the tag identifier
				 */
				if(*cp == '>')
				  {
					StrAllocCopy(new_markup, END_TAG_NAME_MARKUP);
					tmp_markup = net_EndColorHTMLTag(obj);
					StrAllocCat(new_markup, tmp_markup);
					FREE_AND_CLEAR(tmp_markup);
				  }
				else if(!XP_IS_SPACE(*cp))
				  {
					obj->state = IN_BEGIN_TAG;
					obj->tag_index = 0;
					obj->tag[obj->tag_index++] = *cp;
					if(*cp == '<')
						StrAllocCopy(new_markup, "&lt;");

				  }
			    break;
		    case IN_BEGIN_TAG:
				/* go to the IN_TAG state when we see
				 * the first whitespace
				 */
				if(XP_IS_SPACE(*cp))
				  {
					StrAllocCopy(new_markup, END_TAG_NAME_MARKUP);
					XP_SPRINTF(tiny_buf, "%c", *cp);
					StrAllocCat(new_markup, tiny_buf);
					obj->state = IN_TAG;
					obj->tag[obj->tag_index] = '\0';
					obj->tag_type = pa_tokenize_tag(obj->tag);
				  }
				else if(*cp == '>')
				  {
					StrAllocCopy(new_markup, END_TAG_NAME_MARKUP);
					tmp_markup = net_EndColorHTMLTag(obj);
					StrAllocCat(new_markup, tmp_markup);
					FREE_AND_CLEAR(tmp_markup);
				  }
				else if(*cp == '<')
				  {
					/* protect ourselves from markup */
					if(!obj->in_broken_html)
					  {
						obj->in_broken_html = TRUE;
						StrAllocCopy(new_markup, BEGIN_BROKEN_ATTRIBUTE_MARKUP);
						StrAllocCat(new_markup, "&lt;");
					  }
					else
					  {
					    StrAllocCopy(new_markup, "&lt;");
					  }
				  }
				else
				  {
					if (obj->tag_index < MAXTAGLEN)
						obj->tag[obj->tag_index++] = *cp;
				  }
			    break;
		    case IN_TAG:
			    /* do nothing until you find a opening '=' or end '>' */
				if(*cp == '=')
				  {
					StrAllocCopy(new_markup, "=");
					StrAllocCat(new_markup, BEGIN_ATTRIBUTE_VALUE_MARKUP);
					obj->state = BEGIN_ATTRIBUTE_VALUE;
				  }
				else if(*cp == '>')
				  {
					new_markup = net_EndColorHTMLTag(obj);
				  }
				else if(*cp == '<')
				  {
					/* protect ourselves from markup */
					StrAllocCopy(new_markup, "&lt;");
				  }
			    break;
		    case BEGIN_ATTRIBUTE_VALUE:
				/* when we reach the first non-whitespace
				 * we will enter the UNQUOTED or the QUOTED
				 * ATTRIBUTE state
				 */
				if(!XP_IS_SPACE(*cp))
				  {
					if(*cp == '"')
                    {
		    			obj->state = IN_QUOTED_ATTRIBUTE_VALUE;
                        /* no need to jump to the quoted attr handler
                         * since this char can't be a dangerous char
                         */
                    }
					else
                    {
		    			obj->state = IN_UNQUOTED_ATTRIBUTE_VALUE;
                        /* need to jump to the unquoted attr handler
                         * since this char can be a dangerous character
                         */
                        goto unquoted_attribute_jump_point;
                    }
				  }
				else if(*cp == '>')
				  {
					StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
					tmp_markup = net_EndColorHTMLTag(obj);
					StrAllocCat(new_markup, tmp_markup);
					FREE_AND_CLEAR(tmp_markup);
				  }
				else if(*cp == '<')
				  {
					/* protect ourselves from markup */
					StrAllocCopy(new_markup, "&lt;");
				  }
			    break;
		    case IN_UNQUOTED_ATTRIBUTE_VALUE:
unquoted_attribute_jump_point:
			    /* do nothing until you find a whitespace */
				if(XP_IS_SPACE(*cp))
				  {
					StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
					XP_SPRINTF(tiny_buf, "%c", *cp);
					StrAllocCat(new_markup, tiny_buf);
					obj->state = IN_TAG;
				  }
				else if(*cp == '>')
				  {
					StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
					tmp_markup = net_EndColorHTMLTag(obj);
					StrAllocCat(new_markup, tmp_markup);
					FREE_AND_CLEAR(tmp_markup);
				  }
				else if(*cp == '<')
				  {
					/* protect ourselves from markup */
					StrAllocCopy(new_markup, "&lt;");
				  }
				else if(*cp == '&')
				  {
					/* protect ourselves from markup */
					StrAllocCopy(new_markup, "&amp;");
				  }
			    break;
		    case IN_QUOTED_ATTRIBUTE_VALUE:
			    /* do nothing until you find a closing '"' */
				if(*cp == '\"')
				  {
					if(obj->in_broken_html)
					  {
                    	StrAllocCopy(new_markup, END_BROKEN_ATTRIBUTE_MARKUP);
						obj->in_broken_html = FALSE;
					  }
					StrAllocCat(new_markup, "\"");
					StrAllocCat(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
					obj->state = IN_TAG;
				  }
				else if(*cp == '<')
				  {
					/* protect ourselves from markup */
					StrAllocCopy(new_markup, "&lt;");
				  }
				else if(*cp == '&')
				  {
					/* protect ourselves from markup */
					StrAllocCopy(new_markup, "&amp;");
				  }
				else if(*cp == '>')
				  {
					/* probably a broken attribute value */
					if(!obj->in_broken_html)
					  {
						obj->in_broken_html = TRUE;
						StrAllocCopy(new_markup, BEGIN_BROKEN_ATTRIBUTE_MARKUP);
						StrAllocCat(new_markup, ">");
					  }
				  }
			    break;
			case IN_COMMENT:
			    /* do nothing until you find a closing '-->' */
				if(!XP_STRNCMP(cp, "-->", 3))
				  {
					StrAllocCopy(new_markup, "&gt;");
					cp += 2;
					i += 2;
					StrAllocCat(new_markup, END_COMMENT_MARKUP);
					obj->state = IN_CONTENT;
				  }
				else if(*cp == '<')
				  {
					/* protect ourselves from markup */
					StrAllocCopy(new_markup, "&lt;");
				  }
			    break;
			case IN_AMPERSAND_THINGY:
			    /* do nothing until you find a ';' or space */
				if(*cp == ';' || XP_IS_SPACE(*cp))
				  {
					XP_SPRINTF(tiny_buf, "%c", *cp);
					StrAllocCopy(new_markup, tiny_buf);
					StrAllocCat(new_markup, END_AMPERSAND_THINGY_MARKUP);
					obj->state = IN_CONTENT;
				  }
				else if(*cp == '<')
				  {
					/* protect ourselves from markup */
					StrAllocCopy(new_markup, "&lt;");
				  }
			    break;
		    default:
			    XP_ASSERT(0);
			    break;
		  }

		if(new_markup)
		  {
			/* push all the way up to but not including *cp */
			status = (*obj->next_stream->put_block)
											(obj->next_stream,
    										&s[last_output_point],
    										i-last_output_point);
    		last_output_point = i+1;

			if(status < 0)
			  {
				FREE(new_markup);
				return(status);
			  }

			/* add new markup */
    		status = (*obj->next_stream->put_block)
											(obj->next_stream,
        									new_markup, XP_STRLEN(new_markup));
			if(status < 0)
			  {
				FREE(new_markup);
				return(status);
			  }

    		FREE_AND_CLEAR(new_markup);
		  }
	  }

	if(last_output_point < l)
		return((*obj->next_stream->put_block)(obj->next_stream,
    									  &s[last_output_point],
    									  (l-last_output_point)));
	else
		return(0);
}