]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 'refs/heads/t/wma_improvements'
authorAndre Noll <maan@tuebingen.mpg.de>
Fri, 21 Apr 2017 15:07:00 +0000 (17:07 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Fri, 21 Apr 2017 15:09:17 +0000 (17:09 +0200)
A couple of simple patches which simplify the WMA code and improve
readability.

Cooking for three weeks.

* refs/heads/t/wma_improvements:
  wmadec: Use read_u32_be().
  wma_afh.c: Remove condition which is always true.
  imdct.c: Replace pointless macro PASS.
  wma_common.c: Remove pointless assignment.
  wma_afh.c: Use DIV_ROUND_UP().

28 files changed:
INSTALL
Makefile.in
Makefile.real
NEWS.md
afs.c
audiod.c
autogen.sh
client_common.c
command.c
configure.ac
crypt.c
crypt.h
crypt_backend.h
crypt_common.c
error.h
gcrypt.c
interactive.c
m4/gengetopt/osx_write.m4 [deleted file]
net.c
net.h
osx_write.c [deleted file]
t/makefile.test
time.c
user_list.c
web/about.in.html
web/download.in.html
web/manual.md
write.c

diff --git a/INSTALL b/INSTALL
index 85b4fab1ff04219e136ea00fe6cfb2d1a5ea97ab..547036b104d03759d79626e6ac3b686b165b88c0 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -16,10 +16,8 @@ Installing paraslash from git
 
 Example for cross-compiling
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-       export CROSS_COMPILE='armv6j-hardfloat-linux-gnueabi-'
+       export CC='armv6j-hardfloat-linux-gnueabi-gcc'
        export PATH="/usr/cross/arm/bin:$PATH"
-       export CC=${CROSS_COMPILE}gcc
-
        export LDFLAGS='
                -L/usr/sysroot/arm/lib
                -L/usr/sysroot/arm/usr/lib
@@ -29,7 +27,7 @@ Example for cross-compiling
        autoconf
        autoheader
        ./configure --host=arm-linux-gnueabi --prefix /usr/sysroot/arm/usr/local
-       make CROSS_COMPILE=$CROSS_COMPILE
+       make
 
 For details see the user manual:
 
index ec55c8e388a78a4fb88164aa0030320738e62c6e..6e84b6fd291b5111f2c0aef473b7d05f10950f5f 100644 (file)
@@ -8,7 +8,6 @@ datarootdir := @datarootdir@
 PACKAGE_TARNAME := @PACKAGE_TARNAME@
 PACKAGE_VERSION := @PACKAGE_VERSION@
 
-INSTALL := @INSTALL@
 M4 := @M4@
 GENGETOPT := @GENGETOPT@
 HELP2MAN := @HELP2MAN@
@@ -52,7 +51,6 @@ alsa_cppflags := @alsa_cppflags@
 oss_cppflags := @oss_cppflags@
 mp4v2_cppflags := @mp4v2_cppflags@
 
-clock_gettime_ldflags := @clock_gettime_ldflags@
 id3tag_ldflags := @id3tag_ldflags@
 ogg_ldflags := @ogg_ldflags@
 vorbis_ldflags := @vorbis_ldflags@
@@ -69,7 +67,6 @@ readline_ldflags := @readline_ldflags@
 samplerate_ldflags := @samplerate_ldflags@
 osl_ldflags := @osl_ldflags@
 curses_ldflags := @curses_ldflags@
-core_audio_ldflags := @core_audio_ldflags@
 crypto_ldflags := @crypto_ldflags@
 iconv_ldflags := @iconv_ldflags@
 mp4v2_ldflags := @mp4v2_ldflags@
index 8ededf6aff8300608a5939429779ecd7b1753626..5e4dbe68c0308bf1b385c84e94d808d4f740b625 100644 (file)
@@ -9,7 +9,6 @@ endif
 
 vardir := /var/paraslash
 mandir := $(datarootdir)/man/man1
-STRIP := $(CROSS_COMPILE)strip
 MKDIR_P := mkdir -p
 prefixed_executables := $(addprefix para_, $(executables))
 
@@ -63,10 +62,11 @@ tarball_pfx := $(PACKAGE_TARNAME)-$(GIT_VERSION)
 tarball_delete := $(addprefix $(tarball_pfx)/, web .gitignore)
 tarball := $(tarball_pfx).tar.bz2
 
-.PHONY: all clean clean2 distclean maintainer-clean install man tarball
 all: $(prefixed_executables) $(man_pages)
+.PHONY: all mostlyclean clean distclean maintainer-clean install \
+       install-strip man dist tarball
+
 man: $(man_pages)
-tarball: $(tarball)
 
 include $(m4_ggo_dir)/makefile
 include $(test_dir)/makefile.test
@@ -113,8 +113,6 @@ STRICT_CFLAGS += -Wformat -Wformat-security
 STRICT_CFLAGS += -Wmissing-format-attribute
 STRICT_CFLAGS += -Wdeclaration-after-statement
 
-LDFLAGS += $(clock_gettime_ldflags)
-
 ifeq ($(uname_s),Linux)
        # these cause warnings on *BSD
        CPPFLAGS += -Wunused-macros
@@ -282,7 +280,7 @@ $(dep_dir)/%.d: %.c | $(dep_dir)
 
 para_recv para_afh para_play para_server: LDFLAGS += $(id3tag_ldflags)
 para_write para_play para_audiod \
-: LDFLAGS += $(ao_ldflags) $(pthread_ldflags) $(core_audio_ldflags)
+: LDFLAGS += $(ao_ldflags) $(pthread_ldflags)
 para_client para_audioc para_play : LDFLAGS += $(readline_ldflags)
 para_server: LDFLAGS += $(osl_ldflags)
 para_gui: LDFLAGS += $(curses_ldflags)
@@ -337,31 +335,36 @@ $(prefixed_executables):
        @[ -z "$(Q)" ] || echo 'LD $@'
        $(Q) $(CC) $^ -o $@ $(LDFLAGS)
 
-clean:
-       @[ -z "$(Q)" ] || echo 'CLEAN'
+mostlyclean:
+       @[ -z "$(Q)" ] || echo 'MOSTLYCLEAN'
        $(Q) rm -f para_*
        $(Q) rm -rf $(object_dir)
-
-clean2: clean
-       @[ -z "$(Q)" ] || echo 'CLEAN2'
+clean: mostlyclean
+       @[ -z "$(Q)" ] || echo 'CLEAN'
        $(Q) rm -rf $(build_dir)
-distclean: clean2 test-clean
+distclean: clean
        @[ -z "$(Q)" ] || echo 'DISTCLEAN'
        $(Q) rm -f Makefile autoscan.log config.status config.log
-       $(Q) rm -f GPATH GRTAGS GSYMS GTAGS
-
+       $(Q) rm -f config.h configure config.h.in
 maintainer-clean: distclean
        @[ -z "$(Q)" ] || echo 'MAINTAINER-CLEAN'
-       $(Q) rm -f *.tar.bz2 config.h configure config.h.in
+       $(Q) rm -f *.tar.bz2
+       $(Q) rm -f GPATH GRTAGS GSYMS GTAGS
+
+INSTALL ?= install
+INSTALL_PROGRAM ?= $(INSTALL)
+INSTALL_DATA ?= $(INSTALL) -m 644
+ifneq ($(findstring strip, $(MAKECMDGOALS)),)
+       strip_option := -s
+endif
 
-install: all man
-       $(MKDIR_P) $(bindir) $(mandir)
-       $(INSTALL) -s --strip-program $(STRIP) -m 755 \
-               $(prefixed_executables) $(bindir)
-       $(INSTALL) -m 644 $(man_pages) $(mandir)
-       $(MKDIR_P) $(vardir) >/dev/null 2>&1 || true # not fatal, so don't complain
+install install-strip: all man
+       $(MKDIR_P) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)
+       $(INSTALL) $(strip_option) $(prefixed_executables) $(DESTDIR)$(bindir)
+       $(INSTALL_DATA) $(man_pages) $(DESTDIR)$(mandir)
+       $(MKDIR_P) $(DESTDIR)$(vardir) >/dev/null 2>&1 || true # not fatal, so don't complain
 
-$(tarball):
+$(tarball) dist tarball:
        $(Q) rm -rf $(tarball) $(tarball_pfx)
        $(Q) git archive --format=tar --prefix=$(tarball_pfx)/ HEAD \
                | tar --delete $(tarball_delete) > $(tarball_pfx).tar
diff --git a/NEWS.md b/NEWS.md
index 2056f90c06716f40f67fa43d477e63787e780ddb..df1a80e352c19edd24dba2683aff1f5c4fd4db5d 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,6 +1,35 @@
 NEWS
 ====
 
+------------------------------------
+0.6.0 (to be announced) "fuzzy flux"
+------------------------------------
+- Support for Mac OS X has been removed.
+- On Linux systems, glibc-2.17 or newer is required to build the
+  source tree.
+- Support for RSA public keys in ASN format (as generated by openssl
+  genrsa) has been removed. These keys have been deprecated since
+  2011, so users should have long switched to keys generated with
+  ssh-keygen(1).
+- If libgcrypt is used as the crypto library, we now require version
+  1.5.0 (released in 2011) or later.
+- The insecure RC4 stream cipher has been removed. It was superseded
+  by aes_ctr128 three years ago but the RC4 code had been kept for
+  backwards compatibility.
+- On Linux, abstract unix domain sockets are used unconditionally.
+- The "install" target no longer strips executables, the new
+  install-strip target can be used to get the old behaviour.
+- The clean targets have been renamed: clean2 is gone, and the new
+  mostlyclean removes only the executables and object files.
+- New target: check (identical to test).
+- The DESTDIR make variable is honored to prepend a path to the
+  installation directory. This feature is orthogonal to the --prefix
+  option to configure.
+- Minor WMA cleanups.
+
+Downloads:
+[tarball](./releases/paraslash-git.tar.bz2),
+
 -------------------------------------
 0.5.7 (2016-12-31) "semantic density"
 -------------------------------------
diff --git a/afs.c b/afs.c
index 0946b6df3b0766f82f95f0cd100f039753543350..7f27b7dd2653d79a0a7679da3e80d2d9c55e37ac 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -649,15 +649,10 @@ static int setup_command_socket_or_die(void)
        char *socket_name = conf.afs_socket_arg;
 
        unlink(socket_name);
-       ret = create_local_socket(socket_name, 0);
+       ret = create_local_socket(socket_name);
        if (ret < 0) {
-               ret = create_local_socket(socket_name,
-                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IROTH);
-               if (ret < 0) {
-                       PARA_EMERG_LOG("%s: %s\n", para_strerror(-ret),
-                               socket_name);
-                       exit(EXIT_FAILURE);
-               }
+               PARA_EMERG_LOG("%s: %s\n", para_strerror(-ret), socket_name);
+               exit(EXIT_FAILURE);
        }
        socket_fd = ret;
        PARA_INFO_LOG("listening on socket %s (fd %d)\n", socket_name,
index db69cf141a3833a5227c12ccba3f81a9e357e3b3..254bcb8d8c4bac2947e52c3310fb7051fe5f1153 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -183,22 +183,9 @@ static uid_t *uid_whitelist;
  */
 static struct status_task *stat_task = &status_task_struct;
 
-/*
- * The task for handling audiod commands.
- *
- * We need two listening sockets for backward compability: on Linux systems
- * fd[0] is an abstract socket (more precisely, a socket bound to an address in
- * the abstract namespace), and fd[1] is the usual pathname socket. On other
- * systems, fd[0] is negative, and only the pathname socket is used.
- *
- * For 0.5.x we accept connections on both sockets to make sure that old
- * para_audioc versions can still connect. New versions use only the abstract
- * socket. Hence after v0.6.0 we can go back to a single socket, either an
- * abstract one (Linux) or a pathname socket (all other systems).
- */
 struct command_task {
-       /** The local listening sockets. */
-       int fd[2];
+       /** The local listening socket. */
+       int fd;
        /** the associated task structure */
        struct task *task;
 };
@@ -1059,7 +1046,7 @@ static int parse_stream_args(void)
 }
 
 /* does not unlink socket on errors */
