示例#1
0
int ss_check_hash(buffer_t *buf, chunk_t *chunk, enc_ctx_t *ctx)
{
    int i, j, k;
    ssize_t blen  = buf->len;
    uint32_t cidx = chunk->idx;

    brealloc(chunk->buf, chunk->len + blen, buf->capacity);
    brealloc(buf, chunk->len + blen, buf->capacity);

    for (i = 0, j = 0, k = 0; i < blen; i++) {
        chunk->buf->array[cidx++] = buf->array[k++];

        if (cidx == CLEN_BYTES) {
            uint16_t clen = ntohs(*((uint16_t *)chunk->buf->array));
            brealloc(chunk->buf, clen + AUTH_BYTES, buf->capacity);
            chunk->len = clen;
        }

        if (cidx == chunk->len + AUTH_BYTES) {
            // Compare hash
            uint8_t hash[ONETIMEAUTH_BYTES * 2];
            uint8_t key[MAX_IV_LENGTH + sizeof(uint32_t)];

            uint32_t c = htonl(chunk->counter);
            memcpy(key, ctx->evp.iv, enc_iv_len);
            memcpy(key + enc_iv_len, &c, sizeof(uint32_t));
#if defined(USE_CRYPTO_OPENSSL)
            HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t),
                 (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash, NULL);
#elif defined(USE_CRYPTO_MBEDTLS)
            mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t),
                            (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash);
#else
            sha1_hmac(key, enc_iv_len + sizeof(uint32_t),
                      (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash);
#endif

            if (safe_memcmp(hash, chunk->buf->array + CLEN_BYTES, ONETIMEAUTH_BYTES) != 0) {
                return 0;
            }

            // Copy chunk back to buffer
            memmove(buf->array + j + chunk->len, buf->array + k, blen - i - 1);
            memcpy(buf->array + j, chunk->buf->array + AUTH_BYTES, chunk->len);

            // Reset the base offset
            j   += chunk->len;
            k    = j;
            cidx = 0;
            chunk->counter++;
        }
    }

    buf->len   = j;
    chunk->idx = cidx;
    return 1;
}
示例#2
0
static int
obfs_tls_response(buffer_t *buf, size_t cap, obfs_t *obfs)
{
    if (obfs == NULL || obfs->obfs_stage < 0) return 0;

    static buffer_t tmp = { 0, 0, 0, NULL };

    if (obfs->obfs_stage == 0) {

        size_t buf_len = buf->len;
        size_t hello_len = sizeof(struct tls_server_hello);
        size_t change_cipher_spec_len = sizeof(struct tls_change_cipher_spec);
        size_t encrypted_handshake_len = sizeof(struct tls_encrypted_handshake);
        size_t tls_len = hello_len + change_cipher_spec_len + encrypted_handshake_len + buf_len;

        brealloc(&tmp, buf_len, cap);
        brealloc(buf,  tls_len, cap);

        memcpy(tmp.data, buf->data, buf_len);

        /* Server Hello */
        memcpy(buf->data, &tls_server_hello_template, hello_len);
        struct tls_server_hello *hello = (struct tls_server_hello *)buf->data;
        hello->random_unix_time = CT_HTONL((uint32_t)time(NULL));
        rand_bytes(hello->random_bytes, 28);
        if (obfs->buf != NULL) {
            memcpy(hello->session_id, obfs->buf->data, 32);
        } else {
            rand_bytes(hello->session_id, 32);
        }

        /* Change Cipher Spec */
        memcpy(buf->data + hello_len, &tls_change_cipher_spec_template, change_cipher_spec_len);

        /* Encrypted Handshake */
        memcpy(buf->data + hello_len + change_cipher_spec_len, &tls_encrypted_handshake_template,
                encrypted_handshake_len);
        memcpy(buf->data + hello_len + change_cipher_spec_len + encrypted_handshake_len,
                tmp.data, buf_len);

        struct tls_encrypted_handshake *encrypted_handshake =
            (struct tls_encrypted_handshake *)(buf->data + hello_len + change_cipher_spec_len);
        encrypted_handshake->len = CT_HTONS(buf_len);

        buf->len = tls_len;

        obfs->obfs_stage++;

    } else if (obfs->obfs_stage == 1) {

        obfs_app_data(buf, cap, obfs);

    }

    return buf->len;
}
示例#3
0
static bool grow_del_list(struct del_ctx *del)
{
   if (del->num_ids == MAX_DEL_LIST_LEN) {
      return false;
   }

   if (del->num_ids == del->max_ids) {
      del->max_ids = (del->max_ids * 3) / 2;
      del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) *
         del->max_ids);
      del->PurgedFiles = (char *)brealloc(del->PurgedFiles, del->max_ids);
   }
   return true;
}
示例#4
0
int
aead_decrypt_all(buffer_t *ciphertext, cipher_t *cipher, size_t capacity)
{
    size_t salt_len = cipher->key_len;
    size_t tag_len  = cipher->tag_len;
    int err         = CRYPTO_OK;

    if (ciphertext->len <= salt_len + tag_len) {
        return CRYPTO_ERROR;
    }

    cipher_ctx_t cipher_ctx;
    aead_ctx_init(cipher, &cipher_ctx, 0);

    static buffer_t tmp = { 0, 0, 0, NULL };
    brealloc(&tmp, ciphertext->len, capacity);
    buffer_t *plaintext = &tmp;
    plaintext->len = ciphertext->len - salt_len - tag_len;

    /* get salt */
    uint8_t *salt = cipher_ctx.salt;
    memcpy(salt, ciphertext->data, salt_len);

    if (ppbloom_check((void *)salt, salt_len) == 1) {
        LOGE("crypto: AEAD: repeat salt detected");
        return CRYPTO_ERROR;
    }

    aead_cipher_ctx_set_key(&cipher_ctx, 0);

    size_t plen = plaintext->len;
    err = aead_cipher_decrypt(&cipher_ctx,
                              (uint8_t *)plaintext->data, &plen,
                              (uint8_t *)ciphertext->data + salt_len,
                              ciphertext->len - salt_len, NULL, 0,
                              cipher_ctx.nonce, cipher_ctx.skey);

    aead_ctx_release(&cipher_ctx);

    if (err)
        return CRYPTO_ERROR;

    ppbloom_add((void *)salt, salt_len);

    brealloc(ciphertext, plaintext->len, capacity);
    memcpy(ciphertext->data, plaintext->data, plaintext->len);
    ciphertext->len = plaintext->len;

    return CRYPTO_OK;
}
示例#5
0
/* TCP */
int
aead_encrypt(buffer_t *plaintext, cipher_ctx_t *cipher_ctx, size_t capacity)
{
    if (cipher_ctx == NULL)
        return CRYPTO_ERROR;

    if (plaintext->len == 0) {
        return CRYPTO_OK;
    }

    static buffer_t tmp = { 0, 0, 0, NULL };
    buffer_t *ciphertext;

    cipher_t *cipher = cipher_ctx->cipher;
    int err          = CRYPTO_ERROR;
    size_t salt_ofst = 0;
    size_t salt_len  = cipher->key_len;
    size_t tag_len   = cipher->tag_len;

    if (!cipher_ctx->init) {
        salt_ofst = salt_len;
    }

    size_t out_len = salt_ofst + 2 * tag_len + plaintext->len + CHUNK_SIZE_LEN;
    brealloc(&tmp, out_len, capacity);
    ciphertext      = &tmp;
    ciphertext->len = out_len;

    if (!cipher_ctx->init) {
        memcpy(ciphertext->data, cipher_ctx->salt, salt_len);
        aead_cipher_ctx_set_key(cipher_ctx, 1);
        cipher_ctx->init = 1;

        ppbloom_add((void *)cipher_ctx->salt, salt_len);
    }

    err = aead_chunk_encrypt(cipher_ctx,
                             (uint8_t *)plaintext->data,
                             (uint8_t *)ciphertext->data + salt_ofst,
                             cipher_ctx->nonce, plaintext->len);
    if (err)
        return err;

    brealloc(plaintext, ciphertext->len, capacity);
    memcpy(plaintext->data, ciphertext->data, ciphertext->len);
    plaintext->len = ciphertext->len;

    return 0;
}
示例#6
0
static inline bool cd_ensure_capacity(calldata_t *data, uint8_t **pos,
		size_t new_size)
{
	size_t offset;
	size_t new_capacity;

	if (new_size < data->capacity)
		return true;
	if (data->fixed) {
		blog(LOG_ERROR, "Tried to go above fixed calldata stack size!");
		return false;
	}

	offset = *pos - data->stack;

	new_capacity = data->capacity * 2;
	if (new_capacity < new_size)
		new_capacity = new_size;

	data->stack    = brealloc(data->stack, new_capacity);
	data->capacity = new_capacity;

	*pos = data->stack + offset;
	return true;
}
示例#7
0
int
ss_onetimeauth(buffer_t *buf, uint8_t *iv, size_t capacity)
{
    uint8_t hash[ONETIMEAUTH_BYTES * 2];
    uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH];
    memcpy(auth_key, iv, enc_iv_len);
    memcpy(auth_key + enc_iv_len, enc_key, enc_key_len);

    brealloc(buf, ONETIMEAUTH_BYTES + buf->len, capacity);

