#include <sys/types.h>
#include <login_cap.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "packet.h"
#include "sshbuf.h"
#include "ssherr.h"
#include "log.h"
#include "misc.h"
#include "servconf.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "auth-options.h"
extern struct sshbuf *loginmsg;
extern ServerOptions options;
int sys_auth_passwd(struct ssh *, const char *);
extern login_cap_t *lc;
#define DAY (24L * 60 * 60)
#define TWO_WEEKS (2L * 7 * DAY)
#define MAX_PASSWORD_LEN 1024
int
auth_password(struct ssh *ssh, const char *password)
{
Authctxt *authctxt = ssh->authctxt;
struct passwd *pw = authctxt->pw;
int ok = authctxt->valid;
if (strlen(password) > MAX_PASSWORD_LEN)
return 0;
if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
ok = 0;
if (*password == '\0' && options.permit_empty_passwd == 0)
return 0;
#ifdef KRB5
if (options.kerberos_authentication == 1) {
int ret = auth_krb5_password(authctxt, password);
if (ret == 1 || ret == 0)
return ret && ok;
}
#endif
return (sys_auth_passwd(ssh, password) && ok);
}
static void
warn_expiry(Authctxt *authctxt, auth_session_t *as)
{
int r;
int64_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime;
pwwarntime = acwarntime = TWO_WEEKS;
pwtimeleft = auth_check_change(as);
actimeleft = auth_check_expire(as);
if (authctxt->valid) {
pwwarntime = login_getcaptime(lc, "password-warn", TWO_WEEKS,
TWO_WEEKS);
acwarntime = login_getcaptime(lc, "expire-warn", TWO_WEEKS,
TWO_WEEKS);
}
if (pwtimeleft != 0 && pwtimeleft < pwwarntime) {
daysleft = pwtimeleft / DAY + 1;
if ((r = sshbuf_putf(loginmsg,
"Your password will expire in %lld day%s.\n",
daysleft, daysleft == 1 ? "" : "s")) != 0)
fatal_fr(r, "buffer error");
}
if (actimeleft != 0 && actimeleft < acwarntime) {
daysleft = actimeleft / DAY + 1;
if ((r = sshbuf_putf(loginmsg,
"Your account will expire in %lld day%s.\n",
daysleft, daysleft == 1 ? "" : "s")) != 0)
fatal_fr(r, "buffer error");
}
}
int
sys_auth_passwd(struct ssh *ssh, const char *password)
{
Authctxt *authctxt = ssh->authctxt;
auth_session_t *as;
static int expire_checked = 0;
as = auth_usercheck(authctxt->pw->pw_name, authctxt->style, "auth-ssh",
(char *)password);
if (as == NULL)
return (0);
if (auth_getstate(as) & AUTH_PWEXPIRED) {
auth_close(as);
auth_restrict_session(ssh);
authctxt->force_pwchange = 1;
return (1);
} else {
if (!expire_checked) {
expire_checked = 1;
warn_expiry(authctxt, as);
}
return (auth_close(as));
}
}