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 | |
26 | static char *osf1c2crypt(const char *pw, char *salt); |
27 | static 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 | |
37 | AuthReturn 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 | /* |
66 | The following code was lifted from the file osfc2.c from the ssh 1.2.26 |
67 | distribution. Parts of the code that were not needed by kcheckpass |
68 | (notably the osf1c2_check_account_and_terminal() function and the code |
69 | to set the external variable days_before_password_expires have been |
70 | removed). The original copyright from the osfc2.c file is included |
71 | below. |
72 | */ |
73 | |
74 | /* |
75 | |
76 | osfc2.c |
77 | |
78 | Author: Christophe Wolfhugel |
79 | |
80 | Copyright (c) 1995 Christophe Wolfhugel |
81 | |
82 | Free use of this file is permitted for any purpose as long as |
83 | this copyright is preserved in the header. |
84 | |
85 | This program implements the use of the OSF/1 C2 security extensions |
86 | within 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 | |
94 | static int c2security = -1; |
95 | static int crypt_algo; |
96 | |
97 | static void |
98 | initialize_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 | |
143 | static int |
144 | osf1c2_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 | |
195 | static char * |
196 | osf1c2crypt(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 | |