Пример #1
0
static krb5_error_code
encode_rx_header (struct rx_header *h,
		  krb5_storage *sp)
{
    krb5_error_code ret;

    ret = krb5_store_uint32(sp, h->epoch);
    if (ret) return ret;
    ret = krb5_store_uint32(sp, h->connid);
    if (ret) return ret;
    ret = krb5_store_uint32(sp, h->callid);
    if (ret) return ret;
    ret = krb5_store_uint32(sp, h->seqno);
    if (ret) return ret;
    ret = krb5_store_uint32(sp, h->serialno);
    if (ret) return ret;
    ret = krb5_store_uint8(sp,  h->type);
    if (ret) return ret;
    ret = krb5_store_uint8(sp,  h->flags);
    if (ret) return ret;
    ret = krb5_store_uint8(sp,  h->status);
    if (ret) return ret;
    ret = krb5_store_uint8(sp,  h->secindex);
    if (ret) return ret;
    ret = krb5_store_uint16(sp, h->reserved);
    if (ret) return ret;
    ret = krb5_store_uint16(sp, h->serviceid);
    if (ret) return ret;

    return 0;
}
Пример #2
0
static int
make_result (krb5_data *data,
             uint16_t result_code,
             const char *expl)
{
    krb5_error_code ret;
    krb5_storage *sp;

    sp = krb5_storage_emem();
    if (sp == NULL) goto out;
    ret = krb5_store_uint16(sp, result_code);
    if (ret) goto out;
    ret = krb5_store_stringz(sp, expl);
    if (ret) goto out;
    ret = krb5_storage_to_data(sp, data);
    if (ret) goto out;
    krb5_storage_free(sp);

    return 0;
out:
    if (sp)
        krb5_storage_free(sp);

    krb5_warnx (context, "Out of memory generating error reply");
    return 1;
}
Пример #3
0
static void
test_uint16(krb5_context context, krb5_storage *sp)
{
    krb5_error_code ret;
    int i;
    uint16_t val[] = {
	0, 1, 65535
    }, v;

    krb5_storage_truncate(sp, 0);

    for (i = 0; i < sizeof(val[0])/sizeof(val); i++) {

	ret = krb5_store_uint16(sp, val[i]);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_store_uint16");
	krb5_storage_seek(sp, 0, SEEK_SET);
	ret = krb5_ret_uint16(sp, &v);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_ret_uint16");
	if (v != val[i])
	    krb5_errx(context, 1, "store and ret mismatch");
    }
}
Пример #4
0
static krb5_error_code
build_logon_name(krb5_context context,
		 time_t authtime,
		 krb5_const_principal principal,
		 krb5_data *logon)
{
    krb5_error_code ret;
    krb5_storage *sp;
    uint64_t t;
    char *s, *s2;
    size_t i, len;

    t = unix2nttime(authtime);

    krb5_data_zero(logon);

    sp = krb5_storage_emem();
    if (sp == NULL)
	return krb5_enomem(context);

    krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);

    CHECK(ret, krb5_store_uint32(sp, t & 0xffffffff), out);
    CHECK(ret, krb5_store_uint32(sp, t >> 32), out);

    ret = krb5_unparse_name_flags(context, principal,
				  KRB5_PRINCIPAL_UNPARSE_NO_REALM, &s);
    if (ret)
	goto out;

    len = strlen(s);

    CHECK(ret, krb5_store_uint16(sp, len * 2), out);

#if 1 /* cheat for now */
    s2 = malloc(len * 2);
    if (s2 == NULL) {
	ret = krb5_enomem(context);
	free(s);
	goto out;
    }
    for (i = 0; i < len; i++) {
	s2[i * 2] = s[i];
	s2[i * 2 + 1] = 0;
    }
    free(s);
#else
    /* write libwind code here */
#endif

    ret = krb5_storage_write(sp, s2, len * 2);
    free(s2);
    if (ret != len * 2) {
	ret = krb5_enomem(context);
	goto out;
    }
    ret = krb5_storage_to_data(sp, logon);
    if (ret)
	goto out;
    krb5_storage_free(sp);

    return 0;
