static int file_generation(char * filename, uint8_t * content, size_t content_len, unsigned char * hash) { unsigned char sha1[128] = {0}; int len = 20; SHA1((const unsigned char *) content, (unsigned long) content_len, (unsigned char *) sha1); cf_b64_encode(sha1, len, (char*)hash); hash[cf_b64_encoded_len(len)] = 0; return 0; }
/** * Generate a Base64 String Representation of the binary string. * Base64 encoding converts three octets into four 6-bit encoded characters. * So, the string 8-bit bytes are broken down into 6 bit values, each of which * is then converted into a base64 value. * So, for example, the string "Man" :: M[77: 0x4d)] a[97(0x61)] n[110(0x6e)] * Bits: (4)0100 (d)1101 (6)0110 (1)0001 (6)0110 (e)1110 * Base 64 bits: 010011 010110 000101 101110 * Base 64 Rep: 010011(19) 010110(22) 000101(5) 101110(46) * Base 64 Chars: T(19) W(22) F(5) u(46) * and so this string is converted into the Base 64 string: "TWFu" */ int generate_base64_string(void *mem_ptr, uint len, char output_buf[]) { uint32_t encoded_len = cf_b64_encoded_len(len); // TODO - check that output_buf is big enough, and/or truncate. cf_b64_encode((const uint8_t*)mem_ptr, len, output_buf); output_buf[encoded_len] = 0; // null-terminate return (int)(encoded_len + 1); // bytes we used, including null-terminator } // end generate_base64_hex_string()
static int file_read(char * filename, uint8_t ** content, size_t * content_len, unsigned char * hash) { char filepath[256] = {0}; FILE * file = NULL; char line[1024] = {0}; size_t line_len = sizeof(line); file_resolve(filepath, filename, NULL); cf_dyn_buf_define(buf); file = fopen(filepath, "r"); if ( file ) { while( fgets(line, line_len, file) != NULL ) { cf_dyn_buf_append_string(&buf, line); } fclose(file); file = NULL; if ( buf.used_sz > 0 ) { char *src = cf_dyn_buf_strdup(&buf); file_generation(filepath, (uint8_t *)src, buf.used_sz, hash); uint32_t src_len = (uint32_t)buf.used_sz; uint32_t out_size = cf_b64_encoded_len(src_len); *content = (uint8_t *)cf_malloc(out_size); *content_len = out_size; cf_b64_encode((const uint8_t*)src, src_len, (char*)(*content)); cf_free(src); src = NULL; return 0; } *content = NULL; *content_len = 0; return 2; } *content = NULL; *content_len = 0; return 1; }
/** * @return AEROSPIKE_OK if successful. Otherwise an error occurred. */ as_status aerospike_udf_put( aerospike * as, as_error * err, const as_policy_info * policy, const char * filename, as_udf_type type, as_bytes * content) { if (type != AS_UDF_TYPE_LUA) { return as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid udf type: %d", type); } as_error_reset(err); if (! policy) { policy = &as->config.policies.info; } char* command = NULL; as_string filename_string; const char* filebase = as_basename(&filename_string, filename); uint32_t encoded_len = cf_b64_encoded_len(content->size); char* content_base64 = malloc(encoded_len + 1); cf_b64_encode(content->value, content->size, content_base64); content_base64[encoded_len] = 0; if (! asprintf(&command, "udf-put:filename=%s;content=%s;content-len=%d;udf-type=%s;", filebase, content_base64, encoded_len, as_udf_type_str[type])) { as_string_destroy(&filename_string); free(content_base64); return as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Udf put asprintf failed"); } as_string_destroy(&filename_string); char* response = 0; as_status status = aerospike_info_any(as, err, policy, command, &response); free(command); free(content_base64); if (status) { return status; } free(response); return AEROSPIKE_OK; }
int udf_cask_info_put(char *name, char * params, cf_dyn_buf * out) { cf_debug(AS_INFO, "UDF CASK INFO PUT"); int rc = 0; char filename[128] = {0}; int filename_len = sizeof(filename); // Content_len from the client and its expected size char content_len[32] = {0}; int clen = sizeof(content_len); // Udf content from the client and its expected length char *udf_content = NULL; int udf_content_len = 0; // Udf type from the client and its expected size char type[8] = {0}; int type_len = sizeof(type); // get (required) script filename char *tmp_char; if ( as_info_parameter_get(params, "filename", filename, &filename_len) || !(tmp_char = strchr(filename, '.')) // No extension in filename || tmp_char == filename // '.' at the begining of filename || strlen (tmp_char) <= 1) { // '.' in filename, but no extnsion e.g. "abc." cf_info(AS_INFO, "invalid or missing filename"); cf_dyn_buf_append_string(out, "error=invalid_filename"); return 0; } if ( as_info_parameter_get(params, "content-len", content_len, &(clen)) ) { cf_info(AS_INFO, "invalid or missing content-len"); cf_dyn_buf_append_string(out, "error=invalid_content_len"); return 0; } if ( as_info_parameter_get(params, "udf-type", type, &type_len) ) { // Replace with DEFAULT IS LUA strcpy(type, as_udf_type_name[0]); } // check type field if (-1 == udf_type_getid(type)) { cf_info(AS_INFO, "invalid or missing udf-type : %s not valid", type); cf_dyn_buf_append_string(out, "error=invalid_udf_type"); return 0; } // get b64 encoded script udf_content_len = atoi(content_len) + 1; udf_content = (char *) cf_malloc(udf_content_len); if ( udf_content == NULL ) { cf_info(AS_UDF, "internal allocation error"); cf_dyn_buf_append_string(out, "error=internal_error"); // As memory is not allocated. // It should not continue. return 0; } // cf_info(AS_UDF, "content_len = %s", content_len); // cf_info(AS_UDF, "udf_content_len = %d", udf_content_len); // get (required) script content - base64 encoded here. if ( as_info_parameter_get(params, "content", udf_content, &(udf_content_len)) ) { cf_info(AS_UDF, "invalid content"); cf_dyn_buf_append_string(out, "error=invalid_content"); cf_free(udf_content); return 0; } // base 64 decode it uint32_t encoded_len = strlen(udf_content); uint32_t decoded_len = cf_b64_decoded_buf_size(encoded_len) + 1; // Don't allow UDF file size > 1MB if ( decoded_len > MAX_UDF_CONTENT_LENGTH) { cf_info(AS_INFO, "lua file size:%d > 1MB", decoded_len); cf_dyn_buf_append_string(out, "error=invalid_udf_content_len, lua file size > 1MB"); return 0; } char * decoded_str = cf_malloc(decoded_len); if ( ! cf_b64_validate_and_decode(udf_content, encoded_len, (uint8_t*)decoded_str, &decoded_len) ) { cf_info(AS_UDF, "invalid base64 content %s", filename); cf_dyn_buf_append_string(out, "error=invalid_base64_content"); cf_free(decoded_str); return 0; } decoded_str[decoded_len] = '\0'; as_module_error err; rc = as_module_validate(&mod_lua, NULL, filename, decoded_str, decoded_len, &err); cf_free(decoded_str); decoded_str = NULL; decoded_len = 0; if ( rc ) { cf_warning(AS_UDF, "udf-put: compile error: [%s:%d] %s", err.file, err.line, err.message); cf_dyn_buf_append_string(out, "error=compile_error"); cf_dyn_buf_append_string(out, ";file="); cf_dyn_buf_append_string(out, err.file); cf_dyn_buf_append_string(out, ";line="); cf_dyn_buf_append_uint32(out, err.line); uint32_t message_len = strlen(err.message); uint32_t enc_message_len = cf_b64_encoded_len(message_len); char enc_message[enc_message_len]; cf_b64_encode((const uint8_t*)err.message, message_len, enc_message); cf_dyn_buf_append_string(out, ";message="); cf_dyn_buf_append_buf(out, (uint8_t *)enc_message, enc_message_len); cf_free(udf_content); return 0; } // Create an empty JSON object json_t *udf_obj = 0; if (!(udf_obj = json_object())) { cf_warning(AS_UDF, "failed to create JSON array for receiving UDF"); if (udf_content) cf_free(udf_content); return -1; } int e = 0; e += json_object_set_new(udf_obj, "content64", json_string(udf_content)); e += json_object_set_new(udf_obj, "type", json_string(type)); e += json_object_set_new(udf_obj, "name", json_string(filename)); if (e) { cf_warning(AS_UDF, "could not encode UDF object, error %d", e); json_decref(udf_obj); if (udf_content) cf_free(udf_content); return(-1); } // make it into a string, yet another buffer copy char *udf_obj_str = json_dumps(udf_obj, 0/*flags*/); json_decref(udf_obj); udf_obj = 0; cf_debug(AS_UDF, "created json object %s", udf_obj_str); // how do I know whether to call create or add? e = as_smd_set_metadata(udf_smd_module_name, filename, udf_obj_str); if (e) { cf_warning(AS_UDF, "could not add UDF metadata, error %d", e); cf_free(udf_obj_str); if (udf_content) cf_free(udf_content); return(-1); } cf_info(AS_UDF, "UDF module '%s' (%s/%s) registered", filename, g_config.mod_lua.user_path, filename); // free the metadata cf_free(udf_obj_str); udf_obj_str = 0; if (udf_content) cf_free(udf_content); return 0; }