make the private key persistent (store in %HOME/.uxplay.pem)

This commit is contained in:
F. Duncanh
2023-11-28 19:10:10 -05:00
parent c2153d2af0
commit 58eb60ea54
8 changed files with 43 additions and 16 deletions

View File

@@ -423,12 +423,12 @@ ed25519_key_t *ed25519_key_generate(const char *keyfile) {
BIO *bp;
FILE *file;
bool new_pk = false;
bool use_keyfile = strlen(keyfile);
key = calloc(1, sizeof(ed25519_key_t));
assert(key);
if (keyfile) {
if (use_keyfile) {
file = fopen(keyfile, "r");
if (file) {
bp = BIO_new_fp(file, BIO_NOCLOSE);
@@ -457,15 +457,13 @@ ed25519_key_t *ed25519_key_generate(const char *keyfile) {
handle_error(__func__);
}
EVP_PKEY_CTX_free(pctx);
if (keyfile) {
if (use_keyfile) {
file = fopen(keyfile, "w");
if (file) {
bp = BIO_new_fp(file, BIO_NOCLOSE);
PEM_write_bio_PrivateKey(bp, key->pkey, NULL, NULL, 0, NULL, NULL);
BIO_free(bp);
fclose(file);
} else {
printf("fopen failed, errno = %d\n", errno);
}
}
}

View File

@@ -83,7 +83,7 @@ int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *pl
typedef struct ed25519_key_s ed25519_key_t;
const unsigned char* ed25519_secret_key(const ed25519_key_t *key);
ed25519_key_t *ed25519_key_generate(void);
ed25519_key_t *ed25519_key_generate(const char * keyfile);
ed25519_key_t *ed25519_key_from_raw(const unsigned char data[ED25519_KEY_SIZE]);
void ed25519_key_get_raw(unsigned char data[ED25519_KEY_SIZE], const ed25519_key_t *key);
/*

View File

@@ -80,7 +80,7 @@ derive_key_internal(pairing_session_t *session, const unsigned char *salt, unsig
}
pairing_t *
pairing_init_generate()
pairing_init_generate(const char * keyfile)
{
pairing_t *pairing;
@@ -89,7 +89,7 @@ pairing_init_generate()
return NULL;
}
pairing->ed = ed25519_key_generate();
pairing->ed = ed25519_key_generate(keyfile);
return pairing;
}

View File

@@ -35,7 +35,7 @@
typedef struct pairing_s pairing_t;
typedef struct pairing_session_s pairing_session_t;
pairing_t *pairing_init_generate();
pairing_t *pairing_init_generate(const char * keyfile);
void pairing_get_public_key(pairing_t *pairing, unsigned char public_key[ED25519_KEY_SIZE]);
pairing_session_t *pairing_session_init(pairing_t *pairing);

View File

@@ -397,7 +397,7 @@ conn_destroy(void *ptr) {
}
raop_t *
raop_init(int max_clients, raop_callbacks_t *callbacks) {
raop_init(int max_clients, raop_callbacks_t *callbacks, const char* keyfile) {
raop_t *raop;
pairing_t *pairing;
httpd_t *httpd;
@@ -428,7 +428,7 @@ raop_init(int max_clients, raop_callbacks_t *callbacks) {
raop->logger = logger_init();
/* create a new public key for pairing */
pairing = pairing_init_generate();
pairing = pairing_init_generate(keyfile);
if (!pairing) {
free(raop);
return NULL;
@@ -610,6 +610,7 @@ int
raop_start(raop_t *raop, unsigned short *port) {
assert(raop);
assert(port);
logger_log(raop->logger, LOGGER_DEBUG, "using Public Key:\n%s", raop->pk_str);
return httpd_start(raop->httpd, port);
}

View File

@@ -65,7 +65,7 @@ typedef struct raop_callbacks_s raop_callbacks_t;
raop_ntp_t *raop_ntp_init(logger_t *logger, raop_callbacks_t *callbacks, const char *remote, int remote_addr_len,
unsigned short timing_rport, timing_protocol_t *time_protocol);
RAOP_API raop_t *raop_init(int max_clients, raop_callbacks_t *callbacks);
RAOP_API raop_t *raop_init(int max_clients, raop_callbacks_t *callbacks, const char* keyfile);
RAOP_API void raop_set_log_level(raop_t *raop, int level);
RAOP_API void raop_set_log_callback(raop_t *raop, raop_log_callback_t callback, void *cls);
RAOP_API int raop_set_plist(raop_t *raop, const char *plist_item, const int value);

View File

@@ -116,6 +116,8 @@ UxPlay 1.67: An open\-source AirPlay mirroring (+ audio streaming) server:
.TP
\fB\-m\fR Use random MAC address (use for concurrent UxPlay's)
.TP
\fB\-key\fI fn \fR Store private key in file fn (Default: $HOME/.uxplay.pem)
.TP
\fB\-vdmp\fR [n] Dump h264 video output to "fn.h264"; fn="videodump", change
.IP
with "-vdmp [n] filename". If [n] is given, file fn.x.h264
@@ -141,6 +143,7 @@ UxPlay 1.67: An open\-source AirPlay mirroring (+ audio streaming) server:
\fB\-h\fR Displays help information
.SH
FILES
Private key stored (for persistence) in $HOME/.uxplay.pem (can be changed)
.TP
Options in one of $UXPLAYRC, or ~/.uxplayrc, or ~/.config/uxplayrc
.TP

View File

@@ -129,6 +129,7 @@ static bool restrict_clients;
static bool setup_legacy_pairing = false;
static bool require_password = false;
static unsigned short pin = 0;
static std::string keyfile = "";
/* logging */
@@ -666,6 +667,7 @@ static void print_info (char *name) {
printf("-f {H|V|I}Horizontal|Vertical flip, or both=Inversion=rotate 180 deg\n");
printf("-r {R|L} Rotate 90 degrees Right (cw) or Left (ccw)\n");
printf("-m Use random MAC address (use for concurrent UxPlay's)\n");
printf("-key <fn> Store private key in file <fn> (default:$HOME/.uxplay.pem)\n");
printf("-vdmp [n] Dump h264 video output to \"fn.h264\"; fn=\"videodump\",change\n");
printf(" with \"-vdmp [n] filename\". If [n] is given, file fn.x.h264\n");
printf(" x=1,2,.. opens whenever a new SPS/PPS NAL arrives, and <=n\n");
@@ -1090,6 +1092,14 @@ static void parse_arguments (int argc, char *argv[]) {
}
pin = n + 10000;
}
} else if (arg == "-key") {
keyfile.erase();
if (i < argc - 1 && *argv[i+1] != '-') {
keyfile.append(argv[++i]);
} else {
fprintf(stderr, "option \"-key <fn>\" requires a path <fn> to a file for persistent key storage\n");
exit(1);
}
} else {
fprintf(stderr, "unknown option %s, stopping (for help use option \"-h\")\n",argv[i]);
exit(1);
@@ -1595,7 +1605,7 @@ int start_raop_server (unsigned short display[5], unsigned short tcp[3], unsigne
raop_cbs.display_pin = display_pin;
/* set max number of connections = 2 to protect against capture by new client */
raop = raop_init(max_connections, &raop_cbs);
raop = raop_init(max_connections, &raop_cbs, keyfile.c_str());
if (raop == NULL) {
LOGE("Error initializing raop!");
return -1;
@@ -1812,8 +1822,8 @@ int main (int argc, char *argv[]) {
if (videosink == "d3d11videosink" && use_video) {
videosink.append(" fullscreen-toggle-mode=alt-enter");
printf("d3d11videosink is being used with option fullscreen-toggle-mode=alt-enter\n"
"Use Alt-Enter key combination to toggle into/out of full-screen mode\n");
LOGI("d3d11videosink is being used with option fullscreen-toggle-mode=alt-enter\n"
"Use Alt-Enter key combination to toggle into/out of full-screen mode");
}
if (bt709_fix && use_video) {
@@ -1821,6 +1831,21 @@ int main (int argc, char *argv[]) {
video_parser.append(BT709_FIX);
}
if (require_password && keyfile == "") {
const char * homedir = get_homedir();
if (homedir) {
keyfile.erase();
keyfile = homedir;
keyfile.append("/.uxplay.pem");
} else {
LOGE("could not determine $HOME: public key wiil no be saved, and so will not be persistent");
}
}
if (keyfile != "") {
LOGI("public key storage (for persistence) is in %s", keyfile.c_str());
}
if (do_append_hostname) {
append_hostname(server_name);
}