Beispiel #1
0
static int kerberosv4_encode(void *context,
			     const struct iovec *invec,
			     unsigned numiov,
			     const char **output,
			     unsigned *outputlen)
{
    int len, ret;
    context_t *text = (context_t *)context;
    struct buffer_info *inblob, bufinfo;
    
    if(numiov > 1) {
	ret = _plug_iovec_to_buf(text->utils, invec, numiov, &text->enc_in_buf);
	if(ret != SASL_OK) return ret;
	inblob = text->enc_in_buf;
    } else {
	bufinfo.data = invec[0].iov_base;
	bufinfo.curlen = invec[0].iov_len;
	inblob = &bufinfo;
    }
    
    ret = _plug_buf_alloc(text->utils, &(text->encode_buf),
			  &text->encode_buf_len, inblob->curlen+40);
    
    if(ret != SASL_OK) return ret;
    
    KRB_LOCK_MUTEX(text->utils);
    
    if (text->sec_type == KRB_SEC_ENCRYPTION) {
	/* Type incompatibility on 4th arg probably means you're
	   building against krb4 in MIT krb5, but got the OpenSSL
	   headers in your way. You need to not use openssl/des.h with
	   MIT kerberos. */
	len=krb_mk_priv(inblob->data, (text->encode_buf+4),
			inblob->curlen,  text->init_keysched, 
			&text->session, &text->ip_local,
			&text->ip_remote);
    } else if (text->sec_type == KRB_SEC_INTEGRITY) {
	len=krb_mk_safe(inblob->data, (text->encode_buf+4),
			inblob->curlen,
			&text->session, &text->ip_local, &text->ip_remote);
    } else {
	len = -1;
    }
    
    KRB_UNLOCK_MUTEX(text->utils);
    
    /* returns -1 on error */
    if (len==-1) return SASL_FAIL;
    
    /* now copy in the len of the buffer in network byte order */
    *outputlen=len+4;
    len=htonl(len);
    memcpy(text->encode_buf, &len, 4);
    
    /* Setup the const pointer */
    *output = text->encode_buf;
    
    return SASL_OK;
}
Beispiel #2
0
static int
krb4_encode(void *app_data, void *from, int length, int level, void **to)
{
    struct krb4_data *d = app_data;
    *to = malloc(length + 31);
    if(level == prot_safe)
	return krb_mk_safe(from, *to, length, &d->key, 
			   (struct sockaddr_in *)LOCAL_ADDR,
			   (struct sockaddr_in *)REMOTE_ADDR);
    else if(level == prot_private)
	return krb_mk_priv(from, *to, length, d->schedule, &d->key, 
			   (struct sockaddr_in *)LOCAL_ADDR,
			   (struct sockaddr_in *)REMOTE_ADDR);
    else
	return -1;
}
Beispiel #3
0
static int
krb4_encode(void *app_data, const void *from, int length, int level, void **to,
            struct connectdata *conn)
{
  struct krb4_data *d = app_data;
  *to = malloc(length + 31);
  if(!*to)
    return -1;
  if(level == prot_safe)
    /* NOTE that the void* cast is safe, krb_mk_safe/priv don't modify the
     * input buffer
     */
    return krb_mk_safe((void*)from, *to, length, &d->key,
                       (struct sockaddr_in *)LOCAL_ADDR,
                       (struct sockaddr_in *)REMOTE_ADDR);
  else if(level == prot_private)
    return krb_mk_priv((void*)from, *to, length, d->schedule, &d->key,
                       (struct sockaddr_in *)LOCAL_ADDR,
                       (struct sockaddr_in *)REMOTE_ADDR);
  else
    return -1;
}
int
auth_krb4(Authctxt *authctxt, KTEXT auth, char **client, KTEXT reply)
{
	AUTH_DAT adat = {0};
	Key_schedule schedule;
	struct sockaddr_in local, foreign;
	char instance[INST_SZ];
	socklen_t slen;
	u_int cksum;
	int r, s;

	s = packet_get_connection_in();

	slen = sizeof(local);
	memset(&local, 0, sizeof(local));
	if (getsockname(s, (struct sockaddr *) & local, &slen) < 0)
		debug("getsockname failed: %.100s", strerror(errno));
	slen = sizeof(foreign);
	memset(&foreign, 0, sizeof(foreign));
	if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) {
		debug("getpeername failed: %.100s", strerror(errno));
		fatal_cleanup();
	}
	instance[0] = '*';
	instance[1] = 0;

	/* Get the encrypted request, challenge, and session key. */
	if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance,
	    0, &adat, ""))) {
		debug("Kerberos v4 krb_rd_req: %.100s", krb_err_txt[r]);
		return (0);
	}
	des_key_sched((des_cblock *) adat.session, schedule);

	*client = xmalloc(MAX_K_NAME_SZ);
	(void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname,
	    *adat.pinst ? "." : "", adat.pinst, adat.prealm);

	/* Check ~/.klogin authorization now. */
	if (kuserok(&adat, authctxt->user) != KSUCCESS) {
		log("Kerberos v4 .klogin authorization failed for %s to "
		    "account %s", *client, authctxt->user);
		xfree(*client);
		*client = NULL;
		return (0);
	}
	/* Increment the checksum, and return it encrypted with the
	   session key. */
	cksum = adat.checksum + 1;
	cksum = htonl(cksum);

	/* If we can't successfully encrypt the checksum, we send back an
	   empty message, admitting our failure. */
	if ((r = krb_mk_priv((u_char *) & cksum, reply->dat, sizeof(cksum) + 1,
	    schedule, &adat.session, &local, &foreign)) < 0) {
		debug("Kerberos v4 mk_priv: (%d) %s", r, krb_err_txt[r]);
		reply->dat[0] = 0;
		reply->length = 0;
	} else
		reply->length = r;

	/* Clear session key. */
	memset(&adat.session, 0, sizeof(&adat.session));
	return (1);
}