login_token.c revision 1.6
147060Ssemenu/* $OpenBSD: login_token.c,v 1.6 2002/06/02 01:27:16 deraadt Exp $ */ 247060Ssemenu 343552Ssemenu/*- 443552Ssemenu * Copyright (c) 1995, 1996 Berkeley Software Design, Inc. All rights reserved. 543552Ssemenu * 643552Ssemenu * Redistribution and use in source and binary forms, with or without 743552Ssemenu * modification, are permitted provided that the following conditions 843552Ssemenu * are met: 943552Ssemenu * 1. Redistributions of source code must retain the above copyright 1043552Ssemenu * notice, this list of conditions and the following disclaimer. 1143552Ssemenu * 2. Redistributions in binary form must reproduce the above copyright 1243552Ssemenu * notice, this list of conditions and the following disclaimer in the 1343552Ssemenu * documentation and/or other materials provided with the distribution. 1443552Ssemenu * 3. All advertising materials mentioning features or use of this software 1543552Ssemenu * must display the following acknowledgement: 1643552Ssemenu * This product includes software developed by Berkeley Software Design, 1743552Ssemenu * Inc. 1843552Ssemenu * 4. The name of Berkeley Software Design, Inc. may not be used to endorse 1943552Ssemenu * or promote products derived from this software without specific prior 2043552Ssemenu * written permission. 2143552Ssemenu * 2243552Ssemenu * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND 2343552Ssemenu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2443552Ssemenu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2543552Ssemenu * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE 2643552Ssemenu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2743552Ssemenu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2850477Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2943552Ssemenu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3043552Ssemenu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3143552Ssemenu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3243552Ssemenu * SUCH DAMAGE. 3343552Ssemenu * 3443552Ssemenu * BSDI $From: login_token.c,v 1.2 1996/09/04 05:33:05 prb Exp $ 3543552Ssemenu */ 3643552Ssemenu 3743552Ssemenu#include <sys/types.h> 3843552Ssemenu#include <sys/param.h> 3943552Ssemenu#include <sys/time.h> 4043552Ssemenu#include <sys/resource.h> 4147060Ssemenu 4243552Ssemenu#include <err.h> 4347060Ssemenu#include <readpassphrase.h> 4443552Ssemenu#include <signal.h> 4543552Ssemenu#include <stdio.h> 4643552Ssemenu#include <syslog.h> 4743552Ssemenu#include <stdlib.h> 4843552Ssemenu#include <string.h> 4943552Ssemenu#include <unistd.h> 5043552Ssemenu#include <login_cap.h> 5143552Ssemenu#include <bsd_auth.h> 5243552Ssemenu 5344142Ssemenu#include "token.h" 5443552Ssemenu 5543552Ssemenuint 5643552Ssemenumain(argc, argv) 5743552Ssemenu int argc; 5843552Ssemenu char **argv; 5943552Ssemenu{ 6043552Ssemenu FILE *back = NULL; 6143552Ssemenu char *class = 0; 6243552Ssemenu char *username = 0; 6343552Ssemenu char *instance; 6443552Ssemenu char challenge[1024]; 6543552Ssemenu char response[1024]; 6643552Ssemenu char *pp = 0; 6743552Ssemenu int c; 6843552Ssemenu int mode = 0; 6943552Ssemenu struct rlimit cds; 7043552Ssemenu sigset_t blockset; 7143552Ssemenu 7243552Ssemenu (void)setpriority(PRIO_PROCESS, 0, 0); 7343552Ssemenu 7443552Ssemenu /* We block keyboard-generated signals during database accesses. */ 7543552Ssemenu sigemptyset(&blockset); 7643552Ssemenu sigaddset(&blockset, SIGINT); 7743552Ssemenu sigaddset(&blockset, SIGQUIT); 7843552Ssemenu sigaddset(&blockset, SIGTSTP); 7943552Ssemenu 8043552Ssemenu openlog(NULL, LOG_ODELAY, LOG_AUTH); 8143552Ssemenu 8243552Ssemenu cds.rlim_cur = 0; 8343552Ssemenu cds.rlim_max = 0; 8443552Ssemenu if (setrlimit(RLIMIT_CORE, &cds) < 0) 8543552Ssemenu syslog(LOG_ERR, "couldn't set core dump size to 0: %m"); 8643552Ssemenu 8743552Ssemenu (void)sigprocmask(SIG_BLOCK, &blockset, NULL); 8843552Ssemenu if (token_init(argv[0]) < 0) { 8943552Ssemenu syslog(LOG_ERR, "unknown token type"); 9043552Ssemenu errx(1, "unknown token type"); 9143552Ssemenu } 9243552Ssemenu (void)sigprocmask(SIG_UNBLOCK, &blockset, NULL); 9343552Ssemenu 9443552Ssemenu while ((c = getopt(argc, argv, "ds:v:")) != -1) 9543552Ssemenu switch (c) { 9643552Ssemenu case 'd': /* to remain undocumented */ 9743552Ssemenu back = stdout; 9843552Ssemenu break; 9943552Ssemenu case 'v': 10043552Ssemenu break; 10143552Ssemenu case 's': /* service */ 10243552Ssemenu if (strcmp(optarg, "login") == 0) 10343552Ssemenu mode = 0; 10443552Ssemenu else if (strcmp(optarg, "challenge") == 0) 10544142Ssemenu mode = 1; 10643552Ssemenu else if (strcmp(optarg, "response") == 0) 10743552Ssemenu mode = 2; 10843552Ssemenu else { 10943552Ssemenu syslog(LOG_ERR, "%s: invalid service", optarg); 11043552Ssemenu exit(1); 11143552Ssemenu } 11243552Ssemenu break; 11343552Ssemenu default: 11443552Ssemenu syslog(LOG_ERR, "usage error"); 11543552Ssemenu exit(1); 11643552Ssemenu } 11743552Ssemenu 11843552Ssemenu switch (argc - optind) { 119 case 2: 120 class = argv[optind + 1]; 121 case 1: 122 username = argv[optind]; 123 break; 124 default: 125 syslog(LOG_ERR, "usage error"); 126 exit(1); 127 } 128 129 130 if (back == NULL && (back = fdopen(3, "r+")) == NULL) { 131 syslog(LOG_ERR, "reopening back channel"); 132 exit(1); 133 } 134 if (mode == 2) { 135 mode = 0; 136 c = -1; 137 while (++c < sizeof(challenge) && 138 read(3, &challenge[c], 1) == 1) { 139 if (challenge[c] == '\0' && ++mode == 2) 140 break; 141 if (challenge[c] == '\0' && mode == 1) 142 pp = challenge + c + 1; 143 } 144 if (mode < 2) { 145 syslog(LOG_ERR, "protocol error on back channel"); 146 exit(1); 147 } 148 } else { 149 (void)sigprocmask(SIG_BLOCK, &blockset, NULL); 150 tokenchallenge(username, challenge, sizeof(challenge), 151 tt->proper); 152 (void)sigprocmask(SIG_UNBLOCK, &blockset, NULL); 153 if (mode == 1) { 154 fprintf(back, BI_VALUE " challenge %s\n", 155 auth_mkvalue(challenge)); 156 fprintf(back, BI_CHALLENGE "\n"); 157 exit(0); 158 } 159 160 pp = readpassphrase(challenge, response, sizeof(response), 0); 161 if (!pp || *pp == '\0') { 162 char buf[64]; 163 snprintf(buf, sizeof(buf), "%s Response [echo on]: ", 164 tt->proper); 165 pp = readpassphrase(buf, response, sizeof(response), 166 RPP_ECHO_ON); 167 } 168 } 169 170 (void)sigprocmask(SIG_BLOCK, &blockset, NULL); 171 if (tokenverify(username, challenge, pp) == 0) { 172 fprintf(back, BI_AUTH "\n"); 173 174 if ((instance = strchr(username, '.'))) { 175 *instance++ = 0; 176 if (strcmp(instance, "root") == 0) 177 fprintf(back, BI_ROOTOKAY "\n"); 178 } 179 fprintf(back, BI_SECURE "\n"); 180 exit(0); 181 } 182 183 fprintf(back, BI_REJECT "\n"); 184 exit(1); 185} 186