login_token.c revision 1.16
1/* $OpenBSD: login_token.c,v 1.16 2019/06/28 13:32:53 deraadt Exp $ */ 2 3/*- 4 * Copyright (c) 1995, 1996 Berkeley Software Design, Inc. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Berkeley Software Design, 17 * Inc. 18 * 4. The name of Berkeley Software Design, Inc. may not be used to endorse 19 * or promote products derived from this software without specific prior 20 * written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * BSDI $From: login_token.c,v 1.2 1996/09/04 05:33:05 prb Exp $ 35 */ 36 37#include <sys/types.h> 38#include <sys/time.h> 39#include <sys/resource.h> 40 41#include <err.h> 42#include <readpassphrase.h> 43#include <signal.h> 44#include <stdlib.h> 45#include <stdio.h> 46#include <syslog.h> 47#include <limits.h> 48#include <string.h> 49#include <unistd.h> 50#include <login_cap.h> 51#include <bsd_auth.h> 52 53#include "token.h" 54 55int 56main(int argc, char *argv[]) 57{ 58 FILE *back = NULL; 59 char *username = NULL; 60 char *instance; 61 char challenge[1024]; 62 char response[1024]; 63 char *pp = NULL; 64 int c; 65 int mode = 0; 66 struct rlimit cds; 67 sigset_t blockset; 68 69 (void)setpriority(PRIO_PROCESS, 0, 0); 70 71 /* We block keyboard-generated signals during database accesses. */ 72 sigemptyset(&blockset); 73 sigaddset(&blockset, SIGINT); 74 sigaddset(&blockset, SIGQUIT); 75 sigaddset(&blockset, SIGTSTP); 76 77 openlog(NULL, LOG_ODELAY, LOG_AUTH); 78 79 cds.rlim_cur = 0; 80 cds.rlim_max = 0; 81 if (setrlimit(RLIMIT_CORE, &cds) == -1) 82 syslog(LOG_ERR, "couldn't set core dump size to 0: %m"); 83 84 if (pledge("stdio rpath wpath cpath fattr flock getpw tty", NULL) == -1) { 85 syslog(LOG_ERR, "pledge: %m"); 86 exit(1); 87 } 88 89 (void)sigprocmask(SIG_BLOCK, &blockset, NULL); 90 if (token_init(argv[0]) < 0) { 91 syslog(LOG_ERR, "unknown token type"); 92 errx(1, "unknown token type"); 93 } 94 (void)sigprocmask(SIG_UNBLOCK, &blockset, NULL); 95 96 while ((c = getopt(argc, argv, "ds:v:")) != -1) 97 switch (c) { 98 case 'd': /* to remain undocumented */ 99 back = stdout; 100 break; 101 case 'v': 102 break; 103 case 's': /* service */ 104 if (strcmp(optarg, "login") == 0) 105 mode = 0; 106 else if (strcmp(optarg, "challenge") == 0) 107 mode = 1; 108 else if (strcmp(optarg, "response") == 0) 109 mode = 2; 110 else { 111 syslog(LOG_ERR, "%s: invalid service", optarg); 112 exit(1); 113 } 114 break; 115 default: 116 syslog(LOG_ERR, "usage error"); 117 exit(1); 118 } 119 120 switch (argc - optind) { 121 case 2: 122 case 1: 123 username = argv[optind]; 124 break; 125 default: 126 syslog(LOG_ERR, "usage error"); 127 exit(1); 128 } 129 130 131 if (back == NULL && (back = fdopen(3, "r+")) == NULL) { 132 syslog(LOG_ERR, "reopening back channel"); 133 exit(1); 134 } 135 if (mode == 2) { 136 mode = 0; 137 c = -1; 138 while (++c < sizeof(challenge) && 139 read(3, &challenge[c], 1) == 1) { 140 if (challenge[c] == '\0' && ++mode == 2) 141 break; 142 if (challenge[c] == '\0' && mode == 1) 143 pp = challenge + c + 1; 144 } 145 if (mode < 2) { 146 syslog(LOG_ERR, "protocol error on back channel"); 147 exit(1); 148 } 149 } else { 150 (void)sigprocmask(SIG_BLOCK, &blockset, NULL); 151 tokenchallenge(username, challenge, sizeof(challenge), 152 tt->proper); 153 (void)sigprocmask(SIG_UNBLOCK, &blockset, NULL); 154 if (mode == 1) { 155 fprintf(back, BI_VALUE " challenge %s\n", 156 auth_mkvalue(challenge)); 157 fprintf(back, BI_CHALLENGE "\n"); 158 exit(0); 159 } 160 161 pp = readpassphrase(challenge, response, sizeof(response), 0); 162 if (pp == NULL) 163 exit(1); 164 if (*pp == '\0') { 165 char buf[64]; 166 snprintf(buf, sizeof(buf), "%s Response [echo on]: ", 167 tt->proper); 168 pp = readpassphrase(buf, response, sizeof(response), 169 RPP_ECHO_ON); 170 if (pp == NULL) 171 exit(1); 172 } 173 } 174 175 (void)sigprocmask(SIG_BLOCK, &blockset, NULL); 176 if (tokenverify(username, challenge, pp) == 0) { 177 fprintf(back, BI_AUTH "\n"); 178 179 if ((instance = strchr(username, '.'))) { 180 *instance++ = 0; 181 if (strcmp(instance, "root") == 0) 182 fprintf(back, BI_ROOTOKAY "\n"); 183 } 184 fprintf(back, BI_SECURE "\n"); 185 exit(0); 186 } 187 188 fprintf(back, BI_REJECT "\n"); 189 exit(1); 190} 191