예제 #1
0
static bytea *
decrypt_internal(int is_pubenc, int need_text, text *data,
				 text *key, text *keypsw, text *args)
{
	int			err;
	MBuf	   *src = NULL,
			   *dst = NULL;
	uint8		tmp[VARHDRSZ];
	uint8	   *restmp;
	bytea	   *res;
	int			res_len;
	PGP_Context *ctx = NULL;
	struct debug_expect ex;
	int			got_unicode = 0;


	init_work(&ctx, need_text, args, &ex);

	src = mbuf_create_from_data((uint8 *) VARDATA(data),
								VARSIZE(data) - VARHDRSZ);
	dst = mbuf_create(VARSIZE(data) + 2048);

	/*
	 * reserve room for header
	 */
	mbuf_append(dst, tmp, VARHDRSZ);

	/*
	 * set key
	 */
	if (is_pubenc)
	{
		uint8	   *psw = NULL;
		int			psw_len = 0;
		MBuf	   *kbuf;

		if (keypsw)
		{
			psw = (uint8 *) VARDATA(keypsw);
			psw_len = VARSIZE(keypsw) - VARHDRSZ;
		}
		kbuf = create_mbuf_from_vardata(key);
		err = pgp_set_pubkey(ctx, kbuf, psw, psw_len, 1);
		mbuf_free(kbuf);
	}
	else
		err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key),
							 VARSIZE(key) - VARHDRSZ);

	/*
	 * decrypt
	 */
	if (err >= 0)
		err = pgp_decrypt(ctx, src, dst);

	/*
	 * failed?
	 */
	if (err < 0)
		goto out;

	if (ex.expect)
		check_expect(ctx, &ex);

	/* remember the setting */
	got_unicode = pgp_get_unicode_mode(ctx);