-static void init_local_sockets(struct command_task *ct)
+static void init_local_socket(struct command_task *ct)
 {
        if (conf.socket_given)
                socket_name = para_strdup(conf.socket_arg);
@@ -1072,12 +1059,10 @@ static void init_local_sockets(struct command_task *ct)
        PARA_NOTICE_LOG("local socket: %s\n", socket_name);
        if (conf.force_given)
                unlink(socket_name);
-       ct->fd[0] = create_local_socket(socket_name, 0);
-       ct->fd[1] = create_local_socket(socket_name,
-               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
-       if (ct->fd[0] >= 0 || ct->fd[1] >= 0)
+       ct->fd = create_local_socket(socket_name);
+       if (ct->fd >= 0)
                return;
-       PARA_EMERG_LOG("%s\n", para_strerror(-ct->fd[1]));
+       PARA_EMERG_LOG("%s\n", para_strerror(-ct->fd));
        exit(EXIT_FAILURE);
 }
 
@@ -1104,16 +1089,12 @@ static int signal_post_select(struct sched *s, void *context)
 static void command_pre_select(struct sched *s, void *context)
 {
        struct command_task *ct = context;
-       int i;
-
-       for (i = 0; i < 2; i++)
-               if (ct->fd[i] >= 0)
-                       para_fd_set(ct->fd[i], &s->rfds, &s->max_fileno);
+       para_fd_set(ct->fd, &s->rfds, &s->max_fileno);
 }
 
 static int command_post_select(struct sched *s, void *context)
 {
-       int ret, i;
+       int ret;
        struct command_task *ct = context;
        static struct timeval last_status_dump;
        struct timeval tmp, delay;
@@ -1122,19 +1103,15 @@ static int command_post_select(struct sched *s, void *context)
        ret = task_get_notification(ct->task);
        if (ret < 0)
                return ret;
-       for (i = 0; i < 2; i++) {
-               if (ct->fd[i] < 0)
-                       continue;
-               ret = handle_connect(ct->fd[i], &s->rfds);
-               if (ret < 0) {
-                       PARA_ERROR_LOG("%s\n", para_strerror(-ret));
-                       if (ret == -E_AUDIOD_TERM) {
-                               task_notify_all(s, -ret);
-                               return ret;
-                       }
-               } else if (ret > 0)
-                       force = true;
-       }
+       ret = handle_connect(ct->fd, &s->rfds);
+       if (ret < 0) {
+               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+               if (ret == -E_AUDIOD_TERM) {
+                       task_notify_all(s, -ret);
+                       return ret;
+               }
+       } else if (ret > 0)
+               force = true;
        if (force == true)
                goto dump;
 
@@ -1162,7 +1139,7 @@ dump:
 
 static void init_command_task(struct command_task *ct)
 {
-       init_local_sockets(ct); /* doesn't return on errors */
+       init_local_socket(ct); /* doesn't return on errors */
 
        ct->task = task_register(&(struct task_info) {
                .name = "command",
index d432adbb64aa08a74e4dab7bd21360ebb2ef4227..708602e7e04c073ff510be8584235fe198ac128e 100755 (executable)
@@ -24,5 +24,5 @@ autoheader
 echo configuring...
 ./configure $@ > /dev/null
 echo compiling...
-make clean2 > /dev/null 2>&1
+make clean > /dev/null 2>&1
 make -j $n > /dev/null
index eea7510fd0589e86fb4058dd7f4361f3c79901aa..ac53b9b547642ceb3e99c4ac47c91068405dec15 100644 (file)
@@ -241,11 +241,6 @@ out:
        return ret;
 }
 
-static bool has_feature(const char *feature, struct client_task *ct)
-{
-       return find_arg(feature, ct->features) >= 0? true : false;
-}
-
 static int send_sb_command(struct client_task *ct)
 {
        int i;
@@ -297,8 +292,8 @@ static int client_post_select(struct sched *s, void *context)
        case CL_RECEIVED_WELCOME: /* send auth command */
                if (!FD_ISSET(ct->scc.fd, &s->wfds))
                        return 0;
-               sprintf(buf, AUTH_REQUEST_MSG "%s sideband%s", ct->user,
-                       has_feature("aes_ctr128", ct)? ",aes_ctr128" : "");
+               sprintf(buf, AUTH_REQUEST_MSG "%s sideband,aes_ctr128",
+                       ct->user);
                PARA_INFO_LOG("--> %s\n", buf);
                ret = write_buffer(ct->scc.fd, buf);
                if (ret < 0)
@@ -314,7 +309,6 @@ static int client_post_select(struct sched *s, void *context)
                /* decrypted challenge/session key buffer */
                unsigned char crypt_buf[1024];
                struct sb_buffer sbb;
-               bool use_aes;
 
                ret = recv_sb(ct, &s->rfds, &sbb);
                if (ret <= 0)
@@ -333,10 +327,9 @@ static int client_post_select(struct sched *s, void *context)
                        goto out;
                ct->challenge_hash = para_malloc(HASH_SIZE);
                hash_function((char *)crypt_buf, CHALLENGE_SIZE, ct->challenge_hash);
-               use_aes = has_feature("aes_ctr128", ct);
-               ct->scc.send = sc_new(crypt_buf + CHALLENGE_SIZE, SESSION_KEY_LEN, use_aes);
+               ct->scc.send = sc_new(crypt_buf + CHALLENGE_SIZE, SESSION_KEY_LEN);
                ct->scc.recv = sc_new(crypt_buf + CHALLENGE_SIZE + SESSION_KEY_LEN,
-                       SESSION_KEY_LEN, use_aes);
+                       SESSION_KEY_LEN);
                hash_to_asc(ct->challenge_hash, buf);
                PARA_INFO_LOG("--> %s\n", buf);
                ct->status = CL_RECEIVED_CHALLENGE;
index fe4b92329b417009613e0f1034f747783699c2e0..58441b02495cef4465da6c675541b9feb64fce65 100644 (file)
--- a/command.c
+++ b/command.c
@@ -807,7 +807,7 @@ static void reset_signals(void)
 }
 
 struct connection_features {
-       bool aes_ctr128_requested;
+       int dummy; /* none at the moment */
 };
 
 static int parse_auth_request(char *buf, int len, struct user **u,
@@ -836,7 +836,7 @@ static int parse_auth_request(char *buf, int len, struct user **u,
                        if (strcmp(features[i], "sideband") == 0)
                                continue;
                        if (strcmp(features[i], "aes_ctr128") == 0)
-                               cf->aes_ctr128_requested = true;
+                               continue;
                        else {
                                ret = -E_BAD_FEATURE;
                                goto out;
@@ -994,10 +994,9 @@ __noreturn void handle_connect(int fd, const char *peername)
        alarm(0);
        PARA_INFO_LOG("good auth for %s\n", cc->u->name);
        /* init stream cipher keys with the second part of the random buffer */
-       cc->scc.recv = sc_new(rand_buf + CHALLENGE_SIZE, SESSION_KEY_LEN,
-               cf.aes_ctr128_requested);
+       cc->scc.recv = sc_new(rand_buf + CHALLENGE_SIZE, SESSION_KEY_LEN);
        cc->scc.send = sc_new(rand_buf + CHALLENGE_SIZE + SESSION_KEY_LEN,
-               SESSION_KEY_LEN, cf.aes_ctr128_requested);
+               SESSION_KEY_LEN);
        ret = send_sb(&cc->scc, NULL, 0, SBD_PROCEED, false);
        if (ret < 0)
                goto net_err;
index 0b00cc2af9f006d492975a54210ce26f4e5aa56e..eed441d639a115b6d78d5f9b4934eaff2d4fc107 100644 (file)
@@ -63,27 +63,10 @@ AC_PATH_PROG([HELP2MAN], [help2man])
 test -z "$HELP2MAN" && AC_MSG_ERROR(
        [help2man is required to build this package])
 
-AC_PATH_PROG([INSTALL], [install])
-test -z "$INSTALL" && AC_MSG_ERROR(
-       [The install program is required to build this package])
-
 AC_PROG_CC
 AC_PROG_CPP
 
 executables="recv filter audioc write afh play"
-################################################################## clock_gettime
-clock_gettime_lib=
-AC_CHECK_LIB([c], [clock_gettime], [clock_gettime_lib=c], [
-       AC_CHECK_LIB([rt], [clock_gettime], [clock_gettime_lib=rt], [], [])
-])
-if test -n "$clock_gettime_lib"; then
-       AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [
-               define to 1 if clock_gettime() is supported])
-fi
-if test "$clock_gettime_lib" = "rt"; then
-       AC_SUBST(clock_gettime_ldflags, -lrt)
-fi
-
 ########################################################################### osl
 STASH_FLAGS
 LIB_ARG_WITH([osl], [-losl])
@@ -213,24 +196,6 @@ AC_MSG_RESULT($have_ip_mreqn)
 if test ${have_ip_mreqn} = yes; then
        AC_DEFINE(HAVE_IP_MREQN, 1, define to 1 you have struct ip_mreqn)
 fi
-########################################################################### osx
-
-AC_MSG_CHECKING(for CoreAudio (MacOs))
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-       #include <CoreAudio/CoreAudio.h>
-]], [[
-       AudioDeviceID id;
-]])],[have_core_audio=yes],[have_core_audio=no])
-AC_MSG_RESULT($have_core_audio)
-if test ${have_core_audio} = yes; then
-       f1="-framework CoreAudio"
-       f2="-framework AudioToolbox"
-       f3="-framework AudioUnit"
-       f4="-framework CoreServices"
-       core_audio_ldflags="$f1 $f2 $f3 $f4"
-       AC_SUBST(core_audio_ldflags)
-       AC_DEFINE(HAVE_CORE_AUDIO, 1, define to 1 on Mac Os X)
-fi
 ########################################################################### ogg
 STASH_FLAGS
 LIB_ARG_WITH([ogg], [-logg])
@@ -544,10 +509,6 @@ if test -n "$CRYPTOLIB"; then
        else
                audiod_errlist_objs="$audiod_errlist_objs gcrypt"
        fi
