Skip to content

Merge latest changes from donald/mxshadow #1

Merged
merged 21 commits into from
May 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,28 @@ INSTALL=install -v
INSTALL_PROGRAM = $(INSTALL)
INSTALL_DATA = $(INSTALL) -m 644

CFLAGS=-O3 -Wall -Werror
#CFLAGS=-O0 -g -Wall
ifdef DEBUG
CFLAGS=-O0 -g -Wall -DDEBUG_MAX_CONNECTS=10
else
CFLAGS=-O3 -Wall -Werror
endif

all: mxshadowsrv libnss_mxshadow.so.2 test_server test_query_shadow

get_shadow_line.o: get_shadow_line.c get_shadow_line.h common.h
gcc $(CFLAGS) -c -fPIC -o get_shadow_line.o get_shadow_line.c

libnss_mxshadow.so.2: libnss_mxshadow.c get_shadow_line.c common.h
gcc $(CFLAGS) -shared -o libnss_mxshadow.so.2 -Wl,-soname,libnss_mxshadow.so.2,-unresolved-symbols=report-all -fPIC libnss_mxshadow.c get_shadow_line.c -l:libssl.a -l:libcrypto.a -lpthread -ldl
gcc $(CFLAGS) -shared -o libnss_mxshadow.so.2 -Wl,-soname,libnss_mxshadow.so.2,-unresolved-symbols=report-all -fPIC libnss_mxshadow.c -l:libssl.a -l:libcrypto.a -lpthread -ldl

test_server: test_server.c get_shadow_line.c common.h
gcc $(CFLAGS) -o test_server test_server.c -l:libssl.a -l:libcrypto.a -lpthread -ldl

test_server: test_server.c get_shadow_line.c common.h get_shadow_line.h
gcc $(CFLAGS) -o test_server test_server.c get_shadow_line.c -l:libssl.a -l:libcrypto.a -lpthread -ldl
test_query_shadow: test_query_shadow.c get_shadow_line.c common.h
gcc $(CFLAGS) -o test_query_shadow test_query_shadow.c -l:libssl.a -l:libcrypto.a -lpthread -ldl

mxshadowsrv: mxshadowsrv.c common.h
gcc $(CFLAGS) -o mxshadowsrv mxshadowsrv.c -l:libssl.a -l:libcrypto.a -lpthread -ldl

clean:
@rm *.o libnss_mxshadow.so.2 mxshadowsrv test_server test_query_shadow >/dev/null || true
@rm *.o libnss_mxshadow.so.2 mxshadowsrv test_server test_query_shadow 2>/dev/null || true

install: all
$(INSTALL) -D -t $(DESTDIR)$(usr_sbindir) mxshadowsrv
Expand Down
44 changes: 31 additions & 13 deletions common.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
#ifndef _COMMON_H
#define _COMMON_H

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <poll.h>
#include <unistd.h>
#include <stdio.h>

#define _cleanup_(x) __attribute__((cleanup(x)))

#ifndef COMMON_LOG
#include <stdio.h>
#define COMMON_LOG(prio, msg, ...) (fprintf(stderr, msg "\n", ## __VA_ARGS__ ))
#endif

