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; }
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; }
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; }
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; }
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); }
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; }
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); }
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, "<"); obj->state = IN_COMMENT; } else { new_markup = net_BeginColorHTMLTag(obj); } } else if(*cp == '&') { StrAllocCopy(new_markup, BEGIN_AMPERSAND_THINGY_MARKUP); StrAllocCat(new_markup, "&"); 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, "<"); } 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, "<"); } else { StrAllocCopy(new_markup, "<"); } } 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, "<"); } 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, "<"); } 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, "<"); } else if(*cp == '&') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "&"); } 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, "<"); } else if(*cp == '&') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "&"); } 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, ">"); cp += 2; i += 2; StrAllocCat(new_markup, END_COMMENT_MARKUP); obj->state = IN_CONTENT; } else if(*cp == '<') { /* protect ourselves from markup */ StrAllocCopy(new_markup, "<"); } 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, "<"); } 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); }