static JSBool jsg_set_prop(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { js_setting_group_t *jsg = JS_GetPrivate(cx, obj); const char *name; if(jsg->jsg_frozen) return JS_TRUE; name = JSVAL_IS_STRING(id) ? JS_GetStringBytes(JSVAL_TO_STRING(id)) : NULL; if(name != NULL) { jsval v = *vp; if(JSVAL_IS_INT(v)) { htsmsg_delete_field(jsg->jsg_store, name); htsmsg_add_s32(jsg->jsg_store, name, JSVAL_TO_INT(v)); } else if(JSVAL_IS_DOUBLE(v)) { double d; if(JS_ValueToNumber(cx, v, &d)) { htsmsg_delete_field(jsg->jsg_store, name); htsmsg_add_dbl(jsg->jsg_store, name, d); } } else if(JSVAL_IS_STRING(v)) { htsmsg_delete_field(jsg->jsg_store, name); htsmsg_add_str(jsg->jsg_store, name, JS_GetStringBytes(JS_ValueToString(cx, v))); } else { return JS_TRUE; } htsmsg_store_save(jsg->jsg_store, jsg->jsg_spath); } return JS_TRUE; }
static void callback_opt(void *opaque, prop_event_t event, ...) { setting_t *s = opaque; prop_callback_string_t *cb; prop_t *c; rstr_t *name; va_list ap; va_start(ap, event); cb = s->s_callback; if(event != PROP_SELECT_CHILD) return; c = va_arg(ap, prop_t *); name = c ? prop_get_name(c) : NULL; va_end(ap); if(cb != NULL) cb(s->s_opaque, rstr_get(name)); if(s->s_store != NULL && s->s_saver != NULL) { htsmsg_delete_field(s->s_store, s->s_id); if(name != NULL) htsmsg_add_str(s->s_store, s->s_id, rstr_get(name)); s->s_saver(s->s_saver_opaque, s->s_store); } rstr_release(name); }
void htsmsg_store_set(const char *store, const char *key, int value_type, ...) { va_list ap; va_start(ap, value_type); hts_mutex_lock(&loaded_msg_mutex); loaded_msg_t *lm = htsmsg_store_obtain(store, 1); htsmsg_delete_field(lm->lm_msg, key); switch(value_type) { case -1: break; case HMF_MAP: case HMF_LIST: htsmsg_add_msg(lm->lm_msg, key, va_arg(ap, htsmsg_t *)); break; case HMF_S64: htsmsg_add_s64(lm->lm_msg, key, va_arg(ap, int64_t)); break; case HMF_STR: htsmsg_add_str(lm->lm_msg, key, va_arg(ap, const char *)); break; default: abort(); } lm->lm_dirty = 1; callout_arm_managed(&lm->lm_timer, htsmsg_store_timer_cb, lm, SETTINGS_CACHE_DELAY, htsmsg_store_lockmgr); hts_mutex_unlock(&loaded_msg_mutex); va_end(ap); }
static void callback_opt(void *opaque, prop_event_t event, ...) { setting_t *s = opaque; prop_callback_string_t *cb; prop_t *c; va_list ap; va_start(ap, event); cb = s->s_callback; if(event != PROP_SELECT_CHILD) return; c = va_arg(ap, prop_t *); if(cb) cb(s->s_opaque, c ? prop_get_name(c) : NULL); if(s->s_store && s->s_saver) { htsmsg_delete_field(s->s_store, s->s_id); if(c != NULL) htsmsg_add_str(s->s_store, s->s_id, prop_get_name(c)); s->s_saver(s->s_saver_opaque, s->s_store); } }
static JSBool jsg_del_prop(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { js_setting_group_t *jsg = JS_GetPrivate(cx, obj); const char *name; name = JSVAL_IS_STRING(id) ? JS_GetStringBytes(JSVAL_TO_STRING(id)) : NULL; if(name != NULL) { htsmsg_delete_field(jsg->jsg_store, name); htsmsg_store_save(jsg->jsg_store, jsg->jsg_spath); } return JS_TRUE; }
static void settings_int_callback(void *opaque, int v) { setting_t *s = opaque; prop_callback_int_t *cb = s->s_callback; if(cb) cb(s->s_opaque, v); if(s->s_store && s->s_saver) { htsmsg_delete_field(s->s_store, s->s_id); htsmsg_add_s32(s->s_store, s->s_id, v); s->s_saver(s->s_saver_opaque, s->s_store); } }
static void settings_string_callback(void *opaque, const char *str) { setting_t *s = opaque; prop_callback_string_t *cb = s->s_callback; if(cb) cb(s->s_opaque, str); if(s->s_store && s->s_saver) { htsmsg_delete_field(s->s_store, s->s_id); if(str != NULL) htsmsg_add_str(s->s_store, s->s_id, str); s->s_saver(s->s_saver_opaque, s->s_store); } }
static htsmsg_t * htsp_reqreply(htsp_connection_t *hc, htsmsg_t *m) { void *buf; size_t len; uint32_t seq; int r; tcpcon_t *tc = hc->hc_tc; uint32_t noaccess; htsmsg_t *reply; htsp_msg_t *hm = NULL; int retry = 0; char id[100]; char *username; char *password; sha1_decl(shactx); uint8_t d[20]; if(tc == NULL) return NULL; /* Generate a sequence number for our message */ seq = atomic_add(&hc->hc_seq_generator, 1); htsmsg_add_u32(m, "seq", seq); again: snprintf(id, sizeof(id), "htsp://%s:%d", hc->hc_hostname, hc->hc_port); r = keyring_lookup(id, &username, &password, NULL, NULL, "TV client", "Access denied", (retry ? KEYRING_QUERY_USER : 0) | KEYRING_SHOW_REMEMBER_ME | KEYRING_REMEMBER_ME_SET); if(r == -1) { /* User rejected */ return NULL; } if(r == 0) { /* Got auth credentials */ htsmsg_delete_field(m, "username"); htsmsg_delete_field(m, "digest"); if(username != NULL) htsmsg_add_str(m, "username", username); if(password != NULL) { sha1_init(shactx); sha1_update(shactx, (const uint8_t *)password, strlen(password)); sha1_update(shactx, hc->hc_challenge, 32); sha1_final(shactx, d); htsmsg_add_bin(m, "digest", d, 20); } free(username); free(password); } if(htsmsg_binary_serialize(m, &buf, &len, -1) < 0) { htsmsg_destroy(m); return NULL; } if(hc->hc_is_async) { /* Async, set up a struct that will be signalled when we get a reply */ hm = malloc(sizeof(htsp_msg_t)); hm->hm_msg = NULL; hm->hm_seq = seq; hm->hm_error = 0; hts_mutex_lock(&hc->hc_rpc_mutex); TAILQ_INSERT_TAIL(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); } if(tc->write(tc, buf, len)) { free(buf); htsmsg_destroy(m); if(hm != NULL) { hts_mutex_lock(&hc->hc_rpc_mutex); TAILQ_REMOVE(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); free(hm); } return NULL; } free(buf); if(hm != NULL) { hts_mutex_lock(&hc->hc_rpc_mutex); while(1) { if(hm->hm_error != 0) { r = hm->hm_error; TAILQ_REMOVE(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); free(hm); htsmsg_destroy(m); return NULL; } if(hm->hm_msg != NULL) break; hts_cond_wait(&hc->hc_rpc_cond, &hc->hc_rpc_mutex); } TAILQ_REMOVE(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); reply = hm->hm_msg; free(hm); } else { if((reply = htsp_recv(hc)) == NULL) { htsmsg_destroy(m); return NULL; } } if(!htsmsg_get_u32(reply, "noaccess", &noaccess) && noaccess) { retry++; goto again; } htsmsg_destroy(m); /* Destroy original message */ return reply; }
int keyring_lookup(const char *id, char **username, char **password, char **domain, int *remember_me, const char *source, const char *reason, int flags) { htsmsg_t *m; rstr_t *r; int remember = !!(flags & KEYRING_REMEMBER_ME_SET); hts_mutex_lock(&keyring_mutex); if(flags & KEYRING_QUERY_USER) { htsmsg_t *parent; prop_t *p = prop_create_root(NULL); prop_set_string(prop_create(p, "type"), "auth"); prop_set_string(prop_create(p, "id"), id); prop_set_string(prop_create(p, "source"), source); prop_set_string(prop_create(p, "reason"), reason); prop_set_int(prop_create(p, "disableUsername"), username == NULL); prop_set_int(prop_create(p, "canRemember"), !!(flags & KEYRING_SHOW_REMEMBER_ME)); prop_t *rememberMe = prop_create(p, "rememberMe"); prop_set_int(rememberMe, remember); prop_sub_t *remember_sub = prop_subscribe(0, PROP_TAG_CALLBACK_INT, set_remember, &remember, PROP_TAG_ROOT, rememberMe, NULL); prop_t *user = prop_create(p, "username"); prop_t *pass = prop_create(p, "password"); TRACE(TRACE_INFO, "keyring", "Requesting credentials for %s : %s : %s", id, source, reason); event_t *e = popup_display(p); prop_unsubscribe(remember_sub); if(flags & KEYRING_ONE_SHOT) parent = NULL; else if(remember) parent = persistent_keyring; else parent = temporary_keyring; if(parent != NULL) htsmsg_delete_field(parent, id); if(event_is_action(e, ACTION_OK)) { /* OK */ m = htsmsg_create_map(); if(username != NULL) { r = prop_get_string(user); htsmsg_add_str(m, "username", r ? rstr_get(r) : ""); *username = strdup(r ? rstr_get(r) : ""); rstr_release(r); } r = prop_get_string(pass); htsmsg_add_str(m, "password", r ? rstr_get(r) : ""); *password = strdup(r ? rstr_get(r) : ""); rstr_release(r); if(parent != NULL) { htsmsg_add_msg(parent, id, m); if(parent == persistent_keyring) keyring_store(); } } else { /* CANCEL */ if(parent == persistent_keyring) keyring_store(); } if(remember_me != NULL) *remember_me = remember; prop_destroy(p); if(event_is_action(e, ACTION_CANCEL)) { /* return CANCEL to caller */ hts_mutex_unlock(&keyring_mutex); event_release(e); return -1; } event_release(e); } else { if((m = htsmsg_get_map(temporary_keyring, id)) == NULL && (m = htsmsg_get_map(persistent_keyring, id)) == NULL) { hts_mutex_unlock(&keyring_mutex); return 1; } setstr(username, m, "username"); setstr(password, m, "password"); setstr(domain, m, "domain"); } hts_mutex_unlock(&keyring_mutex); return 0; }
int keyring_lookup(const char *id, char **username, char **password, char **domain, int query, const char *source, const char *reason, int force_temporary) { htsmsg_t *m; rstr_t *r; hts_mutex_lock(&keyring_mutex); if(query) { htsmsg_t *parent; prop_t *p = prop_create_root(NULL); prop_set_string(prop_create(p, "type"), "auth"); prop_set_string(prop_create(p, "id"), id); prop_set_string(prop_create(p, "source"), source); prop_set_string(prop_create(p, "reason"), reason); int remember = !force_temporary; prop_set_int(prop_create(p, "canRemember"), remember); prop_t *rememberMe = prop_create(p, "rememberMe"); prop_set_int(rememberMe, remember); prop_sub_t *remember_sub = prop_subscribe(0, PROP_TAG_CALLBACK_INT, set_remember, &remember, PROP_TAG_ROOT, rememberMe, NULL); prop_t *user = prop_create(p, "username"); prop_t *pass = prop_create(p, "password"); TRACE(TRACE_INFO, "keyring", "Requesting credentials for %s : %s : %s", id, source, reason); event_t *e = popup_display(p); prop_unsubscribe(remember_sub); if(remember) parent = persistent_keyring; else parent = temporary_keyring; htsmsg_delete_field(parent, id); if(event_is_action(e, ACTION_OK)) { /* OK */ m = htsmsg_create_map(); r = prop_get_string(user); htsmsg_add_str(m, "username", r ? rstr_get(r) : ""); rstr_release(r); r = prop_get_string(pass); htsmsg_add_str(m, "password", r ? rstr_get(r) : ""); rstr_release(r); htsmsg_add_msg(parent, id, m); if(parent == persistent_keyring) keyring_store(); } else { /* CANCEL, store without adding anything */ keyring_store(); } prop_destroy(p); if(event_is_action(e, ACTION_CANCEL)) { /* return CANCEL to caller */ hts_mutex_unlock(&keyring_mutex); event_release(e); return -1; } event_release(e); } if((m = htsmsg_get_map(temporary_keyring, id)) == NULL && (m = htsmsg_get_map(persistent_keyring, id)) == NULL) { hts_mutex_unlock(&keyring_mutex); return 1; } setstr(username, m, "username"); setstr(password, m, "password"); setstr(domain, m, "domain"); hts_mutex_unlock(&keyring_mutex); return 0; }