Was this ever committed?

On Wed Dec 03 2014 at 12:13:43 PM Michal Nazarewicz <[email protected]> wrote:

> From: Michal Nazarewicz <[email protected]>
>
> Instead of storing password in MPD_HOST environment variable (which
> is passed around everywhere) allow saving password in an ~/.authinfo
> file.  This is especially useful if MPD is listening on default
> host:port, i.e. localhost:6600, in which case all one needs to do is
> to put line like
>         machine localhost port 6600 password some-password
> to make MPD clients use “some-password” when connecting to it.
> ---
>  src/fd_util.c  |  23 ++++++++++++
>  src/fd_util.h  |   8 ++++
>  src/settings.c | 117 ++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++
>  3 files changed, 148 insertions(+)
>
> diff --git a/src/fd_util.c b/src/fd_util.c
> index 09373e3..3a21ce5 100644
> --- a/src/fd_util.c
> +++ b/src/fd_util.c
> @@ -38,6 +38,8 @@
>  #include <stdbool.h>
>  #include <fcntl.h>
>  #include <errno.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
>
>  #ifdef WIN32
>  #include <winsock2.h>
> @@ -117,3 +119,24 @@ socket_cloexec_nonblock(int domain, int type, int
> protocol)
>
>         return fd;
>  }
> +
> +FILE *
> +mpd_fopen(const char *path)
> +{
> +       int fd = -1;
> +
> +#ifdef O_CLOEXEC
> +       fd = open(path, O_RDONLY | O_CLOEXEC);
> +       if (fd < 0 && errno != EINVAL)
> +               return NULL;
> +#endif
> +
> +       if (fd < 0) {
> +               fd = open(path, O_RDONLY);
> +               if (fd == -1)
> +                       return NULL;
> +               fd_set_cloexec(fd, true);
> +       }
> +
> +       return fdopen(fd, "r");
> +}
> diff --git a/src/fd_util.h b/src/fd_util.h
> index f0c13c9..858896d 100644
> --- a/src/fd_util.h
> +++ b/src/fd_util.h
> @@ -36,6 +36,8 @@
>  #ifndef FD_UTIL_H
>  #define FD_UTIL_H
>
> +#include <stdio.h>
> +
>  /**
>   * Wrapper for socket(), which sets the CLOEXEC and the NONBLOCK flag
>   * (atomically if supported by the OS).
> @@ -43,4 +45,10 @@
>  int
>  socket_cloexec_nonblock(int domain, int type, int protocol);
>
> +/**
> + * Opens FILE for reading (mode="r") setting O_CLOEXEC flag.
> + */
> +FILE *
> +mpd_fopen(const char *path);
> +
>  #endif
> diff --git a/src/settings.c b/src/settings.c
> index f153452..5a27dc7 100644
> --- a/src/settings.c
> +++ b/src/settings.c
> @@ -29,10 +29,13 @@
>  #include <mpd/settings.h>
>  #include "config.h"
>
> +#include "fd_util.h"
> +
>  #include <assert.h>
>  #include <ctype.h>
>  #include <string.h>
>  #include <stdlib.h>
> +#include <stdio.h>
>
>  #ifdef ENABLE_TCP
>  #  ifdef WIN32
> @@ -146,6 +149,115 @@ mpd_check_port(unsigned port)
>         return port;
>  }
>
> +#ifdef ENABLE_TCP
> +
> +static char *
> +mpd_parse_authinfo_line(const char *host, unsigned port, char *line)
> +{
> +       /* If port is zero (e.g. if socket is used), allow authinfo lines
> w/o
> +        * a port. */
> +       bool got_host = false, got_port = !port;
> +       char *pwd = NULL, *saveptr, *kw, *val;
> +
> +       while ((kw = strtok_r(line, " \t\n", &saveptr))) {
> +               val = strtok_r(NULL, " \t\n", &saveptr);
> +               /* Ignore line if there's a keyword w/o value. */
> +               if (!val)
> +                       return NULL;
> +               line = NULL;
> +
> +               if (!strcmp(kw, "machine")) {
> +                       /* Ignore line if hosts differ. */
> +                       if (strcmp(val, host))
> +                               return NULL;
> +                       got_host = true;
> +
> +               } else if (!strcmp(kw, "port")) {
> +                       /* Ignore line if ports differ. */
> +                       if (!port || mpd_parse_port(val) != port)
> +                               return NULL;
> +                       got_port = true;
> +
> +               } else if (!strcmp(kw, "password")) {
> +                       pwd = val;
> +
> +               } else {
> +                       /* Unknown keyword present, ignore line. */
> +                       return NULL;
> +               }
> +       }
> +
> +       return got_host && got_port ? pwd : NULL;
> +}
> +
> +static char *
> +mpd_parse_authinfo(const char *host, unsigned port, FILE *fd)
> +{
> +       char line[1024], *pwd = NULL;
> +
> +       do {
> +               if (!fgets(line, sizeof line, fd)) {
> +                       return NULL;
> +               }
> +
> +               if (!strchr(line, '\n')) {
> +                       /* Discard partial lines.  TODO: handle lines of
> +                        * arbitrary length */
> +                       while (fgets(line, sizeof line, fd) &&
> +                              !strchr(line, '\n')) { }
> +               } else {
> +                       pwd = mpd_parse_authinfo_line(host, port, line);
> +               }
> +       } while (!pwd);
> +
> +       return strdup(pwd);
> +}
> +
> +static char *
> +mpd_read_authinfo_password(const char *host, unsigned port)
> +{
> +       static const char *const filenames[] = {
> +               /* Code assumes the first entry is the longest. */
> +               ".authinfo", ".netrc"
> +       };
> +
> +       char *str = getenv("HOME");
> +       if (!str) {
> +               return NULL;
> +       }
> +
> +       size_t i = strlen(str);
> +       char *path = malloc(i + strlen(filenames[0]) + 2);
> +       memcpy(path, str, i);
> +       path[i] = '/';
> +       str = path + i + 1;
> +
> +       char *pwd = NULL;
> +       for (i = 0; !pwd && i < sizeof filenames / sizeof *filenames; ++i)
> {
> +               strcpy(str,  filenames[i]);
> +               FILE *fd = mpd_fopen(path);
> +               if (fd) {
> +                       pwd = mpd_parse_authinfo(host, port, fd);
> +                       fclose(fd);
> +               }
> +       }
> +       free(path);
> +       return pwd;
> +}
> +
> +#else
> +
> +static char *
> +mpd_read_authinfo_password(const char *host, unsigned port)
> +{
> +       host = host;
> +       port = port;
> +       return NULL;
> +}
> +
> +#endif
> +
> +
>  static unsigned
>  mpd_default_timeout_ms(void)
>  {
> @@ -199,6 +311,11 @@ mpd_settings_new(const char *host, unsigned port,
> unsigned timeout_ms,
>                 ? 0 /* no port for local socket */
>                 : (port != 0 ? port : DEFAULT_PORT);
>
> +       if (settings->host && !settings->password) {
> +               settings->password = mpd_read_authinfo_password(
> +                       settings->host, settings->port);
> +       }
> +
>         return settings;
>  }
>
> --
> 2.2.0.rc0.207.ga3a616c
>
> _______________________________________________
> mpd-devel mailing list
> [email protected]
> http://mailman.blarg.de/listinfo/mpd-devel
>
_______________________________________________
mpd-devel mailing list
[email protected]
http://mailman.blarg.de/listinfo/mpd-devel

Reply via email to