1/*
2 *
3 * Copyright (C) 1999 Mark Davies <mark@MCS.VUW.AC.NZ>
4 * Copyright (C) 2003 Oswald Buddenhagen <ossi@kde.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 */
21
22#include "kcheckpass.h"
23
24#ifdef HAVE_OSF_C2_PASSWD
25
26static char *osf1c2crypt(const char *pw, char *salt);
27static int osf1c2_getprpwent(char *p, char *n, int len);
28
29/*******************************************************************
30 * This is the authentication code for OSF C2 security passwords
31 *******************************************************************/
32
33#include <stdio.h>
34#include <string.h>
35#include <stdlib.h>
36
37AuthReturn Authenticate(const char *method,
38 const char *login, char *(*conv) (ConvRequest, const char *))
39{
40 char *passwd;
41 char *crpt_passwd;
42 char c2passwd[256];
43
44 if (strcmp(method, "classic"))
45 return AuthError;
46
47 if (!osf1c2_getprpwent(c2passwd, login, sizeof(c2passwd)))
48 return AuthBad;
49
50 if (!*c2passwd)
51 return AuthOk;
52
53 if (!(passwd = conv(ConvGetHidden, 0)))
54 return AuthAbort;
55
56 if ((crpt_passwd = osf1c2crypt(passwd, c2passwd)) && !strcmp(c2passwd, crpt_passwd)) {
57 dispose(passwd);
58 return AuthOk; /* Success */
59 }
60 dispose(passwd);
61 return AuthBad; /* Password wrong or account locked */
62}
63
64
65/*
66The following code was lifted from the file osfc2.c from the ssh 1.2.26
67distribution. Parts of the code that were not needed by kcheckpass
68(notably the osf1c2_check_account_and_terminal() function and the code
69to set the external variable days_before_password_expires have been
70removed). The original copyright from the osfc2.c file is included
71below.
72*/
73
74/*
75
76osfc2.c
77
78Author: Christophe Wolfhugel
79
80Copyright (c) 1995 Christophe Wolfhugel
81
82Free use of this file is permitted for any purpose as long as
83this copyright is preserved in the header.
84
85This program implements the use of the OSF/1 C2 security extensions
86within ssh. See the file COPYING for full licensing information.
87
88*/
89
90#include <sys/security.h>
91#include <prot.h>
92#include <sia.h>
93
94static int c2security = -1;
95static int crypt_algo;
96
97static void
98initialize_osf_security(int ac, char **av)
99{
100 FILE *f;
101 char buf[256];
102 char siad[] = "siad_ses_init=";
103
104 if (access(SIAIGOODFILE, F_OK) == -1)
105 {
106 /* Broken OSF/1 system, better don't run on it. */
107 fprintf(stderr, SIAIGOODFILE);
108 fprintf(stderr, " does not exist. Your OSF/1 system is probably broken\n");
109 exit(1);
110 }
111 if ((f = fopen(MATRIX_CONF, "r")) == NULL)
112 {
113 /* Another way OSF/1 is probably broken. */
114 fprintf(stderr, "%s unreadable. Your OSF/1 system is probably broken.\n"
115
116 MATRIX_CONF);
117 exit(1);
118 }
119
120 /* Read matrix.conf to check if we run C2 or not */
121 while (fgets(buf, sizeof(buf), f) != NULL)
122 {
123 if (strncmp(buf, siad, sizeof(siad) - 1) == 0)
124 {
125 if (strstr(buf, "OSFC2") != NULL)
126 c2security = 1;
127 else if (strstr(buf, "BSD") != NULL)
128 c2security = 0;
129 break;
130 }
131 }
132 fclose(f);
133 if (c2security == -1)
134 {
135 fprintf(stderr, "C2 security initialization failed : could not determine security level.\n");
136 exit(1);
137 }
138 if (c2security == 1)
139 set_auth_parameters(ac, av);
140}
141
142
143static int
144osf1c2_getprpwent(char *p, char *n, int len)
145{
146 time_t pschg, tnow;
147
148 if (c2security == 1)
149 {
150 struct es_passwd *es;
151 struct pr_passwd *pr = getprpwnam(n);
152 if (pr)
153 {
154 strlcpy(p, pr->ufld.fd_encrypt, len);
155 crypt_algo = pr->ufld.fd_oldcrypt;
156
157 tnow = time(NULL);
158 if (pr->uflg.fg_schange == 1)
159 pschg = pr->ufld.fd_schange;
160 else
161 pschg = 0;
162 if (pr->uflg.fg_template == 0)
163 {
164 /** default template, system values **/
165 if (pr->sflg.fg_lifetime == 1)
166 if (pr->sfld.fd_lifetime > 0 &&
167 pschg + pr->sfld.fd_lifetime < tnow)
168 return 1;
169 }
170 else /** user template, specific values **/
171 {
172 es = getespwnam(pr->ufld.fd_template);
173 if (es)
174 {
175 if (es->uflg->fg_expire == 1)
176 if (es->ufld->fd_expire > 0 &&
177 pschg + es->ufld->fd_expire < tnow)
178 return 1;
179 }
180 }
181 }
182 }
183 else
184 {
185 struct passwd *pw = getpwnam(n);
186 if (pw)
187 {
188 strlcpy(p, pw->pw_passwd, len);
189 return 1;
190 }
191 }
192 return 0;
193}
194
195static char *
196osf1c2crypt(const char *pw, char *salt)
197{
198 if (c2security == 1) {
199 return(dispcrypt(pw, salt, crypt_algo));
200 } else
201 return(crypt(pw, salt));
202}
203
204#endif
205