EAPI Eina_Bool evas_cserve_mem_resize(Mem *m, int size) { if (m->size == size) return 1; if (m->write) { if (ftruncate(m->fd, size) < 0) return 0; munmap(m->data, m->size); eina_mmap_safety_enabled_set(EINA_TRUE); m->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, m->fd, 0); } else { munmap(m->data, m->size); eina_mmap_safety_enabled_set(EINA_TRUE); m->data = mmap(NULL, size, PROT_READ, MAP_SHARED, m->fd, 0); } if (m->data == MAP_FAILED) { m->data = NULL; return 0; } m->size = size; return 1; }
EAPI Mem * evas_cserve_mem_new(int size, const char *name) { Mem *m; static int id = 0; char buf[PATH_MAX]; m = calloc(1, sizeof(Mem)); if (!m) return NULL; if (name) snprintf(buf, sizeof(buf), "/evas-shm-%x.%s", getuid(), name); else { id++; snprintf(buf, sizeof(buf), "/evas-shm-%x.%x.%x", getuid(), getpid(), id); } m->id = id; m->offset = 0; m->name = strdup(buf); if (!m->name) { free(m); return NULL; } m->size = size; m->fd = shm_open(m->name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (m->fd < 0) { free(m->name); free(m); return NULL; } if (ftruncate(m->fd, m->size) < 0) { shm_unlink(m->name); close(m->fd); free(m->name); free(m); return NULL; } eina_mmap_safety_enabled_set(EINA_TRUE); m->data = mmap(NULL, m->size, PROT_READ | PROT_WRITE, MAP_SHARED, m->fd, 0); if (m->data == MAP_FAILED) { shm_unlink(m->name); close(m->fd); free(m->name); free(m); return NULL; } m->ref = 1; m->write = 1; return m; }
void _evas_xcb_xdefaults_init(void) { char buff[PATH_MAX]; snprintf(buff, sizeof(buff), "%s/.Xdefaults", getenv("HOME")); if ((_evas_xcb_xdefaults_file = eina_file_open(buff, EINA_FALSE))) { eina_mmap_safety_enabled_set(EINA_TRUE); _evas_xcb_xdefaults_data = eina_file_map_all(_evas_xcb_xdefaults_file, EINA_FILE_SEQUENTIAL); } }
EAPI Mem * evas_cserve_mem_open(int pid, int id, const char *name, int size, int do_write) { Mem *m; char buf[PATH_MAX]; m = calloc(1, sizeof(Mem)); if (!m) return NULL; if (name) snprintf(buf, sizeof(buf), "/evas-shm-%x.%s", getuid(), name); else snprintf(buf, sizeof(buf), "/evas-shm-%x.%x.%x", getuid(), pid, id); m->name = strdup(buf); if (!m->name) { free(m); return NULL; } m->size = size; if (do_write) m->fd = shm_open(m->name, O_RDWR, S_IRUSR | S_IWUSR); else m->fd = shm_open(m->name, O_RDONLY, S_IRUSR); if (m->fd < 0) { free(m->name); free(m); return NULL; } m->write = do_write; eina_mmap_safety_enabled_set(EINA_TRUE); if (do_write) m->data = mmap(NULL, m->size, PROT_READ | PROT_WRITE, MAP_SHARED, m->fd, 0); else m->data = mmap(NULL, m->size, PROT_READ, MAP_SHARED, m->fd, 0); if (m->data == MAP_FAILED) { close(m->fd); free(m->name); free(m); return NULL; } m->ref = 1; return m; }
static Eina_Bool _load(Eina_File *ef, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, void *pixels, int *error, Eina_Bool get_data) { Eina_Bool res = EINA_FALSE; int w = 0, h = 0, alpha = 0; const char *dot1 = NULL, *dot2 = NULL, *end, *p; char *cmd = NULL, decoders[3][128], buf[4096]; char *loader = "/evas/utils/evas_image_loader"; char *img_loader = NULL; const char *libdir; // eg $libdir/evas/generic_loaders int cmd_len, len, decoders_num = 0, try_count = 0; int read_data = 0; char *tmpfname = NULL, *shmfname = NULL; DATA32 *body; FILE *f = NULL; libdir = _evas_module_libdir_get(); cmd_len = strlen(libdir); cmd_len += strlen(loader); img_loader = alloca(cmd_len + 1); strcpy(img_loader, libdir); strcat(img_loader, loader); // params excluding file, key and loadopts cmd_len += 1024; cmd_len += strlen(eina_file_filename_get(ef)) * 2; if (key) cmd_len += strlen(key) * 2; cmd = alloca(cmd_len + 1); len = strlen(eina_file_filename_get(ef)); if (len < 1) { *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; return EINA_FALSE; } end = eina_file_filename_get(ef) + len; for (p = end - 1; p >= eina_file_filename_get(ef); p--) { if ((!dot1) && (*p == '.')) dot1 = p; else if ((!dot2) && (*p == '.')) dot2 = p; else if ((dot1) && (dot2)) break; } if (dot2) { // double extn not too long if (((end - dot2) <= 10) && (!illegal_char(dot2))) { strncpy(&(decoders[decoders_num][0]), img_loader, 127); decoders[decoders_num][127] = 0; dotcat(&(decoders[decoders_num][0]), dot2); decoders_num++; } // single extn not too long if (((end - dot1) <= 5) && (!illegal_char(dot1))) { strncpy(&(decoders[decoders_num][0]), img_loader, 127); decoders[decoders_num][127] = 0; dotcat(&(decoders[decoders_num][0]), dot1); decoders_num++; } strncpy(decoders[decoders_num], img_loader, 127); decoders[decoders_num][127] = 0; decoders_num++; } else if (dot1) { // single extn not too long if (((end - dot1) <= 5) && (!illegal_char(dot1))) { strncpy(&(decoders[decoders_num][0]), img_loader, 127); decoders[decoders_num][127] = 0; dotcat(&(decoders[decoders_num][0]), dot1); decoders_num++; } strncpy(decoders[decoders_num], img_loader, 127); decoders[decoders_num][127] = 0; decoders_num++; } else { strncpy(decoders[decoders_num], img_loader, 127); decoders[decoders_num][127] = 0; decoders_num++; } for (try_count = 0; try_count < decoders_num; try_count++) { // FIXME: strcats could be more efficient, not that it matters much // here as we are about to build a cmd to exec via a shell that // will interpret shell stuff and path hunt that will then exec the // program itself that will dynamically link that will again // parse the arguments and finally do something... if (access(decoders[try_count], X_OK)) continue; strcpy(cmd, decoders[try_count]); strcat(cmd, " "); // filename first arg len = strlen(cmd); escape_copy(eina_file_filename_get(ef), cmd + len); if (!get_data) { strcat(cmd, " -head "); } if (key) { strcat(cmd, " -key "); len = strlen(cmd); escape_copy(key, cmd + len); } if (opts->scale_down_by > 1) { strcat(cmd, " -opt-scale-down-by "); snprintf(buf, sizeof(buf), "%i", opts->scale_down_by); strcat(cmd, buf); } if (opts->dpi > 0.0) { strcat(cmd, " -opt-dpi "); snprintf(buf, sizeof(buf), "%i", (int)(opts->dpi * 1000.0)); strcat(cmd, buf); } if ((opts->w > 0) && (opts->h > 0)) { strcat(cmd, " -opt-size "); snprintf(buf, sizeof(buf), "%i %i", opts->w, opts->h); strcat(cmd, buf); } f = popen(cmd, "r"); if (f) break; } if (!f) { *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; return EINA_FALSE; } while (fgets(buf, sizeof(buf), f)) { len = strlen(buf); if (len > 0) { if (buf[len - 1] == '\n') buf[len - 1] = 0; if (!strncmp(buf, "size ", 5)) { int tw = 0, th = 0; len = sscanf(buf, "%*s %i %i", &tw, &th); if (len == 2) { if ((tw > 0) && (th > 0)) { w = tw; h = th; } } } else if (!strncmp(buf, "alpha ", 6)) { int ta; len = sscanf(buf, "%*s %i", &ta); if (len == 1) { alpha = ta; } } else if (!strncmp(buf, "tmpfile ", 8)) { tmpfname = buf + 8; goto getdata; } #ifdef HAVE_SHM_OPEN else if (!strncmp(buf, "shmfile ", 8)) { shmfname = buf + 8; goto getdata; } #endif else if (!strncmp(buf, "data", 4)) { read_data = 1; goto getdata; } else if (!strncmp(buf, "done", 4)) { read_data = 2; goto getdata; } } } getdata: if ((!read_data) && (!tmpfname) && (!shmfname)) { *error = EVAS_LOAD_ERROR_CORRUPT_FILE; goto on_error; } if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || IMG_TOO_BIG(w, h)) { *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto on_error; } if (!get_data) { if (alpha) prop->alpha = 1; prop->w = w; prop->h = h; } else { if ((int)prop->w != w || (int)prop->h != h) { *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto on_error; } body = pixels; if ((tmpfname) || (shmfname)) { int fd = -1; // open if (tmpfname) fd = open(tmpfname, O_RDONLY, S_IRUSR); #ifdef HAVE_SHM_OPEN else if (shmfname) fd = shm_open(shmfname, O_RDONLY, S_IRUSR); #endif if (fd >= 0) { void *addr; eina_mmap_safety_enabled_set(EINA_TRUE); // mmap addr = mmap(NULL, w * h * sizeof(DATA32), PROT_READ, MAP_SHARED, fd, 0); if (addr != MAP_FAILED) { memcpy(body, addr, w * h * sizeof(DATA32)); munmap(addr, w * h * sizeof(DATA32)); } // close if (tmpfname) { close(fd); unlink(tmpfname); } #ifdef HAVE_SHM_OPEN else if (shmfname) { close(fd); shm_unlink(shmfname); } #endif } else { *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto on_error; } } else if (read_data) { if (fread(body, w * h * sizeof(DATA32), 1, f) != 1) { *error = EVAS_LOAD_ERROR_CORRUPT_FILE; goto on_error; } } } res = EINA_TRUE; *error = EVAS_LOAD_ERROR_NONE; on_error: if (f) pclose(f); return res; }
/** * @internal * @param file The file to parse * @return Returns an Eina_Hash with the contents of @a file, or NULL if the * file fails to parse or if the file doesn't exist * @brief Parses the ini file @a file into an Eina_Hash */ static Eina_Hash * efreet_ini_parse(const char *file) { Eina_Hash *data = NULL, *section = NULL; Eina_Iterator *it = NULL; Eina_File_Line *line; Eina_File *f; EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); f = eina_file_open(file, EINA_FALSE); if (!f) return NULL; data = eina_hash_string_small_new(EINA_FREE_CB(eina_hash_free)); if (!data) goto error; /* let's make mmap safe and just get 0 pages for IO erro */ eina_mmap_safety_enabled_set(EINA_TRUE); it = eina_file_map_lines(f); if (!it) goto error; EINA_ITERATOR_FOREACH(it, line) { const char *eq; unsigned int start = 0; /* skip empty lines */ if (line->length == 0) continue; /* skip white space at start of line */ while ((start < line->length) && (isspace((unsigned char)line->start[start]))) start++; /* skip empty lines */ if (start == line->length) continue; /* skip comments */ if (line->start[start] == '#') continue; /* new section */ if (line->start[start] == '[') { const char *head_start; const char *head_end; head_start = &(line->start[start]) + 1; head_end = memchr(line->start, ']', line->length); if (head_end) { char *header; size_t len; len = head_end - head_start + 1; header = alloca(len); memcpy(header, head_start, len - 1); header[len - 1] = '\0'; section = eina_hash_string_small_new(EINA_FREE_CB(eina_stringshare_del)); eina_hash_del_by_key(data, header); eina_hash_add(data, header, section); } else { /* invalid file - skip line? or refuse to parse file? */ /* just printf for now till we figure out what to do */ // ERR("Invalid file (%s) (missing ] on group name)", file); } continue; } if (!section) { INF("Invalid file (%s) (missing section)", file); goto error; } eq = memchr(line->start, '=', line->length); if (eq) { const char *key_start, *key_end; const char *value_start, *value_end; char *key, *value; size_t len; key_start = &(line->start[start]); key_end = eq - 1; /* trim whitespace from end of key */ while ((isspace((unsigned char)*key_end)) && (key_end > key_start)) key_end--; key_end++; /* make sure we have a key */ if (key_start == key_end) continue; value_start = eq + 1; value_end = line->end; /* line->end points to char after '\n' or '\r' */ value_end--; /* trim whitespace from end of value */ while ((isspace((unsigned char)*value_end)) && (value_end > value_start)) value_end--; value_end++; /* trim whitespace from start of value */ while ((isspace((unsigned char)*value_start)) && (value_start < value_end)) value_start++; len = key_end - key_start + 1; key = alloca(len); memcpy(key, key_start, len - 1); key[len - 1] = '\0'; /* empty value allowed */ if (value_end == value_start) { eina_hash_del_by_key(section, key); eina_hash_add(section, key, ""); } else { len = value_end - value_start + 1; value = alloca(len); memcpy(value, value_start, len - 1); value[len - 1] = '\0'; eina_hash_del_by_key(section, key); eina_hash_add(section, key, efreet_ini_unescape(value)); } } else { /* invalid file... */ INF("Invalid file (%s) (missing = from key=value pair)", file); goto error; } } eina_iterator_free(it); eina_file_close(f); #if 0 if (!eina_hash_population(data)) { eina_hash_free(data); return NULL; } #endif return data; error: if (data) eina_hash_free(data); if (it) eina_iterator_free(it); eina_file_close(f); return NULL; }
EAPI Eet_Key * eet_identity_open(const char *certificate_file, const char *private_key_file, Eet_Key_Password_Callback cb) { #ifdef HAVE_SIGNATURE /* Signature declarations */ Eet_Key *key = NULL; # ifdef HAVE_GNUTLS /* Gnutls private declarations */ Eina_File *f = NULL; void *data = NULL; gnutls_datum_t load_file = { NULL, 0 }; char pass[1024]; if (!emile_cipher_init()) return NULL; /* Init */ if (!(key = malloc(sizeof(Eet_Key)))) goto on_error; key->references = 1; if (gnutls_x509_crt_init(&(key->certificate))) goto on_error; if (gnutls_x509_privkey_init(&(key->private_key))) goto on_error; /* Mmap certificate_file */ f = eina_file_open(certificate_file, 0); if (!f) goto on_error; /* let's make mmap safe and just get 0 pages for IO erro */ eina_mmap_safety_enabled_set(EINA_TRUE); data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); if (!data) goto on_error; /* Import the certificate in Eet_Key structure */ load_file.data = data; load_file.size = eina_file_size_get(f); if (gnutls_x509_crt_import(key->certificate, &load_file, GNUTLS_X509_FMT_PEM) < 0) goto on_error; eina_file_map_free(f, data); /* Reset values */ eina_file_close(f); f = NULL; data = NULL; load_file.data = NULL; load_file.size = 0; /* Mmap private_key_file */ f = eina_file_open(private_key_file, 0); if (!f) goto on_error; /* let's make mmap safe and just get 0 pages for IO erro */ eina_mmap_safety_enabled_set(EINA_TRUE); data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); if (!data) goto on_error; /* Import the private key in Eet_Key structure */ load_file.data = data; load_file.size = eina_file_size_get(f); /* Try to directly import the PEM encoded private key */ if (gnutls_x509_privkey_import(key->private_key, &load_file, GNUTLS_X509_FMT_PEM) < 0) { /* Else ask for the private key pass */ if (cb && cb(pass, 1024, 0, NULL)) { /* If pass then try to decode the pkcs 8 private key */ if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file, GNUTLS_X509_FMT_PEM, pass, 0)) goto on_error; } else /* Else try to import the pkcs 8 private key without pass */ if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file, GNUTLS_X509_FMT_PEM, NULL, 1)) goto on_error; } eina_file_map_free(f, data); eina_file_close(f); return key; on_error: if (data) eina_file_map_free(f, data); if (f) eina_file_close(f); if (key) { if (key->certificate) gnutls_x509_crt_deinit(key->certificate); if (key->private_key) gnutls_x509_privkey_deinit(key->private_key); free(key); } # else /* ifdef HAVE_GNUTLS */ /* Openssl private declarations */ FILE *fp; EVP_PKEY *pkey = NULL; X509 *cert = NULL; if (!emile_cipher_init()) return NULL; /* Load the X509 certificate in memory. */ fp = fopen(certificate_file, "rb"); if (!fp) return NULL; cert = PEM_read_X509(fp, NULL, NULL, NULL); fclose(fp); if (!cert) goto on_error; /* Check the presence of the public key. Just in case. */ pkey = X509_get_pubkey(cert); if (!pkey) goto on_error; /* Load the private key in memory. */ fp = fopen(private_key_file, "rb"); if (!fp) goto on_error; pkey = PEM_read_PrivateKey(fp, NULL, cb, NULL); fclose(fp); if (!pkey) goto on_error; /* Load the certificate and the private key in Eet_Key structure */ key = malloc(sizeof(Eet_Key)); if (!key) goto on_error; key->references = 1; key->certificate = cert; key->private_key = pkey; return key; on_error: if (cert) X509_free(cert); if (pkey) EVP_PKEY_free(pkey); # endif /* ifdef HAVE_GNUTLS */ #else (void) certificate_file; (void) private_key_file; (void) cb; #endif /* ifdef HAVE_SIGNATURE */ return NULL; }
Eet_Error eet_identity_sign(FILE *fp, Eet_Key *key) { #ifdef HAVE_SIGNATURE Eet_Error err = EET_ERROR_NONE; struct stat st_buf; void *data; int fd; int head[3]; unsigned char *sign = NULL; unsigned char *cert = NULL; # ifdef HAVE_GNUTLS gnutls_datum_t datum = { NULL, 0 }; size_t sign_len = 0; size_t cert_len = 0; gnutls_datum_t signum = { NULL, 0 }; gnutls_privkey_t privkey; # else /* ifdef HAVE_GNUTLS */ # if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) EVP_MD_CTX *md_ctx; # else EVP_MD_CTX md_ctx; # endif unsigned int sign_len = 0; int cert_len = 0; # endif /* ifdef HAVE_GNUTLS */ /* A few check and flush pending write. */ if (!fp || !key || !key->certificate || !key->private_key) return EET_ERROR_BAD_OBJECT; if (!emile_cipher_init()) return EET_ERROR_NOT_IMPLEMENTED; /* Get the file size. */ fd = fileno(fp); if (fd < 0) return EET_ERROR_BAD_OBJECT; if (fstat(fd, &st_buf) < 0) return EET_ERROR_MMAP_FAILED; /* let's make mmap safe and just get 0 pages for IO erro */ eina_mmap_safety_enabled_set(EINA_TRUE); /* Map the file in memory. */ data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (data == MAP_FAILED) return EET_ERROR_MMAP_FAILED; # ifdef HAVE_GNUTLS datum.data = data; datum.size = st_buf.st_size; /* Get the signature length */ if (gnutls_privkey_init(&privkey) < 0) { err = EET_ERROR_SIGNATURE_FAILED; goto on_error; } if (gnutls_privkey_import_x509(privkey, key->private_key, 0) < 0) { err = EET_ERROR_SIGNATURE_FAILED; goto on_error; } if (gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &datum, &signum) < 0) { err = EET_ERROR_SIGNATURE_FAILED; goto on_error; } sign = signum.data; sign_len = signum.size; /* Get the certificate length */ if (gnutls_x509_crt_export(key->certificate, GNUTLS_X509_FMT_DER, cert, &cert_len) && !cert_len) { err = EET_ERROR_SIGNATURE_FAILED; goto on_error; } /* Get the certificate */ cert = malloc(cert_len); if (!cert || gnutls_x509_crt_export(key->certificate, GNUTLS_X509_FMT_DER, cert, &cert_len)) { if (!cert) err = EET_ERROR_OUT_OF_MEMORY; else err = EET_ERROR_SIGNATURE_FAILED; goto on_error; } # else /* ifdef HAVE_GNUTLS */ sign_len = EVP_PKEY_size(key->private_key); sign = malloc(sign_len); if (!sign) { err = EET_ERROR_OUT_OF_MEMORY; goto on_error; } /* Do the signature. */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) md_ctx = EVP_MD_CTX_new(); EVP_SignInit(md_ctx, EVP_sha1()); EVP_SignUpdate(md_ctx, data, st_buf.st_size); err = EVP_SignFinal(md_ctx, sign, (unsigned int *)&sign_len, key->private_key); EVP_MD_CTX_free(md_ctx); #else EVP_SignInit(&md_ctx, EVP_sha1()); EVP_SignUpdate(&md_ctx, data, st_buf.st_size); err = EVP_SignFinal(&md_ctx, sign, (unsigned int *)&sign_len, key->private_key); EVP_MD_CTX_cleanup(&md_ctx); #endif if (err != 1) { ERR_print_errors_fp(stdout); err = EET_ERROR_SIGNATURE_FAILED; goto on_error; } /* Give me the der (binary form for X509). */ cert_len = i2d_X509(key->certificate, &cert); if (cert_len < 0) { ERR_print_errors_fp(stdout); err = EET_ERROR_X509_ENCODING_FAILED; goto on_error; } # endif /* ifdef HAVE_GNUTLS */ /* Append the signature at the end of the file. */ head[0] = (int)htonl ((unsigned int)EET_MAGIC_SIGN); head[1] = (int)htonl ((unsigned int)sign_len); head[2] = (int)htonl ((unsigned int)cert_len); if (fwrite(head, sizeof(head), 1, fp) != 1) { err = EET_ERROR_WRITE_ERROR; goto on_error; } if (fwrite(sign, sign_len, 1, fp) != 1) { err = EET_ERROR_WRITE_ERROR; goto on_error; } if (fwrite(cert, cert_len, 1, fp) != 1) { err = EET_ERROR_WRITE_ERROR; goto on_error; } on_error: # ifdef HAVE_GNUTLS if (cert) free(cert); # else /* ifdef HAVE_GNUTLS */ if (cert) OPENSSL_free(cert); # endif /* ifdef HAVE_GNUTLS */ if (sign) free(sign); munmap(data, st_buf.st_size); return err; #else /* ifdef HAVE_SIGNATURE */ fp = NULL; key = NULL; return EET_ERROR_NOT_IMPLEMENTED; #endif /* ifdef HAVE_SIGNATURE */ }