static JSBool js_getAuthCredentials(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { char buf[256]; const char *id = NULL, *reason, *source; char *username, *password; JSBool query, forcetmp = 0; int r; jsval val; js_plugin_t *jsp = JS_GetPrivate(cx, obj); if(!JS_ConvertArguments(cx, argc, argv, "ssb/sb", &source, &reason, &query, &id, &forcetmp)) return JS_FALSE; snprintf(buf, sizeof(buf), "plguin-%s%s%s", jsp->jsp_id, id ? "-" : "", id ?: ""); int flags = 0; flags |= query ? KEYRING_QUERY_USER : 0; flags |= forcetmp ? 0 : KEYRING_SHOW_REMEMBER_ME | KEYRING_REMEMBER_ME_SET; r = keyring_lookup(buf, &username, &password, NULL, NULL, source, reason, flags); if(r == 1) { *rval = BOOLEAN_TO_JSVAL(0); return JS_TRUE; } JSObject *robj = JS_NewObject(cx, NULL, NULL, NULL); *rval = OBJECT_TO_JSVAL(robj); if(r == -1) { val = BOOLEAN_TO_JSVAL(1); JS_SetProperty(cx, robj, "rejected", &val); } else { val = STRING_TO_JSVAL(JS_NewString(cx, username, strlen(username))); JS_SetProperty(cx, robj, "username", &val); val = STRING_TO_JSVAL(JS_NewString(cx, password, strlen(password))); JS_SetProperty(cx, robj, "password", &val); } return JS_TRUE; }
static JSBool js_getAuthCredentials(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { const char *id, *reason, *source; char *username, *password; JSBool query; int r; jsval val; if(!JS_ConvertArguments(cx, argc, argv, "sssb", &id, &source, &reason, &query)) return JS_FALSE; r = keyring_lookup(id, &username, &password, NULL, query, source, reason); if(r == 1) { *rval = BOOLEAN_TO_JSVAL(0); return JS_TRUE; } JSObject *robj = JS_NewObject(cx, NULL, NULL, NULL); *rval = OBJECT_TO_JSVAL(robj); if(r == -1) { val = BOOLEAN_TO_JSVAL(1); JS_SetProperty(cx, robj, "rejected", &val); } else { val = STRING_TO_JSVAL(JS_NewString(cx, username, strlen(username))); JS_SetProperty(cx, robj, "username", &val); val = STRING_TO_JSVAL(JS_NewString(cx, password, strlen(password))); JS_SetProperty(cx, robj, "password", &val); } return JS_TRUE; }
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; }