1/* $OpenBSD: login_radius.c,v 1.10 2021/01/02 20:32:20 millert Exp $ */ 2 3/*- 4 * Copyright (c) 1996, 1997 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_radius.c,v 1.4 1998/04/14 00:39:02 prb Exp $ 35 */ 36/* 37 * Copyright(c) 1996 by tfm associates. 38 * All rights reserved. 39 * 40 * tfm associates 41 * P.O. Box 2086 42 * Eugene OR 97402-0031 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. The name of tfm associates may not be used to endorse or promote 53 * products derived from this software without specific prior written 54 * permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY TFM ASSOC``AS IS'' AND ANY EXPRESS OR 57 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 58 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 59 * IN NO EVENT SHALL TFM ASSOCIATES BE LIABLE FOR ANY DIRECT, INDIRECT, 60 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 61 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 62 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 63 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 64 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 65 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 66 */ 67 68#include <sys/types.h> 69#include <netinet/in.h> 70 71#include <ctype.h> 72#include <err.h> 73#include <login_cap.h> 74#include <pwd.h> 75#include <stdio.h> 76#include <stdlib.h> 77#include <string.h> 78#include <syslog.h> 79#include <unistd.h> 80#include <bsd_auth.h> 81#include "login_radius.h" 82 83static int cleanstring(char *); 84 85int 86main(int argc, char **argv) 87{ 88 FILE *back; 89 char challenge[1024]; 90 char *class, *service, *style, *username, *password, *emsg; 91 int c, n; 92 extern char *__progname; 93 94 if (pledge("stdio rpath wpath inet dns tty", NULL) == -1) { 95 syslog(LOG_AUTH|LOG_ERR, "pledge: %m"); 96 exit(1); 97 } 98 back = NULL; 99 password = class = service = NULL; 100 101 /* 102 * Usage: login_xxx [-s service] [-v var] user [class] 103 */ 104 while ((c = getopt(argc, argv, "ds:v:")) != -1) 105 switch (c) { 106 case 'd': 107 back = stdout; 108 break; 109 case 'v': 110 break; 111 case 's': /* service */ 112 service = optarg; 113 if (strcmp(service, "login") != 0 && 114 strcmp(service, "challenge") != 0 && 115 strcmp(service, "response") != 0) 116 errx(1, "%s not supported", service); 117 break; 118 default: 119 syslog(LOG_ERR, "usage error"); 120 exit(1); 121 } 122 123 if (service == NULL) 124 service = LOGIN_DEFSERVICE; 125 126 switch (argc - optind) { 127 case 2: 128 class = argv[optind + 1]; 129 case 1: 130 username = argv[optind]; 131 break; 132 default: 133 syslog(LOG_ERR, "usage error"); 134 exit(1); 135 } 136 137 if ((style = strrchr(__progname, '/'))) 138 ++style; 139 else 140 style = __progname; 141 142 if (strncmp(style, "login_", 6) == 0) 143 style += 6; 144 145 if (!cleanstring(style)) 146 errx(1, "style contains non-printables"); 147 if (!cleanstring(username)) 148 errx(1, "username contains non-printables"); 149 if (service && !cleanstring(service)) 150 errx(1, "service contains non-printables"); 151 if (class && !cleanstring(class)) 152 errx(1, "class contains non-printables"); 153 154 /* 155 * Filedes 3 is the back channel, where we send back results. 156 */ 157 if (back == NULL && (back = fdopen(3, "a")) == NULL) { 158 syslog(LOG_ERR, "reopening back channel"); 159 exit(1); 160 } 161 162 memset(challenge, 0, sizeof(challenge)); 163 164 if (strcmp(service, "response") == 0) { 165 c = -1; 166 n = 0; 167 while (++c < sizeof(challenge) && 168 read(3, &challenge[c], 1) == 1) { 169 if (challenge[c] == '\0' && ++n == 2) 170 break; 171 if (challenge[c] == '\0' && n == 1) 172 password = challenge + c + 1; 173 } 174 if (n < 2) { 175 syslog(LOG_ERR, "protocol error on back channel"); 176 exit(1); 177 } 178 } 179 180 emsg = NULL; 181 182 c = raddauth(username, class, style, 183 strcmp(service, "login") ? challenge : NULL, password, &emsg); 184 185 if (c == 0) { 186 if (*challenge == '\0') { 187 (void)fprintf(back, BI_AUTH "\n"); 188 exit(0); 189 } else { 190 char *val = auth_mkvalue(challenge); 191 if (val != NULL) { 192 (void)fprintf(back, BI_VALUE " challenge %s\n", 193 val); 194 (void)fprintf(back, BI_CHALLENGE "\n"); 195 exit(0); 196 } 197 emsg = "unable to allocate memory"; 198 } 199 } 200 if (emsg != NULL) { 201 if (strcmp(service, "login") == 0) { 202 (void)fprintf(stderr, "%s\n", emsg); 203 } else { 204 emsg = auth_mkvalue(emsg); 205 (void)fprintf(back, BI_VALUE " errormsg %s\n", 206 emsg ? emsg : "unable to allocate memory"); 207 } 208 } 209 if (strcmp(service, "challenge") == 0) { 210 (void)fprintf(back, BI_SILENT "\n"); 211 exit(0); 212 } 213 (void)fprintf(back, BI_REJECT "\n"); 214 exit(1); 215} 216 217static int 218cleanstring(char *s) 219{ 220 221 while (isgraph((unsigned char)*s) && *s != '\\') 222 ++s; 223 return(*s == '\0' ? 1 : 0); 224} 225