out:
    krb5_storage_free(sp);
    return ret;
}
Пример #5
0
static krb5_error_code
chgpw_prexmit(krb5_context context, int proto,
              void *ctx, rk_socket_t fd, krb5_data *data)
{
    struct request *request = ctx;
    krb5_data ap_req_data, krb_priv_data, passwd_data;
    krb5_storage *sp = NULL;
    krb5_error_code ret;
    krb5_ssize_t slen;
    size_t len;

    krb5_data_zero(&ap_req_data);
    krb5_data_zero(&krb_priv_data);

    ret = krb5_auth_con_genaddrs(context, request->ac, fd,
                                 KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR);
    if (ret)
        goto out;

    ret = krb5_mk_req_extended(context,
                               &request->ac,
                               AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY,
                               NULL,
                               request->creds,
                               &ap_req_data);
    if (ret)
        goto out;

    passwd_data.data   = rk_UNCONST(request->password);
    passwd_data.length = strlen(request->password);

    ret = krb5_mk_priv(context,
                       request->ac,
                       &passwd_data,
                       &krb_priv_data,
                       NULL);
    if (ret)
        goto out;

    sp = krb5_storage_emem();
    if (sp == NULL) {
        ret = ENOMEM;
        goto out;
    }

    len = 6 + ap_req_data.length + krb_priv_data.length;

    ret = krb5_store_uint16(sp, len);
    if (ret) goto out;
    ret = krb5_store_uint16(sp, 1);
    if (ret) goto out;
    ret = krb5_store_uint16(sp, ap_req_data.length);
    if (ret) goto out;
    slen = krb5_storage_write(sp, ap_req_data.data, ap_req_data.length);
    if (slen != ap_req_data.length) {
        ret = EINVAL;
        goto out;
    }
    slen = krb5_storage_write(sp, krb_priv_data.data, krb_priv_data.length);
    if (slen != krb_priv_data.length) {
        ret = EINVAL;
        goto out;
    }

    ret = krb5_storage_to_data(sp, data);

out:
    if (ret)
        _krb5_debugx(context, 10, "chgpw_prexmit failed with: %d", ret);
    if (sp)
        krb5_storage_free(sp);
    krb5_data_free(&krb_priv_data);
    krb5_data_free(&ap_req_data);
    return ret;
}
Пример #6
0
static krb5_error_code
setpw_prexmit(krb5_context context, int proto,
              void *ctx, int fd, krb5_data *data)
{
    struct request *request = ctx;
    krb5_data ap_req_data, krb_priv_data, pwd_data;
    krb5_error_code ret;
    ChangePasswdDataMS chpw;
    krb5_storage *sp = NULL;
    ssize_t slen;
    size_t len;

    krb5_data_zero(&ap_req_data);
    krb5_data_zero(&krb_priv_data);
    krb5_data_zero(&pwd_data);

    ret = krb5_auth_con_genaddrs(context, request->ac, fd,
                                 KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR);
    if (ret)
        goto out;

    ret = krb5_mk_req_extended(context,
                               &request->ac,
                               AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY,
                               NULL,
                               request->creds,
                               &ap_req_data);
    if (ret)
        goto out;

    chpw.newpasswd.length = strlen(request->password);
    chpw.newpasswd.data = rk_UNCONST(request->password);
    if (request->target) {
        chpw.targname = &request->target->name;
        chpw.targrealm = &request->target->realm;
    } else {
        chpw.targname = NULL;
        chpw.targrealm = NULL;
    }

    ASN1_MALLOC_ENCODE(ChangePasswdDataMS, pwd_data.data, pwd_data.length,
                       &chpw, &len, ret);
    if (ret)
        goto out;
    if(pwd_data.length != len)
        krb5_abortx(context, "internal error in ASN.1 encoder");

    ret = krb5_mk_priv (context,
                        request->ac,
                        &pwd_data,
                        &krb_priv_data,
                        NULL);
    if (ret)
        goto out;

    sp = krb5_storage_emem();
    if (sp == NULL) {
        ret = ENOMEM;
        goto out;
    }

    len = 6 + ap_req_data.length + krb_priv_data.length;

    ret = krb5_store_uint16(sp, len);
    if (ret) goto out;
    ret = krb5_store_uint16(sp, 0xff80);
    if (ret) goto out;
    ret = krb5_store_uint16(sp, ap_req_data.length);
    if (ret) goto out;
    slen = krb5_storage_write(sp, ap_req_data.data, ap_req_data.length);
    if (slen != ap_req_data.length) {
        ret = EINVAL;
        goto out;
    }
    slen = krb5_storage_write(sp, krb_priv_data.data, krb_priv_data.length);
    if (slen != krb_priv_data.length) {
        ret = EINVAL;
        goto out;
    }

    ret = krb5_storage_to_data(sp, data);

out:
    if (ret)
        _krb5_debugx(context, 10, "setpw_prexmit failed with %d", ret);
    if (sp)
        krb5_storage_free(sp);
    krb5_data_free(&krb_priv_data);
    krb5_data_free(&ap_req_data);
    krb5_data_free(&pwd_data);

    return ret;
}
Пример #7
0
static krb5_error_code
build_logon_name(krb5_context context,
		 time_t authtime,
		 krb5_const_principal principal,
		 krb5_data *logon)
{
    krb5_error_code ret;
    krb5_storage *sp;
    uint64_t t;
    char *s, *s2;
    size_t s2_len;

    t = unix2nttime(authtime);

    krb5_data_zero(logon);

    sp = krb5_storage_emem();
    if (sp == NULL)
	return krb5_enomem(context);

    krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);

    CHECK(ret, krb5_store_uint32(sp, t & 0xffffffff), out);
    CHECK(ret, krb5_store_uint32(sp, t >> 32), out);

    ret = krb5_unparse_name_flags(context, principal,
				  KRB5_PRINCIPAL_UNPARSE_NO_REALM |
				  KRB5_PRINCIPAL_UNPARSE_DISPLAY,
				  &s);
    if (ret)
	goto out;

    {
	size_t ucs2_len;
	uint16_t *ucs2;
	unsigned int flags;

	ret = wind_utf8ucs2_length(s, &ucs2_len);
	if (ret) {
	    krb5_set_error_message(context, ret, "Principal %s is not valid UTF-8", s);
	    free(s);
	    return ret;
	}

	ucs2 = malloc(sizeof(ucs2[0]) * ucs2_len);
	if (ucs2 == NULL) {
	    free(s);
	    return krb5_enomem(context);
	}

	ret = wind_utf8ucs2(s, ucs2, &ucs2_len);
	if (ret) {
	    free(ucs2);
	    krb5_set_error_message(context, ret, "Principal %s is not valid UTF-8", s);
	    free(s);
	    return ret;
	} else 
	    free(s);

	s2_len = (ucs2_len + 1) * 2;
	s2 = malloc(s2_len);
	if (s2 == NULL) {
	    free(ucs2);
	    return krb5_enomem(context);
	}

	flags = WIND_RW_LE;
	ret = wind_ucs2write(ucs2, ucs2_len,
			     &flags, s2, &s2_len);
	free(ucs2);
	if (ret) {
	    free(s2);
	    krb5_set_error_message(context, ret, "Failed to write to UCS-2 buffer");
	    return ret;
	}

	/*
	 * we do not want zero termination
	 */
	s2_len = ucs2_len * 2;
    }

    CHECK(ret, krb5_store_uint16(sp, s2_len), out);

    ret = krb5_storage_write(sp, s2, s2_len);
    free(s2);
    if (ret != (int)s2_len) {
	ret = krb5_enomem(context);
	goto out;
    }
    ret = krb5_storage_to_data(sp, logon);
    if (ret)
	goto out;
    krb5_storage_free(sp);

    return 0;
out:
    krb5_storage_free(sp);
    return ret;
}