static void __attribute__((unused)) free_ssl_ctx(SSL_CTX **ctxp) {
if (*ctxp) {
SSL_CTX_free(*ctxp);
Expand Down Expand Up @@ -37,8 +44,15 @@ static void __attribute__((unused)) free_string(char **ptr) {
}

static void __attribute__((unused)) psslerror(char *str) {
fprintf(stderr, "%s\n", str);
ERR_print_errors_fp(stderr);
COMMON_LOG(LOG_ERR, "%s:", str);
unsigned long ssl_err;
while ((ssl_err = ERR_get_error())) {
COMMON_LOG(LOG_ERR, "ssl error: %lud:%s:%s:%s",
ssl_err,
ERR_lib_error_string(ssl_err),
ERR_func_error_string(ssl_err),
ERR_reason_error_string(ssl_err));
}
}

static int wait_rd_with_timeout(int fd, int timeout) {
Expand Down Expand Up @@ -77,7 +91,8 @@ static int __attribute__((unused)) ssl_write_with_timeout(SSL *ssl, int fd, char
if (status > 0) {
if (status == datalen)
return 0;
fprintf(stderr, "%s: unexpected partial write. requested %lud bytes, returned: %d\n", __func__, datalen, status);
COMMON_LOG(LOG_ERR, "%s: unexpected partial write. requested %lud bytes, returned: %d", __func__, datalen, status);
errno = EPIPE;
return -1;
}
int ssl_error = SSL_get_error(ssl, status);
Expand All @@ -88,14 +103,14 @@ static int __attribute__((unused)) ssl_write_with_timeout(SSL *ssl, int fd, char
return -1;
continue;
case SSL_ERROR_SYSCALL:
perror(__func__);
COMMON_LOG(LOG_ERR, "%s: %m", __func__);
return -1;
case SSL_ERROR_SSL:
ERR_print_errors_fp(stderr);
psslerror("");
errno = EPROTO;
return -1;
default:
fprintf(stderr, "%s: %s unimplemented\n", __func__, ssl_err(ssl_error));
COMMON_LOG(LOG_ERR, "%s: %s unimplemented", __func__, ssl_err(ssl_error));
errno = ENOSYS;
return -1;
}
Expand All @@ -116,15 +131,16 @@ static int __attribute__((unused)) ssl_read_with_timeout(SSL *ssl, int fd, void
continue;
case SSL_ERROR_SYSCALL:
if (errno==0) {
fprintf(stderr, "%s: unexpected EOF from peer\n", __func__);
COMMON_LOG(LOG_ERR, "%s: unexpected EOF from peer", __func__);
errno = ECONNABORTED;
return -1;
}
perror(__func__);
COMMON_LOG(LOG_ERR, "%s: %m", __func__);
return -1;
case SSL_ERROR_ZERO_RETURN:
return 0;
default:
fprintf(stderr, "%s: %s unimplemented\n", __func__, ssl_err(ssl_error));
COMMON_LOG(LOG_ERR, "%s: %s unimplemented", __func__, ssl_err(ssl_error));
errno = ENOSYS;
return -1;
}
Expand All @@ -144,16 +160,18 @@ static int __attribute__((unused)) ssl_accept_with_timeout(SSL *ssl, int fd, in
return -1;
continue;
case SSL_ERROR_SYSCALL:
perror(__func__);
COMMON_LOG(LOG_ERR, "%s: %m", __func__);
return -1;
case SSL_ERROR_SSL:
ERR_print_errors_fp(stderr);
psslerror("");
errno = EPROTO;
return -1;
default:
fprintf(stderr, "%s: %s unimplemented\n", __func__, ssl_err(ssl_error));
COMMON_LOG(LOG_ERR, "%s: %s unimplemented", __func__, ssl_err(ssl_error));
errno = ENOSYS;
return -1;
}
}
}

#endif /* _COMMON_H */
31 changes: 17 additions & 14 deletions get_shadow_line.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,24 @@
#include <unistd.h>

#include "common.h"
#include "get_shadow_line.h"

static char conf_filename[] = "/etc/mxshadow.conf";
#define TIMEOUT 5000

static int read_config(struct sockaddr_in *addr) {
static const char conf_filename[] = "/etc/mxshadow.conf";
FILE *f _cleanup_(free_file) = NULL;
char *line _cleanup_(free_string) = NULL;
size_t n = 0;
f = fopen(conf_filename, "r");
if (f == NULL) { perror(conf_filename); return(-1); }
if (f == NULL) { COMMON_LOG(LOG_ERR, "%s: %m", conf_filename); return(-1); }
char *server _cleanup_(free_string) = NULL;
int port = -1;
while (1) {
int status = getline(&line, &n, f);
if (status == -1) {
if (feof(f))
break;
perror(conf_filename);
COMMON_LOG(LOG_ERR, "%s: %m", conf_filename);
return -1;
}
char *comment = strchr(line, '#');
Expand All @@ -36,12 +36,15 @@ static int read_config(struct sockaddr_in *addr) {
sscanf(line, "port = %u \n", &port);
}
if (server == NULL || port == -1) {
fprintf(stderr, "%s: does not set server and port\n", conf_filename);
COMMON_LOG(LOG_ERR, "%s: does not set server and port", conf_filename);
errno = EINVAL;
return -1;
}
int status = inet_aton(server, &addr->sin_addr);
if (status == 0) {
fprintf(stderr, "%s: not a invalid ip address: %s\n", conf_filename, server);
COMMON_LOG(LOG_ERR, "%s: not a invalid ip address: %s\n", conf_filename, server);
errno = EINVAL;
return -1;
}
addr->sin_port = htons(port);
return 0;
Expand Down Expand Up @@ -78,11 +81,11 @@ static int connect_with_timeout(int sockfd, struct sockaddr *addr, socklen_t add

#define BUFLEN_SPWD (1024)

int get_shadow_line(char *user, char **line) {
static int get_shadow_line(char *user, char **line) {

struct sockaddr_in sockaddr;
bzero(&sockaddr, sizeof(sockaddr));
sockaddr.sin_family =AF_INET;
sockaddr.sin_family = AF_INET;

int status = read_config(&sockaddr);
if (status == -1) return -1;
Expand All @@ -94,10 +97,10 @@ int get_shadow_line(char *user, char **line) {
if (SSL_CTX_load_verify_locations(ssl_ctx, "/etc/mxshadow.cert.pem", NULL) == 0) { psslerror("SSL_CTX_load_verify_locations"); return -1; }

int sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if (sock == 0) { perror("socket"); return -1; }
if (sock == 0) { COMMON_LOG(LOG_ERR, "socket: %m"); return -1; }

status = connect_with_timeout(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr), 1000);
if (status == -1) { perror("connect"); return -1; }
status = connect_with_timeout(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr), TIMEOUT);
if (status == -1) { COMMON_LOG(LOG_ERR, "connect: %m"); return -1; }

SSL *ssl _cleanup_(free_ssl) = SSL_new(ssl_ctx);
if (ssl == NULL) { psslerror("SSL_new"); return -1; }
Expand All @@ -108,17 +111,17 @@ int get_shadow_line(char *user, char **line) {
if (status == 0) { psslerror("SSL_set_fd"); return -1; }

int len = strlen(user);
status = ssl_write_with_timeout(ssl, sock, user, len, 1000);
status = ssl_write_with_timeout(ssl, sock, user, len, TIMEOUT);
if (status == -1) {
fprintf(stderr, "ssl_write_with_timeout failed\n");
COMMON_LOG(LOG_ERR, "ssl_write_with_timeout failed");
return -1;
}

char *buffer _cleanup_(free_string) = malloc(BUFLEN_SPWD);
if (buffer == NULL)
return -1;

len = ssl_read_with_timeout(ssl, sock, buffer, BUFLEN_SPWD, 1000);
len = ssl_read_with_timeout(ssl, sock, buffer, BUFLEN_SPWD, TIMEOUT);
if (len<0)
return -1;
SSL_shutdown(ssl);
Expand Down
6 changes: 0 additions & 6 deletions get_shadow_line.h

This file was deleted.

4 changes: 3 additions & 1 deletion libnss_mxshadow.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#include <nss.h>
#include <shadow.h>
#include <errno.h>
#include <syslog.h>

#include "get_shadow_line.h"
#define COMMON_LOG(prio, msg, ...) (syslog(LOG_AUTH|prio, msg, ## __VA_ARGS__ ))
#include "get_shadow_line.c"
#include "common.h"

enum nss_status _nss_mxshadow_getspnam_r(const char *name, struct spwd *spwd, char *buffer, size_t buflen, int *errnop) {
Expand Down
Loading