1/* 2 * Copyright (c) 1999-2005, 2008, 2010 3 * Todd C. Miller <Todd.Miller@courtesan.com> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * 17 * Sponsored in part by the Defense Advanced Research Projects 18 * Agency (DARPA) and Air Force Research Laboratory, Air Force 19 * Materiel Command, USAF, under agreement number F39502-99-1-0512. 20 */ 21 22#include <config.h> 23 24#include <sys/types.h> 25#include <sys/param.h> 26#include <stdio.h> 27#ifdef STDC_HEADERS 28# include <stdlib.h> 29# include <stddef.h> 30#else 31# ifdef HAVE_STDLIB_H 32# include <stdlib.h> 33# endif 34#endif /* STDC_HEADERS */ 35#ifdef HAVE_STRING_H 36# include <string.h> 37#endif /* HAVE_STRING_H */ 38#ifdef HAVE_STRINGS_H 39# include <strings.h> 40#endif /* HAVE_STRING_H */ 41#ifdef HAVE_UNISTD_H 42# include <unistd.h> 43#endif /* HAVE_UNISTD_H */ 44#include <pwd.h> 45 46#include <auth.h> 47#include <firewall.h> 48 49#include "sudo.h" 50#include "sudo_auth.h" 51 52int 53fwtk_init(pw, auth) 54 struct passwd *pw; 55 sudo_auth *auth; 56{ 57 static Cfg *confp; /* Configuration entry struct */ 58 char resp[128]; /* Response from the server */ 59 60 if ((confp = cfg_read("sudo")) == (Cfg *)-1) { 61 warningx("cannot read fwtk config"); 62 return AUTH_FATAL; 63 } 64 65 if (auth_open(confp)) { 66 warningx("cannot connect to authentication server"); 67 return AUTH_FATAL; 68 } 69 70 /* Get welcome message from auth server */ 71 if (auth_recv(resp, sizeof(resp))) { 72 warningx("lost connection to authentication server"); 73 return AUTH_FATAL; 74 } 75 if (strncmp(resp, "Authsrv ready", 13) != 0) { 76 warningx("authentication server error:\n%s", resp); 77 return AUTH_FATAL; 78 } 79 80 return AUTH_SUCCESS; 81} 82 83int 84fwtk_verify(pw, prompt, auth) 85 struct passwd *pw; 86 char *prompt; 87 sudo_auth *auth; 88{ 89 char *pass; /* Password from the user */ 90 char buf[SUDO_PASS_MAX + 12]; /* General prupose buffer */ 91 char resp[128]; /* Response from the server */ 92 int error; 93 94 /* Send username to authentication server. */ 95 (void) snprintf(buf, sizeof(buf), "authorize %s 'sudo'", pw->pw_name); 96restart: 97 if (auth_send(buf) || auth_recv(resp, sizeof(resp))) { 98 warningx("lost connection to authentication server"); 99 return AUTH_FATAL; 100 } 101 102 /* Get the password/response from the user. */ 103 if (strncmp(resp, "challenge ", 10) == 0) { 104 (void) snprintf(buf, sizeof(buf), "%s\nResponse: ", &resp[10]); 105 pass = tgetpass(buf, def_passwd_timeout * 60, tgetpass_flags); 106 if (pass && *pass == '\0') { 107 pass = tgetpass("Response [echo on]: ", 108 def_passwd_timeout * 60, tgetpass_flags | TGP_ECHO); 109 } 110 } else if (strncmp(resp, "chalnecho ", 10) == 0) { 111 pass = tgetpass(&resp[10], def_passwd_timeout * 60, tgetpass_flags); 112 } else if (strncmp(resp, "password", 8) == 0) { 113 pass = tgetpass(prompt, def_passwd_timeout * 60, 114 tgetpass_flags); 115 } else if (strncmp(resp, "display ", 8) == 0) { 116 fprintf(stderr, "%s\n", &resp[8]); 117 strlcpy(buf, "response dummy", sizeof(buf)); 118 goto restart; 119 } else { 120 warningx("%s", resp); 121 return AUTH_FATAL; 122 } 123 if (!pass) { /* ^C or error */ 124 return AUTH_INTR; 125 } 126 127 /* Send the user's response to the server */ 128 (void) snprintf(buf, sizeof(buf), "response '%s'", pass); 129 if (auth_send(buf) || auth_recv(resp, sizeof(resp))) { 130 warningx("lost connection to authentication server"); 131 error = AUTH_FATAL; 132 goto done; 133 } 134 135 if (strncmp(resp, "ok", 2) == 0) { 136 error = AUTH_SUCCESS; 137 goto done; 138 } 139 140 /* Main loop prints "Permission Denied" or insult. */ 141 if (strcmp(resp, "Permission Denied.") != 0) 142 warningx("%s", resp); 143 error = AUTH_FAILURE; 144done: 145 zero_bytes(pass, strlen(pass)); 146 zero_bytes(buf, strlen(buf)); 147 return error; 148} 149 150int 151fwtk_cleanup(pw, auth) 152 struct passwd *pw; 153 sudo_auth *auth; 154{ 155 156 auth_close(); 157 return AUTH_SUCCESS; 158} 159