00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "includes.h"
00039 RCSID("$OpenBSD: auth-passwd.c,v 1.34 2005/07/19 15:32:26 otto Exp $");
00040
00041 #include "packet.h"
00042 #include "buffer.h"
00043 #include "log.h"
00044 #include "servconf.h"
00045 #include "auth.h"
00046 #include "auth-options.h"
00047
00048 extern Buffer loginmsg;
00049 extern ServerOptions options;
00050
00051 #ifdef HAVE_LOGIN_CAP
00052 extern login_cap_t *lc;
00053 #endif
00054
00055
00056 #define DAY (24L * 60 * 60)
00057 #define TWO_WEEKS (2L * 7 * DAY)
00058
00059 void
00060 disable_forwarding(void)
00061 {
00062 no_port_forwarding_flag = 1;
00063 no_agent_forwarding_flag = 1;
00064 no_x11_forwarding_flag = 1;
00065 }
00066
00067
00068
00069
00070
00071 int
00072 auth_password(Authctxt *authctxt, const char *password)
00073 {
00074 struct passwd * pw = authctxt->pw;
00075 int result, ok = authctxt->valid;
00076 #if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
00077 static int expire_checked = 0;
00078 #endif
00079
00080 #ifndef HAVE_CYGWIN
00081 if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
00082 ok = 0;
00083 #endif
00084 if (*password == '\0' && options.permit_empty_passwd == 0)
00085 return 0;
00086
00087 #ifdef KRB5
00088 if (options.kerberos_authentication == 1) {
00089 int ret = auth_krb5_password(authctxt, password);
00090 if (ret == 1 || ret == 0)
00091 return ret && ok;
00092
00093 }
00094 #endif
00095 #ifdef HAVE_CYGWIN
00096 if (is_winnt) {
00097 HANDLE hToken = cygwin_logon_user(pw, password);
00098
00099 if (hToken == INVALID_HANDLE_VALUE)
00100 return 0;
00101 cygwin_set_impersonation_token(hToken);
00102 return ok;
00103 }
00104 #endif
00105 #ifdef USE_PAM
00106 if (options.use_pam)
00107 return (sshpam_auth_passwd(authctxt, password) && ok);
00108 #endif
00109 #if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
00110 if (!expire_checked) {
00111 expire_checked = 1;
00112 if (auth_shadow_pwexpired(authctxt))
00113 authctxt->force_pwchange = 1;
00114 }
00115 #endif
00116 result = sys_auth_passwd(authctxt, password);
00117 if (authctxt->force_pwchange)
00118 disable_forwarding();
00119 return (result && ok);
00120 }
00121
00122 #ifdef BSD_AUTH
00123 static void
00124 warn_expiry(Authctxt *authctxt, auth_session_t *as)
00125 {
00126 char buf[256];
00127 quad_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime;
00128
00129 pwwarntime = acwarntime = TWO_WEEKS;
00130
00131 pwtimeleft = auth_check_change(as);
00132 actimeleft = auth_check_expire(as);
00133 #ifdef HAVE_LOGIN_CAP
00134 if (authctxt->valid) {
00135 pwwarntime = login_getcaptime(lc, "password-warn", TWO_WEEKS,
00136 TWO_WEEKS);
00137 acwarntime = login_getcaptime(lc, "expire-warn", TWO_WEEKS,
00138 TWO_WEEKS);
00139 }
00140 #endif
00141 if (pwtimeleft != 0 && pwtimeleft < pwwarntime) {
00142 daysleft = pwtimeleft / DAY + 1;
00143 snprintf(buf, sizeof(buf),
00144 "Your password will expire in %lld day%s.\n",
00145 daysleft, daysleft == 1 ? "" : "s");
00146 buffer_append(&loginmsg, buf, strlen(buf));
00147 }
00148 if (actimeleft != 0 && actimeleft < acwarntime) {
00149 daysleft = actimeleft / DAY + 1;
00150 snprintf(buf, sizeof(buf),
00151 "Your account will expire in %lld day%s.\n",
00152 daysleft, daysleft == 1 ? "" : "s");
00153 buffer_append(&loginmsg, buf, strlen(buf));
00154 }
00155 }
00156
00157 int
00158 sys_auth_passwd(Authctxt *authctxt, const char *password)
00159 {
00160 struct passwd *pw = authctxt->pw;
00161 auth_session_t *as;
00162 static int expire_checked = 0;
00163
00164 as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh",
00165 (char *)password);
00166 if (as == NULL)
00167 return (0);
00168 if (auth_getstate(as) & AUTH_PWEXPIRED) {
00169 auth_close(as);
00170 disable_forwarding();
00171 authctxt->force_pwchange = 1;
00172 return (1);
00173 } else {
00174 if (!expire_checked) {
00175 expire_checked = 1;
00176 warn_expiry(authctxt, as);
00177 }
00178 return (auth_close(as));
00179 }
00180 }
00181 #elif !defined(CUSTOM_SYS_AUTH_PASSWD)
00182 int
00183 sys_auth_passwd(Authctxt *authctxt, const char *password)
00184 {
00185 struct passwd *pw = authctxt->pw;
00186 char *encrypted_password;
00187
00188
00189 char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;
00190
00191
00192 if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
00193 return (1);
00194
00195
00196 encrypted_password = xcrypt(password,
00197 (pw_password[0] && pw_password[1]) ? pw_password : "xx");
00198
00199
00200
00201
00202
00203 return (strcmp(encrypted_password, pw_password) == 0);
00204 }
00205 #endif