-       if test "$have_core_audio" = "yes"; then
-               audiod_errlist_objs="$audiod_errlist_objs osx_write ipc"
-               audiod_cmdline_objs="$audiod_cmdline_objs osx_write"
-       fi
        NEED_VORBIS_OBJECTS && {
                audiod_errlist_objs="$audiod_errlist_objs oggdec_filter"
                audiod_audio_formats="$audiod_audio_formats ogg"
@@ -880,10 +841,6 @@ play_cmdline_objs="
        play
        sync_filter
 "
-if test "$have_core_audio" = "yes"; then
-       play_errlist_objs="$play_errlist_objs osx_write ipc"
-       play_cmdline_objs="$play_cmdline_objs osx_write"
-fi
 NEED_OGG_OBJECTS && play_errlist_objs="$play_errlist_objs ogg_afh_common"
 NEED_VORBIS_OBJECTS && {
        play_errlist_objs="$play_errlist_objs oggdec_filter ogg_afh"
@@ -957,12 +914,6 @@ write_errlist_objs="
 writers="file"
 default_writer="FILE_WRITE"
 
-if test "$have_core_audio" = "yes"; then
-       write_errlist_objs="$write_errlist_objs osx_write ipc"
-       write_cmdline_objs="$write_cmdline_objs osx_write"
-       writers="$writers osx"
-       default_writer="OSX_WRITE"
-fi
 NEED_AO_OBJECTS && {
        write_errlist_objs="$write_errlist_objs ao_write"
        write_cmdline_objs="$write_cmdline_objs ao_write"
diff --git a/crypt.c b/crypt.c
index 8116fb6eeacdbeaa0f1f22d14cfcc3726ee3bbbf..f1e42d4a228f7c0c498ac505575b6a0f3667bf27 100644 (file)
--- a/crypt.c
+++ b/crypt.c
@@ -11,7 +11,6 @@
 #include <sys/socket.h>
 #include <openssl/rand.h>
 #include <openssl/err.h>
-#include <openssl/rc4.h>
 #include <openssl/pem.h>
 #include <openssl/sha.h>
 #include <openssl/bn.h>
@@ -61,41 +60,24 @@ void init_random_seed_or_die(void)
        srandom(seed);
 }
 
-static EVP_PKEY *load_key(const char *file, int private)
+static int get_private_key(const char *path, RSA **rsa)
 {
-       BIO *key;
-       EVP_PKEY *pkey = NULL;
-       int ret = check_key_file(file, private);
-
-       if (ret < 0) {
-               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
-               return NULL;
-       }
-       key = BIO_new(BIO_s_file());
-       if (!key)
-               return NULL;
-       if (BIO_read_filename(key, file) > 0) {
-               if (private == LOAD_PRIVATE_KEY)
-                       pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);
-               else
-                       pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
-       }
-       BIO_free(key);
-       return pkey;
-}
-
-static int get_openssl_key(const char *key_file, RSA **rsa, int private)
-{
-       EVP_PKEY *key = load_key(key_file, private);
-
-       if (!key)
-               return (private == LOAD_PRIVATE_KEY)? -E_PRIVATE_KEY
-                       : -E_PUBLIC_KEY;
-       *rsa = EVP_PKEY_get1_RSA(key);
-       EVP_PKEY_free(key);
-       if (!*rsa)
-               return -E_RSA;
-       return RSA_size(*rsa);
+       EVP_PKEY *pkey;
+       BIO *bio = BIO_new(BIO_s_file());
+
+       *rsa = NULL;
+       if (!bio)
+               return -E_PRIVATE_KEY;
+       if (BIO_read_filename(bio, path) <= 0)
+               goto bio_free;
+       pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
+       if (!pkey)
+               goto bio_free;
+       *rsa = EVP_PKEY_get1_RSA(pkey);
+       EVP_PKEY_free(pkey);
+bio_free:
+       BIO_free(bio);
+       return *rsa? RSA_size(*rsa) : -E_PRIVATE_KEY;
 }
 
 /*
@@ -160,8 +142,7 @@ fail:
        return ret;
 }
 
-int get_asymmetric_key(const char *key_file, int private,
-               struct asymmetric_key **result)
+int get_public_key(const char *key_file, struct asymmetric_key **result)
 {
        struct asymmetric_key *key = NULL;
        void *map = NULL;
@@ -171,21 +152,13 @@ int get_asymmetric_key(const char *key_file, int private,
        char *cp;
 
        key = para_malloc(sizeof(*key));
-       if (private) {
-               ret = get_openssl_key(key_file, &key->rsa, LOAD_PRIVATE_KEY);
-               goto out;
-       }
        ret = mmap_full_file(key_file, O_RDONLY, &map, &map_size, NULL);
        if (ret < 0)
                goto out;
        ret = is_ssh_rsa_key(map, map_size);
        if (!ret) {
-               ret = para_munmap(map, map_size);
-               map = NULL;
-               if (ret < 0)
-                       goto out;
-               ret = get_openssl_key(key_file, &key->rsa, LOAD_PUBLIC_KEY);
-               goto out;
+               para_munmap(map, map_size);
+               return -E_SSH_PARSE;
        }
        cp = map + ret;
        encoded_size = map_size - ret;
@@ -215,7 +188,7 @@ out:
        return ret;
 }
 
-void free_asymmetric_key(struct asymmetric_key *key)
+void free_public_key(struct asymmetric_key *key)
 {
        if (!key)
                return;
@@ -229,11 +202,17 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf,
        struct asymmetric_key *priv;
        int ret;
 
+       ret = check_private_key_file(key_file);
+       if (ret < 0)
+               return ret;
        if (inlen < 0)
                return -E_RSA;
-       ret = get_asymmetric_key(key_file, LOAD_PRIVATE_KEY, &priv);
-       if (ret < 0)
+       priv = para_malloc(sizeof(*priv));
+       ret = get_private_key(key_file, &priv->rsa);
+       if (ret < 0) {
+               free(priv);
                return ret;
+       }
        /*
         * RSA is vulnerable to timing attacks. Generate a random blinding
         * factor to protect against this kind of attack.
@@ -247,7 +226,8 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf,
        if (ret <= 0)
                ret = -E_DECRYPT;
 out:
-       free_asymmetric_key(priv);
+       RSA_free(priv->rsa);
+       free(priv);
        return ret;
 }
 
@@ -264,26 +244,16 @@ int pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf,
 }
 
 struct stream_cipher {
-       bool use_aes;
-       union {
-               RC4_KEY rc4_key;
-               EVP_CIPHER_CTX *aes;
-       } context;
+       EVP_CIPHER_CTX *aes;
 };
 
-struct stream_cipher *sc_new(const unsigned char *data, int len,
-               bool use_aes)
+struct stream_cipher *sc_new(const unsigned char *data, int len)
 {
        struct stream_cipher *sc = para_malloc(sizeof(*sc));
 
-       sc->use_aes = use_aes;
-       if (!use_aes) {
-               RC4_set_key(&sc->context.rc4_key, len, data);
-               return sc;
-       }
        assert(len >= 2 * AES_CRT128_BLOCK_SIZE);
-       sc->context.aes = EVP_CIPHER_CTX_new();
-       EVP_EncryptInit_ex(sc->context.aes, EVP_aes_128_ctr(), NULL, data,
+       sc->aes = EVP_CIPHER_CTX_new();
+       EVP_EncryptInit_ex(sc->aes, EVP_aes_128_ctr(), NULL, data,
                data + AES_CRT128_BLOCK_SIZE);
        return sc;
 }
@@ -292,40 +262,10 @@ void sc_free(struct stream_cipher *sc)
 {
        if (!sc)
                return;
-       EVP_CIPHER_CTX_free(sc->context.aes);
+       EVP_CIPHER_CTX_free(sc->aes);
        free(sc);
 }
 
-/**
- * The RC4() implementation of openssl apparently reads and writes data in
- * blocks of 8 bytes. So we have to make sure our buffer sizes are a multiple
- * of this.
- */
-#define RC4_ALIGN 8
-
-static void rc4_crypt(RC4_KEY *key, struct iovec *src, struct iovec *dst)
-{
-       size_t len = src->iov_len, l1, l2;
-
-       assert(len > 0);
-       assert(len < ((typeof(src->iov_len))-1) / 2);
-       l1 = ROUND_DOWN(len, RC4_ALIGN);
-       l2 = ROUND_UP(len, RC4_ALIGN);
-
-       *dst = (typeof(*dst)) {
-               /* Add one for the terminating zero byte. */
-               .iov_base = para_malloc(l2 + 1),
-               .iov_len = len
-       };
-       RC4(key, l1, src->iov_base, dst->iov_base);
-       if (len > l1) {
-               unsigned char remainder[RC4_ALIGN] = "";
-               memcpy(remainder, src->iov_base + l1, len - l1);
-               RC4(key, len - l1, remainder, dst->iov_base + l1);
-       }
-       ((char *)dst->iov_base)[len] = '\0';
-}
-
 static void aes_ctr128_crypt(EVP_CIPHER_CTX *ctx, struct iovec *src,
                struct iovec *dst)
 {
@@ -347,9 +287,7 @@ static void aes_ctr128_crypt(EVP_CIPHER_CTX *ctx, struct iovec *src,
 
 void sc_crypt(struct stream_cipher *sc, struct iovec *src, struct iovec *dst)
 {
-       if (sc->use_aes)
-               return aes_ctr128_crypt(sc->context.aes, src, dst);
-       return rc4_crypt(&sc->context.rc4_key, src, dst);
+       return aes_ctr128_crypt(sc->aes, src, dst);
 }
 
 void hash_function(const char *data, unsigned long len, unsigned char *hash)
diff --git a/crypt.h b/crypt.h
index 9be7a23e6da4d6d1796d4d98da7d8280152c6c2a..5e25748c09551bf1b33e7b142baaafd73df5bd36 100644 (file)
--- a/crypt.h
+++ b/crypt.h
@@ -51,22 +51,21 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf,
  * Read an asymmetric key from a file.
  *
  * \param key_file The file containing the key.
- * \param private if non-zero, read the private key, otherwise the public key.
  * \param result The key structure is returned here.
  *
  * \return The size of the key on success, negative on errors.
  */
-int get_asymmetric_key(const char *key_file, int private,
-               struct asymmetric_key **result);
+int get_public_key(const char *key_file, struct asymmetric_key **result);
 
 /**
- * Deallocate an asymmetric key structure.
+ * Deallocate a public key.
  *
  * \param key Pointer to the key structure to free.
  *
- * This must be called for any key obtained by get_asymmetric_key().
+ * This should be called for keys obtained by get_public_key() if the key is no
+ * longer needed.
  */
-void free_asymmetric_key(struct asymmetric_key *key);
+void free_public_key(struct asymmetric_key *key);
 
 
 /**
@@ -119,16 +118,14 @@ struct stream_cipher_context {
 };
 
 /**
- * Allocate and initialize a stream cipher structure.
+ * Allocate and initialize an aes_ctr128 stream cipher structure.
  *
  * \param data The key.
  * \param len The size of the key.
- * \param use_aes True: Use the aes_ctr128 stream cipher, false: Use RC4.
  *
  * \return A new stream cipher structure.
  */
-struct stream_cipher *sc_new(const unsigned char *data, int len,
-               bool use_aes);
+struct stream_cipher *sc_new(const unsigned char *data, int len);
 
 /**
  * Encrypt or decrypt a buffer using a stream cipher.
index f9a69d9490057382126e4efe04a15bfda9025419..fccdd2efbda6da1f8dac7a3a4731885e4e8f7290 100644 (file)
@@ -14,4 +14,4 @@
 size_t is_ssh_rsa_key(char *data, size_t size);
 uint32_t read_ssh_u32(const void *vp);
 int check_ssh_key_header(const unsigned char *blob, int blen);
-int check_key_file(const char *file, bool private_key);
+int check_private_key_file(const char *file);
index a05572df85b1de5fb5e1043abfc34c66e26c65e7..1fd8189ca3c5a201bd2d227bb366bd800757a5a5 100644 (file)
@@ -103,25 +103,22 @@ int check_ssh_key_header(const unsigned char *blob, int blen)
 }
 
 /**
- * Check existence and permissions of a key file.
+ * Check existence and permissions of a private key file.
  *
  * \param file The path of the key file.
- * \param private_key Whether this is a private key.
  *
- * This checks whether the file exists. If it is a private key, we additionally
- * check that the permissions are restrictive enough. It is considered an error
- * if we own the file and it is readable for others.
+ * This checks whether the file exists and its permissions are restrictive
+ * enough. It is considered an error if we own the file and it is readable for
+ * others.
  *
  * \return Standard.
  */
-int check_key_file(const char *file, bool private_key)
+int check_private_key_file(const char *file)
 {
        struct stat st;
 
        if (stat(file, &st) != 0)
                return -ERRNO_TO_PARA_ERROR(errno);
-       if (!private_key)
-               return 0;
        if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0)
                return -E_KEY_PERM;
        return 1;
diff --git a/error.h b/error.h
index 899c574b315cd9e8ee7356eb29c1828e1dd6ae04..fad417297df865267937ea48e8ba2f217cbfe652 100644 (file)
--- a/error.h
+++ b/error.h
@@ -12,7 +12,6 @@
        PARA_ERROR(AACDEC_INIT, "failed to init aac decoder"), \
        PARA_ERROR(AAC_DECODE, "aac decode error"), \
        PARA_ERROR(ACL_PERM, "access denied by acl"), \
-       PARA_ERROR(ADD_CALLBACK, "can not add callback"), \
        PARA_ERROR(ADDRESS_LOOKUP, "can not resolve requested address"),\
        PARA_ERROR(AFH_RECV_BAD_FILENAME, "no file name given"), \
        PARA_ERROR(AFS_SHORT_READ, "short read from afs socket"), \
@@ -88,7 +87,6 @@
        PARA_ERROR(CREATE_OPUS_DECODER, "could not create opus decoder"), \
        PARA_ERROR(DCCP_OVERRUN, "dccp output buffer buffer overrun"), \
        PARA_ERROR(DECRYPT, "decrypt error"), \
-       PARA_ERROR(DEFAULT_COMP, "can not find default audio output component"), \
        PARA_ERROR(DUMMY_ROW, "attempted to access blob dummy object"), \
        PARA_ERROR(DUP_PIPE, "exec error: can not create pipe"), \
        PARA_ERROR(EMPTY, "file is empty"), \
        PARA_ERROR(MP3_INFO, "could not read mp3 info"), \
        PARA_ERROR(MP4ASC, "audio spec config error"), \
        PARA_ERROR(MP4V2, "mp4v2 library error"), \
-       PARA_ERROR(MPI_PRINT, "could not convert multi-precision integer"), \
        PARA_ERROR(MPI_SCAN, "could not scan multi-precision integer"), \
        PARA_ERROR(NAME_TOO_LONG, "name too long for struct sockaddr_un"), \
        PARA_ERROR(NO_AFHI, "audio format handler info required"), \
        PARA_ERROR(NOT_PLAYING, "not playing"), \
        PARA_ERROR(NO_VALID_FILES, "no valid file found in playlist"), \
        PARA_ERROR(NO_WMA, "asf/wma format not recognized"), \
-       PARA_ERROR(OEAP, "error during oeap (un)padding"), \
        PARA_ERROR(OGGDEC_BADHEADER, "invalid vorbis bitstream header"), \
        PARA_ERROR(OGGDEC_BADLINK, "invalid stream section or requested link corrupt"), \
        PARA_ERROR(OGGDEC_FAULT, "bug or heap/stack corruption"), \
        PARA_ERROR(OGG_PACKET_IN, "ogg_stream_packetin() failed"), \
        PARA_ERROR(OGG_STREAM_FLUSH, "ogg_stream_flush() failed"), \
        PARA_ERROR(OGG_SYNC, "internal ogg storage overflow"), \
-       PARA_ERROR(OPEN_COMP, "OpenAComponent() error"), \
        PARA_ERROR(OPUS_COMMENT, "invalid or corrupted opus comment"), \
        PARA_ERROR(OPUS_DECODE, "opus decode error"), \
        PARA_ERROR(OPUS_HEADER, "invalid opus header"), \
        PARA_ERROR(PLAY_SYNTAX, "para_play: syntax error"), \
        PARA_ERROR(PREBUFFER_SUCCESS, "prebuffering complete"), \
        PARA_ERROR(PRIVATE_KEY, "can not read private key"), \
-       PARA_ERROR(PUBLIC_KEY, "can not read public key"), \
        PARA_ERROR(QUEUE, "packet queue overrun"), \
        PARA_ERROR(READ_PATTERN, "did not read expected pattern"), \
        PARA_ERROR(RECV_EOF, "end of file"), \
        PARA_ERROR(REGEX, "regular expression error"), \
        PARA_ERROR(RESAMPLE_EOF, "resample filter: end of file"), \
        PARA_ERROR(RSA, "RSA error"), \
+       PARA_ERROR(RSA_DECODE, "RSA decoding error"), \
        PARA_ERROR(SB_PACKET_SIZE, "invalid sideband packet size or protocol error"), \
        PARA_ERROR(SCM_CREDENTIALS, "did not receive SCM credentials"), \
        PARA_ERROR(SENDER_CMD, "command not supported by this sender"), \
        PARA_ERROR(STAT_ITEM_PARSE, "failed to parse status item"), \
        PARA_ERROR(STATUS_TIMEOUT, "status item timeout"), \
        PARA_ERROR(STCO, "did not find stco atom"), \
-       PARA_ERROR(STREAM_FORMAT, "could not set stream format"), \
        PARA_ERROR(STREAM_PACKETIN, "ogg stream packet-in error"), \
        PARA_ERROR(STREAM_PACKETOUT, "ogg stream packet-out error"), \
        PARA_ERROR(STREAM_PAGEIN, "ogg stream page-in error"), \
        PARA_ERROR(TOO_MANY_CLIENTS, "maximal number of stat clients exceeded"), \
        PARA_ERROR(UCRED_PERM, "permission denied"), \
        PARA_ERROR(UDP_OVERRUN, "output buffer overrun"), \
-       PARA_ERROR(UNIT_INIT, "AudioUnitInitialize() error"), \
-       PARA_ERROR(UNIT_START, "AudioUnitStart() error"), \
        PARA_ERROR(UNKNOWN_STAT_ITEM, "status item not recognized"), \
        PARA_ERROR(UNSUPPORTED_AUDIO_FORMAT, "given audio format not supported"), \
        PARA_ERROR(UNSUPPORTED_FILTER, "given filter not supported"), \
index 7c19aeb0c3edc022c5b0f0425a202e37fd38d906..1fde479e1be97656bd01002a2071a3d6f1b4b026 100644 (file)
--- a/gcrypt.c
+++ b/gcrypt.c
@@ -19,9 +19,6 @@
 
 //#define GCRYPT_DEBUG 1
 
-static bool libgcrypt_has_oaep;
-static const char *rsa_decrypt_sexp;
-
 #ifdef GCRYPT_DEBUG
 static void dump_buffer(const char *msg, unsigned char *buf, int len)
 {
@@ -63,134 +60,25 @@ void get_random_bytes_or_die(unsigned char *buf, int num)
  * don't have to initialize any random seed here, but we must initialize the
  * gcrypt library. This task is performed by gcry_check_version() which can
  * also check that the gcrypt library version is at least the minimal required
- * version. This function also tells us whether we have to use our own OAEP
- * padding code.
+ * version.
  */
 void init_random_seed_or_die(void)
 {
-       const char *ver, *req_ver;
-
-       ver = gcry_check_version(NULL);
-       req_ver = "1.4.0";
-       if (!gcry_check_version(req_ver)) {
-               PARA_EMERG_LOG("fatal: need at least libgcrypt-%s, have: %s\n",
-                       req_ver, ver);
-               exit(EXIT_FAILURE);
-       }
-       req_ver = "1.5.0";
-       if (gcry_check_version(req_ver)) {
-               libgcrypt_has_oaep = true;
-               rsa_decrypt_sexp = "(enc-val(flags oaep)(rsa(a %m)))";
-       } else {
-               libgcrypt_has_oaep = false;
-               rsa_decrypt_sexp = "(enc-val(rsa(a %m)))";
-       }
+       const char *req_ver = "1.5.0";
+
+       if (gcry_check_version(req_ver))
+               return;
+       PARA_EMERG_LOG("fatal: need at least libgcrypt-%s, have: %s\n",
+               req_ver, gcry_check_version(NULL));
+       exit(EXIT_FAILURE);
 }
 
 /** S-expression for the public part of an RSA key. */
 #define RSA_PUBKEY_SEXP "(public-key (rsa (n %m) (e %m)))"
 /** S-expression for a private RSA key. */
 #define RSA_PRIVKEY_SEXP "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))"
-
-/* rfc 3447, appendix B.2 */
-static void mgf1(unsigned char *seed, size_t seed_len, unsigned result_len,
-               unsigned char *result)
-{
-       gcry_error_t gret;
-       gcry_md_hd_t handle;
-       size_t n;
-       unsigned char *md;
-       unsigned char octet_string[4], *rp = result, *end = rp + result_len;
-
-       assert(result_len / HASH_SIZE < 1ULL << 31);
-       gret = gcry_md_open(&handle, GCRY_MD_SHA1, 0);
-       assert(gret == 0);
-       for (n = 0; rp < end; n++) {
-               gcry_md_write(handle, seed, seed_len);
-               octet_string[0] = (unsigned char)((n >> 24) & 255);
-               octet_string[1] = (unsigned char)((n >> 16) & 255);
-               octet_string[2] = (unsigned char)((n >> 8)) & 255;
-               octet_string[3] = (unsigned char)(n & 255);
-               gcry_md_write(handle, octet_string, 4);
-               gcry_md_final(handle);
-               md = gcry_md_read(handle, GCRY_MD_SHA1);
-               memcpy(rp, md, PARA_MIN(HASH_SIZE, (int)(end - rp)));
-               rp += HASH_SIZE;
-               gcry_md_reset(handle);
-       }
-       gcry_md_close(handle);
-}
-
-/** The sha1 hash of an empty file. */
-static const unsigned char empty_hash[HASH_SIZE] =
-       "\xda" "\x39" "\xa3" "\xee" "\x5e"
-       "\x6b" "\x4b" "\x0d" "\x32" "\x55"
-       "\xbf" "\xef" "\x95" "\x60" "\x18"
-       "\x90" "\xaf" "\xd8" "\x07" "\x09";
-
-/* rfc3447, section 7.1.1 */
-static void pad_oaep(unsigned char *in, size_t in_len, unsigned char *out,
-               size_t out_len)
-{
-       size_t ps_len = out_len - in_len - 2 * HASH_SIZE - 2;
-       size_t n, mask_len = out_len - HASH_SIZE - 1;
-       unsigned char *seed = out + 1, *db = seed + HASH_SIZE,
-               *ps = db + HASH_SIZE, *one = ps + ps_len;
-       unsigned char *db_mask, seed_mask[HASH_SIZE];
-
-       assert(in_len <= out_len - 2 - 2 * HASH_SIZE);
-       assert(out_len > 2 * HASH_SIZE + 2);
-       PARA_DEBUG_LOG("padding %zu byte input -> %zu byte output\n",
-               in_len, out_len);
-       dump_buffer("unpadded buffer", in, in_len);
-
-       out[0] = '\0';
-       get_random_bytes_or_die(seed, HASH_SIZE);
-       memcpy(db, empty_hash, HASH_SIZE);
-       memset(ps, 0, ps_len);
-       *one = 0x01;
-       memcpy(one + 1, in, in_len);
-       db_mask = para_malloc(mask_len);
-       mgf1(seed, HASH_SIZE, mask_len, db_mask);
-       for (n = 0; n < mask_len; n++)
-               db[n] ^= db_mask[n];
-       mgf1(db, mask_len, HASH_SIZE, seed_mask);
-       for (n = 0; n < HASH_SIZE; n++)
-               seed[n] ^= seed_mask[n];
-       free(db_mask);
-       dump_buffer("padded buffer", out, out_len);
-}
-
-/* rfc 3447, section 7.1.2 */
-static int unpad_oaep(unsigned char *in, size_t in_len, unsigned char *out,
-               size_t *out_len)
-{
-       unsigned char *masked_seed = in + 1;
-       unsigned char *db = in + 1 + HASH_SIZE;
-       unsigned char seed[HASH_SIZE], seed_mask[HASH_SIZE];
-       unsigned char *db_mask, *p;
-       size_t n, mask_len = in_len - HASH_SIZE - 1;
-
-       mgf1(db, mask_len, HASH_SIZE, seed_mask);
-       for (n = 0; n < HASH_SIZE; n++)
-               seed[n] = masked_seed[n] ^ seed_mask[n];
-       db_mask = para_malloc(mask_len);
-       mgf1(seed, HASH_SIZE, mask_len, db_mask);
-       for (n = 0; n < mask_len; n++)
-               db[n] ^= db_mask[n];
-       free(db_mask);
-       if (memcmp(db, empty_hash, HASH_SIZE))
-               return -E_OEAP;
-       for (p = db + HASH_SIZE; p < in + in_len - 1; p++)
-               if (*p != '\0')
-                       break;
-       if (p >= in + in_len - 1)
-               return -E_OEAP;
-       p++;
-       *out_len = in + in_len - p;
-       memcpy(out, p, *out_len);
-       return 1;
-}
+/** S-expression for decryption. */
+#define RSA_DECRYPT_SEXP "(enc-val(flags oaep)(rsa(a %m)))"
 
 struct asymmetric_key {
        gcry_sexp_t sexp;
@@ -301,64 +189,6 @@ static inline int get_long_form_num_length_bytes(unsigned char c)
        return c & 0x7f;
 }
 
-static int find_pubkey_bignum_offset(const unsigned char *data, int len)
-{
-       const unsigned char *p = data, *end = data + len;
-
-       /* the whole thing starts with one sequence */
-       if (*p != ASN1_TYPE_SEQUENCE)
-               return -E_ASN1_PARSE;
-       p++;
-       if (p >= end)
-               return -E_ASN1_PARSE;
-       if (is_short_form(*p))
-               p++;
-       else
-               p += 1 + get_long_form_num_length_bytes(*p);
-       if (p >= end)
-               return -E_ASN1_PARSE;
-       /* another sequence containing the object id, skip it */
-       if (*p != ASN1_TYPE_SEQUENCE)
-               return -E_ASN1_PARSE;
-       p++;
-       if (p >= end)
-               return -E_ASN1_PARSE;
-       if (!is_short_form(*p))
-               return -E_ASN1_PARSE;
-       p += 1 + get_short_form_length(*p);
-       if (p >= end)
-               return -E_ASN1_PARSE;
-       /* all numbers are wrapped in a bit string object that follows */
-       if (*p != ASN1_TYPE_BIT_STRING)
-               return -E_ASN1_PARSE;
-       p++;
-       if (p >= end)
-               return -E_ASN1_PARSE;
-       if (is_short_form(*p))
-               p++;
-       else
-               p += 1 + get_long_form_num_length_bytes(*p);
-       p++; /* skip number of unused bits in the bit string */
-       if (p >= end)
-               return -E_ASN1_PARSE;
-
-       /* next, we have a sequence of two integers (n and e) */
-       if (*p != ASN1_TYPE_SEQUENCE)
-               return -E_ASN1_PARSE;
-       p++;
-       if (p >= end)
-               return -E_ASN1_PARSE;
-       if (is_short_form(*p))
-               p++;
-       else
-               p += 1 + get_long_form_num_length_bytes(*p);
-       if (p >= end)
-               return -E_ASN1_PARSE;
-       if (*p != ASN1_TYPE_INTEGER)
-               return -E_ASN1_PARSE;
-       return p - data;
-}
-
 /*
  * Returns: Number of bytes scanned. This may differ from the value returned via
  * bn_bytes because the latter does not include the ASN.1 prefix and a leading
@@ -460,6 +290,7 @@ static int get_private_key(const char *key_file, struct asymmetric_key **result)
        gcry_sexp_t sexp;
        struct asymmetric_key *key;
 
+       *result = NULL;
        ret = decode_key(key_file, PRIVATE_KEY_HEADER, PRIVATE_KEY_FOOTER,
                &blob);
        if (ret < 0)
@@ -538,65 +369,6 @@ free_blob:
        return ret;
 }
 
-/** Public keys start with this header. */
-#define PUBLIC_KEY_HEADER "-----BEGIN PUBLIC KEY-----"
-/** Public keys end with this footer. */
-#define PUBLIC_KEY_FOOTER "-----END PUBLIC KEY-----"
-
-static int get_asn_public_key(const char *key_file, struct asymmetric_key **result)
-{
-       gcry_mpi_t n = NULL, e = NULL;
-       unsigned char *blob, *cp, *end;
-       int blob_size, ret, n_size;
-       gcry_error_t gret;
-       size_t erroff;
-       gcry_sexp_t sexp;
-       struct asymmetric_key *key;
-
-       ret = decode_key(key_file, PUBLIC_KEY_HEADER, PUBLIC_KEY_FOOTER,
-               &blob);
-       if (ret < 0)
-               return ret;
-       blob_size = ret;
-       end = blob + blob_size;
-       ret = find_pubkey_bignum_offset(blob, blob_size);
-       if (ret < 0)
-               goto free_blob;
-       PARA_DEBUG_LOG("decoding public RSA params at offset %d\n", ret);
-       cp = blob + ret;
-
-       ret = read_bignum(cp, end, &n, &n_size);
-       if (ret < 0)
-               goto free_blob;
-       cp += ret;
-
-       ret = read_bignum(cp, end, &e, NULL);
-       if (ret < 0)
-               goto release_n;
-
-       gret = gcry_sexp_build(&sexp, &erroff, RSA_PUBKEY_SEXP, n, e);
-       if (gret) {
-               PARA_ERROR_LOG("offset %zu: %s\n", erroff,
-                       gcry_strerror(gcry_err_code(gret)));
-               ret = -E_SEXP_BUILD;
-               goto release_e;
-       }
-       key = para_malloc(sizeof(*key));
-       key->sexp = sexp;
-       key->num_bytes = n_size;
-       *result = key;
-       ret = n_size;
-       PARA_INFO_LOG("successfully read %d bit asn public key\n", n_size * 8);
-
-release_e:
-       gcry_mpi_release(e);
-release_n:
-       gcry_mpi_release(n);
-free_blob:
-       free(blob);
-       return ret;
-}
-
 static int get_ssh_public_key(unsigned char *data, int size, gcry_sexp_t *result)
 {
        int ret;
@@ -658,8 +430,7 @@ free_blob:
        return ret;
 }
 
-int get_asymmetric_key(const char *key_file, int private,
-               struct asymmetric_key **result)
+int get_public_key(const char *key_file, struct asymmetric_key **result)
 {
        int ret, ret2;
        void *map;
@@ -668,17 +439,13 @@ int get_asymmetric_key(const char *key_file, int private,
        gcry_sexp_t sexp;
        struct asymmetric_key *key;
 
-       if (private)
-               return get_private_key(key_file, result);
        ret = mmap_full_file(key_file, O_RDONLY, &map, &map_size, NULL);
        if (ret < 0)
                return ret;
        ret = is_ssh_rsa_key(map, map_size);
        if (!ret) {
-               ret = para_munmap(map, map_size);
-               if (ret < 0)
-                       return ret;
-               return get_asn_public_key(key_file, result);
+               para_munmap(map, map_size);
+               return -E_SSH_PARSE;
        }
        start = map + ret;
        end = map + map_size;
@@ -699,7 +466,7 @@ unmap:
        return ret;
 }
 
-void free_asymmetric_key(struct asymmetric_key *key)
+void free_public_key(struct asymmetric_key *key)
 {
        if (!key)
                return;
@@ -707,78 +474,27 @@ void free_asymmetric_key(struct asymmetric_key *key)
        free(key);
 }
 
-static int decode_rsa(gcry_sexp_t sexp, int key_size, unsigned char *outbuf,
-               size_t *nbytes)
+static int decode_rsa(gcry_sexp_t sexp, unsigned char *outbuf, size_t *nbytes)
 {
-       int ret;
-       gcry_error_t gret;
-       unsigned char oaep_buf[512];
-       gcry_mpi_t out_mpi;
-
-       if (libgcrypt_has_oaep) {
-               const char *p = gcry_sexp_nth_data(sexp, 1, nbytes);
-
-               if (!p) {
-                       PARA_ERROR_LOG("could not get data from list\n");
-                       return -E_OEAP;
-               }
-               memcpy(outbuf, p, *nbytes);
-               return 1;
-       }
-       out_mpi = gcry_sexp_nth_mpi(sexp, 0, GCRYMPI_FMT_USG);
-       if (!out_mpi)
-               return -E_SEXP_FIND;
-       gret = gcry_mpi_print(GCRYMPI_FMT_USG, oaep_buf, sizeof(oaep_buf),
-               nbytes, out_mpi);
-       if (gret) {
-               PARA_ERROR_LOG("mpi_print: %s\n", gcrypt_strerror(gret));
-               ret = -E_MPI_PRINT;
-               goto out_mpi_release;
-       }
-       /*
-        * An oaep-encoded buffer always starts with at least one zero byte.
-        * However, leading zeroes in an mpi are omitted in the output of
-        * gcry_mpi_print() when using the GCRYMPI_FMT_USG format. The
-        * alternative, GCRYMPI_FMT_STD, does not work either because here the
-        * leading zero(es) might also be omitted, depending on the value of
-        * the second byte.
-        *
-        * To circumvent this, we shift the oaep buffer to the right. But first
-        * we check that the buffer actually started with a zero byte, i.e. that
-        * nbytes < key_size. Otherwise a decoding error occurred.
-        */
-       ret = -E_SEXP_DECRYPT;
-       if (*nbytes >= key_size)
-               goto out_mpi_release;
-       memmove(oaep_buf + key_size - *nbytes, oaep_buf, *nbytes);
-       memset(oaep_buf, 0, key_size - *nbytes);
+       const char *p = gcry_sexp_nth_data(sexp, 1, nbytes);
 
-       PARA_DEBUG_LOG("decrypted buffer before unpad (%d bytes):\n",
-               key_size);
-       dump_buffer("non-unpadded decrypted buffer", oaep_buf, key_size);
-       ret = unpad_oaep(oaep_buf, key_size, outbuf, nbytes);
-       if (ret < 0)
-               goto out_mpi_release;
-       PARA_DEBUG_LOG("decrypted buffer after unpad (%zu bytes):\n",
-               *nbytes);
-       dump_buffer("unpadded decrypted buffer", outbuf, *nbytes);
-       ret = 1;
-out_mpi_release:
-       gcry_mpi_release(out_mpi);
-       return ret;
+       if (!p)
+               return -E_RSA_DECODE;
+       memcpy(outbuf, p, *nbytes);
+       return 1;
 }
 
 int priv_decrypt(const char *key_file, unsigned char *outbuf,
                unsigned char *inbuf, int inlen)
 {
        gcry_error_t gret;
-       int ret, key_size;
+       int ret;
        struct asymmetric_key *priv;
        gcry_mpi_t in_mpi = NULL;
        gcry_sexp_t in, out, priv_key;
        size_t nbytes;
 
-       ret = check_key_file(key_file, true);
+       ret = check_private_key_file(key_file);
        if (ret < 0)
                return ret;
        PARA_INFO_LOG("decrypting %d byte input\n", inlen);
@@ -786,7 +502,6 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf,
        ret = get_private_key(key_file, &priv);
        if (ret < 0)
                return ret;
-       key_size = ret / 8;
 
        /* asymmetric key priv -> sexp priv_key */
        ret = -E_SEXP_FIND;
@@ -803,7 +518,7 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf,
                goto key_release;
        }
        /* in_mpi -> in sexp */
-       gret = gcry_sexp_build(&in, NULL, rsa_decrypt_sexp, in_mpi);
+       gret = gcry_sexp_build(&in, NULL, RSA_DECRYPT_SEXP, in_mpi);
        if (gret) {
                PARA_ERROR_LOG("%s\n", gcrypt_strerror(gret));
                ret = -E_SEXP_BUILD;
@@ -817,7 +532,7 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf,
                ret = -E_SEXP_DECRYPT;
                goto in_release;
        }
-       ret = decode_rsa(out, key_size, outbuf, &nbytes);
+       ret = decode_rsa(out, outbuf, &nbytes);
        if (ret < 0)
                goto out_release;
        PARA_INFO_LOG("successfully decrypted %zu byte message\n", nbytes);
@@ -831,7 +546,8 @@ in_mpi_release:
 key_release:
        gcry_sexp_release(priv_key);
 free_key:
-       free_asymmetric_key(priv);
+       gcry_sexp_release(priv->sexp);
+       free(priv);
        return ret;
 }
 
@@ -850,18 +566,7 @@ int pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf,
        pub_key = gcry_sexp_find_token(pub->sexp, "public-key", 0);
        if (!pub_key)
                return -E_SEXP_FIND;
-       if (libgcrypt_has_oaep) {
-               gret = gcry_sexp_build(&in, NULL,
-                       "(data(flags oaep)(value %b))", len, inbuf);
-       } else {
-               unsigned char padded_input[256];
-               const size_t pad_size = 256;
-               /* inbuf -> padded inbuf */
-               pad_oaep(inbuf, len, padded_input, pad_size);
-               /* padded inbuf -> in sexp */
-               gret = gcry_sexp_build(&in, NULL,
-                       "(data(flags raw)(value %b))", pad_size, padded_input);
-       }
+       gret = gcry_sexp_build(&in, NULL, "(data(flags oaep)(value %b))", len, inbuf);
        if (gret) {
                PARA_ERROR_LOG("%s\n", gcrypt_strerror(gret));
                ret = -E_SEXP_BUILD;
@@ -912,33 +617,20 @@ struct stream_cipher {
        gcry_cipher_hd_t handle;
 };
 
-struct stream_cipher *sc_new(const unsigned char *data, int len,
-               bool use_aes)
+struct stream_cipher *sc_new(const unsigned char *data, int len)
 {
        gcry_error_t gret;
        struct stream_cipher *sc = para_malloc(sizeof(*sc));
 
-       if (use_aes) {
-               assert(len >= 2 * AES_CRT128_BLOCK_SIZE);
-               gret = gcry_cipher_open(&sc->handle, GCRY_CIPHER_AES128,
-                       GCRY_CIPHER_MODE_CTR, 0);
-               assert(gret == 0);
-               gret = gcry_cipher_setkey(sc->handle, data,
-                       AES_CRT128_BLOCK_SIZE);
-               assert(gret == 0);
-               gret = gcry_cipher_setctr(sc->handle,
-                       data + AES_CRT128_BLOCK_SIZE, AES_CRT128_BLOCK_SIZE);
-               assert(gret == 0);
-               return sc;
-       }
-       gret = gcry_cipher_open(&sc->handle, GCRY_CIPHER_ARCFOUR,
-               GCRY_CIPHER_MODE_STREAM, 0);
-       if (gret) {
-               PARA_ERROR_LOG("%s\n", gcrypt_strerror(gret));
-               free(sc);
-               return NULL;
-       }
-       gret = gcry_cipher_setkey(sc->handle, data, (size_t)len);
+       assert(len >= 2 * AES_CRT128_BLOCK_SIZE);
+       gret = gcry_cipher_open(&sc->handle, GCRY_CIPHER_AES128,
+               GCRY_CIPHER_MODE_CTR, 0);
+       assert(gret == 0);
+       gret = gcry_cipher_setkey(sc->handle, data,
+               AES_CRT128_BLOCK_SIZE);
+       assert(gret == 0);
+       gret = gcry_cipher_setctr(sc->handle,
+               data + AES_CRT128_BLOCK_SIZE, AES_CRT128_BLOCK_SIZE);
        assert(gret == 0);
        return sc;
 }
index c34a0f6eb3c5ff3fd6fcb0e85546a180d21fd880..91ab1559629725f4b9ae25a3ec167231937bc27d 100644 (file)
@@ -206,26 +206,7 @@ void i9e_attach_to_stdout(struct btr_node *producer)
 
 static void wipe_bottom_line(void)
 {
-       char x[] = "          ";
-       int n = i9ep->num_columns;
-
-       /*
-        * For reasons beyond my understanding, writing more than 68 characters
-        * here causes MacOS to mess up the terminal. Writing a line of spaces
-        * in smaller chunks works fine though. Weird.
-        */
-       fprintf(i9ep->stderr_stream, "\r");
-       while (n > 0) {
-               if (n >= sizeof(x)) {
-                       fprintf(i9ep->stderr_stream, "%s", x);
-                       n -= sizeof(x);
-                       continue;
-               }
-               x[n] = '\0';
-               fprintf(i9ep->stderr_stream, "%s", x);
-               break;
-       }
-       fprintf(i9ep->stderr_stream, "\r");
+       fprintf(i9ep->stderr_stream, "\r%s\r", i9ep->empty_line);
 }
 
 #ifndef RL_FREE_KEYMAP_DECLARED
diff --git a/m4/gengetopt/osx_write.m4 b/m4/gengetopt/osx_write.m4
deleted file mode 100644 (file)
index 83ed737..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-args "--no-version --no-help"
-
-purpose "Output plugin for Mac OS coreaudio"
-
-section "osx options"
-#####################
-
-option "numbuffers" n
-#~~~~~~~~~~~~~~~~~~~~~
-
-"number of audio buffers to allocate (increase if
-you get buffer underruns)"
-
-       int typestr="num"
-       default="20"
-       optional
-       details = ""
diff --git a/net.c b/net.c
index fa7cd4b80a7d96b26e35add01ad97d9a123f138d..023d78d08175f2f3810af6dd387f5eec14a06dcc 100644 (file)
--- a/net.c
+++ b/net.c
@@ -818,25 +818,37 @@ int dccp_available_ccids(uint8_t **ccid_array)
        return nccids;
 }
 
-/**
- * Prepare a structure for \p AF_UNIX socket addresses.
- *
- * \param u Pointer to the struct to be prepared.
- * \param name The socket pathname.
+/*
+ * Prepare a structure for AF_UNIX socket addresses.
  *
- * This just copies \a name to the sun_path component of \a u.
+ * This just copies name to the sun_path component of u, prepending a zero byte
+ * if abstract sockets are supported.
  *
- * \return Positive on success, \p -E_NAME_TOO_LONG if \a name is longer
- * than \p UNIX_PATH_MAX.
+ * The first call to this function tries to bind a socket to the abstract name
+ * space. The result of this test is stored in a static variable. Subsequent
+ * calls read this variable and create abstract sockets on systems that support
+ * them.
  */
-static int init_unix_addr(struct sockaddr_un *u, const char *name,
-               bool abstract)
+static int init_unix_addr(struct sockaddr_un *u, const char *name)
 {
-       if (strlen(name) + abstract >= UNIX_PATH_MAX)
+       static int use_abstract;
+
+       if (strlen(name) + 1 >= UNIX_PATH_MAX)
                return -E_NAME_TOO_LONG;
        memset(u->sun_path, 0, UNIX_PATH_MAX);
        u->sun_family = PF_UNIX;
-       strcpy(u->sun_path + abstract, name);
+       if (use_abstract == 0) { /* executed only once */
+               int fd = socket(PF_UNIX, SOCK_STREAM, 0);
+               memcpy(u->sun_path, "\0x\0", 3);
+               if (bind(fd, (struct sockaddr *)u, sizeof(*u)) == 0)
+                       use_abstract = 1; /* yes */
+               else
+                       use_abstract = -1; /* no */
+               close(fd);
+               PARA_NOTICE_LOG("%susing abstract socket namespace\n",
+                       use_abstract == 1? "" : "not ");
+       }
+       strcpy(u->sun_path + (use_abstract == 1? 1 : 0), name);
        return 1;
 }
 
@@ -844,28 +856,22 @@ static int init_unix_addr(struct sockaddr_un *u, const char *name,
  * Create a socket for local communication and listen on it.
  *
  * \param name The socket pathname.
- * \param mode The desired permissions of the socket.
  *
  * This function creates a passive local socket for sequenced, reliable,
  * two-way, connection-based byte streams. The socket file descriptor is set to
  * nonblocking mode and listen(2) is called to prepare the socket for
  * accepting incoming connection requests.
  *
- * If mode is zero, an abstract socket (a non-portable Linux extension) is
- * created. In this case the socket name has no connection with filesystem
- * pathnames.
- *
  * \return The file descriptor on success, negative error code on failure.
  *
  * \sa socket(2), \sa bind(2), \sa chmod(2), listen(2), unix(7).
  */
-int create_local_socket(const char *name, mode_t mode)
+int create_local_socket(const char *name)
 {
        struct sockaddr_un unix_addr;
        int fd, ret;
-       bool abstract = mode == 0;
 
-       ret = init_unix_addr(&unix_addr, name, abstract);
+       ret = init_unix_addr(&unix_addr, name);
        if (ret < 0)
                return ret;
        ret = socket(PF_UNIX, SOCK_STREAM, 0);
@@ -880,7 +886,9 @@ int create_local_socket(const char *name, mode_t mode)
                ret = -ERRNO_TO_PARA_ERROR(errno);
                goto err;
        }
-       if (!abstract) {
+       if (unix_addr.sun_path[0] != 0) { /* pathname socket */
+               mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
+                       | S_IROTH | S_IWOTH;
                ret = -E_CHMOD;
                if (chmod(name, mode) < 0)
                        goto err;
@@ -917,14 +925,7 @@ int connect_local_socket(const char *name)
        fd = socket(PF_UNIX, SOCK_STREAM, 0);
        if (fd < 0)
                return -ERRNO_TO_PARA_ERROR(errno);
-       /* first try (linux-only) abstract socket */
-       ret = init_unix_addr(&unix_addr, name, true);
-       if (ret < 0)
-               goto err;
-       if (connect(fd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)) != -1)
-               return fd;
-       /* next try pathname socket */
-       ret = init_unix_addr(&unix_addr, name, false);
+       ret = init_unix_addr(&unix_addr, name);
        if (ret < 0)
                goto err;
        if (connect(fd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)) != -1)
diff --git a/net.h b/net.h
index b2bb47c9b40b43fe2eb7c8813e6ffa7364b0853e..a70954a95fa742f5fedf27320f7d500bf20a2fa0 100644 (file)
--- a/net.h
+++ b/net.h
@@ -147,7 +147,7 @@ int recv_bin_buffer(int fd, char *buf, size_t size);
 int recv_buffer(int fd, char *buf, size_t size);
 
 int para_accept(int fd, fd_set *rfds, void *addr, socklen_t size, int *new_fd);
-int create_local_socket(const char *name, mode_t mode);
+int create_local_socket(const char *name);
 int connect_local_socket(const char *name);
 int recv_cred_buffer(int, char *, size_t);
 ssize_t send_cred_buffer(int, char*);
diff --git a/osx_write.c b/osx_write.c
deleted file mode 100644 (file)
index 18a2c08..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2006 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
-
-/** \file osx_write.c paraslash's output plugin for MacOs */
-
-/*
- * based on mosx-mpg123, by Guillaume Outters and Steven A. Kortze
- * <skortze@sourceforge.net>
- */
-
-#include <regex.h>
-#include <sys/types.h>
-
-#include "para.h"
-#include "fd.h"
-#include "string.h"
-#include "list.h"
-#include "sched.h"
-#include "ggo.h"
-#include "buffer_tree.h"
-#include "write.h"
-#include "write_common.h"
-#include "osx_write.cmdline.h"
-#include "ipc.h"
-#include "error.h"
-
-#include <CoreServices/CoreServices.h>
-#include <AudioUnit/AudioUnit.h>
-#include <AudioToolbox/AudioToolbox.h>
-
-/** Data specific to the osx writer. */
-struct private_osx_write_data {
-       /** The main CoreAudio handle. */
-       AudioUnit audio_unit;
-       /** True if we wrote some audio data. */
-       bool playing;
-       /** Sample rate of the current audio stream. */
-       unsigned sample_rate;
-       /** Sample format of the current audio stream */
-       unsigned sample_format;
-       /** Number of channels of the current audio stream. */
-       unsigned channels;
-       /**
-        * Serializes access to buffer tree nodes between the writer and
-        * the callback which runs in a different thread.
-        */
-       int mutex;
-       /**
-        * The btr node of the callback.
-        *
-        * Although access to the btr node is serialized between the writer and
-        * the callback via the above mutex, this does not stop other buffer
-        * tree nodes, for example the decoder, to race against the osx
-        * callback.
-        *
-        * However, since all operations on buffer tree nodes are local in the
-        * sense that they only affect one level in the buffer tree (i.e.
-        * parent or child nodes, but not the grandparent or the
-        * grandchildren), we may work around this problem by using another
-        * buffer tree node for the callback.
-        *
-        * The writer grabs the mutex in its post_select method and pushes down
-        * the buffers to the callback node.
-        */
-       struct btr_node *callback_btrn;
-};
-
-/* This function writes the address and the number of bytes to one end of the socket.
- * The post_select() function then fills the buffer and notifies the callback also
- * through the socket.
- */
-static OSStatus osx_callback(void *cb_arg, __a_unused AudioUnitRenderActionFlags *af,
-               __a_unused const AudioTimeStamp *ts, __a_unused  UInt32 bus_number,
-               __a_unused UInt32 num_frames, AudioBufferList *abl)
-{
-       int i;
-       struct writer_node *wn = cb_arg;
-       struct private_osx_write_data *powd;
-       size_t samples_have, samples_want = 0;
-
-       powd = wn->private_data;
-       mutex_lock(powd->mutex);
-       powd = wn->private_data;
-       if (!powd || !wn->btrn)
-               goto out;
-       /*
-        * We fill with zeros if no data was yet written and we do not have
-        * enough to fill all buffers.
-        */
-       if (!powd->playing) {
-               size_t want = 0, have =
-                       btr_get_input_queue_size(powd->callback_btrn);
-               for (i = 0; i < abl->mNumberBuffers; i++)
-                       want += abl->mBuffers[i].mDataByteSize;
-               if (have < want) {
-                       PARA_DEBUG_LOG("deferring playback (have = %zu < %zu = want)\n",
-                               have, want);
-                       for (i = 0; i < abl->mNumberBuffers; i++)
-                               memset(abl->mBuffers[i].mData, 0,
-                                       abl->mBuffers[i].mDataByteSize);
-                       goto out;
-               }
-               powd->playing = true;
-       }
-
-       for (i = 0; i < abl->mNumberBuffers; i++) {
-               /* what we have to fill */
-               void *dest = abl->mBuffers[i].mData;
-               size_t sz = abl->mBuffers[i].mDataByteSize, samples, bytes;
-
-               samples_want = sz / wn->min_iqs;
-               while (samples_want > 0) {
-                       char *buf;
-                       btr_merge(powd->callback_btrn, wn->min_iqs);
-                       samples_have = btr_next_buffer(powd->callback_btrn, &buf) / wn->min_iqs;
-                       //PARA_INFO_LOG("i: %d want %zu samples to addr %p, have: %zu\n", i, samples_want,
-                       //      dest, samples_have);
-                       samples = PARA_MIN(samples_have, samples_want);
-                       if (samples == 0)
-                               break;
-                       bytes = samples * wn->min_iqs;
-                       memcpy(dest, buf, bytes);
-                       btr_consume(powd->callback_btrn, bytes);
-                       samples_want -= samples;
-                       dest += bytes;
-               }
-               if (samples_want == 0)
-                       continue;
-               if (btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_LEAF) >= 0)
-                       PARA_INFO_LOG("zero-padding (%zu samples)\n",
-                               samples_want);
-               memset(dest, 0, samples_want * wn->min_iqs);
-               break;
-       }
-out:
-       mutex_unlock(powd->mutex);
-       return noErr;
-}
-
-static int core_audio_init(struct writer_node *wn)
-{
-       struct private_osx_write_data *powd = para_calloc(sizeof(*powd));
-       Component comp;
-       int ret;
-       int32_t val;
-       AURenderCallbackStruct input_callback;
-       ComponentDescription desc = {
-               .componentType = kAudioUnitType_Output,
-               .componentSubType = kAudioUnitSubType_DefaultOutput,
-               .componentManufacturer = kAudioUnitManufacturer_Apple,
-       };
-       AudioStreamBasicDescription format = {
-               .mFormatID = kAudioFormatLinearPCM,
-               .mFramesPerPacket = 1,
-       };
-       struct btr_node *btrn = wn->btrn;
-       struct btr_node_description bnd;
-
-       PARA_INFO_LOG("wn: %p\n", wn);
-       ret = -E_DEFAULT_COMP;
-       comp = FindNextComponent(NULL, &desc);
-       if (!comp)
-               goto e0;
-       ret = -E_OPEN_COMP;
-       if (OpenAComponent(comp, &powd->audio_unit))
-               goto e0;
-       ret = -E_UNIT_INIT;
-       if (AudioUnitInitialize(powd->audio_unit))
-               goto e1;
-       get_btr_sample_rate(btrn, &val);
-       powd->sample_rate = val;
-       get_btr_channels(btrn, &val);
-       powd->channels = val;
-       get_btr_sample_format(btrn, &val);
-       powd->sample_format = val;
-       /*
-        * Choose PCM format. We tell the Output Unit what format we're going
-        * to supply data to it. This is necessary if you're providing data
-        * through an input callback AND you want the DefaultOutputUnit to do
-        * any format conversions necessary from your format to the device's
-        * format.
-        */
-
-       format.mSampleRate = powd->sample_rate;
-       format.mChannelsPerFrame = powd->channels;
-
-       switch (powd->sample_format) {
-       case SF_S8:
-       case SF_U8:
-               wn->min_iqs = powd->channels;
-               format.mBitsPerChannel = 8;
-               format.mBytesPerPacket = powd->channels;
-               format.mFormatFlags |= kLinearPCMFormatFlagIsPacked;
-               break;
-       default:
-               wn->min_iqs = powd->channels * 2;
-               format.mBytesPerPacket = powd->channels * 2;
-               format.mBitsPerChannel = 16;
-               format.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
-       }
-       format.mBytesPerFrame = format.mBytesPerPacket;
-
-       if (powd->sample_format == SF_S16_BE || powd->sample_format == SF_U16_BE)
-               format.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
-
-       input_callback = (AURenderCallbackStruct){osx_callback, wn};
-       ret = -E_STREAM_FORMAT;
-       if (AudioUnitSetProperty(powd->audio_unit, kAudioUnitProperty_StreamFormat,
-                       kAudioUnitScope_Input, 0, &format, sizeof(format)))
-               goto e2;
-       ret = -E_ADD_CALLBACK;
-       if (AudioUnitSetProperty(powd->audio_unit, kAudioUnitProperty_SetRenderCallback,
-                       kAudioUnitScope_Input, 0, &input_callback,
-                       sizeof(input_callback)) < 0)
-               goto e2;
-
-       ret = mutex_new();
-       if (ret < 0)
-               goto e2;
-       powd->mutex = ret;
-       /* set up callback btr node */
-       bnd.name = "cb_node";
-       bnd.parent = btrn;
-       bnd.child = NULL;
-       bnd.handler = NULL;
-       bnd.context = powd;
-       powd->callback_btrn = btr_new_node(&bnd);
-       wn->private_data = powd;
-       return 1;
-e2:
-       AudioUnitUninitialize(powd->audio_unit);
-e1:
-       CloseComponent(powd->audio_unit);
-e0:
-       free(powd);
-       wn->private_data = NULL;
-       return ret;
-}
-
-__malloc static void *osx_write_parse_config_or_die(int argc, char **argv)
-{
-       struct osx_write_args_info *conf = para_calloc(sizeof(*conf));
-
-       /* exits on errors */
-       osx_write_cmdline_parser(argc, argv, conf);
-       return conf;
-}
-
-static void osx_free_config(void *conf)
-{
-       osx_write_cmdline_parser_free(conf);
-}
-
-static void osx_write_close(struct writer_node *wn)
-{
-       struct private_osx_write_data *powd = wn->private_data;
-
-       if (!powd)
-               return;
-       PARA_INFO_LOG("closing writer node %p\n", wn);
-       mutex_destroy(powd->mutex);
-       free(powd);
-       wn->private_data = NULL;
-}
-
-/* must be called with the mutex held */
-static inline bool need_drain_delay(struct private_osx_write_data *powd)
-{
-       if (!powd->playing)
-               return false;
-       return btr_get_input_queue_size(powd->callback_btrn) != 0;
-}
-
-static void osx_write_pre_select(struct sched *s, void *context)
-{
-       struct writer_node *wn = context;
-       struct private_osx_write_data *powd = wn->private_data;
-       int ret;
-       bool drain_delay_nec = false;
-
-       if (!powd) {
-               ret = btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_LEAF);
-               if (ret != 0)
-                       sched_min_delay(s);
-               return;
-       }
-
-       mutex_lock(powd->mutex);
-       ret = btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_INTERNAL);
-       if (ret < 0)
-               drain_delay_nec = need_drain_delay(powd);
-       mutex_unlock(powd->mutex);
-
-       if (drain_delay_nec)
-               return sched_request_timeout_ms(50, s);
-       if (ret != 0)
-               return sched_min_delay(s);
-       sched_request_timeout_ms(50, s);
-}
-
-static int osx_write_post_select(__a_unused struct sched *s, void *context)
-{
-       struct writer_node *wn = context;
-       struct private_osx_write_data *powd = wn->private_data;
-       struct btr_node *btrn = wn->btrn;
-       int ret;
-
-       ret = task_get_notification(wn->task);
-       if (ret < 0)
-               goto fail;
-       if (!powd) {
-               ret = btr_node_status(btrn, wn->min_iqs, BTR_NT_LEAF);
-               if (ret == 0)
-                       return 0;
-               if (ret < 0)
-                       goto fail;
-               ret = core_audio_init(wn);
-               if (ret < 0)
-                       goto fail;
-               powd = wn->private_data;
-               ret = -E_UNIT_START;
-               if (AudioOutputUnitStart(powd->audio_unit) != noErr) {
-                       AudioUnitUninitialize(powd->audio_unit);
-                       CloseComponent(powd->audio_unit);
-                       btr_remove_node(&powd->callback_btrn);
-                       goto fail;
-               }
-       }
-       mutex_lock(powd->mutex);
-       ret = btr_node_status(btrn, wn->min_iqs, BTR_NT_INTERNAL);
-       if (ret > 0)
-               btr_pushdown(btrn);
-       if (ret < 0 && need_drain_delay(powd))
-               ret = 0;
-       mutex_unlock(powd->mutex);
-       if (ret >= 0)
-               return 0;
-fail:
-       assert(ret < 0);
-       if (powd && powd->callback_btrn) {
-               AudioOutputUnitStop(powd->audio_unit);
-               AudioUnitUninitialize(powd->audio_unit);
-               CloseComponent(powd->audio_unit);
-               btr_remove_node(&powd->callback_btrn);
-       }
-       btr_remove_node(&wn->btrn);
-       PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
-       return ret;
-}
-
-/**
- * The init function of the osx writer.
- *
- * \param w Filled in by the function.
- */
-void osx_write_init(struct writer *w)
-{
-       struct osx_write_args_info dummy;
-
-       osx_write_cmdline_parser_init(&dummy);
-       w->close = osx_write_close;
-       w->pre_select = osx_write_pre_select;
-       w->post_select = osx_write_post_select;
-       w->parse_config_or_die = osx_write_parse_config_or_die;
-       w->free_config = osx_free_config;
-       w->help = (struct ggo_help)DEFINE_GGO_HELP(osx_write);
-       osx_write_cmdline_parser_free(&dummy);
-}
index 15bb6859b1c2e668245bf0663bc57d7593710f83..a71963c9bbda192f047f144e970d92dcfd764a77 100644 (file)
@@ -18,6 +18,7 @@ endif
 
 tests := $(sort $(wildcard $(test_dir)/t[0-9][0-9][0-9][0-9]-*.sh))
 
+check: $(tests)
 test: $(tests)
 
 $(tests): all
@@ -30,4 +31,4 @@ test-clean:
        $(RM) -r $(results_dir)
        $(RM) -r $(trash_dir)
 
-.PHONY: $(tests) test-help
+.PHONY: $(tests) test-help test-clean test check
diff --git a/time.c b/time.c
index 6bb9a50f5b32f7441943817dc22f868d0f0131cd..90c6735644540f1431afcc1b376da0662823e80c 100644 (file)
--- a/time.c
+++ b/time.c
@@ -198,22 +198,14 @@ void compute_chunk_time(long unsigned chunk_num,
 struct timeval *clock_get_realtime(struct timeval *tv)
 {
        static struct timeval user_friendly;
+       struct timespec t;
+       int ret;
 
        if (!tv)
                tv = &user_friendly;
-#ifdef HAVE_CLOCK_GETTIME
-       {
-               struct timespec t;
-               int ret;
-
-               ret = clock_gettime(CLOCK_REALTIME, &t);
-               assert(ret == 0);
-               tv->tv_sec = t.tv_sec;
-               tv->tv_usec = t.tv_nsec / 1000;
-       }
-#else
-       #include <sys/time.h>
-       gettimeofday(tv, NULL);
-#endif /* HAVE_CLOCK_GETTIME */
+       ret = clock_gettime(CLOCK_REALTIME, &t);
+       assert(ret == 0);
+       tv->tv_sec = t.tv_sec;
+       tv->tv_usec = t.tv_nsec / 1000;
        return tv;
 }
index 9c751244339c34197d52229b75b4d55e5a58a43f..23fe086f189e89b3a729aa5afe145006446371bb 100644 (file)
@@ -48,7 +48,7 @@ static void populate_user_list(char *user_list_file)
                if (strcmp(w, "user"))
                        continue;
                PARA_DEBUG_LOG("found entry for user %s\n", n);
-               ret = get_asymmetric_key(k, LOAD_PUBLIC_KEY, &pubkey);
+               ret = get_public_key(k, &pubkey);
                if (ret < 0) {
                        PARA_NOTICE_LOG("skipping entry for user %s: %s\n", n,
                                para_strerror(-ret));
@@ -63,7 +63,7 @@ static void populate_user_list(char *user_list_file)
                if (ret <= CHALLENGE_SIZE + 2 * SESSION_KEY_LEN + 41) {
                        PARA_WARNING_LOG("public key %s too short (%d)\n",
                                k, ret);
-                       free_asymmetric_key(pubkey);
+                       free_public_key(pubkey);
                        continue;
                }
                u = para_malloc(sizeof(*u));
@@ -114,7 +114,7 @@ void init_user_list(char *user_list_file)
                list_for_each_entry_safe(u, tmp, &user_list, node) {
                        list_del(&u->node);
                        free(u->name);
-                       free_asymmetric_key(u->pubkey);
+                       free_public_key(u->pubkey);
                        free(u);
                }
        } else
index 2c72f28126d2ba083ac0de69f643c6b501820987..d91a2ad4d5626c137551ae31ba9bb13b2bfcc7b0 100644 (file)
@@ -5,7 +5,7 @@ Paraslash is a collection of network audio streaming tools for Unix
 systems. It is written in C and released under the GPLv2.
 
 <ul>
-       <li> Runs on Linux, Mac OS, FreeBSD, NetBSD </li>
+       <li> Runs on Linux, FreeBSD, NetBSD </li>
        <li> Mp3, ogg/vorbis, ogg/speex, aac (m4a), wma, flac and ogg/opus support </li>
        <li> http, dccp and udp network streaming </li>
        <li> Stand-alone decoder, player, tagger </li>
index a09fd1c868f5c9aa1eabd9b004d00dc30754d256..c6ba266bfb834790e9f1fd868bf020412b4e0a4e 100644 (file)
@@ -9,9 +9,9 @@ provided at this point. There are several ways to download the source:
 
                Clone the git repository by executing
 
-               <p> <pre> <kbd>
+               <pre> <kbd>
                        git clone git://git.tuebingen.mpg.de/paraslash.git
-               </kbd> </pre> </p>
+               </kbd> </pre>
 
                <p> The repository contains the full history of the
                project since 2006, all work in progress and the source
index 12454ee2ae55ba131165ae2d442041879dad33b1..fef8123a3ac13bf44f0551e53aece8d001ac7495 100644 (file)
@@ -152,9 +152,8 @@ an array of offsets within the audio file.
 ### para_write ###
 
 A modular audio stream writer. It supports a simple file writer
-output plug-in and optional WAV/raw players for ALSA (Linux) and for
-coreaudio (Mac OS). para_write can also be used as a stand-alone WAV
-or raw audio player.
+output plug-in and optional WAV/raw players for ALSA (Linux) and OSS.
+para_write can also be used as a stand-alone WAV or raw audio player.
 
 ### para_play ###
 
@@ -448,9 +447,9 @@ User management
 para_server uses a challenge-response mechanism to authenticate
 requests from incoming connections, similar to ssh's public key
 authentication method. Authenticated connections are encrypted using
-a stream cipher, either RC4 or AES in integer counter mode.
+the AES stream cipher in integer counter mode.
 
-In this chapter we briefly describe RSA, RC4 and AES, and sketch the
+In this chapter we briefly describe RSA and AES, and sketch the
 [authentication handshake](#Client-server.authentication)
 between para_client and para_server. User management is discussed
 in the section on [the user_list file](#The.user_list.file).
@@ -458,33 +457,33 @@ These sections are all about communication between the client and the
 server. Connecting para_audiod is a different matter and is described
 in a [separate section](#Connecting.para_audiod).
 
-RSA, RC4, AES
--------------
+RSA and AES
+-----------
 
-RSA is an asymmetric block cipher which is used in many applications,
-including ssh and gpg. An RSA key consists in fact of two keys,
+A block cipher is a transformation which operates on fixed-length
+blocks. For symmetric block ciphers the transformation is determined
+by a single key for both encryption and decryption. For asymmetric
+block ciphers, on the other hand, the key consists of two parts,
 called the public key and the private key. A message can be encrypted
-with either key and only the counterpart of that key can decrypt
-the message. While RSA can be used for both signing and encrypting
-a message, paraslash uses RSA only for the latter purpose. The
-RSA public key encryption and signatures algorithms are defined in
-detail in RFC 2437.
-
-RC4 is a stream cipher, i.e. the input is XORed with a pseudo-random
-key stream to produce the output. Decryption uses the same function
-calls as encryption. While RC4 supports variable key lengths,
-paraslash uses a fixed length of 256 bits, which is considered a
-strong encryption by today's standards. Since the same key must never
-be used twice, a different, randomly-generated key is used for every
-new connection.
+with either key and only the counterpart of that key can decrypt the
+message. Asymmetric block ciphers can be used for both signing and
+encrypting a message.
+
+RSA is an asymmetric block cipher which is used in many applications,
+including ssh and gpg. The RSA public key encryption and signatures
+algorithms are defined in detail in RFC 2437. Paraslash relies on
+RSA for authentication.
+
+Stream ciphers XOR the input with a pseudo-random key stream to produce
+the output. Decryption uses the same function calls as encryption.
+Any block cipher can be turned into a stream cipher by generating the
+pseudo-random key stream by encrypting successive values of a counter
+(counter mode).
 
 AES, the advanced encryption standard, is a well-known symmetric block
-cipher, i.e. a transformation operating on fixed-length blocks which
-is determined by a single key for both encryption and decryption. Any
-block cipher can be turned into a stream cipher by generating
-a pseudo-random key stream by encrypting successive values of a
-counter. The AES_CTR128 stream cipher used in paraslash is obtained
-in this way from the AES block cipher with a 128 bit block size.
+cipher. Paraslash employs AES in counter mode as described above to
+encrypt communications. Since a stream cipher key must not be used
+twice, a random key is generated for every new connection.
 
 Client-server authentication
 ----------------------------
@@ -524,8 +523,8 @@ point on the communication is encrypted using the stream cipher with
 the session key known to both peers.
 
 paraslash relies on the quality of the pseudo-random bytes provided
-by the crypto library (openssl or libgcrypt), on the security of the
-implementation of the RSA, RC4 and AES crypto routines and on the
+by the crypto library (openssl or libgcrypt), on the security of
+the implementation of the RSA and AES crypto routines and on the
 infeasibility to invert the SHA1 function.
 
 Neither para_server or para_client create RSA keys on their
@@ -1700,10 +1699,6 @@ emulation for backwards compatibility. This API is rather simple but
 also limited. For example only one application can open the device
 at any time. The OSS writer is activated by default on BSD Systems.
 
-- *OSX*. Mac OS X has yet another API called CoreAudio. The OSX writer
-for this API is only compiled in on such systems and is of course
-the default there.
-
 - *FILE*. The file writer allows to capture the audio stream and
 write the PCM data to a file on the file system rather than playing
 it through a sound device. It is supported on all platforms and is
diff --git a/write.c b/write.c
index 62caf09757ec52d45f825698d7f4656696d7bcff..9ff3bc8406a252819a686d4d6e14d330951a6278 100644 (file)
--- a/write.c
+++ b/write.c
@@ -52,8 +52,8 @@ __noreturn static void print_help_and_die(void)
  * \param wn The writer node.
  *
  * If arg is \p NULL, the OS-dependent default writer is used with no
- * arguments.  The default writers are alsa for Linux, osx for OS X, oss for
- * *BSD, and the file writer if the default writer is not supported.
+ * arguments. The default writers are alsa for Linux and oss for *BSD, and the
+ * file writer if neither is supported.
  *
  * Once the writer configuration has been retrieved from the ->parse_config
  * callback a writer node is created, its buffer tree node is added to the