Example #1
0
/* Read the contents of file FILENAME into *DATUM. */
static int read_to_datum(const char *filename, gnutls_datum *datum)
{
    FILE *f = fopen(filename, "r");
    ne_buffer *buf;
    char tmp[4192];
    size_t len;

    if (!f) {
        return -1;
    }

    buf = ne_buffer_ncreate(8192);
    while ((len = fread(tmp, 1, sizeof tmp, f)) > 0) {
        ne_buffer_append(buf, tmp, len);
    }

    if (!feof(f)) {
        fclose(f);
        ne_buffer_destroy(buf);
        return -1;
    }
    
    fclose(f);

    datum->size = ne_buffer_size(buf);
    datum->data = (unsigned char *)ne_buffer_finish(buf);
    return 0;
}
Example #2
0
char *ne_ssl_readable_dname(const ne_ssl_dname *name)
{
    gnutls_x509_dn_t dn;
    int ret, rdn = 0, flag = 0;
    ne_buffer *buf;
    gnutls_x509_ava_st val;

#ifdef HAVE_NEW_DN_API
    dn = name->dn;
#else
    if (name->subject)
        ret = gnutls_x509_crt_get_subject(name->cert, &dn);
    else
        ret = gnutls_x509_crt_get_issuer(name->cert, &dn);
    
    if (ret)
        return ne_strdup(_("[unprintable]"));
#endif /* HAVE_NEW_DN_API */

    buf = ne_buffer_create();
    
    /* Find the highest rdn... */
    while (gnutls_x509_dn_get_rdn_ava(dn, rdn++, 0, &val) == 0)
        ;        

    /* ..then iterate back to the first: */
    while (--rdn >= 0) {
        int ava = 0;

        /* Iterate through all AVAs for multivalued AVAs; better than
         * ne_openssl can do! */
        do {
            ret = gnutls_x509_dn_get_rdn_ava(dn, rdn, ava, &val);

            /* If the *only* attribute to append is the common name or
             * email address, use it; otherwise skip those
             * attributes. */
            if (ret == 0 && val.value.size > 0
                && ((!CMPOID(&val, OID_emailAddress)
                     && !CMPOID(&val, OID_commonName))
                    || (buf->used == 1 && rdn == 0))) {
                flag = 1;
                if (buf->used > 1) ne_buffer_append(buf, ", ", 2);

                append_dirstring(buf, &val.value, val.value_tag);
            }
            
            ava++;
        } while (ret == 0);
    }

    return ne_buffer_finish(buf);
}
Example #3
0
/* Return a malloc-allocated human-readable error string describing
 * GnuTLS verification error bitmask 'status'; return value must be
 * freed by the caller. */
static char *verify_error_string(unsigned int status)
{
    ne_buffer *buf = ne_buffer_create();

    /* sorry, i18n-ers */
    if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
        ne_buffer_zappend(buf, _("signed using insecure algorithm"));
    }
    else {
        ne_buffer_snprintf(buf, 64, _("unrecognized errors (%u)"),
                           status);
    }
    
    return ne_buffer_finish(buf);
}
Example #4
0
char *ne_ssl_readable_dname(const ne_ssl_dname *name)
{
    ne_buffer *buf = ne_buffer_create();
    int ret, idx = 0;

    do {
        char oid[32] = {0};
        size_t oidlen = sizeof oid;
        
        ret = name->subject 
            ? gnutls_x509_crt_get_dn_oid(name->cert, idx, oid, &oidlen)
            : gnutls_x509_crt_get_issuer_dn_oid(name->cert, idx, oid, &oidlen);
        
        if (ret == 0) {
            append_rdn(buf, name->cert, name->subject, oid);
            idx++;
        }
    } while (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);

    return ne_buffer_finish(buf);
}
Example #5
0
char *ne_uri_unparse(const ne_uri *uri)
{
    ne_buffer *buf = ne_buffer_create();

    if (uri->scheme) {
        ne_buffer_concat(buf, uri->scheme, ":", NULL);
    }

    if (uri->host) {
        ne_buffer_czappend(buf, "//");
        if (uri->userinfo) {
            ne_buffer_concat(buf, uri->userinfo, "@", NULL);
        }
        ne_buffer_zappend(buf, uri->host);
        
        if (uri->port > 0
            && (!uri->scheme 
                || ne_uri_defaultport(uri->scheme) != uri->port)) {
            char str[20];
            ne_snprintf(str, 20, ":%d", uri->port);
            ne_buffer_zappend(buf, str);
        }
    }

    ne_buffer_zappend(buf, uri->path);

    if (uri->query) {
        ne_buffer_concat(buf, "?", uri->query, NULL);
    }
    
    if (uri->fragment) {
        ne_buffer_concat(buf, "#", uri->fragment, NULL);
    }

    return ne_buffer_finish(buf);
}
Example #6
0
char *ne_ssl_readable_dname(const ne_ssl_dname *name)
{
    int n, flag = 0;
    ne_buffer *dump = ne_buffer_create();
    const ASN1_OBJECT * const cname = OBJ_nid2obj(NID_commonName),
	* const email = OBJ_nid2obj(NID_pkcs9_emailAddress);

    for (n = X509_NAME_entry_count(name->dn); n > 0; n--) {
	X509_NAME_ENTRY *ent = X509_NAME_get_entry(name->dn, n-1);
	
        /* Skip commonName or emailAddress except if there is no other
         * attribute in dname. */
	if ((OBJ_cmp(ent->object, cname) && OBJ_cmp(ent->object, email)) ||
            (!flag && n == 1)) {
 	    if (flag++)
		ne_buffer_append(dump, ", ", 2);

            if (append_dirstring(dump, ent->value))
                ne_buffer_czappend(dump, "???");
	}
    }

    return ne_buffer_finish(dump);
}
Example #7
0
/* Return Digest authentication credentials header value for the given
 * session. */
