예제 #1
0
파일: passdss.c 프로젝트: BlueSkyGjj/impala
/* Decode a single PASSDSS packet */
static int passdss_decode_packet(void *context,
				 const char *input,
				 unsigned inputlen,
				 char **output,
				 unsigned *outputlen)
{
    context_t *text = (context_t *) context;
    uint32_t tmpnum;
    unsigned char hmac[EVP_MAX_MD_SIZE];
    unsigned hmaclen;
    int ret;

    if (text->secmask & PRIVACY_LAYER_FLAG) {
	unsigned declen, padlen;

	/* allocate a buffer for the output */
	ret = _plug_buf_alloc(text->utils, &(text->decode_pkt_buf),
			      &(text->decode_pkt_buf_len), inputlen);
	if (ret != SASL_OK) return ret;

	/* decrypt the data into the output buffer */
	ret = EVP_DecryptUpdate(&text->cipher_dec_ctx,
				text->decode_pkt_buf, &declen,
				(char *) input, inputlen);
	if (ret)
	    EVP_DecryptFinal_ex(&text->cipher_dec_ctx,  /* should be no output */
				text->decode_pkt_buf + declen, &declen);
	if (!ret) {
	    SETERROR(text->utils, "Error decrypting input");
	    return SASL_BADPROT;
	}
	input = text->decode_pkt_buf;

	/* trim padding */
	padlen = text->decode_pkt_buf[inputlen - 1] + 1;
	inputlen -= padlen;
    }

    /* trim HMAC */
    inputlen -= SHA_DIGEST_LENGTH;

    /* prepend packet number to integrity key */
    tmpnum = htonl(text->pktnum_in++);
    memcpy(text->recv_integrity_key, &tmpnum, 4);

    /* calculate the HMAC */
    HMAC(EVP_sha1(), text->recv_integrity_key, 4+SHA_DIGEST_LENGTH,
	 input, inputlen, hmac, &hmaclen);

    /* verify HMAC */
    if (memcmp(hmac, input+inputlen, hmaclen)) {
	SETERROR(text->utils, "HMAC is incorrect\n");
	return SASL_BADMAC;
    }

    *output = (char *) input;
    *outputlen = inputlen;

    return SASL_OK;
}
예제 #2
0
static int kerberosv4_decode_packet(void *context,
				    const char *input, unsigned inputlen,
				    char **output, unsigned *outputlen)
{
    context_t *text = (context_t *) context;
    int result;
    MSG_DAT data;
    
    memset(&data,0,sizeof(MSG_DAT));
    
    KRB_LOCK_MUTEX(text->utils);
    
    if (text->sec_type == KRB_SEC_ENCRYPTION) {
	result=krb_rd_priv(input, inputlen, text->init_keysched, 
			   &text->session, &text->ip_remote,
			   &text->ip_local, &data);
    } else if (text->sec_type == KRB_SEC_INTEGRITY) {
        result = krb_rd_safe(input, inputlen,
			     &text->session, &text->ip_remote,
			     &text->ip_local, &data);
    } else {
        KRB_UNLOCK_MUTEX(text->utils);
	text->utils->seterror(text->utils->conn, 0,
			      "KERBEROS_4 decode called with KRB_SEC_NONE");
	return SASL_FAIL;
    }
    
    KRB_UNLOCK_MUTEX(text->utils);
    
    /* see if the krb library gave us a failure */
    if (result != 0) {
	text->utils->seterror(text->utils->conn, 0, get_krb_err_txt(result));
	return SASL_FAIL;
    }
    
    /* check to make sure the timestamps are ok */
    if ((data.time_sec < text->time_sec) || /* if an earlier time */
	(((data.time_sec == text->time_sec) && /* or the exact same time */
	  (data.time_5ms < text->time_5ms)))) 
	{
	    text->utils->seterror(text->utils->conn, 0, "timestamps not ok");
	    return SASL_FAIL;
	}
    
    text->time_sec = data.time_sec;
    text->time_5ms = data.time_5ms;
    
    result = _plug_buf_alloc(text->utils, &text->decode_once_buf,
			     &text->decode_once_buf_len,
			     data.app_length + 1);
    if(result != SASL_OK)
	return result;
    
    *output = text->decode_once_buf;
    *outputlen = data.app_length;
    memcpy(*output, data.app_data, data.app_length);
    (*output)[*outputlen] = '\0';
    
    return SASL_OK;
}
예제 #3
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;
}
예제 #4
0
파일: passdss.c 프로젝트: BlueSkyGjj/impala
static int passdss_encode(void *context,
			  const struct iovec *invec,
			  unsigned numiov,
			  const char **output,
			  unsigned *outputlen)
{
    context_t *text = (context_t *) context;
    unsigned long inputlen;
    unsigned char hmac[EVP_MAX_MD_SIZE];
    unsigned i, hmaclen;
    uint32_t tmpnum;
    int ret;
    
    if (!context || !invec || !numiov || !output || !outputlen) {
	PARAMERROR( text->utils );
	return SASL_BADPARAM;
    }

    /* calculate total size of input */
    for (i = 0, inputlen = 0; i < numiov; i++)
	inputlen += invec[i].iov_len;

    /* allocate a buffer for the output */
    ret = _plug_buf_alloc(text->utils, &text->encode_buf,
			  &text->encode_buf_len,
			  4 +				/* length */
			  inputlen +			/* content */
			  EVP_MAX_MD_SIZE +		/* HMAC */
			  EVP_MAX_BLOCK_LENGTH - 1);	/* padding */
    if (ret != SASL_OK) return ret;

    *outputlen = 4; /* skip length */

    /* prepend packet number to integrity key */
    tmpnum = htonl(text->pktnum_out++);
    memcpy(text->send_integrity_key, &tmpnum, 4);

    /* key the HMAC */
    HMAC_Init_ex(&text->hmac_send_ctx, text->send_integrity_key,
		 4+SHA_DIGEST_LENGTH, EVP_sha1(), NULL);

    /* operate on each iovec */
    for (i = 0; i < numiov; i++) {
	/* hash the content */
	HMAC_Update(&text->hmac_send_ctx, invec[i].iov_base, invec[i].iov_len);

	if (text->secmask & PRIVACY_LAYER_FLAG) {
	    unsigned enclen;

	    /* encrypt the data into the output buffer */
	    EVP_EncryptUpdate(&text->cipher_enc_ctx,
			      text->encode_buf + *outputlen, &enclen,
			      invec[i].iov_base, invec[i].iov_len);
	    *outputlen += enclen;
	}
	else {
	    /* copy the raw input to the output */
	    memcpy(text->encode_buf + *outputlen, invec[i].iov_base,
		   invec[i].iov_len);
	    *outputlen += invec[i].iov_len;
	}
    }

    /* calculate the HMAC */
    HMAC_Final(&text->hmac_send_ctx, hmac, &hmaclen);

    if (text->secmask & PRIVACY_LAYER_FLAG) {
	unsigned enclen;
	unsigned char padlen;

	/* encrypt the HMAC into the output buffer */
	EVP_EncryptUpdate(&text->cipher_enc_ctx,
			  text->encode_buf + *outputlen, &enclen,
			  hmac, hmaclen);
	*outputlen += enclen;

	/* pad output buffer to multiple of blk_siz
	   with padlen-1 as last octet */
	padlen = text->blk_siz - ((inputlen + hmaclen) % text->blk_siz) - 1;
	EVP_EncryptUpdate(&text->cipher_enc_ctx,
			  text->encode_buf + *outputlen, &enclen,
			  text->padding, padlen);
	*outputlen += enclen;
	EVP_EncryptUpdate(&text->cipher_enc_ctx,
			  text->encode_buf + *outputlen, &enclen,
			  &padlen, 1);
	*outputlen += enclen;

	/* encrypt the last block of data into the output buffer */
	EVP_EncryptFinal_ex(&text->cipher_enc_ctx,
			    text->encode_buf + *outputlen, &enclen);
	*outputlen += enclen;
    }
    else {
	/* copy the HMAC to the output */
	memcpy(text->encode_buf + *outputlen, hmac, hmaclen);
	*outputlen += hmaclen;
    }

    /* prepend the length of the output */
    tmpnum = *outputlen - 4;
    tmpnum = htonl(tmpnum);
    memcpy(text->encode_buf, &tmpnum, 4);

    *output = text->encode_buf;
    
    return SASL_OK;
}
예제 #5
0
파일: gssapi.c 프로젝트: 1ack/Impala
static int gssapi_decode_packet(void *context,
				const char *input, unsigned inputlen,
				char **output, unsigned *outputlen)
{
    context_t *text = (context_t *) context;
    OM_uint32 maj_stat, min_stat;
    gss_buffer_t input_token, output_token;
    gss_buffer_desc real_input_token, real_output_token;
    int result;
    
    if (text->state != SASL_GSSAPI_STATE_AUTHENTICATED) {
	SETERROR(text->utils, "GSSAPI Failure");
	return SASL_NOTDONE;
    }
    
    input_token = &real_input_token; 
    real_input_token.value = (char *) input;
    real_input_token.length = inputlen;
    
    output_token = &real_output_token;
    output_token->value = NULL;
    output_token->length = 0;
    
    GSS_LOCK_MUTEX(text->utils);
    maj_stat = gss_unwrap (&min_stat,
			   text->gss_ctx,
			   input_token,
			   output_token,
			   NULL,
			   NULL);
    GSS_UNLOCK_MUTEX(text->utils);
    
    if (GSS_ERROR(maj_stat))
	{
	    sasl_gss_seterror(text->utils,maj_stat,min_stat);
	    if (output_token->value) {
		GSS_LOCK_MUTEX(text->utils);
		gss_release_buffer(&min_stat, output_token);
		GSS_UNLOCK_MUTEX(text->utils);
	    }
	    return SASL_FAIL;
	}
    
    if (outputlen)
	*outputlen = output_token->length;
    
    if (output_token->value) {
	if (output) {
	    result = _plug_buf_alloc(text->utils, &text->decode_once_buf,
				     &text->decode_once_buf_len,
				     *outputlen);
	    if(result != SASL_OK) {
		GSS_LOCK_MUTEX(text->utils);
		gss_release_buffer(&min_stat, output_token);
		GSS_UNLOCK_MUTEX(text->utils);
		return result;
	    }
	    *output = text->decode_once_buf;
	    memcpy(*output, output_token->value, *outputlen);
	}
	GSS_LOCK_MUTEX(text->utils);
	gss_release_buffer(&min_stat, output_token);
	GSS_UNLOCK_MUTEX(text->utils);
    }
    
    return SASL_OK;
}
예제 #6
0
파일: gssapi.c 프로젝트: 1ack/Impala
static int 
sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov,
		const char **output, unsigned *outputlen, int privacy)
{
    context_t *text = (context_t *)context;
    OM_uint32 maj_stat, min_stat;
    gss_buffer_t input_token, output_token;
    gss_buffer_desc real_input_token, real_output_token;
    int ret;
    struct buffer_info *inblob, bufinfo;
    
    if(!output) return SASL_BADPARAM;
    
    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;
    }
    
    if (text->state != SASL_GSSAPI_STATE_AUTHENTICATED) return SASL_NOTDONE;
    
    input_token = &real_input_token;
    
    real_input_token.value  = inblob->data;
    real_input_token.length = inblob->curlen;
    
    output_token = &real_output_token;
    output_token->value = NULL;
    output_token->length = 0;
    
    GSS_LOCK_MUTEX(text->utils);
    maj_stat = gss_wrap (&min_stat,
			 text->gss_ctx,
			 privacy,
			 GSS_C_QOP_DEFAULT,
			 input_token,
			 NULL,
			 output_token);
    GSS_UNLOCK_MUTEX(text->utils);
    
    if (GSS_ERROR(maj_stat))
	{
	    sasl_gss_seterror(text->utils, maj_stat, min_stat);
	    if (output_token->value) {
		GSS_LOCK_MUTEX(text->utils);
		gss_release_buffer(&min_stat, output_token);
		GSS_UNLOCK_MUTEX(text->utils);
	    }
	    return SASL_FAIL;
	}
    
    if (output_token->value && output) {
	int len;
	
	ret = _plug_buf_alloc(text->utils, &(text->encode_buf),
			      &(text->encode_buf_len), output_token->length + 4);
	
	if (ret != SASL_OK) {
	    GSS_LOCK_MUTEX(text->utils);
	    gss_release_buffer(&min_stat, output_token);
	    GSS_UNLOCK_MUTEX(text->utils);
	    return ret;
	}
	
	len = htonl(output_token->length);
	memcpy(text->encode_buf, &len, 4);
	memcpy(text->encode_buf + 4, output_token->value, output_token->length);
    }
    
    if (outputlen) {
	*outputlen = output_token->length + 4;
    }
    
    *output = text->encode_buf;
    
    if (output_token->value) {
	GSS_LOCK_MUTEX(text->utils);
	gss_release_buffer(&min_stat, output_token);
	GSS_UNLOCK_MUTEX(text->utils);
    } 
    return SASL_OK;
}
예제 #7
0
파일: gssapi.c 프로젝트: 1ack/Impala
static int
sasl_gss_seterror_(const sasl_utils_t *utils, OM_uint32 maj, OM_uint32 min,
		   int logonly)
{
    OM_uint32 maj_stat, min_stat;
    gss_buffer_desc msg;
    OM_uint32 msg_ctx;
    int ret;
    char *out = NULL;
    size_t len, curlen = 0;
    const char prefix[] = "GSSAPI Error: ";
    
    len = sizeof(prefix);
    ret = _plug_buf_alloc(utils, &out, &curlen, 256);
    if(ret != SASL_OK) return SASL_OK;
    
    strcpy(out, prefix);
    
    msg_ctx = 0;
    while (1) {
	GSS_LOCK_MUTEX(utils);
	maj_stat = gss_display_status(&min_stat, maj,
				      GSS_C_GSS_CODE, GSS_C_NULL_OID,
				      &msg_ctx, &msg);
	GSS_UNLOCK_MUTEX(utils);
	
	if(GSS_ERROR(maj_stat)) {
	    if (logonly) {
		utils->log(utils->conn, SASL_LOG_FAIL,
			"GSSAPI Failure: (could not get major error message)");
	    } else {
		utils->seterror(utils->conn, 0,
				"GSSAPI Failure "
				"(could not get major error message)");
	    }
	    utils->free(out);
	    return SASL_OK;
	}
	
	len += len + msg.length;
	ret = _plug_buf_alloc(utils, &out, &curlen, len);
	
	if(ret != SASL_OK) {
	    utils->free(out);
	    return SASL_OK;
	}
	
	strcat(out, msg.value);
	
	GSS_LOCK_MUTEX(utils);
	gss_release_buffer(&min_stat, &msg);
	GSS_UNLOCK_MUTEX(utils);
	
	if (!msg_ctx)
	    break;
    }
    
    /* Now get the minor status */
    
    len += 2;
    ret = _plug_buf_alloc(utils, &out, &curlen, len);
    if(ret != SASL_OK) {
	utils->free(out);
	return SASL_NOMEM;
    }
    
    strcat(out, " (");
    
    msg_ctx = 0;
    while (1) {
	GSS_LOCK_MUTEX(utils);
	maj_stat = gss_display_status(&min_stat, min,
				      GSS_C_MECH_CODE, GSS_C_NULL_OID,
				      &msg_ctx, &msg);
	GSS_UNLOCK_MUTEX(utils);
	
	if(GSS_ERROR(maj_stat)) {
	    if (logonly) {
		utils->log(utils->conn, SASL_LOG_FAIL,
			"GSSAPI Failure: (could not get minor error message)");
	    } else {
		utils->seterror(utils->conn, 0,
				"GSSAPI Failure "
				"(could not get minor error message)");
	    }
	    utils->free(out);
	    return SASL_OK;
	}
	
	len += len + msg.length;

	ret = _plug_buf_alloc(utils, &out, &curlen, len);
	if(ret != SASL_OK) {
	    utils->free(out);
	    return SASL_NOMEM;
	}
	
	strcat(out, msg.value);
	
	GSS_LOCK_MUTEX(utils);
	gss_release_buffer(&min_stat, &msg);
	GSS_UNLOCK_MUTEX(utils);
	
	if (!msg_ctx)
	    break;
    }
    
    len += 1;
    ret = _plug_buf_alloc(utils, &out, &curlen, len);
    if(ret != SASL_OK) {
	utils->free(out);
	return SASL_NOMEM;
    }
    
    strcat(out, ")");
    
    if (logonly) {
	utils->log(utils->conn, SASL_LOG_FAIL, out);
    } else {
	utils->seterror(utils->conn, 0, out);
    }
    utils->free(out);

    return SASL_OK;
}