mirror of
https://github.com/morgan9e/UxPlay
synced 2026-04-14 00:04:13 +09:00
clean up digest verification in pairing,c
This commit is contained in:
10
README.md
10
README.md
@@ -1,9 +1,9 @@
|
||||
# UxPlay 1.72 (beta): AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (now also runs on Windows).
|
||||
# UxPlay 1.72 (beta): AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (also runs on Windows).
|
||||
|
||||
### **Now developed at the GitHub site <https://github.com/FDH2/UxPlay> (where ALL user issues should be posted, and latest versions can be found).**
|
||||
|
||||
- ***NEW in v1.72**: Improved Support for (YouTube) HLS (HTTP Live Streaming)
|
||||
video with the new "-hls" option.* **Only streaming from the YouTube iOS app
|
||||
video with the new "-hls" option (introduced in 1.71).* **Only streaming from the YouTube iOS app
|
||||
(in \"m3u8\" protocol) is currently supported**: (streaming using the AirPlay icon in a browser window
|
||||
is **not** yet supported).Click on the airplay icon in the
|
||||
YouTube app to stream video.
|
||||
@@ -13,10 +13,10 @@
|
||||
GStreamer playbin v3: use "-hls 2" to revert to playbin v2 if
|
||||
some videos fail to play_.
|
||||
|
||||
* added support for setting a password (as an alternative to on-screen
|
||||
* user-requested features: added support for setting a password (as an alternative to on-screen
|
||||
pin codes) to control client access (-pw option); added support for
|
||||
setting initial audion volume (--vol option), and output of audio-mode
|
||||
metatdate to file (for display, -md option).
|
||||
setting initial client audio-streaming volume (-vol option), and output of audio-mode
|
||||
metadata to file (for display by some external process, -md option).
|
||||
|
||||
## Highlights:
|
||||
|
||||
|
||||
@@ -246,9 +246,10 @@ char *get_token(char **cursor, char *token_name, char start_char, char end_char)
|
||||
bool
|
||||
pairing_digest_verify(const char *method, const char * authorization, const char *password) {
|
||||
/* RFC 2617 HTTP md5 Digest password authentication */
|
||||
|
||||
char *sentence = (char *) calloc(strlen(authorization) + 1, sizeof(char));
|
||||
strncpy(sentence, authorization, strlen(authorization));
|
||||
size_t authlen = strlen(authorization);
|
||||
char *sentence = (char *) malloc(authlen + 1);
|
||||
memcpy(sentence, authorization, authlen);
|
||||
*(sentence + authlen) = '\0';
|
||||
char *username = NULL;
|
||||
char *realm = NULL;
|
||||
char *nonce = NULL;
|
||||
@@ -309,35 +310,50 @@ pairing_digest_verify(const char *method, const char * authorization, const char
|
||||
/* H1 = H(username : realm : password ) */
|
||||
len = strlen(username) + strlen(realm) + strlen(pwd) + 3;
|
||||
raw = (char *) calloc(len, sizeof(char));
|
||||
snprintf(raw, len, "%s:%s:%s", username, realm, pwd);
|
||||
strncat(raw, username, len - strlen(raw) - 1);
|
||||
strncat(raw, ":", len - strlen(raw) - 1);
|
||||
strncat(raw, realm, len - strlen(raw) - 1);
|
||||
strncat(raw, ":", len - strlen(raw) - 1);
|
||||
strncat(raw, pwd, len - strlen(raw) - 1);
|
||||
char *hash1 = get_md5(raw);
|
||||
free (raw);
|
||||
|
||||
#ifdef test_digest
|
||||
printf("hash1: should be %s, was: %s\n ", HA1, hash1_str);
|
||||
printf("hash1: should be %s, was: %s\n", HA1, hash1);
|
||||
#endif
|
||||
|
||||
/* H2 = H(method : uri) */
|
||||
len = strlen(mthd) + strlen(uri) + 2;
|
||||
raw = (char *) calloc(len, sizeof(char));
|
||||
snprintf(raw, len, "%s:%s", mthd, uri);
|
||||
strncat(raw, mthd, len - strlen(raw) - 1);
|
||||
strncat(raw, ":", len - strlen(raw) - 1);
|
||||
strncat(raw, uri, len - strlen(raw) - 1);
|
||||
char *hash2 = get_md5(raw);
|
||||
free (raw);
|
||||
|
||||
#ifdef test_digest
|
||||
printf("hash2: should be %s, was: %s\n", HA2, hash2_str);
|
||||
printf("hash2: should be %s, was: %s\n", HA2, hash2);
|
||||
#endif
|
||||
|
||||
/* result = H(H1 : nonce (or nonce:nc:cnonce:qop) : H2) */
|
||||
len = strlen(hash1) + strlen(nonce) + strlen(hash2) + 3;
|
||||
if (qop) {
|
||||
len += strlen(nc) + strlen(cnonce) + strlen(qop) + 3;
|
||||
raw = (char *) calloc(len, sizeof(char));
|
||||
snprintf(raw, len, "%s:%s:%s:%s:%s:%s", hash1, nonce, nc, cnonce, qop, hash2);
|
||||
} else {
|
||||
raw = (char *) calloc(len, sizeof(char));
|
||||
snprintf(raw, len, "%s:%s:%s", hash1, nonce, hash2);
|
||||
}
|
||||
raw = (char *) calloc(len, sizeof(char));
|
||||
strncat(raw, hash1, len - strlen(raw) - 1);
|
||||
strncat(raw, ":", len - strlen(raw) - 1);
|
||||
strncat(raw, nonce, len - strlen(raw) - 1);
|
||||
strncat(raw, ":", len - strlen(raw) - 1);
|
||||
if (qop) {
|
||||
strncat(raw, nc, len - strlen(raw) - 1);
|
||||
strncat(raw, ":", len - strlen(raw) - 1);
|
||||
strncat(raw, cnonce, len - strlen(raw) - 1);
|
||||
strncat(raw, ":", len - strlen(raw) - 1);
|
||||
strncat(raw, qop, len - strlen(raw) - 1);
|
||||
strncat(raw, ":", len - strlen(raw) - 1);
|
||||
}
|
||||
strncat(raw, hash2, len - strlen(raw) - 1);
|
||||
free (hash1);
|
||||
free (hash2);
|
||||
char *result = get_md5(raw);
|
||||
|
||||
@@ -597,18 +597,16 @@ raop_handler_setup(raop_conn_t *conn,
|
||||
}
|
||||
char pin[6] = {'\0'};
|
||||
snprintf(pin, 5, "%04u", pin_4 % 10000);
|
||||
printf("*** set new pin = [%s]\n", pin);
|
||||
conn->raop->random_pw = strndup((const char *) pin, 6);
|
||||
printf("*** stored new pin = [%s]\n", conn->raop->random_pw);
|
||||
}
|
||||
if (len == -1 && conn->raop->callbacks.display_pin) {
|
||||
char *pin = conn->raop->random_pw;
|
||||
assert(pin);
|
||||
if (conn->raop->callbacks.display_pin) {
|
||||
conn->raop->callbacks.display_pin(conn->raop->callbacks.cls, pin);
|
||||
}
|
||||
logger_log(conn->raop->logger, LOGGER_INFO, "*** CLIENT MUST NOW ENTER PIN = \"%s\" AS AIRPLAY PASSWORD", pin);
|
||||
password = (const char *) pin;
|
||||
}
|
||||
if (len && !conn->authenticated) {
|
||||
if (len == -1) {
|
||||
password = (const char *) conn->raop->random_pw;
|
||||
}
|
||||
char nonce_string[33] = { '\0' };
|
||||
//bool stale = false; //not implemented
|
||||
const char *authorization = NULL;
|
||||
@@ -627,7 +625,6 @@ raop_handler_setup(raop_conn_t *conn,
|
||||
}
|
||||
}
|
||||
if (conn->authenticated && conn->raop->random_pw) {
|
||||
printf("*********free random_pw\n");
|
||||
free (conn->raop->random_pw);
|
||||
conn->raop->random_pw = NULL;
|
||||
}
|
||||
@@ -649,8 +646,8 @@ raop_handler_setup(raop_conn_t *conn,
|
||||
}
|
||||
conn->raop->nonce = utils_hex_to_string(nonce, len);
|
||||
char response_text[80] = "Digest realm=\"raop\", nonce=\"";
|
||||
strncat(response_text, conn->raop->nonce, strlen(conn->raop->nonce));
|
||||
strncat(response_text, "\"", 1);
|
||||
strncat(response_text, conn->raop->nonce, 80 - strlen(response_text) - 1);
|
||||
strncat(response_text, "\"", 80 - strlen(response_text) - 1);
|
||||
http_response_init(response, "RTSP/1.0", 401, "Unauthorized");
|
||||
http_response_add_header(response, "WWW-Authenticate", response_text);
|
||||
return;
|
||||
|
||||
@@ -1232,9 +1232,7 @@ static void parse_arguments (int argc, char *argv[]) {
|
||||
}
|
||||
} else if (arg == "-pw") {
|
||||
setup_legacy_pairing = false;
|
||||
if (!option_has_value(i, argc, arg, argv[i+1])) {
|
||||
pin_pw = 3;
|
||||
} else if (i < argc - 1 && *argv[i+1] != '-') {
|
||||
if (i < argc - 1 && *argv[i+1] != '-') {
|
||||
password.erase();
|
||||
password.append(argv[++i]);
|
||||
pin_pw = 2;
|
||||
@@ -1242,6 +1240,8 @@ static void parse_arguments (int argc, char *argv[]) {
|
||||
fprintf(stderr, "invalid client-access password \"%s\": length must be at least %u characters\n", password.c_str(), min_password_length);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
pin_pw = 3; //a random password (pin) will be displayed at each connection
|
||||
}
|
||||
} else if (arg == "-dacp") {
|
||||
dacpfile.erase();
|
||||
|
||||
Reference in New Issue
Block a user