out:
	if (src)
		mbuf_free(src);
	if (ctx)
		pgp_free(ctx);

	if (err)
	{
		px_set_debug_handler(NULL);
		if (dst)
			mbuf_free(dst);
		ereport(ERROR,
				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
				 errmsg("%s", px_strerror(err))));
	}

	res_len = mbuf_steal_data(dst, &restmp);
	mbuf_free(dst);

	/* res_len includes VARHDRSZ */
	res = (bytea *) restmp;
	SET_VARSIZE(res, res_len);

	if (need_text && got_unicode)
	{
		text	   *utf = convert_from_utf8(res);

		if (utf != res)
		{
			clear_and_pfree(res);
			res = utf;
		}
	}
	px_set_debug_handler(NULL);

	/*
	 * add successful decryptions also into RNG
	 */
	add_entropy(res, key, keypsw);

	return res;
}
예제 #2
0
static bytea *
encrypt_internal(int is_pubenc, int is_text,
				 text *data, text *key, text *args)
{
	MBuf	   *src,
			   *dst;
	uint8		tmp[VARHDRSZ];
	uint8	   *restmp;
	bytea	   *res;
	int			res_len;
	PGP_Context *ctx;
	int			err;
	struct debug_expect ex;
	text	   *tmp_data = NULL;

	/*
	 * Add data and key info RNG.
	 */
	add_entropy(data, key, NULL);

	init_work(&ctx, is_text, args, &ex);

	if (is_text && pgp_get_unicode_mode(ctx))
	{
		tmp_data = convert_to_utf8(data);
		if (tmp_data == data)
			tmp_data = NULL;
		else
			data = tmp_data;
	}

	src = create_mbuf_from_vardata(data);
	dst = mbuf_create(VARSIZE(data) + 128);

	/*
	 * reserve room for header
	 */
	mbuf_append(dst, tmp, VARHDRSZ);

	/*
	 * set key
	 */
	if (is_pubenc)
	{
		MBuf	   *kbuf = create_mbuf_from_vardata(key);

		err = pgp_set_pubkey(ctx, kbuf,
							 NULL, 0, 0);
		mbuf_free(kbuf);
	}
	else
		err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key),
							 VARSIZE(key) - VARHDRSZ);

	/*
	 * encrypt
	 */
	if (err >= 0)
		err = pgp_encrypt(ctx, src, dst);

	/*
	 * check for error
	 */
	if (err)
	{
		if (ex.debug)
			px_set_debug_handler(NULL);
		if (tmp_data)
			clear_and_pfree(tmp_data);
		pgp_free(ctx);
		mbuf_free(src);
		mbuf_free(dst);
		ereport(ERROR,
				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
				 errmsg("%s", px_strerror(err))));
	}

	/* res_len includes VARHDRSZ */
	res_len = mbuf_steal_data(dst, &restmp);
	res = (bytea *) restmp;
	SET_VARSIZE(res, res_len);

	if (tmp_data)
		clear_and_pfree(tmp_data);
	pgp_free(ctx);
	mbuf_free(src);
	mbuf_free(dst);

	px_set_debug_handler(NULL);

	return res;
}
예제 #3
0
/* This will be called many time to advance rendering of an ubjson ctx */
static void ub_render_cont(struct ub_ctx *ctx) {
  struct mbuf *buf = &ctx->out, *stack = &ctx->stack;
  struct visit *cur;

  if (ctx->out.len > 0) {
    ub_call_cb(ctx, 0);
  }

  for (cur = cur_visit(stack); cur != NULL; cur = cur_visit(stack)) {
    ub_val_t obj = cur->obj;

    if (obj.kind == UBJSON_TYPE_NULL) {
      cs_ubjson_emit_null(buf);
    } else if (obj.kind == UBJSON_TYPE_TRUE) {
      cs_ubjson_emit_boolean(buf, 1);
    } else if (obj.kind == UBJSON_TYPE_FALSE) {
      cs_ubjson_emit_boolean(buf, 0);
    } else if (obj.kind == UBJSON_TYPE_NUMBER) {
      cs_ubjson_emit_autonumber(buf, obj.val.n);
    } else if (obj.kind == UBJSON_TYPE_STRING) {
      cs_ubjson_emit_string(buf, obj.val.s->s, strlen(obj.val.s->s));
    } else if (obj.kind == UBJSON_TYPE_ARRAY) {
      unsigned long cur_idx = cur->v.next_idx;

      if (cur->v.next_idx == 0) {
        cs_ubjson_open_array(buf);
      }

      cur->v.next_idx++;

      if (cur->v.next_idx > ub_array_length(cur->obj)) {
        cs_ubjson_close_array(buf);
      } else {
        cur = push_visit(stack, ub_array_get(obj, cur_idx));
        /* skip default popping of visitor frame */
        continue;
      }
    } else if (obj.kind == UBJSON_TYPE_BIN) {
      ctx->bytes_left = obj.val.b->size;
      cs_ubjson_emit_bin_header(buf, ctx->bytes_left);
      pop_visit(stack);

      obj.val.b->cb(ctx, obj.val.b->user_data);
      /*
       * The user generator will reenter calling this function again with the
       * same context.
       */
      return;

    } else if (obj.kind == UBJSON_TYPE_OBJECT) {
      const char *s;

      if (cur->v.p == NULL) {
        cs_ubjson_open_object(buf);
      }

      cur->v.p = ub_next_prop(obj, cur->v.p);

      if (cur->v.p == NULL) {
        cs_ubjson_close_object(buf);
      } else {
        s = cur->v.p->name->s;
        cs_ubjson_emit_object_key(buf, s, strlen(s));

        cur = push_visit(stack, ub_get(obj, s));
        /* skip default popping of visitor frame */
        continue;
      }
    } else {
      printf("ubsjon: unsupported object: %d\n", obj.kind);
    }

    pop_visit(stack);
  }

  ub_call_cb(ctx, 1);
  mbuf_free(&ctx->out);
  ub_ctx_free(ctx);
}
예제 #4
0
static void console_make_clubby_call_mbuf(struct v7 *v7, struct mbuf *logs) {
  mbuf_append(logs, "\0", 1);
  console_make_clubby_call(v7, logs->buf);
  mbuf_free(logs);
}
UInt32 IOMbufMemoryCursor::genPhysicalSegments(mbuf_t packet, void *vector,
                                               UInt32 maxSegs, bool doCoalesce)
{
    bool doneCoalesce = false;

    if (!packet || !(mbuf_flags(packet) & MBUF_PKTHDR))
        return 0;

    if (!maxSegs)
    {
        maxSegs = maxNumSegments;
        if (!maxSegs) return 0;
    }

    if ( mbuf_next(packet) == 0 )
    {
        uintptr_t               src;
        struct IOPhysicalSegment  physSeg;

        /*
         * the packet consists of only 1 mbuf
         * so if the data buffer doesn't span a page boundary
         * we can take the simple way out
         */
        src = (uintptr_t)mbuf_data(packet);

        if ( trunc_page(src) == trunc_page(src + mbuf_len(packet) - 1) )
        {
            physSeg.location = (IOPhysicalAddress) mbuf_data_to_physical((char *)src);
            if ( physSeg.location )
            {
                physSeg.length = mbuf_len(packet);
                (*outSeg)(physSeg, vector, 0);
                return 1;
            }
            
            maxSegs = 1;
            if ( doCoalesce == false ) return 0;
        }
    }

    if ( doCoalesce == true && maxSegs == 1 )
    {
        uintptr_t               src;
        uintptr_t               dst;
        mbuf_t               m;
        mbuf_t               mnext;
        mbuf_t               out;
        UInt32                    len = 0;
        struct IOPhysicalSegment  physSeg;

        if ( mbuf_pkthdr_len(packet) > MCLBYTES ) return 0;

        m = packet;

        // Allocate a non-header mbuf + cluster.
        if (mbuf_getpacket( MBUF_DONTWAIT, &out ))
			return 0;
		mbuf_setflags( out, mbuf_flags( out ) & ~MBUF_PKTHDR );
        dst = (uintptr_t)mbuf_data(out);

        do
        {
            src = (uintptr_t)mbuf_data(m);
            BCOPY( src, dst, mbuf_len(m) );
            dst += mbuf_len(m);
            len += mbuf_len(m);
        } while ( (m = mbuf_next(m)) != 0 );

        mbuf_setlen(out , len);

        dst = (uintptr_t)mbuf_data(out);
        physSeg.location = (IOPhysicalAddress) mbuf_data_to_physical((char *)dst);
        if (!physSeg.location)
        {
            mbuf_free(out);
            return 0;
        }
        physSeg.length = mbuf_len(out);
        (*outSeg)(physSeg, vector, 0);

        m = mbuf_next(packet);
        while (m != 0)
        {
            mnext = mbuf_next(m);
            mbuf_free(m);
            m = mnext;
        }

        // The initial header mbuf is preserved, its length set to zero,
        // and linked to the new packet chain.

        mbuf_setlen(packet , 0);
        mbuf_setnext(packet , out);
        mbuf_setnext(out , 0);

        return 1;
    }

    //
    // Iterate over the mbuf, translating segments were allowed.  When we
    // are not allowed to translate segments then accumulate segment
    // statistics up to kMBufDataCacheSize of mbufs.  Finally
    // if we overflow our cache just count how many segments this
    // packet represents.
    //
    UInt32 segsPerMBuf[kMBufDataCacheSize];

tryAgain:
    UInt32 curMBufIndex = 0;
    UInt32 curSegIndex  = 0;
    UInt32 lastSegCount = 0;
    mbuf_t m = packet;

    // For each mbuf in incoming packet.
    do {
        vm_size_t   mbufLen, thisLen = 0;
        uintptr_t src;

        // Step through each segment in the current mbuf
        for (mbufLen = mbuf_len(m), src = (uintptr_t)mbuf_data(m);
             mbufLen;
             src += thisLen, mbufLen -= thisLen)
        {
            // If maxSegmentSize is atleast PAGE_SIZE, then
            // thisLen = MIN(next_page(src), src + mbufLen) - src;

            thisLen = MIN(mbufLen, maxSegmentSize);
            thisLen = MIN(next_page(src), src + thisLen) - src;

            // If room left then find the current segment addr and output
            if (curSegIndex < maxSegs) {
                struct IOPhysicalSegment physSeg;

                physSeg.location = (IOPhysicalAddress) mbuf_data_to_physical((char *)src);
                if ( physSeg.location == 0 )
                {
                    return doCoalesce ?
                           genPhysicalSegments(packet, vector, 1, true) : 0;
                }
                physSeg.length = thisLen;
                (*outSeg)(physSeg, vector, curSegIndex);
            }

            // Count segments if we are coalescing. 
            curSegIndex++;
        }

        // Cache the segment count data if room is available.
        if (curMBufIndex < kMBufDataCacheSize) {
            segsPerMBuf[curMBufIndex] = curSegIndex - lastSegCount;
            lastSegCount = curSegIndex;
        }

        // Move on to next imcoming mbuf
        curMBufIndex++;
        m = mbuf_next(m);
    } while (m);

    // If we finished cleanly return number of segments found
    if (curSegIndex <= maxSegs)
        return curSegIndex;
    if (!doCoalesce)
        return 0;   // if !coalescing we've got a problem.

    // If we are coalescing and it is possible then attempt coalesce, 
    if (!doneCoalesce
    &&  (UInt) mbuf_pkthdr_len(packet) <= maxSegs * maxSegmentSize) {
        // Hmm, we have to do some coalescing.
        bool analysisRet;
            
        analysisRet = analyseSegments(packet,
                                      MIN(curMBufIndex, kMBufDataCacheSize),
                                      segsPerMBuf,
                                      curSegIndex, maxSegs);
        if (analysisRet) {
            doneCoalesce = true;
            coalesceCount++;
            goto tryAgain;
        }
    }

    assert(!doneCoalesce);  // Problem in Coalesce code.
    packetTooBigErrors++;
    return 0;
}
static inline void coalesceSegments(mbuf_t srcm, mbuf_t dstm)
{
    uintptr_t src, dst;
    SInt32 srcLen, dstLen;
    mbuf_t temp;
    mbuf_t head = srcm;
	
    srcLen = (SInt32)mbuf_len( srcm );
    src = (uintptr_t) mbuf_data(srcm);

    dstLen = (SInt32)mbuf_len( dstm );
    dst = (uintptr_t) mbuf_data( dstm );
	
    for (;;) {
        if (srcLen < dstLen) {

            // Copy remainder of src mbuf to current dst.
            BCOPY(src, dst, srcLen);
            dst += srcLen;
            dstLen -= srcLen;

            // Move on to the next source mbuf.
            temp = mbuf_next( srcm ); assert(temp);
			if(srcm != head)
				mbuf_free(srcm);
            srcm = temp;

            srcLen = (SInt32)mbuf_len( srcm );
            src = (uintptr_t)mbuf_data(srcm);
        }
        else if (srcLen > dstLen) {

            // Copy some of src mbuf to remaining space in dst mbuf.
            BCOPY(src, dst, dstLen);
            src += dstLen;
            srcLen -= dstLen;
            
            // Move on to the next destination mbuf.
            temp = mbuf_next( dstm ); assert(temp);
            dstm = temp;

            dstLen = (SInt32)mbuf_len( dstm );
            dst = (uintptr_t)mbuf_data( dstm );
        }
        else {  /* (srcLen == dstLen) */

            // copy remainder of src into remaining space of current dst
            BCOPY(src, dst, srcLen);

            // Free current mbuf and move the current onto the next
            temp = mbuf_next( srcm );
			if(srcm != head)
				mbuf_free(srcm);
			srcm = temp;
			
            // Do we have any more dest buffers to copy to?
            if (! mbuf_next ( dstm ))
			{
				// nope- hook the remainder of source chain to end of dest chain
				mbuf_setnext(dstm, srcm);
                break;
			}
            dstm = mbuf_next ( dstm );

            assert(srcm);
            dstLen = (SInt32)mbuf_len ( dstm );
            dst = (uintptr_t)mbuf_data( dstm );
            srcLen = (SInt32)mbuf_len( srcm );
            src = (uintptr_t)mbuf_data( srcm );
        }
    }
}