Skip to content

Commit

Permalink
Merge pull request #1 from donald/main
Browse files Browse the repository at this point in the history
Merge latest changes from donald/mxshadow
donald authored May 18, 2021
2 parents 97e50e9 + 854dea9 commit cfd7ba9
Showing 8 changed files with 167 additions and 90 deletions.
21 changes: 12 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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
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);
@@ -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) {
@@ -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);
@@ -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;
}
@@ -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;
}
@@ -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
@@ -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, '#');
@@ -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;
@@ -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;
@@ -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; }
@@ -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);
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) {
Loading

0 comments on commit cfd7ba9

Please sign in to comment.