int update_block_list(char *addr, int err_level) { size_t addr_len = strlen(addr); if (cache_key_exist(block_list, addr, addr_len)) { int *count = NULL; cache_lookup(block_list, addr, addr_len, &count); if (count != NULL) { if (*count > MAX_TRIES) return 1; (*count) += err_level; } } else if (err_level > 0) { int *count = (int *)ss_malloc(sizeof(int)); *count = 1; cache_insert(block_list, addr, addr_len, count); #ifdef __linux__ if (mode != NO_FIREWALL_MODE) set_firewall_rule(addr, 1); #endif } return 0; }
int remove_from_block_list(char *addr) { size_t addr_len = strlen(addr); #ifdef __linux__ if (cache_key_exist(block_list, addr, addr_len)) set_firewall_rule(addr, 0); #endif return cache_remove(block_list, addr, addr_len); }
int check_block_list(char *addr) { size_t addr_len = strlen(addr); if (cache_key_exist(block_list, addr, addr_len)) { int *count = NULL; cache_lookup(block_list, addr, addr_len, &count); if (count != NULL && *count > MAX_TRIES) return 1; } return 0; }
int check_block_list(char *addr, int err_level) { size_t addr_len = strlen(addr); if (cache_key_exist(block_list, addr, addr_len)) { int *count = NULL; cache_lookup(block_list, addr, addr_len, &count); if (count != NULL) { if (*count > MAX_TRIES) return 1; (*count) += err_level; } } else { int *count = (int *)ss_malloc(sizeof(int)); *count = 1; cache_insert(block_list, addr, addr_len, count); } return 0; }
int ss_decrypt(buffer_t *cipher, enc_ctx_t *ctx, size_t capacity) { if (ctx != NULL) { static buffer_t tmp = { 0, 0, 0, NULL }; size_t iv_len = 0; int err = 1; brealloc(&tmp, cipher->len, capacity); buffer_t *plain = &tmp; plain->len = cipher->len; if (!ctx->init) { uint8_t iv[MAX_IV_LENGTH]; iv_len = enc_iv_len; plain->len -= iv_len; memcpy(iv, cipher->array, iv_len); cipher_context_set_iv(&ctx->evp, iv, iv_len, 0); ctx->counter = 0; ctx->init = 1; if (enc_method >= RC4_MD5) { if (cache_key_exist(iv_cache, (char *)iv, iv_len)) { bfree(cipher); return -1; } else { cache_insert(iv_cache, (char *)iv, iv_len, NULL); } } } if (enc_method >= SALSA20) { int padding = ctx->counter % SODIUM_BLOCK_SIZE; brealloc(plain, (plain->len + padding) * 2, capacity); if (padding) { brealloc(cipher, cipher->len + padding, capacity); memmove(cipher->array + iv_len + padding, cipher->array + iv_len, cipher->len - iv_len); memset(cipher->array + iv_len, 0, padding); } crypto_stream_xor_ic((uint8_t *)plain->array, (const uint8_t *)(cipher->array + iv_len), (uint64_t)(cipher->len - iv_len + padding), (const uint8_t *)ctx->evp.iv, ctx->counter / SODIUM_BLOCK_SIZE, enc_key, enc_method); ctx->counter += cipher->len - iv_len; if (padding) { memmove(plain->array, plain->array + padding, plain->len); } } else { err = cipher_context_update(&ctx->evp, (uint8_t *)plain->array, &plain->len, (const uint8_t *)(cipher->array + iv_len), cipher->len - iv_len); } if (!err) { bfree(cipher); return -1; } #ifdef DEBUG dump("PLAIN", plain->array, plain->len); dump("CIPHER", cipher->array + iv_len, cipher->len - iv_len); #endif brealloc(cipher, plain->len, capacity); memcpy(cipher->array, plain->array, plain->len); cipher->len = plain->len; return 0; } else { char *begin = cipher->array; char *ptr = cipher->array; while (ptr < begin + cipher->len) { *ptr = (char)dec_table[(uint8_t)*ptr]; ptr++; } return 0; } }
char * ss_decrypt(int buf_size, char *ciphertext, ssize_t *len, struct enc_ctx *ctx) { if (ctx != NULL) { static int tmp_len = 0; static char *tmp_buf = NULL; size_t c_len = *len, p_len = *len; size_t iv_len = 0; int err = 1; int buf_len = max(p_len, buf_size); if (tmp_len < buf_len) { tmp_len = buf_len; tmp_buf = realloc(tmp_buf, buf_len); } char *plaintext = tmp_buf; if (!ctx->init) { uint8_t iv[MAX_IV_LENGTH]; iv_len = enc_iv_len; p_len -= iv_len; memcpy(iv, ciphertext, iv_len); cipher_context_set_iv(&ctx->evp, iv, iv_len, 0); ctx->counter = 0; ctx->init = 1; if (enc_method >= RC4_MD5) { if (cache_key_exist(iv_cache, (char *)iv, iv_len)) { free(ciphertext); return NULL; } else { cache_insert(iv_cache, (char *)iv, iv_len, NULL); } } } if (enc_method >= SALSA20) { int padding = ctx->counter % SODIUM_BLOCK_SIZE; if (buf_len < (p_len + padding) * 2) { buf_len = max((p_len + padding) * 2, buf_size); plaintext = realloc(plaintext, buf_len); tmp_len = buf_len; tmp_buf = plaintext; } if (padding) { ciphertext = realloc(ciphertext, max(c_len + padding, buf_size)); memmove(ciphertext + iv_len + padding, ciphertext + iv_len, c_len - iv_len); memset(ciphertext + iv_len, 0, padding); } crypto_stream_xor_ic((uint8_t *)plaintext, (const uint8_t *)(ciphertext + iv_len), (uint64_t)(c_len - iv_len + padding), (const uint8_t *)ctx->evp.iv, ctx->counter / SODIUM_BLOCK_SIZE, enc_key, enc_method); ctx->counter += c_len - iv_len; if (padding) { memmove(plaintext, plaintext + padding, p_len); } } else { err = cipher_context_update(&ctx->evp, (uint8_t *)plaintext, &p_len, (const uint8_t *)(ciphertext + iv_len), c_len - iv_len); } if (!err) { free(ciphertext); return NULL; } #ifdef DEBUG dump("PLAIN", plaintext, p_len); dump("CIPHER", ciphertext + iv_len, c_len - iv_len); #endif if (buf_size < p_len) { ciphertext = realloc(ciphertext, p_len); } *len = p_len; memcpy(ciphertext, plaintext, *len); return ciphertext; } else { char *begin = ciphertext; while (ciphertext < begin + *len) { *ciphertext = (char)dec_table[(uint8_t)*ciphertext]; ciphertext++; } return begin; } }