summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2020-10-30 09:50:05 +0000
committerDaiki Ueno <ueno@gnu.org>2020-10-30 09:50:05 +0000
commitcc89b3c82a13fc88a6fbfb1e4d47278bebcf913a (patch)
treed915a35fa5d4353fb371d37f402d5759aa845114
parentf8c64c0c5bb23d04fb86a1fa524c2730ea8d048a (diff)
parente6f959a70235aaf2c31f719d66ff085f1ac85414 (diff)
downloadgnutls-cc89b3c82a13fc88a6fbfb1e4d47278bebcf913a.tar.gz
Merge branch 'wip/dueno/psk-colon' into 'master'
psktool: encode username if it contains special character Closes #1103 See merge request gnutls/gnutls!1345
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--bootstrap.conf14
-rw-r--r--configure.ac2
-rw-r--r--lib/psk.c5
-rw-r--r--src/psk.c102
-rw-r--r--src/srptool.c2
-rw-r--r--tests/suite/mini-record-timing.c29
7 files changed, 110 insertions, 46 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 82f52e5365..f09ebbf075 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -686,7 +686,7 @@ Debian.cross.i686-linux-gnu:
- export CC_FOR_BUILD="ccache gcc"
- export CC="ccache $host-gcc"
- ./bootstrap
- - sed -i '/errno.==.EINVAL/d' gl/tests/test-strerror.c
+ - sed -i '/errno.==.EINVAL/d' src/gl/tests/test-strerror.c
- mkdir -p build
- cd build
# Debian's softhsm package is not multiarch yet. Missing softhsm libraries
diff --git a/bootstrap.conf b/bootstrap.conf
index 8f7da96fd1..9e5a834cb5 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -19,16 +19,18 @@ source_base=gl
tests_base=gl/tests
m4_base=m4
gnulib_name=libgnu
-gnulib_tool_option_extras="--with-tests --avoid=alignof-tests --avoid=lock-tests --avoid=lseek-tests --lgpl=2"
+gnulib_tool_option_extras="--without-tests --avoid=alignof-tests --avoid=lock-tests --avoid=lseek-tests --lgpl=2"
use_libtool=1
checkout_only_file=
local_gl_dir=gl/override/
required_submodules="tests/suite/tls-fuzzer/python-ecdsa tests/suite/tls-fuzzer/tlsfuzzer tests/suite/tls-fuzzer/tlslite-ng devel/nettle devel/libtasn1"
-# Reproduce by: gnulib-tool --import --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --with-tests --avoid=alignof-tests --avoid=lock-tests --avoid=lseek-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files alloca attribute byteswap c-ctype extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash-pjw-bare havelib intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv snprintf stdint strcase strndup strtok_r strverscmp sys_socket sys_stat threadlib time_r unistd vasprintf verify vsnprintf warnings
-
+# Those modules are common to lib/ and src/.
+common_modules="
+alloca attribute byteswap c-ctype c-strcase fopen-gnu func getline gettext-h gettimeofday hash hash-pjw-bare arpa_inet inet_ntop inet_pton intprops memmem-simple minmax netdb netinet_in read-file secure_getenv setsockopt snprintf stdint stpcpy strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types threadlib time_r unistd valgrind-tests vasprintf verify vsnprintf
+"
gnulib_modules="
-alloca attribute byteswap c-ctype c-strcase extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash hash-pjw-bare havelib arpa_inet inet_ntop inet_pton intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv setsockopt snprintf stdint stpcpy strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types threadlib time_r unistd valgrind-tests vasprintf verify vsnprintf warnings
+$common_modules extensions gendocs havelib ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings pmccabe2html warnings
"
unistring_modules="
@@ -36,7 +38,7 @@ unictype/category-all unictype/property-default-ignorable-code-point unictype/pr
"
src_modules="
-accept bind close connect getaddrinfo getpass gettext-h arpa_inet inet_ntop inet_pton inttypes listen linked-list minmax parse-datetime progname read-file recv recvfrom select send sendto servent setsockopt shutdown socket sockets socklen stpcpy xalloc xlist xsize
+$common_modules accept bind close close-stream connect getaddrinfo getpass inttypes listen linked-list parse-datetime progname read-file recv recvfrom select send sendto servent setsockopt shutdown socket sockets socklen xalloc xlist xsize
"
# Build prerequisites
@@ -95,7 +97,7 @@ bootstrap_post_import_hook ()
${GNULIB_SRCDIR}/gnulib-tool --import --local-dir=lib/unistring/override --lib=libunistring --source-base=lib/unistring --m4-base=lib/unistring/m4 --doc-base=doc --aux-dir=build-aux --lgpl=3orGPLv2 --no-conditional-dependencies --libtool --without-tests --macro-prefix=unistring ${unistring_modules}
- ${GNULIB_SRCDIR}/gnulib-tool --import --local-dir=src/gl/override --lib=libgnu_gpl --source-base=src/gl --m4-base=src/gl/m4 --doc-base=doc --aux-dir=build-aux --no-conditional-dependencies --libtool --macro-prefix=ggl --without-tests --no-vc-files ${src_modules}
+ ${GNULIB_SRCDIR}/gnulib-tool --import --local-dir=src/gl/override --lib=libgnu_gpl --source-base=src/gl --m4-base=src/gl/m4 --doc-base=doc --tests-base=src/gl/tests --aux-dir=build-aux --no-conditional-dependencies --libtool --macro-prefix=ggl --with-tests --no-vc-files ${src_modules}
# git -C ${GNULIB_SRCDIR} reset --hard
diff --git a/configure.ac b/configure.ac
index e485699f30..42e3c0bc3f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1209,7 +1209,6 @@ AC_CONFIG_FILES([
libdane/includes/Makefile
libdane/gnutls-dane.pc
gl/Makefile
- gl/tests/Makefile
guile/Makefile
guile/src/Makefile
lib/Makefile
@@ -1231,6 +1230,7 @@ AC_CONFIG_FILES([
src/Makefile
src/args-std.def
src/gl/Makefile
+ src/gl/tests/Makefile
tests/Makefile
tests/windows/Makefile
tests/cert-tests/Makefile
diff --git a/lib/psk.c b/lib/psk.c
index 6ea3adb63c..e5f2b05311 100644
--- a/lib/psk.c
+++ b/lib/psk.c
@@ -231,6 +231,11 @@ gnutls_psk_allocate_server_credentials(gnutls_psk_server_credentials_t *
* #gnutls_psk_server_credentials_t type. This password file
* holds usernames and keys and will be used for PSK authentication.
*
+ * Each entry in the file consists of a username, followed by a colon
+ * (':') and a hex-encoded key. If the username contains a colon or
+ * any other special character, it can be hex-encoded preceded by a
+ * '#'.
+ *
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
* an error code is returned.
**/
diff --git a/src/psk.c b/src/psk.c
index 6f77c6f285..b79401cf16 100644
--- a/src/psk.c
+++ b/src/psk.c
@@ -37,11 +37,13 @@ int main(int argc, char **argv)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
#include <gnutls/gnutls.h>
#include <psktool-args.h>
#include <gnutls/crypto.h> /* for random */
+#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -54,9 +56,11 @@ int main(int argc, char **argv)
/* Gnulib portability files. */
#include <minmax.h>
+#include "close-stream.h"
#include "getpass.h"
-static int write_key(const char *username, const char *key, int key_size,
+static int write_key(const char *username,
+ const unsigned char *key, size_t key_size,
const char *passwd_file);
#define MAX_KEY_SIZE 512
@@ -67,11 +71,8 @@ int main(int argc, char **argv)
struct passwd *pwd;
#endif
unsigned char key[MAX_KEY_SIZE];
- char hex_key[MAX_KEY_SIZE * 2 + 1];
- int key_size;
- gnutls_datum_t dkey;
+ size_t key_size;
const char *passwd, *username;
- size_t hex_key_size = sizeof(hex_key);
if ((ret = gnutls_global_init()) < 0) {
fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret));
@@ -123,16 +124,7 @@ int main(int argc, char **argv)
exit(1);
}
- dkey.data = key;
- dkey.size = key_size;
-
- ret = gnutls_hex_encode(&dkey, hex_key, &hex_key_size);
- if (ret < 0) {
- fprintf(stderr, "HEX encoding error\n");
- exit(1);
- }
-
- ret = write_key(username, hex_key, hex_key_size, passwd);
+ ret = write_key(username, key, key_size, passwd);
if (ret == 0)
printf("Key stored to %s\n", passwd);
@@ -175,19 +167,18 @@ static int filecopy(const char *src, const char *dst)
}
static int
-write_key(const char *username, const char *key, int key_size,
+write_key(const char *username, const unsigned char *key, size_t key_size,
const char *passwd_file)
{
FILE *fp;
char line[5 * 1024];
char *p, *pp;
char tmpname[1024];
-
-
- /* delete previous entry */
+ gnutls_datum_t tmp, _username = { NULL, 0 }, _key = { NULL, 0 };
struct stat st;
FILE *fp2;
- int put;
+ bool put;
+ int ret = 0;
if (strlen(passwd_file) + 5 > sizeof(tmpname)) {
fprintf(stderr, "file '%s' is tooooo long\n", passwd_file);
@@ -223,8 +214,49 @@ write_key(const char *username, const char *key, int key_size,
return -1;
}
- put = 0;
- do {
+ /* encode username if it contains special characters */
+ if (strcspn(username, ":\n") != strlen(username)) {
+ char *new_data;
+
+ tmp.data = (void *)username;
+ tmp.size = strlen(username);
+
+ ret = gnutls_hex_encode2(&tmp, &_username);
+ if (ret < 0) {
+ fprintf(stderr, "HEX encoding error\n");
+ ret = -1;
+ goto out;
+ }
+
+ /* prepend '#' */
+ new_data = gnutls_realloc(_username.data, _username.size + 2);
+ if (!new_data) {
+ ret = -1;
+ goto out;
+ }
+ memmove(_username.data + 1, _username.data, _username.size);
+ new_data[0] = '#';
+ new_data[_username.size] = '\0';
+ _username.data = (void *)new_data;
+ _username.size += 1;
+ } else {
+ _username.data = (void *)strdup(username);
+ _username.size = strlen(username);
+ }
+
+ /* encode key */
+ tmp.data = (void *)key;
+ tmp.size = key_size;
+
+ ret = gnutls_hex_encode2(&tmp, &_key);
+ if (ret < 0) {
+ fprintf(stderr, "HEX encoding error\n");
+ ret = -1;
+ goto out;
+ }
+
+ put = false;
+ while (true) {
p = fgets(line, sizeof(line) - 1, fp2);
if (p == NULL)
break;
@@ -233,28 +265,34 @@ write_key(const char *username, const char *key, int key_size,
if (pp == NULL)
continue;
- if (strncmp(p, username,
- MAX(strlen(username),
+ if (strncmp(p, (const char *) _username.data,
+ MAX(_username.size,
(unsigned int) (pp - p))) == 0) {
- put = 1;
- fprintf(fp, "%s:%s\n", username, key);
+ put = true;
+ fprintf(fp, "%s:%s\n", _username.data, _key.data);
} else {
fputs(line, fp);
}
}
- while (1);
- if (put == 0) {
- fprintf(fp, "%s:%s\n", username, key);
+ if (!put) {
+ fprintf(fp, "%s:%s\n", _username.data, _key.data);
+ }
+
+ out:
+ if (close_stream(fp) == EOF) {
+ fprintf(stderr, "Error writing %s: %s\n",
+ passwd_file, strerror(errno));
+ ret = -1;
}
- fclose(fp);
fclose(fp2);
(void)remove(tmpname);
+ gnutls_free(_username.data);
+ gnutls_free(_key.data);
-
- return 0;
+ return ret;
}
#endif /* ENABLE_PSK */
diff --git a/src/srptool.c b/src/srptool.c
index 7da14afa6c..a9715e6a37 100644
--- a/src/srptool.c
+++ b/src/srptool.c
@@ -529,6 +529,7 @@ crypt_int(const char *username, const char *passwd, int salt_size,
p = fgets(line, sizeof(line) - 1, fp);
}
while (p != NULL && atoi(p) != uindex);
+ fclose(fp);
if (p == NULL) {
fprintf(stderr, "Cannot find entry in %s\n", tpasswd_conf);
@@ -536,7 +537,6 @@ crypt_int(const char *username, const char *passwd, int salt_size,
}
line[sizeof(line) - 1] = 0;
- fclose(fp);
if ((iindex = read_conf_values(&g, &n, line)) < 0) {
fprintf(stderr, "Cannot parse conf file '%s'\n",
tpasswd_conf);
diff --git a/tests/suite/mini-record-timing.c b/tests/suite/mini-record-timing.c
index 093f3d5d32..4cdd78f472 100644
--- a/tests/suite/mini-record-timing.c
+++ b/tests/suite/mini-record-timing.c
@@ -495,11 +495,30 @@ static void ch_handler(int sig)
wait(&status);
if (WEXITSTATUS(status) != 0 ||
(WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)) {
- if (WIFSIGNALED(status))
- fprintf(stderr, "Child died with sigsegv\n");
- else
- fprintf(stderr, "Child died with status %d\n",
- WEXITSTATUS(status));
+ /* This code must be async-signal-safe. */
+ if (WIFSIGNALED(status)) {
+ const char msg[] = "Child died with sigsegv\n";
+ write(STDERR_FILENO, "Child died with sigsegv\n", sizeof(msg));
+ } else {
+ char buf[64] = { 0 };
+ char *p;
+
+ p = stpcpy(buf, "Child died with status ");
+
+ status = WEXITSTATUS(status) & 0377;
+ if (status > 100) {
+ *p++ = '0' + status / 100;
+ status %= 100;
+ }
+ if (status > 10) {
+ *p++ = '0' + status / 10;
+ status %= 10;
+ }
+ *p++ = '0' + status;
+ *p++ = '\n';
+
+ write(STDERR_FILENO, buf, p - buf);
+ }
}
return;
}