diff options
Diffstat (limited to 'ostp.d/net')
-rw-r--r-- | ostp.d/net/otd_auth.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/ostp.d/net/otd_auth.c b/ostp.d/net/otd_auth.c index 6e757ae..67b4885 100644 --- a/ostp.d/net/otd_auth.c +++ b/ostp.d/net/otd_auth.c @@ -27,13 +27,16 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include <sys/wait.h> #include <arpa/inet.h> #include <net/auth.h> +#include <net/listen.h> #include <net/param.h> #include <net/stpsession.h> #include <crypto/ecdh.h> #include <otconfig.h> #include <stdio.h> +#include <unistd.h> #define KEY_BYTE_WIDTH 32 @@ -62,6 +65,92 @@ send_motd(int client_fd, const unsigned char *session_key) } /* + * Check a password to see if it matches with + * the hash in /etc/shadow by using the pwcheck + * script. Returns 0 on success. + */ +static int +pwcheck(char *username, char *pw) +{ + char *pwcheck = "/usr/local/bin/pwcheck"; + pid_t pid; + char *args[] = {pwcheck, username, pw, NULL}; + int status; + + pid = fork(); + if (pid == 0) { + execv(pwcheck, args); + } + + if (waitpid(pid, &status, 0) < 0) { + printf("waidpid() failed\n"); + return -1; + } + + if (WIFEXITED(status)) { + return WEXITSTATUS(status); + } + + return -1; +} + +static int +passwd_auth(int client_fd, const unsigned char *session_key) +{ + int error; + struct session_auth auth; + const size_t LEN = sizeof(auth); + + if (!REQUIRE_USER_AUTH) { + return 0; + } + + error = recv_frame(client_fd, sizeof(auth), session_key, &auth); + if (error < 0) { + return error; + } + + if (pwcheck(auth.username, auth.password) != 0) { + printf("Got bad password for %s\n", auth.username); + auth.code = AUTH_BAD_PW; + error = send_frame(client_fd, &auth, sizeof(auth), session_key); + if (error < 0) { + printf("Failed to ACK user authentication with frame\n"); + } + return -1; + } + + auth.code = AUTH_SUCCESS; + error = send_frame(client_fd, &auth, sizeof(auth), session_key); + if (error < 0) { + printf("Failed to ACK user authentication with frame\n"); + return error; + } + return 0; +} + +static int +client_echo(int client_fd, const unsigned char *session_key) +{ + char buf[4096]; + int error; + + error = recv_frame(client_fd, sizeof(buf) - 1, session_key, buf); + if (error < 0) { + return error; + } + + /* Echo frame to all clients */ + for (size_t i = 1; i < MAX_CLIENTS; ++i) { + if (clients[i] <= 0) + continue; + + send_frame(clients[i], buf, sizeof(buf), session_key); + } + + return 0; +} +/* * Verify the session request packet and handle * the rest. * @@ -75,6 +164,13 @@ handle_srq(int client_fd, struct session_request *srq) unsigned char *session_key; int error; + if (REQUIRE_USER_AUTH && !ISSET(srq->options, SESSION_REQ_USER)) { + printf("%x\n", srq->options); + printf("User authentication enforced but client 'U' bit not set\n"); + printf("Closing connection...\n"); + return -1; + } + printf("Got public key from peer: \n"); log_pubkey(srq->pubkey); printf("Generating keys...\n"); |