#if defined(USE_CRYPTO_OPENSSL)
    HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, (uint8_t *)hash, NULL);
#elif defined(USE_CRYPTO_MBEDTLS)
    mbedtls_md_hmac(mbedtls_md_info_from_type(
                        MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len,
                    (uint8_t *)hash);
#else
    sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, (uint8_t *)hash);
#endif

    memcpy(buf->array + buf->len, hash, ONETIMEAUTH_BYTES);
    buf->len += ONETIMEAUTH_BYTES;

    return 0;
}
示例#8
0
/* external function definitions */
void 
buffroom(struct buff * p, int add)
{
  int def;			/* space deficiency */

  if ((p != (struct buff *) (0))
      && ((def = add - (p->max - p->put)) > 0)) {
    int len = p->put - p->get;
    int off = p->get - p->min;

    if (def > off) {
      /* deficiency is more than the offset */
      int siz = p->max - p->min;
      int req = siz + def;

      siz += siz / 2;
      if (siz < req)
	siz = req;
      if (siz < sizeof(*p))
	siz = sizeof(*p);
      p->min = (char *) brealloc(p->min, siz);
      p->get = p->min + off;
      p->put = p->get + len;
      p->max = p->min + siz;
    } else {
      bcopy(p->get, p->min, len);
      p->get -= off;
      p->put -= off;
    }
  }
  return;
}
示例#9
0
char *read_line(HANDLE hin)
{
  char *buf;
  int bufsize = 32, strind = 0;
  DWORD bytes_read;

  buf = bmalloc(bufsize);

  while (1) {
    if (!ReadFile(hin, &buf[strind], 1, &bytes_read, NULL)) {
      printf("Read error\n");
      break;
    }
    if (bytes_read == 0) {
      buf[strind] = '\0';
      break;
    } else if (buf[strind] == '\r')
      continue;
    else if (buf[strind] == '\n') {
      buf[strind++] = '\0';
      break;
    } else {
      strind++;
      if (strind >= bufsize) {
        bufsize *= 2;
        buf = brealloc(buf, bufsize);
      }
    }
  }
  if (strind == 0) {
    bfree(buf);
    return NULL;
  } else
    return buf;
}
示例#10
0
static int inputGetc(ej_t* ep)
{
    ejinput_t	*ip;
    int			c, len;

    a_assert(ep);
    ip = ep->input;

    if ((len = ringqLen(&ip->script)) == 0) {
        return -1;
    }

    c = ringqGetc(&ip->script);

    if (c == '\n') {
        ip->lineNumber++;
        ip->lineColumn = 0;
    } else {
        if ((ip->lineColumn + 2) >= ip->lineLength) {
            ip->lineLength += EJ_INC;
            ip->line = brealloc(B_L, ip->line, ip->lineLength * sizeof(char_t));
        }
        ip->line[ip->lineColumn++] = c;
        ip->line[ip->lineColumn] = '\0';
    }
    return c;
}
示例#11
0
int ss_gen_hash(buffer_t *buf, uint32_t *counter, enc_ctx_t *ctx, size_t capacity)
{
    ssize_t blen       = buf->len;
    uint16_t chunk_len = htons((uint16_t)blen);
    uint8_t hash[ONETIMEAUTH_BYTES * 2];
    uint8_t key[MAX_IV_LENGTH + sizeof(uint32_t)];
    uint32_t c = htonl(*counter);

    brealloc(buf, AUTH_BYTES + blen, capacity);
    memcpy(key, ctx->evp.iv, enc_iv_len);
    memcpy(key + enc_iv_len, &c, sizeof(uint32_t));
#if defined(USE_CRYPTO_OPENSSL)
    HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash, NULL);
