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"); | 
