diff --git a/misc/pam_authentication/makefile b/misc/pam_authentication/makefile index 47830dc9451abcd3baddb7cce9478e7998287afd..0cd1b7d250358a116a32a45ba18875d5f72d887a 100644 --- a/misc/pam_authentication/makefile +++ b/misc/pam_authentication/makefile @@ -4,6 +4,8 @@ # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen +# Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> +# Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -23,5 +25,5 @@ # Makefile for pam_authentication.c main: pam_authentication.c - [ -d ./bin ] || mkdir ./bin + mkdir -p ./bin gcc -o ./bin/pam_authentication pam_authentication.c -lpam -lpam_misc diff --git a/misc/pam_authentication/pam_authentication.c b/misc/pam_authentication/pam_authentication.c index 5d71ec2973fa59d18d10ffa4918a5236707b85af..906af84295829d1956175518f9fbfa9ef422f851 100644 --- a/misc/pam_authentication/pam_authentication.c +++ b/misc/pam_authentication/pam_authentication.c @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -23,17 +25,21 @@ // Pam Authentication // A. Schlemmer, 07/2018 -#include <security/pam_appl.h> -#include <security/pam_misc.h> +#include <stdbool.h> #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <termios.h> + +#include <security/pam_appl.h> +#include <security/pam_misc.h> -char * password; // needs to be global +char *password; // needs to be global int supply_password(int num_msg, const struct pam_message **msgm, struct pam_response **responsep, void *appdata_ptr) { - struct pam_response* response = (struct pam_response*)calloc(sizeof(struct pam_response), num_msg); + struct pam_response *response = + (struct pam_response*)calloc(sizeof(struct pam_response), num_msg); int i; for (i=0; i<num_msg; i++) { if (msgm[i]->msg_style == PAM_PROMPT_ECHO_OFF) { @@ -51,15 +57,76 @@ static struct pam_conv conv = NULL }; -int main(int args, char** argv) { - if (args != 3) { - fprintf(stderr, "Usage: pam_authentication username password\n"); +/** + * @brief Obtain the password from the given file. + * + * @param filename: If "-", read from stdin. + * + * @return 0 if successful, else 1. + */ +bool get_password(char *filename) { + // With code from https://stackoverflow.com/a/1196696/232888 + // by user https://stackoverflow.com/users/89266/dfa + struct termios backup, secret_setting; + + /* disable echo */ + tcgetattr(fileno(stdin), &backup); + secret_setting = backup; + secret_setting.c_lflag &= ~ECHO; + secret_setting.c_lflag |= ECHONL; + + if (tcsetattr(fileno(stdin), TCSANOW, &secret_setting) != 0) { + perror("Setting echo-less output flags failed."); + return EXIT_FAILURE; + } + + FILE *pwfile; + if (strcmp(filename, "-")) { + pwfile = fopen(filename, "r"); + if (pwfile == NULL) { + perror(filename); + tcsetattr(fileno(stdin), TCSANOW, &backup); + return false; + } + } else { + pwfile = stdin; + printf("Enter the password: "); + } + password = NULL; + size_t n = 0; + ssize_t pwlen = getline(&password, &n, pwfile); + if (strcmp(filename, "-")) { + fclose(pwfile); + } + password[pwlen - 1] = 0; + + /* restore terminal settings */ + if (tcsetattr(fileno(stdin), TCSANOW, &backup) != 0) { + perror("Resetting output flags failed."); + return EXIT_FAILURE; + } + + return true; +} + +int main(int argc, char **argv) { + if (argc < 2 || argc > 3) { + fprintf(stderr, "Usage: pam_authentication <username> [<password_file>]\n"); return 2; } pam_handle_t *pamh; - char * username = argv[1]; - password = argv[2]; + char *username = argv[1]; + char *pw_file = "-"; + if (argc == 3) { + pw_file = argv[2]; + } + + if (! get_password(pw_file)) { + fprintf(stderr, "Error while reading password.\n"); + return 3; + } + int res = pam_start("login", username, &conv, &pamh); if (!res == PAM_SUCCESS) { @@ -69,6 +136,7 @@ int main(int args, char** argv) { res = pam_authenticate(pamh, 0); // printf("Return code %i: %s\n", res, pam_strerror(pamh, res)); + free(password); return res; } diff --git a/misc/pam_authentication/pam_authentication.sh b/misc/pam_authentication/pam_authentication.sh index e2a6fb76d8bada2f21749d1e9c9f3f5330ef8555..972e48f1ccc9c65ca0c56773f7e20a5da0977ebb 100755 --- a/misc/pam_authentication/pam_authentication.sh +++ b/misc/pam_authentication/pam_authentication.sh @@ -5,6 +5,8 @@ # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen +# Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> +# Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -21,7 +23,7 @@ # # ** end header # -if ./bin/pam_authentication $1 $2 ; then +if ./bin/pam_authentication $1 ; then echo "[OK]" exit 0 else