#elif defined(USE_CRYPTO_MBEDTLS)
    mbedtls_md_hmac(mbedtls_md_info_from_type(
                        MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash);
#else
    sha1_hmac(key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash);
#endif

    memmove(buf->array + AUTH_BYTES, buf->array, blen);
    memcpy(buf->array + CLEN_BYTES, hash, ONETIMEAUTH_BYTES);
    memcpy(buf->array, &chunk_len, CLEN_BYTES);

    *counter = *counter + 1;
    buf->len = blen + AUTH_BYTES;

    return 0;
}
示例#12
0
int
stream_encrypt_all(buffer_t *plaintext, cipher_t *cipher, size_t capacity)
{
    cipher_ctx_t cipher_ctx;
    stream_ctx_init(cipher, &cipher_ctx, 1);

    size_t nonce_len = cipher->nonce_len;
    int err          = CRYPTO_OK;

    static buffer_t tmp = { 0, 0, 0, NULL };
    brealloc(&tmp, nonce_len + plaintext->len, capacity);
    buffer_t *ciphertext = &tmp;
    ciphertext->len = plaintext->len;

    uint8_t *nonce = cipher_ctx.nonce;
    cipher_ctx_set_nonce(&cipher_ctx, nonce, nonce_len, 1);
    memcpy(ciphertext->data, nonce, nonce_len);

    if (cipher->method >= SALSA20) {
        crypto_stream_xor_ic((uint8_t *)(ciphertext->data + nonce_len),
                             (const uint8_t *)plaintext->data, (uint64_t)(plaintext->len),
                             (const uint8_t *)nonce,
                             0, cipher->key, cipher->method);
    } else {
        err = cipher_ctx_update(&cipher_ctx, (uint8_t *)(ciphertext->data + nonce_len),
                                &ciphertext->len, (const uint8_t *)plaintext->data,
                                plaintext->len);
    }

    stream_ctx_release(&cipher_ctx);

    if (err)
        return CRYPTO_ERROR;

#ifdef SS_DEBUG
    dump("PLAIN", plaintext->data, plaintext->len);
    dump("CIPHER", ciphertext->data + nonce_len, ciphertext->len);
    dump("NONCE", ciphertext->data, nonce_len);
#endif

    brealloc(plaintext, nonce_len + ciphertext->len, capacity);
    memcpy(plaintext->data, ciphertext->data, nonce_len + ciphertext->len);
    plaintext->len = nonce_len + ciphertext->len;

    return CRYPTO_OK;
}
示例#13
0
/* internal function definitions */
static void 
acpt(struct lstn * p)
{
  static char fnc[] = "acpt";
  int r_namelen = p->r_namelen;
  struct sockaddr *r_name;
  int fd;
  int l_namelen = p->l_namelen;
  struct sockaddr *l_name;

  r_name = (struct sockaddr *) balloc(r_namelen);
  if ((fd = accept(p->fd, r_name, &r_namelen)) < 0) {
    if ((errno == EWOULDBLOCK)
	|| (errno == EINTR)) {
      /* nothing to report */
    } else if ((errno == EMFILE)
	       || (errno == ENFILE)
	       || (errno == ENXIO)
	       || (errno == EIO)) {

      Warn("%t %s(%s): warn: accept(%d): %m\n",
	   fnc, p->name, p->fd);
    } else {
      Warn("%t %s(%s): error: accept(%d): %m\n",
	   fnc, p->name, p->fd);
      lstnclose(p);
    }
    bfree((char *) r_name);
    return;
  }
  l_name = (struct sockaddr *) balloc(l_namelen);
  if (getsockname(fd, l_name, &l_namelen) < 0) {
    Warn("%t %s(%s): error: getsockname(%d): %m\n",
	 fnc, p->name, fd);
    doclose(fd);
    bfree((char *) l_name);
    bfree((char *) r_name);
    return;
  }
  p->acpttod = todsec();
  (p->acptcount)++;
  r_name = (struct sockaddr *) brealloc((char *) r_name, r_namelen);
  l_name = (struct sockaddr *) brealloc((char *) l_name, l_namelen);
  (*(p->acptfunc)) (p, fd, r_name, r_namelen, l_name, l_namelen);
  return;
}
示例#14
0
/*
 * Called here to make in memory list of JobIds to be
 *  deleted and the associated PurgedFiles flag.
 *  The in memory list will then be transversed
 *  to issue the SQL DELETE commands.  Note, the list
 *  is allowed to get to MAX_DEL_LIST_LEN to limit the
 *  maximum malloc'ed memory.
 */