static char *request_digest(auth_session *sess, struct auth_request *req) 
{
    struct ne_md5_ctx a2, rdig;
    unsigned char a2_md5[16], rdig_md5[16];
    char a2_md5_ascii[33], rdig_md5_ascii[33];
    char nc_value[9] = {0};
    const char *qop_value = "auth"; /* qop-value */
    ne_buffer *ret;

    /* Increase the nonce-count */
    if (sess->qop != auth_qop_none) {
	sess->nonce_count++;
	ne_snprintf(nc_value, 9, "%08x", sess->nonce_count);
	NE_DEBUG(NE_DBG_HTTPAUTH, "Nonce count is %u, nc is [%s]\n", 
		 sess->nonce_count, nc_value);
    }

    /* Calculate H(A2). */
    ne_md5_init_ctx(&a2);
    ne_md5_process_bytes(req->method, strlen(req->method), &a2);
    ne_md5_process_bytes(":", 1, &a2);
    ne_md5_process_bytes(req->uri, strlen(req->uri), &a2);
    ne_md5_finish_ctx(&a2, a2_md5);
    ne_md5_to_ascii(a2_md5, a2_md5_ascii);
    NE_DEBUG(NE_DBG_HTTPAUTH, "H(A2): %s\n", a2_md5_ascii);

    NE_DEBUG(NE_DBG_HTTPAUTH, "Calculating Request-Digest.\n");
    /* Now, calculation of the Request-Digest.
     * The first section is the regardless of qop value
     *     H(A1) ":" unq(nonce-value) ":" */
    ne_md5_init_ctx(&rdig);

    /* Use the calculated H(A1) */
    ne_md5_process_bytes(sess->h_a1, 32, &rdig);

    ne_md5_process_bytes(":", 1, &rdig);
    ne_md5_process_bytes(sess->nonce, strlen(sess->nonce), &rdig);
    ne_md5_process_bytes(":", 1, &rdig);
    if (sess->qop != auth_qop_none) {
	/* Add on:
	 *    nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":"
	 */
	NE_DEBUG(NE_DBG_HTTPAUTH, "Have qop directive, digesting: [%s:%s:%s]\n",
		 nc_value, sess->cnonce, qop_value);
	ne_md5_process_bytes(nc_value, 8, &rdig);
	ne_md5_process_bytes(":", 1, &rdig);
	ne_md5_process_bytes(sess->cnonce, strlen(sess->cnonce), &rdig);
	ne_md5_process_bytes(":", 1, &rdig);
	/* Store a copy of this structure (see note below) */
	sess->stored_rdig = rdig;
	ne_md5_process_bytes(qop_value, strlen(qop_value), &rdig);
	ne_md5_process_bytes(":", 1, &rdig);
    } else {
	/* Store a copy of this structure... we do this because the
	 * calculation of the rspauth= field in the Auth-Info header 
	 * is the same as this digest, up to this point. */
	sess->stored_rdig = rdig;
    }
    /* And finally, H(A2) */
    ne_md5_process_bytes(a2_md5_ascii, 32, &rdig);
    ne_md5_finish_ctx(&rdig, rdig_md5);
    ne_md5_to_ascii(rdig_md5, rdig_md5_ascii);
    
    ret = ne_buffer_create();

    ne_buffer_concat(ret, 
		     "Digest username=\"", sess->username, "\", "
		     "realm=\"", sess->realm, "\", "
		     "nonce=\"", sess->nonce, "\", "
		     "uri=\"", req->uri, "\", "
		     "response=\"", rdig_md5_ascii, "\", "
		     "algorithm=\"", sess->alg == auth_alg_md5 ? "MD5" : "MD5-sess", "\"", 
		     NULL);
    
    if (sess->opaque != NULL) {
	ne_buffer_concat(ret, ", opaque=\"", sess->opaque, "\"", NULL);
    }

    if (sess->qop != auth_qop_none) {
	/* Add in cnonce and nc-value fields */
	ne_buffer_concat(ret, ", cnonce=\"", sess->cnonce, "\", "
			 "nc=", nc_value, ", "
			 "qop=\"", qop_value, "\"", NULL);
    }

    ne_buffer_zappend(ret, "\r\n");
    
    NE_DEBUG(NE_DBG_HTTPAUTH, "Digest request header is %s\n", ret->data);

    return ne_buffer_finish(ret);
}