int job_delete_handler(void *ctx, int num_fields, char **row)
{
   struct del_ctx *del = (struct del_ctx *)ctx;

   if (del->num_ids == MAX_DEL_LIST_LEN) {
      return 1;
   }
   if (del->num_ids == del->max_ids) {
      del->max_ids = (del->max_ids * 3) / 2;
      del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) * del->max_ids);
      del->PurgedFiles = (char *)brealloc(del->PurgedFiles, del->max_ids);
   }
   del->JobId[del->num_ids] = (JobId_t)str_to_int64(row[0]);
// Dmsg2(60, "row=%d val=%d\n", del->num_ids, del->JobId[del->num_ids]);
   del->PurgedFiles[del->num_ids++] = (char)str_to_int64(row[1]);
   return 0;
}
示例#15
0
int
bprepend(buffer_t *dst, buffer_t *src, size_t capacity)
{
    brealloc(dst, dst->len + src->len, capacity);
    memmove(dst->data + src->len, dst->data, dst->len);
    memcpy(dst->data, src->data, src->len);
    dst->len = dst->len + src->len;
    return dst->len;
}
示例#16
0
void bstr_expandby(bstr *str, unsigned extralength)
{
  if (str->bufsiz >= str->length + 1 + extralength)
    return;

  while (str->bufsiz < str->length + 1 + extralength)
    str->bufsiz *= 2;
  str->text = brealloc(str->text, str->bufsiz);
}
示例#17
0
static __inline void
array_grow(struct array *array, size_t newsize)
{
	size_t i;

	array->data = brealloc(array->data, newsize * sizeof(*array->data));
	for (i = array->size; i < newsize; i++)
		array->data[i].array = NULL;
	array->size = newsize;
}
示例#18
0
文件: blametest.c 项目: noamsml/kanka
int main()
{
	binit();
	char* a = bmalloc(20);
	printf("%d\n", (int)a);
	a = brealloc(a, 40);
	printf("%d\n", (int)a);
	bfree(a);
	blame();
	return 0;
}
示例#19
0
int
aead_encrypt_all(buffer_t *plaintext, cipher_t *cipher, size_t capacity)
{
    cipher_ctx_t cipher_ctx;
    aead_ctx_init(cipher, &cipher_ctx, 1);

    size_t salt_len = cipher->key_len;
    size_t tag_len  = cipher->tag_len;
    int err         = CRYPTO_OK;

    static buffer_t tmp = { 0, 0, 0, NULL };
    brealloc(&tmp, salt_len + tag_len + plaintext->len, capacity);
    buffer_t *ciphertext = &tmp;
    ciphertext->len = tag_len + plaintext->len;

    /* copy salt to first pos */
    memcpy(ciphertext->data, cipher_ctx.salt, salt_len);

    ppbloom_add((void *)cipher_ctx.salt, salt_len);

    aead_cipher_ctx_set_key(&cipher_ctx, 1);

    size_t clen = ciphertext->len;
    err = aead_cipher_encrypt(&cipher_ctx,
                              (uint8_t *)ciphertext->data + salt_len, &clen,
                              (uint8_t *)plaintext->data, plaintext->len,
                              NULL, 0, cipher_ctx.nonce, cipher_ctx.skey);

    aead_ctx_release(&cipher_ctx);

    if (err)
        return CRYPTO_ERROR;

    assert(ciphertext->len == clen);

    brealloc(plaintext, salt_len + ciphertext->len, capacity);
    memcpy(plaintext->data, ciphertext->data, salt_len + ciphertext->len);
    plaintext->len = salt_len + ciphertext->len;

    return CRYPTO_OK;
}
示例#20
0
static inline void copy_data(struct ffmpeg_decode *decode, uint8_t *data,
		size_t size)
{
	size_t new_size = size + FF_INPUT_BUFFER_PADDING_SIZE;

	if (decode->packet_size < new_size) {
		decode->packet_buffer = brealloc(decode->packet_buffer,
				new_size);
	}

	memset(decode->packet_buffer + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
	memcpy(decode->packet_buffer, data, size);
}
示例#21
0
static void
stack_grow(struct stack *stack)
{
	int new_size, i;

	if (++stack->sp == stack->size) {
		new_size = stack->size * 2 + 1;
		stack->stack = brealloc(stack->stack,
		    new_size * sizeof(*stack->stack));
		for (i = stack->size; i < new_size; i++)
			stack->stack[i].array = NULL;
		stack->size = new_size;
	}
}
示例#22
0
/*
 * Add a new string to the output struct, resizing the string array as
 * necessary.  Calls bail if memory allocation fails.
 */
void
output_add(struct output *output, const char *string)
{
    size_t next = output->count;
    size_t size;

    if (output->count == output->allocated) {
        size = output->allocated + 1;
        output->strings = brealloc(output->strings, size * sizeof(char *));
        output->allocated = size;
    }
    output->strings[next] = bstrdup(string);
    output->count++;
}
示例#23
0
static int
obfs_app_data(buffer_t *buf, size_t cap, obfs_t *obfs)
{
    size_t buf_len = buf->len;

    brealloc(buf, buf_len + 5, cap);
    memmove(buf->data + 5, buf->data, buf_len);
    memcpy(buf->data, tls_data_header, 3);

    *(uint16_t*)(buf->data + 3) = CT_HTONS(buf_len);
    buf->len = buf_len + 5;

    return 0;
}
示例#24
0
/*
 * Called here to make in memory list of JobIds to be
 *  deleted. The in memory list will then be transversed
 *  to issue the SQL DELETE commands.  Note, the list
 *  is allowed to get to MAX_DEL_LIST_LEN to limit the
 *  maximum malloc'ed memory.
 */
static int delete_handler(void *ctx, int num_fields, char **row)
{
   struct s_del_ctx *del = (struct s_del_ctx *)ctx;

   if (del->num_ids == MAX_DEL_LIST_LEN) {
      return 1;
   }
   if (del->num_ids == del->max_ids) {
      del->max_ids = (del->max_ids * 3) / 2;
      del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) *
         del->max_ids);
   }
   del->JobId[del->num_ids++] = (JobId_t)str_to_int64(row[0]);
   return 0;
}
示例#25
0
static inline void cd_ensure_capacity(calldata_t data, uint8_t **pos,
		size_t new_size)
{
	size_t offset;
	size_t new_capacity;

	if (new_size < data->capacity)
		return;

	offset = *pos - data->stack;

	new_capacity = data->capacity * 2;
	if (new_capacity < new_size)
		new_capacity = new_size;

	data->stack    = brealloc(data->stack, new_capacity);
	data->capacity = new_capacity;

	*pos = data->stack + offset;
}
示例#26
0
文件: handler.c 项目: sd-eblana/bawx
int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir, int arg,
		int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webdir, int arg, 
		char_t *url, char_t *path, char_t *query), int flags)
{
	websUrlHandlerType	*sp;
	int					len;

	a_assert(urlPrefix);
	a_assert(handler);

/*
 *	Grow the URL handler array to create a new slot
 */
	len = (websUrlHandlerMax + 1) * sizeof(websUrlHandlerType);
	if ((websUrlHandler = brealloc(B_L, websUrlHandler, len)) == NULL) {
		return -1;
	}
	sp = &websUrlHandler[websUrlHandlerMax++];
	memset(sp, 0, sizeof(websUrlHandlerType));

	sp->urlPrefix = bstrdup(B_L, urlPrefix);
	sp->len = gstrlen(sp->urlPrefix);
	if (webDir) {
		sp->webDir = bstrdup(B_L, webDir);
	} else {
		sp->webDir = bstrdup(B_L, T(""));
	}
	sp->handler = handler;
	sp->arg = arg;
	sp->flags = flags;

/*
 *	Sort in decreasing URL length order observing the flags for first and last
 */
	qsort(websUrlHandler, websUrlHandlerMax, sizeof(websUrlHandlerType), 
		websUrlHandlerSort);
	return 0;
}
示例#27
0
char *
read_string(struct source *src)
{
	int count, i, sz, new_sz, ch;
	char *p;
	bool escape;

	escape = false;
	count = 1;
	i = 0;
	sz = 15;
	p = bmalloc(sz + 1);

	while ((ch = (*src->vtable->readchar)(src)) != EOF) {
		if (!escape) {
			if (ch == '[')
				count++;
			else if (ch == ']')
				count--;
			if (count == 0)
				break;
		}
		if (ch == '\\' && !escape)
			escape = true;
		else {
			escape = false;
			if (i == sz) {
				new_sz = sz * 2;
				p = brealloc(p, new_sz + 1);
				sz = new_sz;
			}
			p[i++] = ch;
		}
	}
	p[i] = '\0';
	return p;
}
示例#28
0
static void
remote_send_cb(EV_P_ ev_io *w, int revents)
{
    remote_ctx_t *remote_send_ctx = (remote_ctx_t *)w;
    remote_t *remote              = remote_send_ctx->remote;
    server_t *server              = remote->server;

    if (!remote_send_ctx->connected) {
        struct sockaddr_storage addr;
        socklen_t len = sizeof addr;
        int r         = getpeername(remote->fd, (struct sockaddr *)&addr, &len);
        if (r == 0) {
            remote_send_ctx->connected = 1;
            ev_io_stop(EV_A_ & remote_send_ctx->io);
            ev_io_stop(EV_A_ & server->recv_ctx->io);
            ev_timer_stop(EV_A_ & remote_send_ctx->watcher);
            ev_timer_start(EV_A_ & remote->recv_ctx->watcher);

            // send destaddr
            buffer_t ss_addr_to_send;
            buffer_t *abuf = &ss_addr_to_send;
            balloc(abuf, BUF_SIZE);

            if (server->hostname_len > 0) { // HTTP/SNI
                uint16_t port;
                if (AF_INET6 == server->destaddr.ss_family) { // IPv6
                    port = (((struct sockaddr_in6 *)&(server->destaddr))->sin6_port);
                } else {                             // IPv4
                    port = (((struct sockaddr_in *)&(server->destaddr))->sin_port);
                }

                abuf->array[abuf->len++] = 3;          // Type 3 is hostname
                abuf->array[abuf->len++] = server->hostname_len;
                memcpy(abuf->array + abuf->len, server->hostname, server->hostname_len);
                abuf->len += server->hostname_len;
                memcpy(abuf->array + abuf->len, &port, 2);
            } else if (AF_INET6 == server->destaddr.ss_family) { // IPv6
                abuf->array[abuf->len++] = 4;          // Type 4 is IPv6 address

                size_t in6_addr_len = sizeof(struct in6_addr);
                memcpy(abuf->array + abuf->len,
                       &(((struct sockaddr_in6 *)&(server->destaddr))->sin6_addr),
                       in6_addr_len);
                abuf->len += in6_addr_len;
                memcpy(abuf->array + abuf->len,
                       &(((struct sockaddr_in6 *)&(server->destaddr))->sin6_port),
                       2);
            } else {                             // IPv4
                abuf->array[abuf->len++] = 1; // Type 1 is IPv4 address

                size_t in_addr_len = sizeof(struct in_addr);
                memcpy(abuf->array + abuf->len,
                       &((struct sockaddr_in *)&(server->destaddr))->sin_addr, in_addr_len);
                abuf->len += in_addr_len;
                memcpy(abuf->array + abuf->len,
                       &((struct sockaddr_in *)&(server->destaddr))->sin_port, 2);
            }

            abuf->len += 2;

            if (auth) {
                abuf->array[0] |= ONETIMEAUTH_FLAG;
                ss_onetimeauth(abuf, server->e_ctx->evp.iv, BUF_SIZE);
            }

            brealloc(remote->buf, remote->buf->len + abuf->len, BUF_SIZE);
            memmove(remote->buf->array + abuf->len, remote->buf->array, remote->buf->len);
            memcpy(remote->buf->array, abuf->array, abuf->len);
            remote->buf->len += abuf->len;
            bfree(abuf);

            int err = ss_encrypt(remote->buf, server->e_ctx, BUF_SIZE);
            if (err) {
                LOGE("invalid password or cipher");
                close_and_free_remote(EV_A_ remote);
                close_and_free_server(EV_A_ server);
                return;
            }

            ev_io_start(EV_A_ & remote->recv_ctx->io);
        } else {
            ERROR("getpeername");
            // not connected
            close_and_free_remote(EV_A_ remote);
            close_and_free_server(EV_A_ server);
            return;
        }
    }

    if (remote->buf->len == 0) {
        // close and free
        close_and_free_remote(EV_A_ remote);
        close_and_free_server(EV_A_ server);
        return;
    } else {
        // has data to send
        ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx,
                         remote->buf->len, 0);
        if (s == -1) {
            if (errno != EAGAIN && errno != EWOULDBLOCK) {
                ERROR("send");
                // close and free
                close_and_free_remote(EV_A_ remote);
                close_and_free_server(EV_A_ server);
            }
            return;
        } else if (s < remote->buf->len) {
            // partly sent, move memory, wait for the next time to send
            remote->buf->len -= s;
            remote->buf->idx += s;
            return;
        } else {
            // all sent out, wait for reading
            remote->buf->len = 0;
            remote->buf->idx = 0;
            ev_io_stop(EV_A_ & remote_send_ctx->io);
            ev_io_start(EV_A_ & server->recv_ctx->io);
        }
    }
}
示例#29
0
int
stream_decrypt(buffer_t *ciphertext, cipher_ctx_t *cipher_ctx, size_t capacity)
{
    if (cipher_ctx == NULL)
        return CRYPTO_ERROR;

    cipher_t *cipher = cipher_ctx->cipher;

    static buffer_t tmp = { 0, 0, 0, NULL };

    int err = CRYPTO_OK;

    brealloc(&tmp, ciphertext->len, capacity);
    buffer_t *plaintext = &tmp;
    plaintext->len = ciphertext->len;

    if (!cipher_ctx->init) {
        if (cipher_ctx->chunk == NULL) {
            cipher_ctx->chunk = (buffer_t *)ss_malloc(sizeof(buffer_t));
            memset(cipher_ctx->chunk, 0, sizeof(buffer_t));
            balloc(cipher_ctx->chunk, cipher->nonce_len);
        }

        size_t left_len = min(cipher->nonce_len - cipher_ctx->chunk->len,
                              ciphertext->len);

        if (left_len > 0) {
            memcpy(cipher_ctx->chunk->data + cipher_ctx->chunk->len, ciphertext->data, left_len);
            memmove(ciphertext->data, ciphertext->data + left_len,
                    ciphertext->len - left_len);
            cipher_ctx->chunk->len += left_len;
            ciphertext->len        -= left_len;
        }

        if (cipher_ctx->chunk->len < cipher->nonce_len)
            return CRYPTO_NEED_MORE;

        uint8_t *nonce   = cipher_ctx->nonce;
        size_t nonce_len = cipher->nonce_len;
        plaintext->len -= left_len;

        memcpy(nonce, cipher_ctx->chunk->data, nonce_len);
        cipher_ctx_set_nonce(cipher_ctx, nonce, nonce_len, 0);
        cipher_ctx->counter = 0;
        cipher_ctx->init    = 1;

        if (cipher->method >= RC4_MD5) {
            if (ppbloom_check((void *)nonce, nonce_len) == 1) {
                LOGE("crypto: stream: repeat IV detected");
                return CRYPTO_ERROR;
            }
        }
    }

    if (ciphertext->len <= 0)
        return CRYPTO_NEED_MORE;

    if (cipher->method >= SALSA20) {
        int padding = cipher_ctx->counter % SODIUM_BLOCK_SIZE;
        brealloc(plaintext, (plaintext->len + padding) * 2, capacity);

        if (padding) {
            brealloc(ciphertext, ciphertext->len + padding, capacity);
            memmove(ciphertext->data + padding, ciphertext->data,
                    ciphertext->len);
            sodium_memzero(ciphertext->data, padding);
        }
        crypto_stream_xor_ic((uint8_t *)plaintext->data,
                             (const uint8_t *)(ciphertext->data),
                             (uint64_t)(ciphertext->len + padding),
                             (const uint8_t *)cipher_ctx->nonce,
                             cipher_ctx->counter / SODIUM_BLOCK_SIZE, cipher->key,
                             cipher->method);
        cipher_ctx->counter += ciphertext->len;
        if (padding) {
            memmove(plaintext->data, plaintext->data + padding, plaintext->len);
        }
    } else {
        err = cipher_ctx_update(cipher_ctx, (uint8_t *)plaintext->data, &plaintext->len,
                                (const uint8_t *)(ciphertext->data),
                                ciphertext->len);
    }

    if (err)
        return CRYPTO_ERROR;

#ifdef SS_DEBUG
    dump("PLAIN", plaintext->data, plaintext->len);
    dump("CIPHER", ciphertext->data, ciphertext->len);
#endif

    brealloc(ciphertext, plaintext->len, capacity);
    memcpy(ciphertext->data, plaintext->data, plaintext->len);
    ciphertext->len = plaintext->len;

    // Add to bloom filter
    if (cipher_ctx->init == 1) {
        if (cipher->method >= RC4_MD5) {
            ppbloom_add((void *)cipher_ctx->nonce, cipher->nonce_len);
            cipher_ctx->init = 2;
        }
    }

    return CRYPTO_OK;
}
示例#30
0
int
stream_encrypt(buffer_t *plaintext, cipher_ctx_t *cipher_ctx, size_t capacity)
{
    if (cipher_ctx == NULL)
        return CRYPTO_ERROR;

    cipher_t *cipher = cipher_ctx->cipher;

    static buffer_t tmp = { 0, 0, 0, NULL };

    int err          = CRYPTO_OK;
    size_t nonce_len = 0;
    if (!cipher_ctx->init) {
        nonce_len = cipher_ctx->cipher->nonce_len;
    }

    brealloc(&tmp, nonce_len + plaintext->len, capacity);
    buffer_t *ciphertext = &tmp;
    ciphertext->len = plaintext->len;

    if (!cipher_ctx->init) {
        cipher_ctx_set_nonce(cipher_ctx, cipher_ctx->nonce, nonce_len, 1);
        memcpy(ciphertext->data, cipher_ctx->nonce, nonce_len);
        cipher_ctx->counter = 0;
        cipher_ctx->init    = 1;
    }

    if (cipher->method >= SALSA20) {
        int padding = cipher_ctx->counter % SODIUM_BLOCK_SIZE;
        brealloc(ciphertext, nonce_len + (padding + ciphertext->len) * 2, capacity);
        if (padding) {
            brealloc(plaintext, plaintext->len + padding, capacity);
            memmove(plaintext->data + padding, plaintext->data, plaintext->len);
            sodium_memzero(plaintext->data, padding);
        }
        crypto_stream_xor_ic((uint8_t *)(ciphertext->data + nonce_len),
                             (const uint8_t *)plaintext->data,
                             (uint64_t)(plaintext->len + padding),
                             (const uint8_t *)cipher_ctx->nonce,
                             cipher_ctx->counter / SODIUM_BLOCK_SIZE, cipher->key,
                             cipher->method);
        cipher_ctx->counter += plaintext->len;
        if (padding) {
            memmove(ciphertext->data + nonce_len,
                    ciphertext->data + nonce_len + padding, ciphertext->len);
        }
    } else {
        err = cipher_ctx_update(cipher_ctx,
                                (uint8_t *)(ciphertext->data + nonce_len),
                                &ciphertext->len, (const uint8_t *)plaintext->data,
                                plaintext->len);
        if (err) {
            return CRYPTO_ERROR;
        }
    }

#ifdef SS_DEBUG
    dump("PLAIN", plaintext->data, plaintext->len);
    dump("CIPHER", ciphertext->data + nonce_len, ciphertext->len);
#endif

    brealloc(plaintext, nonce_len + ciphertext->len, capacity);
    memcpy(plaintext->data, ciphertext->data, nonce_len + ciphertext->len);
    plaintext->len = nonce_len + ciphertext->len;

    return CRYPTO_OK;
}