Forcibly revert to mainline.
This commit is contained in:
parent
f4df40b218
commit
989dd127e4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=98941
@ -212,47 +212,3 @@ OpenSSH contains no GPL code.
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
8)
|
||||
Initial PAM adaptation was performed by ThinkSec AS and sponsored
|
||||
by Enitel AS.
|
||||
|
||||
9)
|
||||
Further FreeBSD- and PAM-specific adaptations were performed by
|
||||
ThinkSec AS and sponsored by DARPA and NAI Labs under the
|
||||
following terms:
|
||||
|
||||
* Copyright (c) 2002 Networks Associates Technology, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed for the FreeBSD Project by ThinkSec AS and
|
||||
* NAI Labs, the Security Research Division of Network Associates, Inc.
|
||||
* under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
|
||||
* DARPA CHATS research program.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
|
||||
$FreeBSD$
|
||||
|
||||
|
@ -1,14 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.11 2002/05/23 19:24:30 markus Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server \
|
||||
ssh-keysign ssh-keyscan sftp scard
|
||||
|
||||
distribution:
|
||||
install -C -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \
|
||||
${DESTDIR}/etc/ssh/ssh_config
|
||||
install -C -o root -g wheel -m 0644 ${.CURDIR}/sshd_config \
|
||||
${DESTDIR}/etc/ssh/sshd_config
|
||||
|
||||
.include <bsd.subdir.mk>
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-chall.c,v 1.8 2001/05/18 14:13:28 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "auth.h"
|
||||
#include "log.h"
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-krb4.c,v 1.27 2002/06/11 05:46:20 mpech Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-krb5.c,v 1.8 2002/03/19 10:49:35 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
@ -42,6 +41,9 @@ RCSID("$FreeBSD$");
|
||||
|
||||
#ifdef KRB5
|
||||
#include <krb5.h>
|
||||
#ifndef HEIMDAL
|
||||
#define krb5_get_err_text(context,code) error_message(code)
|
||||
#endif /* !HEIMDAL */
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
@ -94,8 +96,15 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client)
|
||||
goto err;
|
||||
|
||||
fd = packet_get_connection_in();
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
|
||||
authctxt->krb5_auth_ctx, &fd);
|
||||
#else
|
||||
problem = krb5_auth_con_genaddrs(authctxt->krb5_ctx,
|
||||
authctxt->krb5_auth_ctx,fd,
|
||||
KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
|
||||
KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
|
||||
#endif
|
||||
if (problem)
|
||||
goto err;
|
||||
|
||||
@ -109,8 +118,14 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client)
|
||||
if (problem)
|
||||
goto err;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
|
||||
&authctxt->krb5_user);
|
||||
#else
|
||||
problem = krb5_copy_principal(authctxt->krb5_ctx,
|
||||
ticket->enc_part2->client,
|
||||
&authctxt->krb5_user);
|
||||
#endif
|
||||
if (problem)
|
||||
goto err;
|
||||
|
||||
@ -161,13 +176,37 @@ auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
|
||||
krb5_error_code problem;
|
||||
krb5_ccache ccache = NULL;
|
||||
char *pname;
|
||||
krb5_creds **creds;
|
||||
|
||||
if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
|
||||
return (0);
|
||||
|
||||
temporarily_use_uid(authctxt->pw);
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
|
||||
#else
|
||||
{
|
||||
char ccname[40];
|
||||
int tmpfd;
|
||||
|
||||
snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
|
||||
|
||||
if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) {
|
||||
log("mkstemp(): %.100s", strerror(errno));
|
||||
problem = errno;
|
||||
goto fail;
|
||||
}
|
||||
if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
log("fchmod(): %.100s", strerror(errno));
|
||||
close(tmpfd);
|
||||
problem = errno;
|
||||
goto fail;
|
||||
}
|
||||
close(tmpfd);
|
||||
problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &ccache);
|
||||
}
|
||||
#endif
|
||||
if (problem)
|
||||
goto fail;
|
||||
|
||||
@ -176,10 +215,20 @@ auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
|
||||
if (problem)
|
||||
goto fail;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
|
||||
ccache, tgt);
|
||||
if (problem)
|
||||
goto fail;
|
||||
#else
|
||||
problem = krb5_rd_cred(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
|
||||
tgt, &creds, NULL);
|
||||
if (problem)
|
||||
goto fail;
|
||||
problem = krb5_cc_store_cred(authctxt->krb5_ctx, ccache, *creds);
|
||||
if (problem)
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
authctxt->krb5_fwd_ccache = ccache;
|
||||
ccache = NULL;
|
||||
@ -212,6 +261,12 @@ auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
|
||||
int
|
||||
auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
{
|
||||
#ifndef HEIMDAL
|
||||
krb5_creds creds;
|
||||
krb5_principal server;
|
||||
char ccname[40];
|
||||
int tmpfd;
|
||||
#endif
|
||||
krb5_error_code problem;
|
||||
|
||||
if (authctxt->pw == NULL)
|
||||
@ -228,6 +283,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
|
||||
&authctxt->krb5_fwd_ccache);
|
||||
if (problem)
|
||||
@ -246,13 +302,69 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
#else
|
||||
problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds,
|
||||
authctxt->krb5_user, (char *)password, NULL, NULL, 0, NULL, NULL);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL,
|
||||
KRB5_NT_SRV_HST, &server);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
restore_uid();
|
||||
problem = krb5_verify_init_creds(authctxt->krb5_ctx, &creds, server,
|
||||
NULL, NULL, NULL);
|
||||
krb5_free_principal(authctxt->krb5_ctx, server);
|
||||
temporarily_use_uid(authctxt->pw);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
|
||||
authctxt->pw->pw_name)) {
|
||||
problem = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
|
||||
|
||||
if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) {
|
||||
log("mkstemp(): %.100s", strerror(errno));
|
||||
problem = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
log("fchmod(): %.100s", strerror(errno));
|
||||
close(tmpfd);
|
||||
problem = errno;
|
||||
goto out;
|
||||
}
|
||||
close(tmpfd);
|
||||
|
||||
problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &authctxt->krb5_fwd_ccache);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
|
||||
authctxt->krb5_user);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
|
||||
&creds);
|
||||
if (problem)
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
|
||||
|
||||
out:
|
||||
restore_uid();
|
||||
|
||||
if (problem) {
|
||||
if (authctxt->krb5_ctx != NULL)
|
||||
if (authctxt->krb5_ctx != NULL && problem!=-1)
|
||||
debug("Kerberos password authentication failed: %s",
|
||||
krb5_get_err_text(authctxt->krb5_ctx, problem));
|
||||
else
|
||||
|
@ -25,41 +25,36 @@
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef USE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
#include "auth.h"
|
||||
#include "auth-pam.h"
|
||||
#include "servconf.h"
|
||||
#include "readpass.h"
|
||||
#include "canohost.h"
|
||||
#include "readpass.h"
|
||||
|
||||
RCSID("$FreeBSD$");
|
||||
extern char *__progname;
|
||||
|
||||
RCSID("$Id: auth-pam.c,v 1.46 2002/05/08 02:27:56 djm Exp $");
|
||||
|
||||
#define NEW_AUTHTOK_MSG \
|
||||
"Warning: Your password has expired, please change it now"
|
||||
|
||||
#define SSHD_PAM_SERVICE "sshd"
|
||||
#define PAM_STRERROR(a, b) pam_strerror((a), (b))
|
||||
|
||||
/* Callbacks */
|
||||
static int do_pam_conversation(int num_msg, const struct pam_message **msg,
|
||||
struct pam_response **resp, void *appdata_ptr);
|
||||
void do_pam_cleanup_proc(void *context);
|
||||
void pam_msg_cat(const char *msg);
|
||||
struct pam_response **resp, void *appdata_ptr);
|
||||
|
||||
/* module-local variables */
|
||||
static struct pam_conv conv = {
|
||||
do_pam_conversation,
|
||||
NULL
|
||||
};
|
||||
static pam_handle_t *pamh = NULL;
|
||||
static const char *pampasswd = NULL;
|
||||
static char *pam_msg = NULL;
|
||||
extern ServerOptions options;
|
||||
static char *__pam_msg = NULL;
|
||||
static pam_handle_t *__pamh = NULL;
|
||||
static const char *__pampasswd = NULL;
|
||||
|
||||
/* states for do_pam_conversation() */
|
||||
typedef enum { INITIAL_LOGIN, OTHER } pamstates;
|
||||
static pamstates pamstate = INITIAL_LOGIN;
|
||||
enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN;
|
||||
/* remember whether pam_acct_mgmt() returned PAM_NEWAUTHTOK_REQD */
|
||||
static int password_change_required = 0;
|
||||
/* remember whether the last pam_authenticate() succeeded or not */
|
||||
@ -69,13 +64,19 @@ static int was_authenticated = 0;
|
||||
static int session_opened = 0;
|
||||
static int creds_set = 0;
|
||||
|
||||
/*
|
||||
* accessor which allows us to switch conversation structs according to
|
||||
* the authentication method being used
|
||||
*/
|
||||
/* accessor which allows us to switch conversation structs according to
|
||||
* the authentication method being used */
|
||||
void do_pam_set_conv(struct pam_conv *conv)
|
||||
{
|
||||
pam_set_item(pamh, PAM_CONV, conv);
|
||||
pam_set_item(__pamh, PAM_CONV, conv);
|
||||
}
|
||||
|
||||
/* start an authentication run */
|
||||
int do_pam_authenticate(int flags)
|
||||
{
|
||||
int retval = pam_authenticate(__pamh, flags);
|
||||
was_authenticated = (retval == PAM_SUCCESS);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -84,10 +85,10 @@ void do_pam_set_conv(struct pam_conv *conv)
|
||||
*
|
||||
* INITIAL_LOGIN mode simply feeds the password from the client into
|
||||
* PAM in response to PAM_PROMPT_ECHO_OFF, and collects output
|
||||
* messages with pam_msg_cat(). This is used during initial
|
||||
* messages with into __pam_msg. This is used during initial
|
||||
* authentication to bypass the normal PAM password prompt.
|
||||
*
|
||||
* OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase(prompt, 1)
|
||||
* OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase()
|
||||
* and outputs messages to stderr. This mode is used if pam_chauthtok()
|
||||
* is called to update expired passwords.
|
||||
*/
|
||||
@ -101,43 +102,31 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg,
|
||||
/* PAM will free this later */
|
||||
reply = malloc(num_msg * sizeof(*reply));
|
||||
if (reply == NULL)
|
||||
return PAM_CONV_ERR;
|
||||
return PAM_CONV_ERR;
|
||||
|
||||
for (count = 0; count < num_msg; count++) {
|
||||
switch ((*msg)[count].msg_style) {
|
||||
if (pamstate == INITIAL_LOGIN) {
|
||||
/*
|
||||
* We can't use stdio yet, queue messages for
|
||||
* printing later
|
||||
*/
|
||||
switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
if (pamstate == INITIAL_LOGIN) {
|
||||
free(reply);
|
||||
return PAM_CONV_ERR;
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
if (__pampasswd == NULL) {
|
||||
free(reply);
|
||||
return PAM_CONV_ERR;
|
||||
} else {
|
||||
fputs((*msg)[count].msg, stderr);
|
||||
fgets(buf, sizeof(buf), stdin);
|
||||
reply[count].resp = xstrdup(buf);
|
||||
reply[count].resp_retcode = PAM_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
if (pamstate == INITIAL_LOGIN) {
|
||||
if (pampasswd == NULL) {
|
||||
free(reply);
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
reply[count].resp = xstrdup(pampasswd);
|
||||
} else {
|
||||
reply[count].resp =
|
||||
xstrdup(read_passphrase((*msg)[count].msg, 1));
|
||||
}
|
||||
reply[count].resp = xstrdup(__pampasswd);
|
||||
reply[count].resp_retcode = PAM_SUCCESS;
|
||||
break;
|
||||
case PAM_ERROR_MSG:
|
||||
case PAM_TEXT_INFO:
|
||||
if ((*msg)[count].msg != NULL) {
|
||||
if (pamstate == INITIAL_LOGIN)
|
||||
pam_msg_cat((*msg)[count].msg);
|
||||
else {
|
||||
fputs((*msg)[count].msg, stderr);
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
message_cat(&__pam_msg,
|
||||
PAM_MSG_MEMBER(msg, count, msg));
|
||||
}
|
||||
reply[count].resp = xstrdup("");
|
||||
reply[count].resp_retcode = PAM_SUCCESS;
|
||||
@ -145,6 +134,36 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg,
|
||||
default:
|
||||
free(reply);
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* stdio is connected, so interact directly
|
||||
*/
|
||||
switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
fputs(PAM_MSG_MEMBER(msg, count, msg), stderr);
|
||||
fgets(buf, sizeof(buf), stdin);
|
||||
reply[count].resp = xstrdup(buf);
|
||||
reply[count].resp_retcode = PAM_SUCCESS;
|
||||
break;
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
reply[count].resp =
|
||||
read_passphrase(PAM_MSG_MEMBER(msg, count,
|
||||
msg), RP_ALLOW_STDIN);
|
||||
reply[count].resp_retcode = PAM_SUCCESS;
|
||||
break;
|
||||
case PAM_ERROR_MSG:
|
||||
case PAM_TEXT_INFO:
|
||||
if ((*msg)[count].msg != NULL)
|
||||
fprintf(stderr, "%s\n",
|
||||
PAM_MSG_MEMBER(msg, count, msg));
|
||||
reply[count].resp = xstrdup("");
|
||||
reply[count].resp_retcode = PAM_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
free(reply);
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,61 +175,60 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg,
|
||||
/* Called at exit to cleanly shutdown PAM */
|
||||
void do_pam_cleanup_proc(void *context)
|
||||
{
|
||||
int pam_retval;
|
||||
int pam_retval = PAM_SUCCESS;
|
||||
|
||||
if (pamh != NULL && session_opened) {
|
||||
pam_retval = pam_close_session(pamh, 0);
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
log("Cannot close PAM session[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
}
|
||||
if (__pamh && session_opened) {
|
||||
pam_retval = pam_close_session(__pamh, 0);
|
||||
if (pam_retval != PAM_SUCCESS)
|
||||
log("Cannot close PAM session[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(__pamh, pam_retval));
|
||||
}
|
||||
|
||||
if (pamh != NULL && creds_set) {
|
||||
pam_retval = pam_setcred(pamh, PAM_DELETE_CRED);
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
if (__pamh && creds_set) {
|
||||
pam_retval = pam_setcred(__pamh, PAM_DELETE_CRED);
|
||||
if (pam_retval != PAM_SUCCESS)
|
||||
debug("Cannot delete credentials[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
}
|
||||
pam_retval, PAM_STRERROR(__pamh, pam_retval));
|
||||
}
|
||||
|
||||
if (pamh != NULL) {
|
||||
pam_retval = pam_end(pamh, pam_retval);
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
log("Cannot release PAM authentication[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
}
|
||||
if (__pamh) {
|
||||
pam_retval = pam_end(__pamh, pam_retval);
|
||||
if (pam_retval != PAM_SUCCESS)
|
||||
log("Cannot release PAM authentication[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(__pamh, pam_retval));
|
||||
}
|
||||
}
|
||||
|
||||
/* Attempt password authentation using PAM */
|
||||
int auth_pam_password(Authctxt *authctxt, const char *password)
|
||||
{
|
||||
struct passwd *pw = authctxt->pw;
|
||||
extern ServerOptions options;
|
||||
int pam_retval;
|
||||
struct passwd *pw = authctxt->pw;
|
||||
|
||||
do_pam_set_conv(&conv);
|
||||
|
||||
/* deny if no user. */
|
||||
if (pw == NULL)
|
||||
return 0;
|
||||
if (pw->pw_uid == 0 && options.permit_root_login == 2)
|
||||
if (pw->pw_uid == 0 && options.permit_root_login == PERMIT_NO_PASSWD)
|
||||
return 0;
|
||||
if (*password == '\0' && options.permit_empty_passwd == 0)
|
||||
return 0;
|
||||
|
||||
pampasswd = password;
|
||||
|
||||
__pampasswd = password;
|
||||
|
||||
pamstate = INITIAL_LOGIN;
|
||||
pam_retval = pam_authenticate(pamh, 0);
|
||||
was_authenticated = (pam_retval == PAM_SUCCESS);
|
||||
pam_retval = do_pam_authenticate(
|
||||
options.permit_empty_passwd == 0 ? PAM_DISALLOW_NULL_AUTHTOK : 0);
|
||||
if (pam_retval == PAM_SUCCESS) {
|
||||
debug("PAM Password authentication accepted for user \"%.100s\"",
|
||||
pw->pw_name);
|
||||
debug("PAM Password authentication accepted for "
|
||||
"user \"%.100s\"", pw->pw_name);
|
||||
return 1;
|
||||
} else {
|
||||
debug("PAM Password authentication for \"%.100s\" failed[%d]: %s",
|
||||
pw->pw_name, pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
debug("PAM Password authentication for \"%.100s\" "
|
||||
"failed[%d]: %s", pw->pw_name, pam_retval,
|
||||
PAM_STRERROR(__pamh, pam_retval));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -221,41 +239,35 @@ int do_pam_account(char *username, char *remote_user)
|
||||
int pam_retval;
|
||||
|
||||
do_pam_set_conv(&conv);
|
||||
|
||||
debug("PAM setting rhost to \"%.200s\"",
|
||||
get_canonical_hostname(options.verify_reverse_mapping));
|
||||
pam_retval = pam_set_item(pamh, PAM_RHOST,
|
||||
get_canonical_hostname(options.verify_reverse_mapping));
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
fatal("PAM set rhost failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
}
|
||||
|
||||
if (remote_user != NULL) {
|
||||
if (remote_user) {
|
||||
debug("PAM setting ruser to \"%.200s\"", remote_user);
|
||||
pam_retval = pam_set_item(pamh, PAM_RUSER, remote_user);
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
fatal("PAM set ruser failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
}
|
||||
pam_retval = pam_set_item(__pamh, PAM_RUSER, remote_user);
|
||||
if (pam_retval != PAM_SUCCESS)
|
||||
fatal("PAM set ruser failed[%d]: %.200s", pam_retval,
|
||||
PAM_STRERROR(__pamh, pam_retval));
|
||||
}
|
||||
|
||||
pam_retval = pam_acct_mgmt(pamh, 0);
|
||||
pam_retval = pam_acct_mgmt(__pamh, 0);
|
||||
debug2("pam_acct_mgmt() = %d", pam_retval);
|
||||
switch (pam_retval) {
|
||||
case PAM_SUCCESS:
|
||||
/* This is what we want */
|
||||
break;
|
||||
#if 0
|
||||
case PAM_NEW_AUTHTOK_REQD:
|
||||
pam_msg_cat(NEW_AUTHTOK_MSG);
|
||||
message_cat(&__pam_msg, NEW_AUTHTOK_MSG);
|
||||
/* flag that password change is necessary */
|
||||
password_change_required = 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
log("PAM rejected by account configuration[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
log("PAM rejected by account configuration[%d]: "
|
||||
"%.200s", pam_retval, PAM_STRERROR(__pamh,
|
||||
pam_retval));
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -268,50 +280,51 @@ void do_pam_session(char *username, const char *ttyname)
|
||||
|
||||
if (ttyname != NULL) {
|
||||
debug("PAM setting tty to \"%.200s\"", ttyname);
|
||||
pam_retval = pam_set_item(pamh, PAM_TTY, ttyname);
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
fatal("PAM set tty failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
}
|
||||
pam_retval = pam_set_item(__pamh, PAM_TTY, ttyname);
|
||||
if (pam_retval != PAM_SUCCESS)
|
||||
fatal("PAM set tty failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(__pamh, pam_retval));
|
||||
}
|
||||
|
||||
debug("do_pam_session: euid %u, uid %u", geteuid(), getuid());
|
||||
pam_retval = pam_open_session(pamh, 0);
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
fatal("PAM session setup failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
}
|
||||
pam_retval = pam_open_session(__pamh, 0);
|
||||
if (pam_retval != PAM_SUCCESS)
|
||||
fatal("PAM session setup failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(__pamh, pam_retval));
|
||||
|
||||
session_opened = 1;
|
||||
}
|
||||
|
||||
/* Set PAM credentials */
|
||||
void do_pam_setcred(void)
|
||||
/* Set PAM credentials */
|
||||
void do_pam_setcred(int init)
|
||||
{
|
||||
int pam_retval;
|
||||
|
||||
if (__pamh == NULL)
|
||||
return;
|
||||
|
||||
do_pam_set_conv(&conv);
|
||||
|
||||
|
||||
debug("PAM establishing creds");
|
||||
pam_retval = pam_setcred(pamh, PAM_ESTABLISH_CRED);
|
||||
pam_retval = pam_setcred(__pamh,
|
||||
init ? PAM_ESTABLISH_CRED : PAM_REINITIALIZE_CRED);
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
if (was_authenticated)
|
||||
fatal("PAM setcred failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
pam_retval, PAM_STRERROR(__pamh, pam_retval));
|
||||
else
|
||||
debug("PAM setcred failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
pam_retval, PAM_STRERROR(__pamh, pam_retval));
|
||||
} else
|
||||
creds_set = 1;
|
||||
}
|
||||
|
||||
/* accessor function for file scope static variable */
|
||||
int pam_password_change_required(void)
|
||||
int is_pam_password_change_required(void)
|
||||
{
|
||||
return password_change_required;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Have user change authentication token if pam_acct_mgmt() indicated
|
||||
* it was expired. This needs to be called after an interactive
|
||||
* session is established and the user's pty is connected to
|
||||
@ -325,16 +338,10 @@ void do_pam_chauthtok(void)
|
||||
|
||||
if (password_change_required) {
|
||||
pamstate = OTHER;
|
||||
/*
|
||||
* XXX: should we really loop forever?
|
||||
*/
|
||||
do {
|
||||
pam_retval = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
log("PAM pam_chauthtok failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
}
|
||||
} while (pam_retval != PAM_SUCCESS);
|
||||
pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
|
||||
if (pam_retval != PAM_SUCCESS)
|
||||
fatal("PAM pam_chauthtok failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(__pamh, pam_retval));
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,32 +353,40 @@ void finish_pam(void)
|
||||
}
|
||||
|
||||
/* Start PAM authentication for specified account */
|
||||
void start_pam(struct passwd *pw)
|
||||
void start_pam(const char *user)
|
||||
{
|
||||
int pam_retval;
|
||||
extern ServerOptions options;
|
||||
extern u_int utmp_len;
|
||||
const char *rhost;
|
||||
|
||||
debug("Starting up PAM with username \"%.200s\"", pw->pw_name);
|
||||
debug("Starting up PAM with username \"%.200s\"", user);
|
||||
|
||||
pam_retval = pam_start(SSHD_PAM_SERVICE, pw->pw_name, &conv, &pamh);
|
||||
pam_retval = pam_start(SSHD_PAM_SERVICE, user, &conv, &__pamh);
|
||||
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
fatal("PAM initialisation failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
}
|
||||
if (pam_retval != PAM_SUCCESS)
|
||||
fatal("PAM initialisation failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(__pamh, pam_retval));
|
||||
|
||||
rhost = get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping);
|
||||
debug("PAM setting rhost to \"%.200s\"", rhost);
|
||||
|
||||
pam_retval = pam_set_item(__pamh, PAM_RHOST, rhost);
|
||||
if (pam_retval != PAM_SUCCESS)
|
||||
fatal("PAM set rhost failed[%d]: %.200s", pam_retval,
|
||||
PAM_STRERROR(__pamh, pam_retval));
|
||||
#ifdef PAM_TTY_KLUDGE
|
||||
/*
|
||||
* Some PAM modules (e.g. pam_time) require a TTY to operate,
|
||||
* and will fail in various stupid ways if they don't get one.
|
||||
* and will fail in various stupid ways if they don't get one.
|
||||
* sshd doesn't set the tty until too late in the auth process and may
|
||||
* not even need one (for tty-less connections)
|
||||
* Kludge: Set a fake PAM_TTY
|
||||
* Kludge: Set a fake PAM_TTY
|
||||
*/
|
||||
pam_retval = pam_set_item(pamh, PAM_TTY, "ssh");
|
||||
if (pam_retval != PAM_SUCCESS) {
|
||||
fatal("PAM set tty failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(pamh, pam_retval));
|
||||
}
|
||||
pam_retval = pam_set_item(__pamh, PAM_TTY, "NODEVssh");
|
||||
if (pam_retval != PAM_SUCCESS)
|
||||
fatal("PAM set tty failed[%d]: %.200s",
|
||||
pam_retval, PAM_STRERROR(__pamh, pam_retval));
|
||||
#endif /* PAM_TTY_KLUDGE */
|
||||
|
||||
fatal_add_cleanup(&do_pam_cleanup_proc, NULL);
|
||||
@ -381,7 +396,7 @@ void start_pam(struct passwd *pw)
|
||||
char **fetch_pam_environment(void)
|
||||
{
|
||||
#ifdef HAVE_PAM_GETENVLIST
|
||||
return(pam_getenvlist(pamh));
|
||||
return(pam_getenvlist(__pamh));
|
||||
#else /* HAVE_PAM_GETENVLIST */
|
||||
return(NULL);
|
||||
#endif /* HAVE_PAM_GETENVLIST */
|
||||
@ -391,433 +406,29 @@ char **fetch_pam_environment(void)
|
||||
/* or account checking to stderr */
|
||||
void print_pam_messages(void)
|
||||
{
|
||||
if (pam_msg != NULL)
|
||||
fputs(pam_msg, stderr);
|
||||
if (__pam_msg != NULL)
|
||||
fputs(__pam_msg, stderr);
|
||||
}
|
||||
|
||||
/* Append a message to the PAM message buffer */
|
||||
void pam_msg_cat(const char *msg)
|
||||
/* Append a message to buffer */
|
||||
void message_cat(char **p, const char *a)
|
||||
{
|
||||
char *p;
|
||||
size_t new_msg_len;
|
||||
size_t pam_msg_len;
|
||||
|
||||
new_msg_len = strlen(msg);
|
||||
|
||||
if (pam_msg) {
|
||||
pam_msg_len = strlen(pam_msg);
|
||||
pam_msg = xrealloc(pam_msg, new_msg_len + pam_msg_len + 2);
|
||||
p = pam_msg + pam_msg_len;
|
||||
} else {
|
||||
pam_msg = p = xmalloc(new_msg_len + 2);
|
||||
}
|
||||
char *cp;
|
||||
size_t new_len;
|
||||
|
||||
memcpy(p, msg, new_msg_len);
|
||||
p[new_msg_len] = '\n';
|
||||
p[new_msg_len + 1] = '\0';
|
||||
}
|
||||
new_len = strlen(a);
|
||||
|
||||
struct inverted_pam_userdata {
|
||||
/*
|
||||
* Pipe for telling whether we are doing conversation or sending
|
||||
* authentication results.
|
||||
*/
|
||||
int statefd[2];
|
||||
int challengefd[2];
|
||||
int responsefd[2];
|
||||
if (*p) {
|
||||
size_t len = strlen(*p);
|
||||
|
||||
/* Whether we have sent off our challenge */
|
||||
int state;
|
||||
};
|
||||
*p = xrealloc(*p, new_len + len + 2);
|
||||
cp = *p + len;
|
||||
} else
|
||||
*p = cp = xmalloc(new_len + 2);
|
||||
|
||||
#define STATE_CONV 1
|
||||
#define STATE_AUTH_OK 2
|
||||
#define STATE_AUTH_FAIL 3
|
||||
|
||||
int
|
||||
ssh_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp,
|
||||
void *userdata) {
|
||||
int i;
|
||||
FILE *reader;
|
||||
char buf[1024];
|
||||
struct pam_response *reply = NULL;
|
||||
char state_to_write = STATE_CONV; /* One char to write */
|
||||
struct inverted_pam_userdata *ud = userdata;
|
||||
char *response = NULL;
|
||||
|
||||
/* The stdio functions are more convenient for the read half */
|
||||
reader = fdopen(ud->responsefd[0], "rb");
|
||||
if (reader == NULL)
|
||||
goto protocol_failure;
|
||||
|
||||
reply = malloc(num_msg * sizeof(struct pam_response));
|
||||
if (reply == NULL)
|
||||
return PAM_CONV_ERR;
|
||||
|
||||
if (write(ud->statefd[1], &state_to_write, 1) != 1)
|
||||
goto protocol_failure;
|
||||
|
||||
/*
|
||||
* Re-package our data and send it off to our better half (the actual SSH
|
||||
* process)
|
||||
*/
|
||||
if (write(ud->challengefd[1], buf,
|
||||
sprintf(buf, "%d\n", num_msg)) == -1)
|
||||
goto protocol_failure;
|
||||
for (i = 0; i < num_msg; i++) {
|
||||
if (write(ud->challengefd[1], buf,
|
||||
sprintf(buf, "%d\n", msg[i]->msg_style)) == -1)
|
||||
goto protocol_failure;
|
||||
if (write(ud->challengefd[1], buf,
|
||||
sprintf(buf, "%d\n", strlen(msg[i]->msg))) == -1)
|
||||
goto protocol_failure;
|
||||
if (write(ud->challengefd[1], msg[i]->msg,
|
||||
strlen(msg[i]->msg)) == -1)
|
||||
goto protocol_failure;
|
||||
}
|
||||
/*
|
||||
* Read back responses. These may not be as nice as we want, as the SSH
|
||||
* protocol isn't exactly a perfect fit with PAM.
|
||||
*/
|
||||
|
||||
for (i = 0; i < num_msg; i++) {
|
||||
char buf[1024];
|
||||
char *endptr;
|
||||
size_t len; /* Length of the response */
|
||||
|
||||
switch (msg[i]->msg_style) {
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
if (fgets(buf, sizeof(buf), reader) == NULL)
|
||||
goto protocol_failure;
|
||||
len = (size_t)strtoul(buf, &endptr, 10);
|
||||
/* The length is supposed to stand on a line by itself */
|
||||
if (endptr == NULL || *endptr != '\n')
|
||||
goto protocol_failure;
|
||||
response = malloc(len+1);
|
||||
if (response == NULL)
|
||||
goto protocol_failure;
|
||||
if (fread(response, len, 1, reader) != 1)
|
||||
goto protocol_failure;
|
||||
response[len] = '\0';
|
||||
reply[i].resp = response;
|
||||
response = NULL;
|
||||
break;
|
||||
default:
|
||||
reply[i].resp = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*resp = reply;
|
||||
return PAM_SUCCESS;
|
||||
protocol_failure:
|
||||
free(reply);
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
|
||||
void
|
||||
ipam_free_cookie(struct inverted_pam_cookie *cookie) {
|
||||
struct inverted_pam_userdata *ud;
|
||||
int i;
|
||||
|
||||
if (cookie == NULL)
|
||||
return;
|
||||
ud = cookie->userdata;
|
||||
cookie->userdata = NULL;
|
||||
/* Free userdata if allocated */
|
||||
if (ud) {
|
||||
/* Close any opened file descriptors */
|
||||
if (ud->statefd[0] != -1)
|
||||
close(ud->statefd[0]);
|
||||
if (ud->statefd[1] != -1)
|
||||
close(ud->statefd[1]);
|
||||
if (ud->challengefd[0] != -1)
|
||||
close(ud->challengefd[0]);
|
||||
if (ud->challengefd[1] != -1)
|
||||
close(ud->challengefd[1]);
|
||||
if (ud->responsefd[0] != -1)
|
||||
close(ud->responsefd[0]);
|
||||
if (ud->responsefd[1] != -1)
|
||||
close(ud->responsefd[1]);
|
||||
free(ud);
|
||||
ud = NULL;
|
||||
}
|
||||
/* Now free the normal cookie */
|
||||
if (cookie->pid != 0 && cookie->pid != -1) {
|
||||
int status;
|
||||
|
||||
/* XXX Use different signal? */
|
||||
kill(cookie->pid, SIGKILL);
|
||||
waitpid(cookie->pid, &status, 0);
|
||||
}
|
||||
for (i = 0; i < cookie->num_msg; i++) {
|
||||
if (cookie->resp && cookie->resp[i]) {
|
||||
free(cookie->resp[i]->resp);
|
||||
free(cookie->resp[i]);
|
||||
}
|
||||
if (cookie->msg && cookie->msg[i]) {
|
||||
free((void *)cookie->msg[i]->msg);
|
||||
free(cookie->msg[i]);
|
||||
}
|
||||
}
|
||||
free(cookie->msg);
|
||||
free(cookie->resp);
|
||||
free(cookie);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do first half of PAM authentication - this comes to the point where
|
||||
* you get a message to send to the user.
|
||||
*/
|
||||
struct inverted_pam_cookie *
|
||||
ipam_start_auth(const char *service, const char *username) {
|
||||
struct inverted_pam_cookie *cookie;
|
||||
struct inverted_pam_userdata *ud;
|
||||
static struct pam_conv conv = {
|
||||
ssh_conv,
|
||||
NULL
|
||||
};
|
||||
const char *rhost;
|
||||
|
||||
cookie = malloc(sizeof(*cookie));
|
||||
if (cookie == NULL)
|
||||
return NULL;
|
||||
cookie->state = 0;
|
||||
/* Set up the cookie so ipam_freecookie can be used on it */
|
||||
cookie->num_msg = 0;
|
||||
cookie->msg = NULL;
|
||||
cookie->resp = NULL;
|
||||
cookie->pid = -1;
|
||||
|
||||
ud = calloc(sizeof(*ud), 1);
|
||||
if (ud == NULL) {
|
||||
free(cookie);
|
||||
return NULL;
|
||||
}
|
||||
cookie->userdata = ud;
|
||||
ud->statefd[0] = ud->statefd[1] = -1;
|
||||
ud->challengefd[0] = ud->challengefd[1] = -1;
|
||||
ud->responsefd[0] = ud->responsefd[1] = -1;
|
||||
|
||||
if (pipe(ud->statefd) != 0) {
|
||||
ud->statefd[0] = ud->statefd[1] = -1;
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
if (pipe(ud->challengefd) != 0) {
|
||||
ud->challengefd[0] = ud->challengefd[1] = -1;
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
if (pipe(ud->responsefd) != 0) {
|
||||
ud->responsefd[0] = ud->responsefd[1] = -1;
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
rhost = get_canonical_hostname(options.verify_reverse_mapping);
|
||||
cookie->pid = fork();
|
||||
if (cookie->pid == -1) {
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
} else if (cookie->pid != 0) {
|
||||
int num_msgs; /* Number of messages from PAM */
|
||||
char *endptr;
|
||||
char buf[1024];
|
||||
FILE *reader;
|
||||
size_t num_msg;
|
||||
int i;
|
||||
char state; /* Which state did the connection just enter? */
|
||||
|
||||
/* We are the parent - wait for a call to the communications
|
||||
function to turn up, or the challenge to be finished */
|
||||
if (read(ud->statefd[0], &state, 1) != 1) {
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
cookie->state = state;
|
||||
switch (state) {
|
||||
case STATE_CONV:
|
||||
/* We are running the conversation function */
|
||||
/* The stdio functions are more convenient for read */
|
||||
reader = fdopen(ud->challengefd[0], "r");
|
||||
if (reader == NULL) {
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
if (fgets(buf, 4, reader) == NULL) {
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
num_msg = (size_t)strtoul(buf, &endptr, 10);
|
||||
/* The length is supposed to stand on a line by itself */
|
||||
if (endptr == NULL || *endptr != '\n') {
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
cookie->msg =
|
||||
malloc(sizeof(struct pam_message *) * num_msg);
|
||||
cookie->resp =
|
||||
malloc(sizeof(struct pam_response *) * num_msg);
|
||||
if (cookie->msg == NULL || cookie->resp == NULL) {
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < num_msg; i++) {
|
||||
cookie->msg[i] =
|
||||
malloc(sizeof(struct pam_message));
|
||||
cookie->resp[i] =
|
||||
malloc(sizeof(struct pam_response));
|
||||
if (cookie->msg[i] == NULL ||
|
||||
cookie->resp[i] == NULL) {
|
||||
for (;;) {
|
||||
free(cookie->msg[i]);
|
||||
free(cookie->resp[i]);
|
||||
if (i == 0)
|
||||
break;
|
||||
i--;
|
||||
}
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
cookie->msg[i]->msg = NULL;
|
||||
cookie->resp[i]->resp = NULL;
|
||||
cookie->resp[i]->resp_retcode = 0;
|
||||
}
|
||||
/* Set up so the above will be freed on failure */
|
||||
cookie->num_msg = num_msg;
|
||||
/*
|
||||
* We have a an allocated response and message for
|
||||
* each of the entries in the PAM structure - transfer
|
||||
* the data sent to the conversation function over.
|
||||
*/
|
||||
for (i = 0; i < num_msg; i++) {
|
||||
size_t len;
|
||||
|
||||
if (fgets(buf, sizeof(buf), reader) == NULL) {
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
cookie->msg[i]->msg_style =
|
||||
(size_t)strtoul(buf, &endptr, 10);
|
||||
if (endptr == NULL || *endptr != '\n') {
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
if (fgets(buf, sizeof(buf), reader) == NULL) {
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
len = (size_t)strtoul(buf, &endptr, 10);
|
||||
if (endptr == NULL || *endptr != '\n') {
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
cookie->msg[i]->msg = malloc(len + 1);
|
||||
if (cookie->msg[i]->msg == NULL) {
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
if (fread((char *)cookie->msg[i]->msg, len, 1, reader) !=
|
||||
1) {
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
*(char *)&(cookie->msg[i]->msg[len]) = '\0';
|
||||
}
|
||||
break;
|
||||
case STATE_AUTH_OK:
|
||||
case STATE_AUTH_FAIL:
|
||||
break;
|
||||
default:
|
||||
/* Internal failure, somehow */
|
||||
fclose(reader);
|
||||
ipam_free_cookie(cookie);
|
||||
return NULL;
|
||||
}
|
||||
return cookie;
|
||||
} else {
|
||||
/* We are the child */
|
||||
pam_handle_t *pamh=NULL;
|
||||
int retval;
|
||||
char state;
|
||||
|
||||
conv.appdata_ptr = ud;
|
||||
retval = pam_start(service, username, &conv, &pamh);
|
||||
fprintf(stderr, "pam_start returned %d\n", retval);
|
||||
if (retval == PAM_SUCCESS)
|
||||
retval = pam_set_item(pamh, PAM_RHOST, rhost);
|
||||
/* Is user really user? */
|
||||
if (retval == PAM_SUCCESS)
|
||||
retval = pam_authenticate(pamh, 0);
|
||||
/* permitted access? */
|
||||
if (retval == PAM_SUCCESS)
|
||||
retval = pam_acct_mgmt(pamh, 0);
|
||||
/* This is where we have been authorized or not. */
|
||||
|
||||
/* Be conservative - flag as auth failure if we can't close */
|
||||
/*
|
||||
* XXX This is based on example code from Linux-PAM -
|
||||
* but can it really be correct to pam_end if
|
||||
* pam_start failed?
|
||||
*/
|
||||
if (pam_end(pamh, retval) != PAM_SUCCESS)
|
||||
retval = PAM_AUTH_ERR;
|
||||
|
||||
/* Message to parent */
|
||||
state = retval == PAM_SUCCESS ? STATE_AUTH_OK : STATE_AUTH_FAIL;
|
||||
if (write(ud->statefd[1], &state, 1) != 1) {
|
||||
_exit(1);
|
||||
}
|
||||
/* FDs will be closed, so further communication will stop */
|
||||
_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do second half of PAM authentication - cookie should now be filled
|
||||
* in with the response to the challenge.
|
||||
*/
|
||||
|
||||
int
|
||||
ipam_complete_auth(struct inverted_pam_cookie *cookie) {
|
||||
int i;
|
||||
char buf[1024];
|
||||
struct inverted_pam_userdata *ud = cookie->userdata;
|
||||
char state;
|
||||
|
||||
/* Send over our responses */
|
||||
for (i = 0; i < cookie->num_msg; i++) {
|
||||
if (cookie->msg[i]->msg_style != PAM_PROMPT_ECHO_ON &&
|
||||
cookie->msg[i]->msg_style != PAM_PROMPT_ECHO_OFF)
|
||||
continue;
|
||||
if (write(ud->responsefd[1], buf,
|
||||
sprintf(buf, "%d\n", strlen(cookie->resp[i]->resp))) == -1) {
|
||||
ipam_free_cookie(cookie);
|
||||
return 0;
|
||||
}
|
||||
if (write(ud->responsefd[1], cookie->resp[i]->resp,
|
||||
strlen(cookie->resp[i]->resp)) == -1) {
|
||||
ipam_free_cookie(cookie);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* Find out what state we are changing to */
|
||||
if (read(ud->statefd[0], &state, 1) != 1) {
|
||||
ipam_free_cookie(cookie);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return state == STATE_AUTH_OK ? 1 : 0;
|
||||
memcpy(cp, a, new_len);
|
||||
cp[new_len] = '\n';
|
||||
cp[new_len + 1] = '\0';
|
||||
}
|
||||
|
||||
#endif /* USE_PAM */
|
||||
|
@ -1,39 +1,22 @@
|
||||
/*
|
||||
* OpenSSH PAM authentication support.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef AUTH_PAM_H
|
||||
#define AUTH_PAM_H
|
||||
/* $Id: auth-pam.h,v 1.12 2002/04/04 19:02:28 stevesk Exp $ */
|
||||
|
||||
#include "includes.h"
|
||||
#ifdef USE_PAM
|
||||
|
||||
#include "auth.h"
|
||||
#include <pwd.h> /* For struct passwd */
|
||||
|
||||
void start_pam(struct passwd *pw);
|
||||
void start_pam(const char *user);
|
||||
void finish_pam(void);
|
||||
int auth_pam_password(Authctxt *authctxt, const char *password);
|
||||
char **fetch_pam_environment(void);
|
||||
int do_pam_authenticate(int flags);
|
||||
int do_pam_account(char *username, char *remote_user);
|
||||
void do_pam_session(char *username, const char *ttyname);
|
||||
void do_pam_setcred(void);
|
||||
void do_pam_setcred(int init);
|
||||
void print_pam_messages(void);
|
||||
int pam_password_change_required(void);
|
||||
int is_pam_password_change_required(void);
|
||||
void do_pam_chauthtok(void);
|
||||
|
||||
struct inverted_pam_cookie {
|
||||
int state; /* Which state have we reached? */
|
||||
pid_t pid; /* PID of child process */
|
||||
|
||||
/* Only valid in state STATE_CONV */
|
||||
int num_msg; /* Number of messages */
|
||||
struct pam_message **msg; /* Message structures */
|
||||
struct pam_response **resp; /* Response structures */
|
||||
struct inverted_pam_userdata *userdata;
|
||||
};
|
||||
void ipam_free_cookie(struct inverted_pam_cookie *cookie);
|
||||
struct inverted_pam_cookie *ipam_start_auth(const char *, const char *);
|
||||
void do_pam_set_conv(struct pam_conv *);
|
||||
void message_cat(char **p, const char *a);
|
||||
|
||||
#endif /* USE_PAM */
|
||||
#endif /* AUTH_PAM_H */
|
||||
|
@ -37,13 +37,48 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "auth.h"
|
||||
|
||||
#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
|
||||
/* Don't need any of these headers for the PAM or SIA cases */
|
||||
# ifdef HAVE_CRYPT_H
|
||||
# include <crypt.h>
|
||||
# endif
|
||||
# ifdef WITH_AIXAUTHENTICATE
|
||||
# include <login.h>
|
||||
# endif
|
||||
# ifdef __hpux
|
||||
# include <hpsecurity.h>
|
||||
# include <prot.h>
|
||||
# endif
|
||||
# ifdef HAVE_SECUREWARE
|
||||
# include <sys/security.h>
|
||||
# include <sys/audit.h>
|
||||
# include <prot.h>
|
||||
# endif /* HAVE_SECUREWARE */
|
||||
# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
# include <shadow.h>
|
||||
# endif
|
||||
# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
|
||||
# include <sys/label.h>
|
||||
# include <sys/audit.h>
|
||||
# include <pwdadj.h>
|
||||
# endif
|
||||
# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT)
|
||||
# include "md5crypt.h"
|
||||
# endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */
|
||||
|
||||
# ifdef HAVE_CYGWIN
|
||||
# undef ERROR
|
||||
# include <windows.h>
|
||||
# include <sys/cygwin.h>
|
||||
# define is_winnt (GetVersion() < 0x80000000)
|
||||
# endif
|
||||
#endif /* !USE_PAM && !HAVE_OSF_SIA */
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
@ -54,13 +89,41 @@ extern ServerOptions options;
|
||||
int
|
||||
auth_password(Authctxt *authctxt, const char *password)
|
||||
{
|
||||
#if defined(USE_PAM)
|
||||
if (*password == '\0' && options.permit_empty_passwd == 0)
|
||||
return 0;
|
||||
return auth_pam_password(authctxt, password);
|
||||
#elif defined(HAVE_OSF_SIA)
|
||||
if (*password == '\0' && options.permit_empty_passwd == 0)
|
||||
return 0;
|
||||
return auth_sia_password(authctxt, password);
|
||||
#else
|
||||
struct passwd * pw = authctxt->pw;
|
||||
char *encrypted_password;
|
||||
char *pw_password;
|
||||
char *salt;
|
||||
#if defined(__hpux) || defined(HAVE_SECUREWARE)
|
||||
struct pr_passwd *spw;
|
||||
#endif /* __hpux || HAVE_SECUREWARE */
|
||||
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
struct spwd *spw;
|
||||
#endif
|
||||
#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
|
||||
struct passwd_adjunct *spw;
|
||||
#endif
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
char *authmsg;
|
||||
char *loginmsg;
|
||||
int reenter = 1;
|
||||
#endif
|
||||
|
||||
/* deny if no user. */
|
||||
if (pw == NULL)
|
||||
return 0;
|
||||
if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
|
||||
#ifndef HAVE_CYGWIN
|
||||
if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
|
||||
return 0;
|
||||
#endif
|
||||
if (*password == '\0' && options.permit_empty_passwd == 0)
|
||||
return 0;
|
||||
#ifdef KRB5
|
||||
@ -71,6 +134,19 @@ auth_password(Authctxt *authctxt, const char *password)
|
||||
/* Fall back to ordinary passwd authentication. */
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CYGWIN
|
||||
if (is_winnt) {
|
||||
HANDLE hToken = cygwin_logon_user(pw, password);
|
||||
|
||||
if (hToken == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
cygwin_set_impersonation_token(hToken);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
return (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0);
|
||||
#endif
|
||||
#ifdef KRB4
|
||||
if (options.kerberos_authentication == 1) {
|
||||
int ret = auth_krb4_password(authctxt, password);
|
||||
@ -85,20 +161,63 @@ auth_password(Authctxt *authctxt, const char *password)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
#else
|
||||
/* Check for users with no password. */
|
||||
if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)
|
||||
return 1;
|
||||
else {
|
||||
/* Encrypt the candidate password using the proper salt. */
|
||||
char *encrypted_password = crypt(password,
|
||||
(pw->pw_passwd[0] && pw->pw_passwd[1]) ?
|
||||
pw->pw_passwd : "xx");
|
||||
/*
|
||||
* Authentication is accepted if the encrypted passwords
|
||||
* are identical.
|
||||
*/
|
||||
return (strcmp(encrypted_password, pw->pw_passwd) == 0);
|
||||
}
|
||||
#endif
|
||||
pw_password = pw->pw_passwd;
|
||||
|
||||
/*
|
||||
* Various interfaces to shadow or protected password data
|
||||
*/
|
||||
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
spw = getspnam(pw->pw_name);
|
||||
if (spw != NULL)
|
||||
pw_password = spw->sp_pwdp;
|
||||
#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
|
||||
|
||||
#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
|
||||
if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL)
|
||||
pw_password = spw->pwa_passwd;
|
||||
#endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */
|
||||
|
||||
#ifdef HAVE_SECUREWARE
|
||||
if ((spw = getprpwnam(pw->pw_name)) != NULL)
|
||||
pw_password = spw->ufld.fd_encrypt;
|
||||
#endif /* HAVE_SECUREWARE */
|
||||
|
||||
#if defined(__hpux) && !defined(HAVE_SECUREWARE)
|
||||
if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL)
|
||||
pw_password = spw->ufld.fd_encrypt;
|
||||
#endif /* defined(__hpux) && !defined(HAVE_SECUREWARE) */
|
||||
|
||||
/* Check for users with no password. */
|
||||
if ((password[0] == '\0') && (pw_password[0] == '\0'))
|
||||
return 1;
|
||||
|
||||
if (pw_password[0] != '\0')
|
||||
salt = pw_password;
|
||||
else
|
||||
salt = "xx";
|
||||
|
||||
#ifdef HAVE_MD5_PASSWORDS
|
||||
if (is_md5_salt(salt))
|
||||
encrypted_password = md5_crypt(password, salt);
|
||||
else
|
||||
encrypted_password = crypt(password, salt);
|
||||
#else /* HAVE_MD5_PASSWORDS */
|
||||
# if defined(__hpux) && !defined(HAVE_SECUREWARE)
|
||||
if (iscomsec())
|
||||
encrypted_password = bigcrypt(password, salt);
|
||||
else
|
||||
encrypted_password = crypt(password, salt);
|
||||
# else
|
||||
# ifdef HAVE_SECUREWARE
|
||||
encrypted_password = bigcrypt(password, salt);
|
||||
# else
|
||||
encrypted_password = crypt(password, salt);
|
||||
# endif /* HAVE_SECUREWARE */
|
||||
# endif /* __hpux && !defined(HAVE_SECUREWARE) */
|
||||
#endif /* HAVE_MD5_PASSWORDS */
|
||||
|
||||
/* Authentication is accepted if the encrypted passwords are identical. */
|
||||
return (strcmp(encrypted_password, pw_password) == 0);
|
||||
#endif /* !USE_PAM && !HAVE_OSF_SIA */
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-rh-rsa.c,v 1.34 2002/03/25 09:25:06 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "packet.h"
|
||||
#include "uidswap.h"
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-rsa.c,v 1.56 2002/06/10 16:53:06 stevesk Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/md5.h>
|
||||
|
@ -23,11 +23,10 @@
|
||||
*/
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-skey.c,v 1.19 2002/06/19 00:27:55 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#ifdef SKEY
|
||||
|
||||
#include <opie.h>
|
||||
#include <skey.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "auth.h"
|
||||
@ -46,11 +45,9 @@ skey_query(void *ctx, char **name, char **infotxt,
|
||||
Authctxt *authctxt = ctx;
|
||||
char challenge[1024], *p;
|
||||
int len;
|
||||
struct opie opie;
|
||||
struct skey skey;
|
||||
|
||||
if (opie_haskey(authctxt->user) != 0)
|
||||
return -1;
|
||||
if (opiechallenge(&opie, authctxt->user, challenge) == -1)
|
||||
if (skeychallenge(&skey, authctxt->user, challenge) == -1)
|
||||
return -1;
|
||||
|
||||
*name = xstrdup("");
|
||||
@ -76,8 +73,8 @@ skey_respond(void *ctx, u_int numresponses, char **responses)
|
||||
|
||||
if (authctxt->valid &&
|
||||
numresponses == 1 &&
|
||||
opie_haskey(authctxt->pw->pw_name) == 0 &&
|
||||
opie_passverify(authctxt->pw->pw_name, responses[0]) != -1)
|
||||
skey_haskey(authctxt->pw->pw_name) == 0 &&
|
||||
skey_passcheck(authctxt->pw->pw_name, responses[0]) != -1)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
@ -24,9 +24,17 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth.c,v 1.43 2002/05/17 14:27:55 millert Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_LOGIN_H
|
||||
#include <login.h>
|
||||
#endif
|
||||
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
#include <shadow.h>
|
||||
#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
|
||||
|
||||
#ifdef HAVE_LIBGEN_H
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "match.h"
|
||||
@ -67,11 +75,53 @@ allowed_user(struct passwd * pw)
|
||||
const char *hostname = NULL, *ipaddr = NULL;
|
||||
char *shell;
|
||||
int i;
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
char *loginmsg;
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \
|
||||
!defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
|
||||
struct spwd *spw;
|
||||
|
||||
/* Shouldn't be called if pw is NULL, but better safe than sorry... */
|
||||
if (!pw || !pw->pw_name)
|
||||
return 0;
|
||||
|
||||
#define DAY (24L * 60 * 60) /* 1 day in seconds */
|
||||
spw = getspnam(pw->pw_name);
|
||||
if (spw != NULL) {
|
||||
time_t today = time(NULL) / DAY;
|
||||
debug3("allowed_user: today %d sp_expire %d sp_lstchg %d"
|
||||
" sp_max %d", (int)today, (int)spw->sp_expire,
|
||||
(int)spw->sp_lstchg, (int)spw->sp_max);
|
||||
|
||||
/*
|
||||
* We assume account and password expiration occurs the
|
||||
* day after the day specified.
|
||||
*/
|
||||
if (spw->sp_expire != -1 && today > spw->sp_expire) {
|
||||
log("Account %.100s has expired", pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (spw->sp_lstchg == 0) {
|
||||
log("User %.100s password has expired (root forced)",
|
||||
pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (spw->sp_max != -1 &&
|
||||
today > spw->sp_lstchg + spw->sp_max) {
|
||||
log("User %.100s password has expired (password aged)",
|
||||
pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Shouldn't be called if pw is NULL, but better safe than sorry... */
|
||||
if (!pw || !pw->pw_name)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get the shell from the password data. An empty shell field is
|
||||
* legal, and means /bin/sh.
|
||||
@ -150,6 +200,24 @@ allowed_user(struct passwd * pw)
|
||||
}
|
||||
ga_free();
|
||||
}
|
||||
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) {
|
||||
if (loginmsg && *loginmsg) {
|
||||
/* Remove embedded newlines (if any) */
|
||||
char *p;
|
||||
for (p = loginmsg; *p; p++) {
|
||||
if (*p == '\n')
|
||||
*p = ' ';
|
||||
}
|
||||
/* Remove trailing newline */
|
||||
*--p = '\0';
|
||||
log("Login restricted for %s: %.100s", pw->pw_name, loginmsg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
|
||||
/* We found no reason not to let this user try to log on... */
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: auth.h,v 1.39 2002/05/31 11:35:15 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -133,6 +132,9 @@ int auth_krb5_password(Authctxt *authctxt, const char *password);
|
||||
void krb5_cleanup_proc(void *authctxt);
|
||||
#endif /* KRB5 */
|
||||
|
||||
#include "auth-pam.h"
|
||||
#include "auth2-pam.h"
|
||||
|
||||
Authctxt *do_authentication(void);
|
||||
Authctxt *do_authentication2(void);
|
||||
|
||||
@ -186,5 +188,5 @@ void auth_debug_reset(void);
|
||||
#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
|
||||
#define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
|
||||
|
||||
#define SKEY_PROMPT "\nOPIE Password: "
|
||||
#define SKEY_PROMPT "\nS/Key Password: "
|
||||
#endif
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth1.c,v 1.41 2002/06/19 00:27:55 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "rsa.h"
|
||||
@ -25,14 +24,9 @@ RCSID("$FreeBSD$");
|
||||
#include "auth.h"
|
||||
#include "channels.h"
|
||||
#include "session.h"
|
||||
#include "canohost.h"
|
||||
#include "uidswap.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
#include <login_cap.h>
|
||||
#include "auth-pam.h"
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
||||
@ -81,16 +75,6 @@ do_authloop(Authctxt *authctxt)
|
||||
u_int ulen;
|
||||
int type = 0;
|
||||
struct passwd *pw = authctxt->pw;
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
login_cap_t *lc;
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
#ifdef USE_PAM
|
||||
struct inverted_pam_cookie *pam_cookie;
|
||||
#endif /* USE_PAM */
|
||||
const char *from_host, *from_ip;
|
||||
|
||||
from_host = get_canonical_hostname(options.verify_reverse_mapping);
|
||||
from_ip = get_remote_ipaddr();
|
||||
|
||||
debug("Attempting authentication for %s%.100s.",
|
||||
authctxt->valid ? "" : "illegal user ", authctxt->user);
|
||||
@ -100,11 +84,7 @@ do_authloop(Authctxt *authctxt)
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
(!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
/* XXX PRIVSEP */ auth_pam_password(authctxt, "")) {
|
||||
#else
|
||||
PRIVSEP(auth_password(authctxt, ""))) {
|
||||
#endif
|
||||
auth_log(authctxt, 1, "without authentication", "");
|
||||
return;
|
||||
}
|
||||
@ -149,7 +129,6 @@ do_authloop(Authctxt *authctxt)
|
||||
snprintf(info, sizeof(info),
|
||||
" tktuser %.100s",
|
||||
client_user);
|
||||
xfree(client_user);
|
||||
}
|
||||
#endif /* KRB4 */
|
||||
} else {
|
||||
@ -163,7 +142,6 @@ do_authloop(Authctxt *authctxt)
|
||||
snprintf(info, sizeof(info),
|
||||
" tktuser %.100s",
|
||||
client_user);
|
||||
xfree(client_user);
|
||||
}
|
||||
#endif /* KRB5 */
|
||||
}
|
||||
@ -262,49 +240,13 @@ do_authloop(Authctxt *authctxt)
|
||||
password = packet_get_string(&dlen);
|
||||
packet_check_eom();
|
||||
|
||||
#ifdef USE_PAM
|
||||
/* Do PAM auth with password */
|
||||
authenticated = /* XXX PRIVSEP */ auth_pam_password(authctxt, password);
|
||||
#else /* !USE_PAM */
|
||||
/* Try authentication with the password. */
|
||||
authenticated = PRIVSEP(auth_password(authctxt, password));
|
||||
#endif /* USE_PAM */
|
||||
|
||||
memset(password, 0, strlen(password));
|
||||
xfree(password);
|
||||
break;
|
||||
|
||||
#ifdef USE_PAM
|
||||
case SSH_CMSG_AUTH_TIS:
|
||||
debug("rcvd SSH_CMSG_AUTH_TIS: Trying PAM");
|
||||
pam_cookie = ipam_start_auth("sshd", pw->pw_name);
|
||||
/* We now have data available to send as a challenge */
|
||||
if (pam_cookie->num_msg != 1 ||
|
||||
(pam_cookie->msg[0]->msg_style != PAM_PROMPT_ECHO_OFF &&
|
||||
pam_cookie->msg[0]->msg_style != PAM_PROMPT_ECHO_ON)) {
|
||||
/* We got several challenges or an unknown challenge type */
|
||||
ipam_free_cookie(pam_cookie);
|
||||
pam_cookie = NULL;
|
||||
break;
|
||||
}
|
||||
packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
|
||||
packet_put_string(pam_cookie->msg[0]->msg, strlen(pam_cookie->msg[0]->msg));
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
continue;
|
||||
case SSH_CMSG_AUTH_TIS_RESPONSE:
|
||||
debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
|
||||
if (pam_cookie != NULL) {
|
||||
char *response = packet_get_string(&dlen);
|
||||
|
||||
pam_cookie->resp[0]->resp = strdup(response);
|
||||
xfree(response);
|
||||
authenticated = ipam_complete_auth(pam_cookie);
|
||||
ipam_free_cookie(pam_cookie);
|
||||
pam_cookie = NULL;
|
||||
}
|
||||
break;
|
||||
#elif defined(SKEY)
|
||||
case SSH_CMSG_AUTH_TIS:
|
||||
debug("rcvd SSH_CMSG_AUTH_TIS");
|
||||
if (options.challenge_response_authentication == 1) {
|
||||
@ -331,12 +273,6 @@ do_authloop(Authctxt *authctxt)
|
||||
xfree(response);
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case SSH_CMSG_AUTH_TIS:
|
||||
/* TIS Authentication is unsupported */
|
||||
log("TIS authentication unsupported.");
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
/*
|
||||
@ -346,26 +282,6 @@ do_authloop(Authctxt *authctxt)
|
||||
log("Unknown message during authentication: type %d", type);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
if (pw != NULL) {
|
||||
lc = login_getpwclass(pw);
|
||||
if (lc == NULL)
|
||||
lc = login_getclassbyname(NULL, pw);
|
||||
if (!auth_hostok(lc, from_host, from_ip)) {
|
||||
log("Denied connection for %.200s from %.200s [%.200s].",
|
||||
pw->pw_name, from_host, from_ip);
|
||||
packet_disconnect("Sorry, you are not allowed to connect.");
|
||||
}
|
||||
if (!auth_timeok(lc, time(NULL))) {
|
||||
log("LOGIN %.200s REFUSED (TIME) FROM %.200s",
|
||||
pw->pw_name, from_host);
|
||||
packet_disconnect("Logins not available right now.");
|
||||
}
|
||||
login_close(lc);
|
||||
lc = NULL;
|
||||
}
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
#ifdef BSD_AUTH
|
||||
if (authctxt->as) {
|
||||
auth_close(authctxt->as);
|
||||
@ -376,23 +292,28 @@ do_authloop(Authctxt *authctxt)
|
||||
fatal("INTERNAL ERROR: authenticated invalid user %s",
|
||||
authctxt->user);
|
||||
|
||||
#ifdef HAVE_CYGWIN
|
||||
if (authenticated &&
|
||||
!check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) {
|
||||
packet_disconnect("Authentication rejected for uid %d.",
|
||||
pw == NULL ? -1 : pw->pw_uid);
|
||||
authenticated = 0;
|
||||
}
|
||||
#else
|
||||
/* Special handling for root */
|
||||
if (authenticated && authctxt->pw->pw_uid == 0 &&
|
||||
!auth_root_allowed(get_authname(type)))
|
||||
authenticated = 0;
|
||||
|
||||
if (pw != NULL && pw->pw_uid == 0)
|
||||
log("ROOT LOGIN as '%.100s' from %.100s",
|
||||
pw->pw_name, from_host );
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
if (!use_privsep && authenticated &&
|
||||
!do_pam_account(pw->pw_name, client_user))
|
||||
authenticated = 0;
|
||||
#endif
|
||||
|
||||
/* Log before sending the reply */
|
||||
auth_log(authctxt, authenticated, get_authname(type), info);
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (authenticated && !do_pam_account(pw->pw_name, client_user))
|
||||
authenticated = 0;
|
||||
#endif
|
||||
|
||||
if (client_user != NULL) {
|
||||
xfree(client_user);
|
||||
client_user = NULL;
|
||||
@ -401,8 +322,15 @@ do_authloop(Authctxt *authctxt)
|
||||
if (authenticated)
|
||||
return;
|
||||
|
||||
if (authctxt->failures++ > AUTH_FAIL_MAX)
|
||||
if (authctxt->failures++ > AUTH_FAIL_MAX) {
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
/* XXX: privsep */
|
||||
loginfailed(authctxt->user,
|
||||
get_canonical_hostname(options.verify_reverse_mapping),
|
||||
"ssh");
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
|
||||
}
|
||||
|
||||
packet_start(SSH_SMSG_FAILURE);
|
||||
packet_send();
|
||||
@ -451,20 +379,22 @@ do_authentication(void)
|
||||
else
|
||||
debug("do_authentication: illegal user %s", user);
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (authctxt->pw != NULL)
|
||||
start_pam(authctxt->pw);
|
||||
#endif
|
||||
setproctitle("%s%s", authctxt->pw ? user : "unknown",
|
||||
use_privsep ? " [net]" : "");
|
||||
|
||||
#ifdef USE_PAM
|
||||
PRIVSEP(start_pam(authctxt->pw == NULL ? "NOUSER" : user));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we are not running as root, the user must have the same uid as
|
||||
* the server.
|
||||
* the server. (Unless you are running Windows)
|
||||
*/
|
||||
#ifndef HAVE_CYGWIN
|
||||
if (!use_privsep && getuid() != 0 && authctxt->pw &&
|
||||
authctxt->pw->pw_uid != getuid())
|
||||
packet_disconnect("Cannot change user when server not running as root.");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Loop until the user has been authenticated or the connection is
|
||||
|
@ -24,7 +24,6 @@
|
||||
*/
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2-chall.c,v 1.18 2002/06/19 00:27:55 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh2.h"
|
||||
#include "auth.h"
|
||||
@ -41,19 +40,19 @@ static void input_userauth_info_response(int, u_int32_t, void *);
|
||||
|
||||
#ifdef BSD_AUTH
|
||||
extern KbdintDevice bsdauth_device;
|
||||
#elif defined(USE_PAM)
|
||||
extern KbdintDevice pam_device;
|
||||
#elif defined(SKEY)
|
||||
#else
|
||||
#ifdef SKEY
|
||||
extern KbdintDevice skey_device;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
KbdintDevice *devices[] = {
|
||||
#ifdef BSD_AUTH
|
||||
&bsdauth_device,
|
||||
#elif defined(USE_PAM)
|
||||
&pam_device,
|
||||
#elif defined(SKEY)
|
||||
#else
|
||||
#ifdef SKEY
|
||||
&skey_device,
|
||||
#endif
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
@ -1,333 +1,158 @@
|
||||
/*-
|
||||
* Copyright (c) 2002 Networks Associates Technology, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed for the FreeBSD Project by ThinkSec AS and
|
||||
* NAI Labs, the Security Research Division of Network Associates, Inc.
|
||||
* under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
|
||||
* DARPA CHATS research program.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include "includes.h"
|
||||
RCSID("$Id: auth2-pam.c,v 1.12 2002/01/22 12:43:13 djm Exp $");
|
||||
|
||||
#ifdef USE_PAM
|
||||
#include "includes.h"
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
#include "auth.h"
|
||||
#include "log.h"
|
||||
#include "auth-pam.h"
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "dispatch.h"
|
||||
#include "log.h"
|
||||
|
||||
struct pam_ctxt {
|
||||
char *pam_user;
|
||||
pid_t pam_pid;
|
||||
int pam_sock;
|
||||
int pam_done;
|
||||
static int do_pam_conversation_kbd_int(int num_msg,
|
||||
const struct pam_message **msg, struct pam_response **resp,
|
||||
void *appdata_ptr);
|
||||
void input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt);
|
||||
|
||||
struct {
|
||||
int finished, num_received, num_expected;
|
||||
int *prompts;
|
||||
struct pam_response *responses;
|
||||
} context_pam2 = {0, 0, 0, NULL};
|
||||
|
||||
static struct pam_conv conv2 = {
|
||||
do_pam_conversation_kbd_int,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void pam_free_ctx(void *);
|
||||
|
||||
/*
|
||||
* Send message to parent or child.
|
||||
*/
|
||||
static int
|
||||
pam_send(struct pam_ctxt *ctxt, char *fmt, ...)
|
||||
int
|
||||
auth2_pam(Authctxt *authctxt)
|
||||
{
|
||||
va_list ap;
|
||||
char *mstr;
|
||||
size_t len;
|
||||
int r;
|
||||
int retval = -1;
|
||||
|
||||
va_start(ap, fmt);
|
||||
len = vasprintf(&mstr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (mstr == NULL)
|
||||
exit(1);
|
||||
if (ctxt->pam_pid != 0)
|
||||
debug2("to child: %s", mstr);
|
||||
r = send(ctxt->pam_sock, mstr, len + 1, MSG_EOR);
|
||||
free(mstr);
|
||||
return (r);
|
||||
if (authctxt->user == NULL)
|
||||
fatal("auth2_pam: internal error: no user");
|
||||
|
||||
conv2.appdata_ptr = authctxt;
|
||||
do_pam_set_conv(&conv2);
|
||||
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
|
||||
&input_userauth_info_response_pam);
|
||||
retval = (do_pam_authenticate(0) == PAM_SUCCESS);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Peek at first byte of next message.
|
||||
*/
|
||||
static int
|
||||
pam_peek(struct pam_ctxt *ctxt)
|
||||
do_pam_conversation_kbd_int(int num_msg, const struct pam_message **msg,
|
||||
struct pam_response **resp, void *appdata_ptr)
|
||||
{
|
||||
char ch;
|
||||
int i, j, done;
|
||||
char *text;
|
||||
|
||||
if (recv(ctxt->pam_sock, &ch, 1, MSG_PEEK) < 1)
|
||||
return (-1);
|
||||
return (ch);
|
||||
}
|
||||
context_pam2.finished = 0;
|
||||
context_pam2.num_received = 0;
|
||||
context_pam2.num_expected = 0;
|
||||
context_pam2.prompts = xmalloc(sizeof(int) * num_msg);
|
||||
context_pam2.responses = xmalloc(sizeof(struct pam_response) * num_msg);
|
||||
memset(context_pam2.responses, 0, sizeof(struct pam_response) * num_msg);
|
||||
|
||||
/*
|
||||
* Receive a message from parent or child.
|
||||
*/
|
||||
static char *
|
||||
pam_receive(struct pam_ctxt *ctxt)
|
||||
{
|
||||
char *buf;
|
||||
size_t len;
|
||||
ssize_t rlen;
|
||||
|
||||
len = 64;
|
||||
buf = NULL;
|
||||
do {
|
||||
len *= 2;
|
||||
buf = xrealloc(buf, len);
|
||||
rlen = recv(ctxt->pam_sock, buf, len, MSG_PEEK);
|
||||
if (rlen < 1) {
|
||||
xfree(buf);
|
||||
return (NULL);
|
||||
}
|
||||
} while (rlen == len);
|
||||
if (recv(ctxt->pam_sock, buf, len, 0) != rlen) {
|
||||
xfree(buf);
|
||||
return (NULL);
|
||||
}
|
||||
if (ctxt->pam_pid != 0)
|
||||
debug2("from child: %s", buf);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Conversation function for child process.
|
||||
*/
|
||||
static int
|
||||
pam_child_conv(int n,
|
||||
const struct pam_message **msg,
|
||||
struct pam_response **resp,
|
||||
void *data)
|
||||
{
|
||||
struct pam_ctxt *ctxt;
|
||||
int i;
|
||||
|
||||
ctxt = data;
|
||||
if (n <= 0 || n > PAM_MAX_NUM_MSG)
|
||||
return (PAM_CONV_ERR);
|
||||
if ((*resp = calloc(n, sizeof **resp)) == NULL)
|
||||
return (PAM_BUF_ERR);
|
||||
for (i = 0; i < n; ++i) {
|
||||
resp[i]->resp_retcode = 0;
|
||||
resp[i]->resp = NULL;
|
||||
switch (msg[i]->msg_style) {
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
pam_send(ctxt, "p%s", msg[i]->msg);
|
||||
resp[i]->resp = pam_receive(ctxt);
|
||||
break;
|
||||
text = NULL;
|
||||
for (i = 0, context_pam2.num_expected = 0; i < num_msg; i++) {
|
||||
int style = PAM_MSG_MEMBER(msg, i, msg_style);
|
||||
switch (style) {
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
pam_send(ctxt, "P%s", msg[i]->msg);
|
||||
resp[i]->resp = pam_receive(ctxt);
|
||||
break;
|
||||
case PAM_ERROR_MSG:
|
||||
/*pam_send(ctxt, "e%s", msg[i]->msg);*/
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
context_pam2.num_expected++;
|
||||
break;
|
||||
case PAM_TEXT_INFO:
|
||||
/*pam_send(ctxt, "i%s", msg[i]->msg);*/
|
||||
break;
|
||||
case PAM_ERROR_MSG:
|
||||
default:
|
||||
goto fail;
|
||||
/* Capture all these messages to be sent at once */
|
||||
message_cat(&text, PAM_MSG_MEMBER(msg, i, msg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (PAM_SUCCESS);
|
||||
fail:
|
||||
while (i)
|
||||
free(resp[--i]);
|
||||
free(*resp);
|
||||
*resp = NULL;
|
||||
return (PAM_CONV_ERR);
|
||||
|
||||
if (context_pam2.num_expected == 0)
|
||||
return PAM_SUCCESS;
|
||||
|
||||
packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
|
||||
packet_put_cstring(""); /* Name */
|
||||
packet_put_cstring(""); /* Instructions */
|
||||
packet_put_cstring(""); /* Language */
|
||||
packet_put_int(context_pam2.num_expected);
|
||||
|
||||
for (i = 0, j = 0; i < num_msg; i++) {
|
||||
int style = PAM_MSG_MEMBER(msg, i, msg_style);
|
||||
|
||||
/* Skip messages which don't need a reply */
|
||||
if (style != PAM_PROMPT_ECHO_ON && style != PAM_PROMPT_ECHO_OFF)
|
||||
continue;
|
||||
|
||||
context_pam2.prompts[j++] = i;
|
||||
if (text) {
|
||||
message_cat(&text, PAM_MSG_MEMBER(msg, i, msg));
|
||||
packet_put_cstring(text);
|
||||
text = NULL;
|
||||
} else
|
||||
packet_put_cstring(PAM_MSG_MEMBER(msg, i, msg));
|
||||
packet_put_char(style == PAM_PROMPT_ECHO_ON);
|
||||
}
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
/*
|
||||
* Grabbing control of execution and spinning until we get what
|
||||
* we want is probably rude, but it seems to work properly, and
|
||||
* the client *should* be in lock-step with us, so the loop should
|
||||
* only be traversed once.
|
||||
*/
|
||||
while(context_pam2.finished == 0) {
|
||||
done = 1;
|
||||
dispatch_run(DISPATCH_BLOCK, &done, appdata_ptr);
|
||||
if(context_pam2.finished == 0)
|
||||
debug("extra packet during conversation");
|
||||
}
|
||||
|
||||
if(context_pam2.num_received == context_pam2.num_expected) {
|
||||
*resp = context_pam2.responses;
|
||||
return PAM_SUCCESS;
|
||||
} else
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Child process.
|
||||
*/
|
||||
static void *
|
||||
pam_child(struct pam_ctxt *ctxt)
|
||||
void
|
||||
input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt)
|
||||
{
|
||||
struct pam_conv pam_conv = { pam_child_conv, ctxt };
|
||||
pam_handle_t *pamh;
|
||||
int pam_err;
|
||||
Authctxt *authctxt = ctxt;
|
||||
unsigned int nresp = 0, rlen = 0, i = 0;
|
||||
char *resp;
|
||||
|
||||
pam_err = pam_start("sshd", ctxt->pam_user, &pam_conv, &pamh);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
goto auth_fail;
|
||||
pam_err = pam_authenticate(pamh, 0);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
goto auth_fail;
|
||||
pam_send(ctxt, "=OK");
|
||||
pam_end(pamh, pam_err);
|
||||
exit(0);
|
||||
auth_fail:
|
||||
pam_send(ctxt, "!%s", pam_strerror(pamh, pam_err));
|
||||
pam_end(pamh, pam_err);
|
||||
exit(0);
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_info_response_pam: no authentication context");
|
||||
|
||||
nresp = packet_get_int(); /* Number of responses. */
|
||||
debug("got %d responses", nresp);
|
||||
|
||||
for (i = 0; i < nresp; i++) {
|
||||
int j = context_pam2.prompts[i];
|
||||
|
||||
resp = packet_get_string(&rlen);
|
||||
context_pam2.responses[j].resp_retcode = PAM_SUCCESS;
|
||||
context_pam2.responses[j].resp = xstrdup(resp);
|
||||
xfree(resp);
|
||||
context_pam2.num_received++;
|
||||
}
|
||||
|
||||
context_pam2.finished = 1;
|
||||
|
||||
packet_check_eom();
|
||||
}
|
||||
|
||||
static void *
|
||||
pam_init_ctx(Authctxt *authctxt)
|
||||
{
|
||||
struct pam_ctxt *ctxt;
|
||||
int socks[2];
|
||||
int i;
|
||||
|
||||
ctxt = xmalloc(sizeof *ctxt);
|
||||
ctxt->pam_user = xstrdup(authctxt->user);
|
||||
ctxt->pam_done = 0;
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, PF_UNSPEC, socks) == -1) {
|
||||
error("%s: failed create sockets: %s",
|
||||
__func__, strerror(errno));
|
||||
xfree(ctxt);
|
||||
return (NULL);
|
||||
}
|
||||
if ((ctxt->pam_pid = fork()) == -1) {
|
||||
error("%s: failed to fork auth-pam child: %s",
|
||||
__func__, strerror(errno));
|
||||
close(socks[0]);
|
||||
close(socks[1]);
|
||||
xfree(ctxt);
|
||||
return (NULL);
|
||||
}
|
||||
if (ctxt->pam_pid == 0) {
|
||||
/* close everything except our end of the pipe */
|
||||
ctxt->pam_sock = socks[1];
|
||||
for (i = 0; i < getdtablesize(); ++i)
|
||||
if (i != ctxt->pam_sock)
|
||||
close(i);
|
||||
pam_child(ctxt);
|
||||
/* not reached */
|
||||
exit(1);
|
||||
}
|
||||
ctxt->pam_sock = socks[0];
|
||||
close(socks[1]);
|
||||
return (ctxt);
|
||||
}
|
||||
|
||||
static int
|
||||
pam_query(void *ctx, char **name, char **info,
|
||||
u_int *num, char ***prompts, u_int **echo_on)
|
||||
{
|
||||
struct pam_ctxt *ctxt = ctx;
|
||||
char *msg;
|
||||
|
||||
if ((msg = pam_receive(ctxt)) == NULL)
|
||||
return (-1);
|
||||
*name = xstrdup("");
|
||||
*info = xstrdup("");
|
||||
*prompts = xmalloc(sizeof(char *));
|
||||
*echo_on = xmalloc(sizeof(u_int));
|
||||
switch (*msg) {
|
||||
case 'P':
|
||||
**echo_on = 1;
|
||||
case 'p':
|
||||
*num = 1;
|
||||
**prompts = xstrdup(msg + 1);
|
||||
**echo_on = (*msg == 'P');
|
||||
break;
|
||||
case '=':
|
||||
*num = 0;
|
||||
**echo_on = 0;
|
||||
ctxt->pam_done = 1;
|
||||
break;
|
||||
case '!':
|
||||
error("%s", msg + 1);
|
||||
default:
|
||||
*num = 0;
|
||||
**echo_on = 0;
|
||||
xfree(msg);
|
||||
ctxt->pam_done = -1;
|
||||
return (-1);
|
||||
}
|
||||
xfree(msg);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pam_respond(void *ctx, u_int num, char **resp)
|
||||
{
|
||||
struct pam_ctxt *ctxt = ctx;
|
||||
char *msg;
|
||||
|
||||
debug2(__func__);
|
||||
switch (ctxt->pam_done) {
|
||||
case 1:
|
||||
return (0);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
if (num != 1) {
|
||||
error("expected one response, got %u", num);
|
||||
return (-1);
|
||||
}
|
||||
pam_send(ctxt, "%s", *resp);
|
||||
switch (pam_peek(ctxt)) {
|
||||
case 'P':
|
||||
case 'p':
|
||||
return (1);
|
||||
case '=':
|
||||
msg = pam_receive(ctxt);
|
||||
xfree(msg);
|
||||
ctxt->pam_done = 1;
|
||||
return (0);
|
||||
default:
|
||||
msg = pam_receive(ctxt);
|
||||
if (*msg == '!')
|
||||
error("%s", msg + 1);
|
||||
xfree(msg);
|
||||
ctxt->pam_done = -1;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pam_free_ctx(void *ctxtp)
|
||||
{
|
||||
struct pam_ctxt *ctxt = ctxtp;
|
||||
int status;
|
||||
|
||||
close(ctxt->pam_sock);
|
||||
kill(ctxt->pam_pid, SIGHUP);
|
||||
waitpid(ctxt->pam_pid, &status, 0);
|
||||
xfree(ctxt->pam_user);
|
||||
xfree(ctxt);
|
||||
}
|
||||
|
||||
KbdintDevice pam_device = {
|
||||
"pam",
|
||||
pam_init_ctx,
|
||||
pam_query,
|
||||
pam_respond,
|
||||
pam_free_ctx
|
||||
};
|
||||
|
||||
#endif /* USE_PAM */
|
||||
#endif
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2.c,v 1.93 2002/05/31 11:35:15 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh2.h"
|
||||
#include "xmalloc.h"
|
||||
@ -35,13 +34,8 @@ RCSID("$FreeBSD$");
|
||||
#include "auth.h"
|
||||
#include "dispatch.h"
|
||||
#include "pathnames.h"
|
||||
#include "canohost.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
#include <login_cap.h>
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern u_char *session_id2;
|
||||
@ -91,6 +85,10 @@ do_authentication2(void)
|
||||
/* challenge-response is implemented via keyboard interactive */
|
||||
if (options.challenge_response_authentication)
|
||||
options.kbd_interactive_authentication = 1;
|
||||
if (options.pam_authentication_via_kbd_int)
|
||||
options.kbd_interactive_authentication = 1;
|
||||
if (use_privsep)
|
||||
options.pam_authentication_via_kbd_int = 0;
|
||||
|
||||
dispatch_init(&dispatch_protocol_error);
|
||||
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
|
||||
@ -139,15 +137,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
Authmethod *m = NULL;
|
||||
char *user, *service, *method, *style = NULL;
|
||||
int authenticated = 0;
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
login_cap_t *lc;
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
#if defined(HAVE_LOGIN_CAP)
|
||||
const char *from_host, *from_ip;
|
||||
|
||||
from_host = get_canonical_hostname(options.verify_reverse_mapping);
|
||||
from_ip = get_remote_ipaddr();
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_request: no authctxt");
|
||||
@ -168,11 +157,13 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
authctxt->valid = 1;
|
||||
debug2("input_userauth_request: setting up authctxt for %s", user);
|
||||
#ifdef USE_PAM
|
||||
start_pam(authctxt->pw);
|
||||
PRIVSEP(start_pam(authctxt->pw->pw_name));
|
||||
#endif
|
||||
} else {
|
||||
log("input_userauth_request: illegal user %s", user);
|
||||
authctxt->pw = NULL;
|
||||
#ifdef USE_PAM
|
||||
PRIVSEP(start_pam("NOUSER"));
|
||||
#endif
|
||||
}
|
||||
setproctitle("%s%s", authctxt->pw ? user : "unknown",
|
||||
use_privsep ? " [net]" : "");
|
||||
@ -187,26 +178,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
"(%s,%s) -> (%s,%s)",
|
||||
authctxt->user, authctxt->service, user, service);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
if (authctxt->pw != NULL) {
|
||||
lc = login_getpwclass(authctxt->pw);
|
||||
if (lc == NULL)
|
||||
lc = login_getclassbyname(NULL, authctxt->pw);
|
||||
if (!auth_hostok(lc, from_host, from_ip)) {
|
||||
log("Denied connection for %.200s from %.200s [%.200s].",
|
||||
authctxt->pw->pw_name, from_host, from_ip);
|
||||
packet_disconnect("Sorry, you are not allowed to connect.");
|
||||
}
|
||||
if (!auth_timeok(lc, time(NULL))) {
|
||||
log("LOGIN %.200s REFUSED (TIME) FROM %.200s",
|
||||
authctxt->pw->pw_name, from_host);
|
||||
packet_disconnect("Logins not available right now.");
|
||||
}
|
||||
login_close(lc);
|
||||
lc = NULL;
|
||||
}
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
/* reset state */
|
||||
auth2_challenge_stop(authctxt);
|
||||
authctxt->postponed = 0;
|
||||
@ -217,10 +188,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
debug2("input_userauth_request: try method %s", method);
|
||||
authenticated = m->userauth(authctxt);
|
||||
}
|
||||
#ifdef USE_PAM
|
||||
if (authenticated && authctxt->user && !do_pam_account(authctxt->user, NULL))
|
||||
authenticated = 0;
|
||||
#endif /* USE_PAM */
|
||||
userauth_finish(authctxt, authenticated, method);
|
||||
|
||||
xfree(service);
|
||||
@ -242,6 +209,12 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
|
||||
!auth_root_allowed(method))
|
||||
authenticated = 0;
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (!use_privsep && authenticated && authctxt->user &&
|
||||
!do_pam_account(authctxt->user, NULL))
|
||||
authenticated = 0;
|
||||
#endif /* USE_PAM */
|
||||
|
||||
/* Log before sending the reply */
|
||||
auth_log(authctxt, authenticated, method, " ssh2");
|
||||
|
||||
@ -258,8 +231,15 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
|
||||
/* now we can break out */
|
||||
authctxt->success = 1;
|
||||
} else {
|
||||
if (authctxt->failures++ > AUTH_FAIL_MAX)
|
||||
if (authctxt->failures++ > AUTH_FAIL_MAX) {
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
/* XXX: privsep */
|
||||
loginfailed(authctxt->user,
|
||||
get_canonical_hostname(options.verify_reverse_mapping),
|
||||
"ssh");
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
|
||||
}
|
||||
methods = authmethods_get();
|
||||
packet_start(SSH2_MSG_USERAUTH_FAILURE);
|
||||
packet_put_cstring(methods);
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: authfd.c,v 1.55 2002/06/19 00:27:55 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
|
@ -37,7 +37,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: authfile.c,v 1.49 2002/05/23 19:24:30 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
@ -485,6 +484,9 @@ key_perm_ok(int fd, const char *filename)
|
||||
* permissions of the file. if the key owned by a different user,
|
||||
* then we don't care.
|
||||
*/
|
||||
#ifdef HAVE_CYGWIN
|
||||
if (check_ntsec(filename))
|
||||
#endif
|
||||
if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
|
||||
|
@ -38,7 +38,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: bufaux.c,v 1.25 2002/04/20 09:14:58 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include "bufaux.h"
|
||||
@ -158,6 +157,7 @@ buffer_get_int(Buffer *buffer)
|
||||
return GET_32BIT(buf);
|
||||
}
|
||||
|
||||
#ifdef HAVE_U_INT64_T
|
||||
u_int64_t
|
||||
buffer_get_int64(Buffer *buffer)
|
||||
{
|
||||
@ -165,6 +165,7 @@ buffer_get_int64(Buffer *buffer)
|
||||
buffer_get(buffer, (char *) buf, 8);
|
||||
return GET_64BIT(buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Stores integers in the buffer, msb first.
|
||||
@ -185,6 +186,7 @@ buffer_put_int(Buffer *buffer, u_int value)
|
||||
buffer_append(buffer, buf, 4);
|
||||
}
|
||||
|
||||
#ifdef HAVE_U_INT64_T
|
||||
void
|
||||
buffer_put_int64(Buffer *buffer, u_int64_t value)
|
||||
{
|
||||
@ -192,6 +194,7 @@ buffer_put_int64(Buffer *buffer, u_int64_t value)
|
||||
PUT_64BIT(buf, value);
|
||||
buffer_append(buffer, buf, 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns an arbitrary binary string from the buffer. The string cannot
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: canohost.c,v 1.32 2002/06/11 08:11:45 itojun Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
@ -43,6 +42,28 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
|
||||
debug("getpeername failed: %.100s", strerror(errno));
|
||||
fatal_cleanup();
|
||||
}
|
||||
#ifdef IPV4_IN_IPV6
|
||||
if (from.ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from;
|
||||
|
||||
/* Detect IPv4 in IPv6 mapped address and convert it to */
|
||||
/* plain (AF_INET) IPv4 address */
|
||||
if (IN6_IS_ADDR_V4MAPPED(&from6->sin6_addr)) {
|
||||
struct sockaddr_in *from4 = (struct sockaddr_in *)&from;
|
||||
struct in_addr addr;
|
||||
u_int16_t port;
|
||||
|
||||
memcpy(&addr, ((char *)&from6->sin6_addr) + 12, sizeof(addr));
|
||||
port = from6->sin6_port;
|
||||
|
||||
memset(&from, 0, sizeof(from));
|
||||
|
||||
from4->sin_family = AF_INET;
|
||||
memcpy(&from4->sin_addr, &addr, sizeof(addr));
|
||||
from4->sin_port = port;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop),
|
||||
NULL, 0, NI_NUMERICHOST) != 0)
|
||||
|
@ -40,7 +40,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: channels.c,v 1.175 2002/06/10 22:28:41 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
@ -130,7 +129,7 @@ static u_int x11_fake_data_len;
|
||||
#define NUM_SOCKS 10
|
||||
|
||||
/* AF_UNSPEC or AF_INET or AF_INET6 */
|
||||
int IPv4or6 = AF_UNSPEC;
|
||||
static int IPv4or6 = AF_UNSPEC;
|
||||
|
||||
/* helper */
|
||||
static void port_open_helper(Channel *c, char *rtype);
|
||||
@ -2058,7 +2057,11 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
|
||||
/* Bind the socket to the address. */
|
||||
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||
/* address can be in use ipv6 address is already bound */
|
||||
verbose("bind: %.100s", strerror(errno));
|
||||
if (!ai->ai_next)
|
||||
error("bind: %.100s", strerror(errno));
|
||||
else
|
||||
verbose("bind: %.100s", strerror(errno));
|
||||
|
||||
close(sock);
|
||||
continue;
|
||||
}
|
||||
@ -2177,6 +2180,7 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
|
||||
hostname = packet_get_string(NULL);
|
||||
host_port = packet_get_int();
|
||||
|
||||
#ifndef HAVE_CYGWIN
|
||||
/*
|
||||
* Check that an unprivileged user is not trying to forward a
|
||||
* privileged port.
|
||||
@ -2184,6 +2188,7 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
|
||||
if (port < IPPORT_RESERVED && !is_root)
|
||||
packet_disconnect("Requested forwarding of port %d but user is not root.",
|
||||
port);
|
||||
#endif
|
||||
/* Initiate forwarding */
|
||||
channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports);
|
||||
|
||||
@ -2355,12 +2360,29 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
|
||||
continue;
|
||||
sock = socket(ai->ai_family, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
error("socket: %.100s", strerror(errno));
|
||||
return -1;
|
||||
if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) {
|
||||
error("socket: %.100s", strerror(errno));
|
||||
return -1;
|
||||
} else {
|
||||
debug("x11_create_display_inet: Socket family %d not supported",
|
||||
ai->ai_family);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#ifdef IPV6_V6ONLY
|
||||
if (ai->ai_family == AF_INET6) {
|
||||
int on = 1;
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
|
||||
error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||
debug("bind port %d: %.100s", port, strerror(errno));
|
||||
close(sock);
|
||||
|
||||
if (ai->ai_next)
|
||||
continue;
|
||||
|
||||
for (n = 0; n < num_socks; n++) {
|
||||
close(socks[n]);
|
||||
}
|
||||
@ -2368,8 +2390,17 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
|
||||
break;
|
||||
}
|
||||
socks[num_socks++] = sock;
|
||||
#ifndef DONT_TRY_OTHER_AF
|
||||
if (num_socks == NUM_SOCKS)
|
||||
break;
|
||||
#else
|
||||
if (x11_use_localhost) {
|
||||
if (num_socks == NUM_SOCKS)
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
freeaddrinfo(aitop);
|
||||
if (num_socks > 0)
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: channels.h,v 1.68 2002/06/10 22:28:41 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: cipher.c,v 1.59 2002/06/19 18:01:00 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
@ -44,6 +43,11 @@ RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00906000L
|
||||
#define SSH_OLD_EVP
|
||||
#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
#include "rijndael.h"
|
||||
static const EVP_CIPHER *evp_rijndael(void);
|
||||
@ -189,7 +193,11 @@ cipher_init(CipherContext *cc, Cipher *cipher,
|
||||
int encrypt)
|
||||
{
|
||||
static int dowarn = 1;
|
||||
#ifdef SSH_OLD_EVP
|
||||
EVP_CIPHER *type;
|
||||
#else
|
||||
const EVP_CIPHER *type;
|
||||
#endif
|
||||
int klen;
|
||||
|
||||
if (cipher->number == SSH_CIPHER_DES) {
|
||||
@ -214,6 +222,15 @@ cipher_init(CipherContext *cc, Cipher *cipher,
|
||||
type = (*cipher->evptype)();
|
||||
|
||||
EVP_CIPHER_CTX_init(&cc->evp);
|
||||
#ifdef SSH_OLD_EVP
|
||||
if (type->key_len > 0 && type->key_len != keylen) {
|
||||
debug("cipher_init: set keylen (%d -> %d)",
|
||||
type->key_len, keylen);
|
||||
type->key_len = keylen;
|
||||
}
|
||||
EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
|
||||
(encrypt == CIPHER_ENCRYPT));
|
||||
#else
|
||||
if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
|
||||
(encrypt == CIPHER_ENCRYPT)) == 0)
|
||||
fatal("cipher_init: EVP_CipherInit failed for %s",
|
||||
@ -228,6 +245,7 @@ cipher_init(CipherContext *cc, Cipher *cipher,
|
||||
if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
|
||||
fatal("cipher_init: EVP_CipherInit: set key failed for %s",
|
||||
cipher->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -235,15 +253,23 @@ cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
|
||||
{
|
||||
if (len % cc->cipher->block_size)
|
||||
fatal("cipher_encrypt: bad plaintext length %d", len);
|
||||
#ifdef SSH_OLD_EVP
|
||||
EVP_Cipher(&cc->evp, dest, (u_char *)src, len);
|
||||
#else
|
||||
if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
|
||||
fatal("evp_crypt: EVP_Cipher failed");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
cipher_cleanup(CipherContext *cc)
|
||||
{
|
||||
#ifdef SSH_OLD_EVP
|
||||
EVP_CIPHER_CTX_cleanup(&cc->evp);
|
||||
#else
|
||||
if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
|
||||
error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -314,6 +340,11 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
EVP_CIPHER_CTX_init(&c->k1);
|
||||
EVP_CIPHER_CTX_init(&c->k2);
|
||||
EVP_CIPHER_CTX_init(&c->k3);
|
||||
#ifdef SSH_OLD_EVP
|
||||
EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc);
|
||||
EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc);
|
||||
EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc);
|
||||
#else
|
||||
if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
|
||||
EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
|
||||
EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
|
||||
@ -322,6 +353,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
static int
|
||||
@ -333,10 +365,16 @@ ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
|
||||
error("ssh1_3des_cbc: no context");
|
||||
return (0);
|
||||
}
|
||||
#ifdef SSH_OLD_EVP
|
||||
EVP_Cipher(&c->k1, dest, (u_char *)src, len);
|
||||
EVP_Cipher(&c->k2, dest, dest, len);
|
||||
EVP_Cipher(&c->k3, dest, dest, len);
|
||||
#else
|
||||
if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
|
||||
EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
|
||||
EVP_Cipher(&c->k3, dest, dest, len) == 0)
|
||||
return (0);
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
static int
|
||||
@ -364,7 +402,9 @@ evp_ssh1_3des(void)
|
||||
ssh1_3des.init = ssh1_3des_init;
|
||||
ssh1_3des.cleanup = ssh1_3des_cleanup;
|
||||
ssh1_3des.do_cipher = ssh1_3des_cbc;
|
||||
#ifndef SSH_OLD_EVP
|
||||
ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
|
||||
#endif
|
||||
return (&ssh1_3des);
|
||||
}
|
||||
|
||||
@ -513,8 +553,10 @@ evp_rijndael(void)
|
||||
rijndal_cbc.init = ssh_rijndael_init;
|
||||
rijndal_cbc.cleanup = ssh_rijndael_cleanup;
|
||||
rijndal_cbc.do_cipher = ssh_rijndael_cbc;
|
||||
#ifndef SSH_OLD_EVP
|
||||
rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
|
||||
EVP_CIPH_ALWAYS_CALL_INIT;
|
||||
#endif
|
||||
return (&rijndal_cbc);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: cipher.h,v 1.33 2002/03/18 17:13:15 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -1,231 +0,0 @@
|
||||
/* $OpenBSD: cli.c,v 1.11 2001/03/06 00:33:04 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: cli.c,v 1.11 2001/03/06 00:33:04 deraadt Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
#include "cli.h"
|
||||
|
||||
#include <vis.h>
|
||||
|
||||
static int cli_input = -1;
|
||||
static int cli_output = -1;
|
||||
static int cli_from_stdin = 0;
|
||||
|
||||
sigset_t oset;
|
||||
sigset_t nset;
|
||||
struct sigaction nsa;
|
||||
struct sigaction osa;
|
||||
struct termios ntio;
|
||||
struct termios otio;
|
||||
int echo_modified;
|
||||
|
||||
volatile int intr;
|
||||
|
||||
static int
|
||||
cli_open(int from_stdin)
|
||||
{
|
||||
if (cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin)
|
||||
return 1;
|
||||
|
||||
if (from_stdin) {
|
||||
if (!cli_from_stdin && cli_input >= 0) {
|
||||
(void)close(cli_input);
|
||||
}
|
||||
cli_input = STDIN_FILENO;
|
||||
cli_output = STDERR_FILENO;
|
||||
} else {
|
||||
cli_input = cli_output = open(_PATH_TTY, O_RDWR);
|
||||
if (cli_input < 0)
|
||||
fatal("You have no controlling tty. Cannot read passphrase.");
|
||||
}
|
||||
|
||||
cli_from_stdin = from_stdin;
|
||||
|
||||
return cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_close(void)
|
||||
{
|
||||
if (!cli_from_stdin && cli_input >= 0)
|
||||
close(cli_input);
|
||||
cli_input = -1;
|
||||
cli_output = -1;
|
||||
cli_from_stdin = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
intrcatch(int sig)
|
||||
{
|
||||
intr = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_echo_disable(void)
|
||||
{
|
||||
sigemptyset(&nset);
|
||||
sigaddset(&nset, SIGTSTP);
|
||||
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
|
||||
intr = 0;
|
||||
|
||||
memset(&nsa, 0, sizeof(nsa));
|
||||
nsa.sa_handler = intrcatch;
|
||||
(void) sigaction(SIGINT, &nsa, &osa);
|
||||
|
||||
echo_modified = 0;
|
||||
if (tcgetattr(cli_input, &otio) == 0 && (otio.c_lflag & ECHO)) {
|
||||
echo_modified = 1;
|
||||
ntio = otio;
|
||||
ntio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
(void) tcsetattr(cli_input, TCSANOW, &ntio);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_echo_restore(void)
|
||||
{
|
||||
if (echo_modified != 0) {
|
||||
tcsetattr(cli_input, TCSANOW, &otio);
|
||||
echo_modified = 0;
|
||||
}
|
||||
|
||||
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
(void) sigaction(SIGINT, &osa, NULL);
|
||||
|
||||
if (intr != 0) {
|
||||
kill(getpid(), SIGINT);
|
||||
sigemptyset(&nset);
|
||||
/* XXX tty has not neccessarily drained by now? */
|
||||
sigsuspend(&nset);
|
||||
intr = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
cli_read(char* buf, int size, int echo)
|
||||
{
|
||||
char ch = 0;
|
||||
int i = 0;
|
||||
int n;
|
||||
|
||||
if (!echo)
|
||||
cli_echo_disable();
|
||||
|
||||
while (ch != '\n') {
|
||||
n = read(cli_input, &ch, 1);
|
||||
if (n == -1 && (errno == EAGAIN || errno == EINTR))
|
||||
continue;
|
||||
if (n != 1)
|
||||
break;
|
||||
if (ch == '\n' || intr != 0)
|
||||
break;
|
||||
if (i < size)
|
||||
buf[i++] = ch;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
|
||||
if (!echo)
|
||||
cli_echo_restore();
|
||||
if (!intr && !echo)
|
||||
(void) write(cli_output, "\n", 1);
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
cli_write(char* buf, int size)
|
||||
{
|
||||
int i, len, pos, ret = 0;
|
||||
char *output, *p;
|
||||
|
||||
output = xmalloc(4*size);
|
||||
for (p = output, i = 0; i < size; i++) {
|
||||
if (buf[i] == '\n' || buf[i] == '\r')
|
||||
*p++ = buf[i];
|
||||
else
|
||||
p = vis(p, buf[i], 0, 0);
|
||||
}
|
||||
len = p - output;
|
||||
|
||||
for (pos = 0; pos < len; pos += ret) {
|
||||
ret = write(cli_output, output + pos, len - pos);
|
||||
if (ret == -1) {
|
||||
xfree(output);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
xfree(output);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Presents a prompt and returns the response allocated with xmalloc().
|
||||
* Uses /dev/tty or stdin/out depending on arg. Optionally disables echo
|
||||
* of response depending on arg. Tries to ensure that no other userland
|
||||
* buffer is storing the response.
|
||||
*/
|
||||
char*
|
||||
cli_read_passphrase(char* prompt, int from_stdin, int echo_enable)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
char* p;
|
||||
|
||||
if (!cli_open(from_stdin))
|
||||
fatal("Cannot read passphrase.");
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
cli_write(prompt, strlen(prompt));
|
||||
cli_read(buf, sizeof buf, echo_enable);
|
||||
|
||||
cli_close();
|
||||
|
||||
p = xstrdup(buf);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return (p);
|
||||
}
|
||||
|
||||
char*
|
||||
cli_prompt(char* prompt, int echo_enable)
|
||||
{
|
||||
return cli_read_passphrase(prompt, 0, echo_enable);
|
||||
}
|
||||
|
||||
void
|
||||
cli_mesg(char* mesg)
|
||||
{
|
||||
cli_open(0);
|
||||
cli_write(mesg, strlen(mesg));
|
||||
cli_write("\n", strlen("\n"));
|
||||
cli_close();
|
||||
return;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/* $OpenBSD: cli.h,v 1.4 2001/03/01 03:38:33 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $OpenBSD: cli.h,v 1.4 2001/03/01 03:38:33 deraadt Exp $ */
|
||||
|
||||
#ifndef CLI_H
|
||||
#define CLI_H
|
||||
|
||||
/*
|
||||
* Presents a prompt and returns the response allocated with xmalloc().
|
||||
* Uses /dev/tty or stdin/out depending on arg. Optionally disables echo
|
||||
* of response depending on arg. Tries to ensure that no other userland
|
||||
* buffer is storing the response.
|
||||
*/
|
||||
char * cli_read_passphrase(char * prompt, int from_stdin, int echo_enable);
|
||||
char * cli_prompt(char * prompt, int echo_enable);
|
||||
void cli_mesg(char * mesg);
|
||||
|
||||
#endif /* CLI_H */
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: compat.c,v 1.63 2002/04/10 08:21:47 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "buffer.h"
|
||||
#include "packet.h"
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: compat.h,v 1.32 2002/04/10 08:21:47 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -37,7 +37,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: hostfile.c,v 1.29 2001/12/18 10:04:21 jakob Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "packet.h"
|
||||
#include "match.h"
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: includes.h,v 1.17 2002/01/26 16:44:22 stevesk Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -17,51 +16,145 @@
|
||||
#ifndef INCLUDES_H
|
||||
#define INCLUDES_H
|
||||
|
||||
#define RCSID(msg) __RCSID(msg)
|
||||
#define RCSID(msg) \
|
||||
static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/resource.h>
|
||||
#include <machine/endian.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fcntl.h> /* For O_NONBLOCK */
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <paths.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "version.h"
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h> /* For PATH_MAX */
|
||||
#endif
|
||||
#ifdef HAVE_GETOPT_H
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
#ifdef HAVE_BSTRING_H
|
||||
# include <bstring.h>
|
||||
#endif
|
||||
#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \
|
||||
defined(GLOB_HAS_GL_MATCHC)
|
||||
# include <glob.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETGROUP_H
|
||||
# include <netgroup.h>
|
||||
#endif
|
||||
#if defined(HAVE_NETDB_H)
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_TTYENT_H
|
||||
# include <ttyent.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTIME_H
|
||||
# include <utime.h>
|
||||
#endif
|
||||
#ifdef HAVE_MAILLOCK_H
|
||||
# include <maillock.h> /* For _PATH_MAILDIR */
|
||||
#endif
|
||||
#ifdef HAVE_NEXT
|
||||
# include <libc.h>
|
||||
#endif
|
||||
#include <unistd.h> /* For STDIN_FILENO, etc */
|
||||
#include <termios.h> /* Struct winsize */
|
||||
|
||||
/*
|
||||
* Define this to use pipes instead of socketpairs for communicating with the
|
||||
* client program. Socketpairs do not seem to work on all systems.
|
||||
* Although pipes are bi-directional in FreeBSD, using pipes here will
|
||||
* make <stdin> uni-directional !
|
||||
*-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively
|
||||
*/
|
||||
/* #define USE_PIPES 1 */
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#ifdef HAVE_LOGIN_H
|
||||
# include <login.h>
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDES_H */
|
||||
#ifdef HAVE_UTMP_H
|
||||
# include <utmp.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTMPX_H
|
||||
# ifdef HAVE_TV_IN_UTMPX
|
||||
# include <sys/time.h>
|
||||
# endif
|
||||
# include <utmpx.h>
|
||||
#endif
|
||||
#ifdef HAVE_LASTLOG_H
|
||||
# include <lastlog.h>
|
||||
#endif
|
||||
#ifdef HAVE_PATHS_H
|
||||
# include <paths.h> /* For _PATH_XXX */
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h> /* For timersub */
|
||||
#endif
|
||||
#include <sys/resource.h>
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_BSDTTY_H
|
||||
# include <sys/bsdtty.h>
|
||||
#endif
|
||||
#include <sys/param.h> /* For MAXPATHLEN and roundup() */
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
# include <sys/un.h> /* For sockaddr_un */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_BITYPES_H
|
||||
# include <sys/bitypes.h> /* For u_intXX_t */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
# include <sys/cdefs.h> /* For __P() */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h> /* For S_* constants and macros */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SYSMACROS_H
|
||||
# include <sys/sysmacros.h> /* For MIN, MAX, etc */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h> /* for MAP_ANONYMOUS */
|
||||
#endif
|
||||
|
||||
#include <netinet/in_systm.h> /* For typedefs */
|
||||
#include <netinet/in.h> /* For IPv6 macros */
|
||||
#include <netinet/ip.h> /* For IPTOS macros */
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifdef HAVE_RPC_TYPES_H
|
||||
# include <rpc/types.h> /* For INADDR_LOOPBACK */
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
# include <security/pam_appl.h>
|
||||
#endif
|
||||
#ifdef HAVE_READPASSPHRASE_H
|
||||
# include <readpassphrase.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/opensslv.h> /* For OPENSSL_VERSION_NUMBER */
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#include "version.h"
|
||||
#include "openbsd-compat/openbsd-compat.h"
|
||||
#include "openbsd-compat/bsd-cygwin_util.h"
|
||||
#include "openbsd-compat/bsd-nextstep.h"
|
||||
|
||||
#include "entropy.h"
|
||||
|
||||
#endif /* INCLUDES_H */
|
||||
|
@ -33,7 +33,6 @@
|
||||
*/
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: key.c,v 1.44 2002/05/31 13:16:48 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.36 2002/06/11 15:23:29 hin Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
LIB= ssh
|
||||
SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \
|
||||
cipher.c compat.c compress.c crc32.c deattack.c fatal.c \
|
||||
hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \
|
||||
rsa.c tildexpand.c ttymodes.c xmalloc.c atomicio.c \
|
||||
key.c dispatch.c kex.c mac.c uuencode.c misc.c \
|
||||
rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c kexgex.c \
|
||||
scard.c monitor_wrap.c monitor_fdpass.c msg.c
|
||||
|
||||
DEBUGLIBS= no
|
||||
NOPROFILE= yes
|
||||
NOPIC= yes
|
||||
|
||||
install:
|
||||
@echo -n
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.if (${KERBEROS5:L} == "yes")
|
||||
CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
|
||||
.endif # KERBEROS5
|
||||
|
||||
.if (${KERBEROS:L} == "yes")
|
||||
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
|
||||
.if (${AFS:L} == "yes")
|
||||
CFLAGS+= -DAFS
|
||||
SRCS+= radix.c
|
||||
.endif # AFS
|
||||
.endif # KERBEROS
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -26,12 +26,11 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: monitor.c,v 1.16 2002/06/21 05:50:51 djm Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#ifdef SKEY
|
||||
#include <opie.h>
|
||||
#include <skey.h>
|
||||
#endif
|
||||
|
||||
#include "ssh.h"
|
||||
@ -117,6 +116,10 @@ int mm_answer_rsa_response(int, Buffer *);
|
||||
int mm_answer_sesskey(int, Buffer *);
|
||||
int mm_answer_sessid(int, Buffer *);
|
||||
|
||||
#ifdef USE_PAM
|
||||
int mm_answer_pam_start(int, Buffer *);
|
||||
#endif
|
||||
|
||||
static Authctxt *authctxt;
|
||||
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
|
||||
|
||||
@ -151,6 +154,9 @@ struct mon_table mon_dispatch_proto20[] = {
|
||||
{MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
|
||||
{MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
|
||||
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
|
||||
#ifdef USE_PAM
|
||||
{MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
|
||||
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
|
||||
@ -182,6 +188,9 @@ struct mon_table mon_dispatch_proto15[] = {
|
||||
{MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
|
||||
{MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge},
|
||||
{MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response},
|
||||
#ifdef USE_PAM
|
||||
{MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
|
||||
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
|
||||
@ -189,6 +198,9 @@ struct mon_table mon_dispatch_proto15[] = {
|
||||
#ifdef SKEY
|
||||
{MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
|
||||
{MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
{MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@ -263,6 +275,10 @@ monitor_child_preauth(struct monitor *pmonitor)
|
||||
if (authctxt->pw->pw_uid == 0 &&
|
||||
!auth_root_allowed(auth_method))
|
||||
authenticated = 0;
|
||||
#ifdef USE_PAM
|
||||
if (!do_pam_account(authctxt->pw->pw_name, NULL))
|
||||
authenticated = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ent->flags & MON_AUTHDECIDE) {
|
||||
@ -510,7 +526,9 @@ mm_answer_pwnamallow(int socket, Buffer *m)
|
||||
buffer_put_cstring(m, pwent->pw_name);
|
||||
buffer_put_cstring(m, "*");
|
||||
buffer_put_cstring(m, pwent->pw_gecos);
|
||||
#ifdef HAVE_PW_CLASS_IN_PASSWD
|
||||
buffer_put_cstring(m, pwent->pw_class);
|
||||
#endif
|
||||
buffer_put_cstring(m, pwent->pw_dir);
|
||||
buffer_put_cstring(m, pwent->pw_shell);
|
||||
|
||||
@ -527,6 +545,9 @@ mm_answer_pwnamallow(int socket, Buffer *m)
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
|
||||
}
|
||||
|
||||
#ifdef USE_PAM
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -657,11 +678,11 @@ mm_answer_bsdauthrespond(int socket, Buffer *m)
|
||||
int
|
||||
mm_answer_skeyquery(int socket, Buffer *m)
|
||||
{
|
||||
struct opie opie;
|
||||
struct skey skey;
|
||||
char challenge[1024];
|
||||
int res;
|
||||
|
||||
res = opiechallenge(&opie, authctxt->user, challenge);
|
||||
res = skeychallenge(&skey, authctxt->user, challenge);
|
||||
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, res);
|
||||
@ -684,8 +705,8 @@ mm_answer_skeyrespond(int socket, Buffer *m)
|
||||
|
||||
authok = (options.challenge_response_authentication &&
|
||||
authctxt->valid &&
|
||||
opie_haskey(authctxt->pw->pw_name) == 0 &&
|
||||
opie_passverify(authctxt->pw->pw_name, response) != -1);
|
||||
skey_haskey(authctxt->pw->pw_name) == 0 &&
|
||||
skey_passcheck(authctxt->pw->pw_name, response) != -1);
|
||||
|
||||
xfree(response);
|
||||
|
||||
@ -701,6 +722,22 @@ mm_answer_skeyrespond(int socket, Buffer *m)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_PAM
|
||||
int
|
||||
mm_answer_pam_start(int socket, Buffer *m)
|
||||
{
|
||||
char *user;
|
||||
|
||||
user = buffer_get_string(m, NULL);
|
||||
|
||||
start_pam(user);
|
||||
|
||||
xfree(user);
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
mm_append_debug(Buffer *m)
|
||||
{
|
||||
@ -1454,8 +1491,13 @@ mm_init_compression(struct mm_master *mm)
|
||||
static void
|
||||
monitor_socketpair(int *pair)
|
||||
{
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
|
||||
fatal("%s: socketpair", __func__);
|
||||
#else
|
||||
fatal("%s: UsePrivilegeSeparation=yes not supported",
|
||||
__func__);
|
||||
#endif
|
||||
FD_CLOSEONEXEC(pair[0]);
|
||||
FD_CLOSEONEXEC(pair[1]);
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: mpaux.c,v 1.16 2001/02/08 19:30:52 itojun Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include "getput.h"
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: myproposal.h,v 1.14 2002/04/03 09:26:11 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -25,7 +24,7 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1"
|
||||
#define KEX_DEFAULT_PK_ALG "ssh-dss,ssh-rsa"
|
||||
#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss"
|
||||
#define KEX_DEFAULT_ENCRYPT \
|
||||
"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \
|
||||
"aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se"
|
||||
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* RCSID("$OpenBSD: nchan.h,v 1.10 2001/02/28 08:54:55 markus Exp $"); */
|
||||
|
||||
#ifndef NCHAN_H
|
||||
#define NCHAN_H
|
||||
|
||||
/*
|
||||
* SSH Protocol 1.5 aka New Channel Protocol
|
||||
* Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
|
||||
* Written by Markus Friedl in October 1999
|
||||
*
|
||||
* Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
|
||||
* tear down of channels:
|
||||
*
|
||||
* 1.3: strict request-ack-protocol:
|
||||
* CLOSE ->
|
||||
* <- CLOSE_CONFIRM
|
||||
*
|
||||
* 1.5: uses variations of:
|
||||
* IEOF ->
|
||||
* <- OCLOSE
|
||||
* <- IEOF
|
||||
* OCLOSE ->
|
||||
* i.e. both sides have to close the channel
|
||||
*
|
||||
* See the debugging output from 'ssh -v' and 'sshd -d' of
|
||||
* ssh-1.2.27 as an example.
|
||||
*
|
||||
*/
|
||||
|
||||
/* ssh-proto-1.5 overloads prot-1.3-message-types */
|
||||
#define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE
|
||||
#define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION
|
||||
|
||||
/* possible input states */
|
||||
#define CHAN_INPUT_OPEN 0x01
|
||||
#define CHAN_INPUT_WAIT_DRAIN 0x02
|
||||
#define CHAN_INPUT_WAIT_OCLOSE 0x04
|
||||
#define CHAN_INPUT_CLOSED 0x08
|
||||
|
||||
/* possible output states */
|
||||
#define CHAN_OUTPUT_OPEN 0x10
|
||||
#define CHAN_OUTPUT_WAIT_DRAIN 0x20
|
||||
#define CHAN_OUTPUT_WAIT_IEOF 0x40
|
||||
#define CHAN_OUTPUT_CLOSED 0x80
|
||||
|
||||
#define CHAN_CLOSE_SENT 0x01
|
||||
#define CHAN_CLOSE_RCVD 0x02
|
||||
|
||||
|
||||
/* Channel EVENTS */
|
||||
typedef void chan_event_fn(Channel * c);
|
||||
|
||||
/* for the input state */
|
||||
extern chan_event_fn *chan_rcvd_oclose;
|
||||
extern chan_event_fn *chan_read_failed;
|
||||
extern chan_event_fn *chan_ibuf_empty;
|
||||
|
||||
/* for the output state */
|
||||
extern chan_event_fn *chan_rcvd_ieof;
|
||||
extern chan_event_fn *chan_write_failed;
|
||||
extern chan_event_fn *chan_obuf_empty;
|
||||
|
||||
int chan_is_dead(Channel * c);
|
||||
|
||||
void chan_init_iostates(Channel * c);
|
||||
void chan_init(void);
|
||||
#endif
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: packet.h,v 1.35 2002/06/19 18:01:00 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: pathnames.h,v 1.13 2002/05/23 19:24:30 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -14,8 +13,14 @@
|
||||
*/
|
||||
|
||||
#define ETCDIR "/etc"
|
||||
|
||||
#ifndef SSHDIR
|
||||
#define SSHDIR ETCDIR "/ssh"
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_SSH_PIDDIR
|
||||
#define _PATH_SSH_PIDDIR "/var/run"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* System-wide file containing host keys of known hosts. This file should be
|
||||
@ -38,7 +43,9 @@
|
||||
/* Backwards compatibility */
|
||||
#define _PATH_DH_PRIMES SSHDIR "/primes"
|
||||
|
||||
#ifndef _PATH_SSH_PROGRAM
|
||||
#define _PATH_SSH_PROGRAM "/usr/bin/ssh"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The process id of the daemon listening for connections is saved here to
|
||||
@ -109,20 +116,54 @@
|
||||
/*
|
||||
* Default location of askpass
|
||||
*/
|
||||
#ifndef _PATH_SSH_ASKPASS_DEFAULT
|
||||
#define _PATH_SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass"
|
||||
#endif
|
||||
|
||||
/* Location of ssh-keysign for hostbased authentication */
|
||||
#define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign"
|
||||
#ifndef _PATH_SSH_KEY_SIGN
|
||||
#define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign"
|
||||
#endif
|
||||
|
||||
/* xauth for X11 forwarding */
|
||||
#ifndef _PATH_XAUTH
|
||||
#define _PATH_XAUTH "/usr/X11R6/bin/xauth"
|
||||
#endif
|
||||
|
||||
/* UNIX domain socket for X11 server; displaynum will replace %u */
|
||||
#ifndef _PATH_UNIX_X
|
||||
#define _PATH_UNIX_X "/tmp/.X11-unix/X%u"
|
||||
#endif
|
||||
|
||||
/* for scp */
|
||||
#ifndef _PATH_CP
|
||||
#define _PATH_CP "cp"
|
||||
#endif
|
||||
|
||||
/* for sftp */
|
||||
#ifndef _PATH_SFTP_SERVER
|
||||
#define _PATH_SFTP_SERVER "/usr/libexec/sftp-server"
|
||||
#define _PATH_LS "ls"
|
||||
#endif
|
||||
|
||||
/* chroot directory for unprivileged user when UsePrivilegeSeparation=yes */
|
||||
#ifndef _PATH_PRIVSEP_CHROOT_DIR
|
||||
#define _PATH_PRIVSEP_CHROOT_DIR "/var/empty"
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_LS
|
||||
#define _PATH_LS "ls"
|
||||
#endif
|
||||
|
||||
/* path to login program */
|
||||
#ifndef LOGIN_PROGRAM
|
||||
# ifdef LOGIN_PROGRAM_FALLBACK
|
||||
# define LOGIN_PROGRAM LOGIN_PROGRAM_FALLBACK
|
||||
# else
|
||||
# define LOGIN_PROGRAM "/usr/bin/login"
|
||||
# endif
|
||||
#endif /* LOGIN_PROGRAM */
|
||||
|
||||
/* Askpass program define */
|
||||
#ifndef ASKPASS_PROGRAM
|
||||
#define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass"
|
||||
#endif /* ASKPASS_PROGRAM */
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: readconf.c,v 1.100 2002/06/19 00:27:55 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
@ -115,7 +114,6 @@ typedef enum {
|
||||
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
|
||||
oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
|
||||
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
|
||||
oVersionAddendum,
|
||||
oDeprecated
|
||||
} OpCodes;
|
||||
|
||||
@ -188,7 +186,6 @@ static struct {
|
||||
{ "smartcarddevice", oSmartcardDevice },
|
||||
{ "clearallforwardings", oClearAllForwardings },
|
||||
{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
|
||||
{ "versionaddendum", oVersionAddendum },
|
||||
{ NULL, oBadOption }
|
||||
};
|
||||
|
||||
@ -202,9 +199,11 @@ add_local_forward(Options *options, u_short port, const char *host,
|
||||
u_short host_port)
|
||||
{
|
||||
Forward *fwd;
|
||||
#ifndef HAVE_CYGWIN
|
||||
extern uid_t original_real_uid;
|
||||
if (port < IPPORT_RESERVED && original_real_uid != 0)
|
||||
fatal("Privileged ports can only be forwarded by root.");
|
||||
#endif
|
||||
if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
|
||||
fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
|
||||
fwd = &options->local_forwards[options->num_local_forwards++];
|
||||
@ -670,13 +669,6 @@ process_config_line(Options *options, const char *host,
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
case oVersionAddendum:
|
||||
ssh_version_set_addendum(strtok(s, "\n"));
|
||||
do {
|
||||
arg = strdelim(&s);
|
||||
} while (arg != NULL && *arg != '\0');
|
||||
break;
|
||||
|
||||
case oDeprecated:
|
||||
debug("%s line %d: Deprecated option \"%s\"",
|
||||
filename, linenum, keyword);
|
||||
@ -854,7 +846,7 @@ fill_default_options(Options * options)
|
||||
if (options->batch_mode == -1)
|
||||
options->batch_mode = 0;
|
||||
if (options->check_host_ip == -1)
|
||||
options->check_host_ip = 0;
|
||||
options->check_host_ip = 1;
|
||||
if (options->strict_host_key_checking == -1)
|
||||
options->strict_host_key_checking = 2; /* 2 is default */
|
||||
if (options->compression == -1)
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: readconf.h,v 1.43 2002/06/08 05:17:01 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: rijndael.c,v 1.13 2001/12/19 07:18:56 deraadt Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/**
|
||||
* rijndael-alg-fst.c
|
||||
@ -26,7 +25,8 @@
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include "includes.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -61,7 +61,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: rsa.c,v 1.24 2001/12/27 18:22:16 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "rsa.h"
|
||||
#include "log.h"
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: rsa.h,v 1.15 2002/03/04 17:27:39 stevesk Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -1,20 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.2 2001/06/29 07:02:09 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
CARDLET= Ssh.bin
|
||||
DATADIR= /usr/libdata/ssh
|
||||
|
||||
all: ${CARDLET}
|
||||
|
||||
clean:
|
||||
rm -f ${CARDLET}
|
||||
|
||||
install: ${CARDLET}
|
||||
install -c -m ${LIBMODE} -o ${LIBOWN} -g ${LIBGRP} \
|
||||
${CARDLET} ${DESTDIR}${DATADIR}
|
||||
|
||||
Ssh.bin: ${.CURDIR}/Ssh.bin.uu
|
||||
uudecode ${.CURDIR}/$@.uu
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Theo de Raadt. All rights reserved.
|
||||
* Copyright (c) 1999 Aaron Campbell. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Parts from:
|
||||
*
|
||||
* Copyright (c) 1983, 1990, 1992, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: scp-common.c,v 1.1 2001/04/16 02:31:43 mouring Exp $");
|
||||
|
||||
char *
|
||||
cleanhostname(host)
|
||||
char *host;
|
||||
{
|
||||
if (*host == '[' && host[strlen(host) - 1] == ']') {
|
||||
host[strlen(host) - 1] = '\0';
|
||||
return (host + 1);
|
||||
} else
|
||||
return host;
|
||||
}
|
||||
|
||||
char *
|
||||
colon(cp)
|
||||
char *cp;
|
||||
{
|
||||
int flag = 0;
|
||||
|
||||
if (*cp == ':') /* Leading colon is part of file name. */
|
||||
return (0);
|
||||
if (*cp == '[')
|
||||
flag = 1;
|
||||
|
||||
for (; *cp; ++cp) {
|
||||
if (*cp == '@' && *(cp+1) == '[')
|
||||
flag = 1;
|
||||
if (*cp == ']' && *(cp+1) == ':' && flag)
|
||||
return (cp+1);
|
||||
if (*cp == ':' && !flag)
|
||||
return (cp);
|
||||
if (*cp == '/')
|
||||
return (0);
|
||||
}
|
||||
return (0);
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/* $OpenBSD: scp-common.h,v 1.1 2001/04/16 02:31:43 mouring Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1999 Theo de Raadt. All rights reserved.
|
||||
* Copyright (c) 1999 Aaron Campbell. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Parts from:
|
||||
*
|
||||
* Copyright (c) 1983, 1990, 1992, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
char *cleanhostname(char *host);
|
||||
char *colon(char *cp);
|
@ -1,15 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.13 2001/05/03 23:09:55 mouring Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= scp
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= scp.1
|
||||
|
||||
SRCS= scp.c misc.c
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -11,13 +11,18 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: servconf.c,v 1.111 2002/06/20 23:05:55 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#if defined(KRB4)
|
||||
#include <krb.h>
|
||||
#endif
|
||||
#if defined(KRB5)
|
||||
#include <krb5.h>
|
||||
#ifdef HEIMDAL
|
||||
#include <krb.h>
|
||||
#else
|
||||
/* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
|
||||
* keytab */
|
||||
#define KEYFILE "/etc/krb5.keytab"
|
||||
#endif
|
||||
#endif
|
||||
#ifdef AFS
|
||||
#include <kafs.h>
|
||||
@ -49,6 +54,11 @@ void
|
||||
initialize_server_options(ServerOptions *options)
|
||||
{
|
||||
memset(options, 0, sizeof(*options));
|
||||
|
||||
/* Portable-specific options */
|
||||
options->pam_authentication_via_kbd_int = -1;
|
||||
|
||||
/* Standard Options */
|
||||
options->num_ports = 0;
|
||||
options->ports_from_cmdline = 0;
|
||||
options->listen_addrs = NULL;
|
||||
@ -102,7 +112,6 @@ initialize_server_options(ServerOptions *options)
|
||||
options->macs = NULL;
|
||||
options->protocol = SSH_PROTO_UNKNOWN;
|
||||
options->gateway_ports = -1;
|
||||
options->connections_period = 0;
|
||||
options->num_subsystems = 0;
|
||||
options->max_startups_begin = -1;
|
||||
options->max_startups_rate = -1;
|
||||
@ -113,7 +122,6 @@ initialize_server_options(ServerOptions *options)
|
||||
options->client_alive_count_max = -1;
|
||||
options->authorized_keys_file = NULL;
|
||||
options->authorized_keys_file2 = NULL;
|
||||
options->check_mail = -1;
|
||||
|
||||
/* Needs to be accessable in many places */
|
||||
use_privsep = -1;
|
||||
@ -122,6 +130,11 @@ initialize_server_options(ServerOptions *options)
|
||||
void
|
||||
fill_default_server_options(ServerOptions *options)
|
||||
{
|
||||
/* Portable-specific options */
|
||||
if (options->pam_authentication_via_kbd_int == -1)
|
||||
options->pam_authentication_via_kbd_int = 0;
|
||||
|
||||
/* Standard Options */
|
||||
if (options->protocol == SSH_PROTO_UNKNOWN)
|
||||
options->protocol = SSH_PROTO_1|SSH_PROTO_2;
|
||||
if (options->num_host_key_files == 0) {
|
||||
@ -130,6 +143,8 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->host_key_files[options->num_host_key_files++] =
|
||||
_PATH_HOST_KEY_FILE;
|
||||
if (options->protocol & SSH_PROTO_2) {
|
||||
options->host_key_files[options->num_host_key_files++] =
|
||||
_PATH_HOST_RSA_KEY_FILE;
|
||||
options->host_key_files[options->num_host_key_files++] =
|
||||
_PATH_HOST_DSA_KEY_FILE;
|
||||
}
|
||||
@ -143,23 +158,21 @@ fill_default_server_options(ServerOptions *options)
|
||||
if (options->server_key_bits == -1)
|
||||
options->server_key_bits = 768;
|
||||
if (options->login_grace_time == -1)
|
||||
options->login_grace_time = 120;
|
||||
options->login_grace_time = 600;
|
||||
if (options->key_regeneration_time == -1)
|
||||
options->key_regeneration_time = 3600;
|
||||
if (options->permit_root_login == PERMIT_NOT_SET)
|
||||
options->permit_root_login = PERMIT_NO;
|
||||
options->permit_root_login = PERMIT_YES;
|
||||
if (options->ignore_rhosts == -1)
|
||||
options->ignore_rhosts = 1;
|
||||
if (options->ignore_user_known_hosts == -1)
|
||||
options->ignore_user_known_hosts = 0;
|
||||
if (options->check_mail == -1)
|
||||
options->check_mail = 1;
|
||||
if (options->print_motd == -1)
|
||||
options->print_motd = 1;
|
||||
if (options->print_lastlog == -1)
|
||||
options->print_lastlog = 1;
|
||||
if (options->x11_forwarding == -1)
|
||||
options->x11_forwarding = 1;
|
||||
options->x11_forwarding = 0;
|
||||
if (options->x11_display_offset == -1)
|
||||
options->x11_display_offset = 10;
|
||||
if (options->x11_use_localhost == -1)
|
||||
@ -186,20 +199,9 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->rsa_authentication = 1;
|
||||
if (options->pubkey_authentication == -1)
|
||||
options->pubkey_authentication = 1;
|
||||
#if defined(KRB4) && defined(KRB5)
|
||||
if (options->kerberos_authentication == -1)
|
||||
options->kerberos_authentication =
|
||||
(access(KEYFILE, R_OK) == 0 ||
|
||||
(access(krb5_defkeyname, R_OK) == 0));
|
||||
#elif defined(KRB4)
|
||||
if (options->kerberos_authentication == -1)
|
||||
options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
|
||||
#elif defined(KRB5)
|
||||
if (options->kerberos_authentication == -1)
|
||||
options->kerberos_authentication =
|
||||
(access(krb5_defkeyname, R_OK) == 0);
|
||||
#endif
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
if (options->kerberos_authentication == -1)
|
||||
options->kerberos_authentication = 0;
|
||||
if (options->kerberos_or_local_passwd == -1)
|
||||
options->kerberos_or_local_passwd = 1;
|
||||
if (options->kerberos_ticket_cleanup == -1)
|
||||
@ -251,14 +253,27 @@ fill_default_server_options(ServerOptions *options)
|
||||
if (options->authorized_keys_file == NULL)
|
||||
options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
|
||||
|
||||
/* Turn privilege separation off by default */
|
||||
/* Turn privilege separation on by default */
|
||||
if (use_privsep == -1)
|
||||
use_privsep = 0;
|
||||
use_privsep = 1;
|
||||
|
||||
#if !defined(HAVE_MMAP) || !defined(MAP_ANON)
|
||||
if (use_privsep && options->compression == 1) {
|
||||
error("This platform does not support both privilege "
|
||||
"separation and compression");
|
||||
error("Compression disabled");
|
||||
options->compression = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Keyword tokens. */
|
||||
typedef enum {
|
||||
sBadOption, /* == unknown option */
|
||||
/* Portable-specific options */
|
||||
sPAMAuthenticationViaKbdInt,
|
||||
/* Standard Options */
|
||||
sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
|
||||
sPermitRootLogin, sLogFacility, sLogLevel,
|
||||
sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
|
||||
@ -284,7 +299,6 @@ typedef enum {
|
||||
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
|
||||
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
|
||||
sUsePrivilegeSeparation,
|
||||
sCheckMail, sVersionAddendum,
|
||||
sDeprecated
|
||||
} ServerOpCodes;
|
||||
|
||||
@ -293,6 +307,9 @@ static struct {
|
||||
const char *name;
|
||||
ServerOpCodes opcode;
|
||||
} keywords[] = {
|
||||
/* Portable-specific options */
|
||||
{ "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
|
||||
/* Standard Options */
|
||||
{ "port", sPort },
|
||||
{ "hostkey", sHostKeyFile },
|
||||
{ "hostdsakey", sHostKeyFile }, /* alias */
|
||||
@ -325,6 +342,7 @@ static struct {
|
||||
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
|
||||
{ "challengeresponseauthentication", sChallengeResponseAuthentication },
|
||||
{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
|
||||
{ "checkmail", sDeprecated },
|
||||
{ "listenaddress", sListenAddress },
|
||||
{ "printmotd", sPrintMotd },
|
||||
{ "printlastlog", sPrintLastLog },
|
||||
@ -358,8 +376,6 @@ static struct {
|
||||
{ "authorizedkeysfile", sAuthorizedKeysFile },
|
||||
{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
|
||||
{ "useprivilegeseparation", sUsePrivilegeSeparation},
|
||||
{ "checkmail", sCheckMail },
|
||||
{ "versionaddendum", sVersionAddendum },
|
||||
{ NULL, sBadOption }
|
||||
};
|
||||
|
||||
@ -438,6 +454,12 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
charptr = NULL;
|
||||
opcode = parse_token(arg, filename, linenum);
|
||||
switch (opcode) {
|
||||
/* Portable-specific options */
|
||||
case sPAMAuthenticationViaKbdInt:
|
||||
intptr = &options->pam_authentication_via_kbd_int;
|
||||
goto parse_flag;
|
||||
|
||||
/* Standard Options */
|
||||
case sBadOption:
|
||||
return -1;
|
||||
case sPort:
|
||||
@ -884,17 +906,6 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
arg = strdelim(&cp);
|
||||
break;
|
||||
|
||||
case sCheckMail:
|
||||
intptr = &options->check_mail;
|
||||
goto parse_flag;
|
||||
|
||||
case sVersionAddendum:
|
||||
ssh_version_set_addendum(strtok(cp, "\n"));
|
||||
do {
|
||||
arg = strdelim(&cp);
|
||||
} while (arg != NULL && *arg != '\0');
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("%s line %d: Missing handler for opcode %s (%d)",
|
||||
filename, linenum, arg, opcode);
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: servconf.h,v 1.58 2002/06/20 23:05:55 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -53,7 +52,6 @@ typedef struct {
|
||||
* for RhostsRsaAuth */
|
||||
int print_motd; /* If true, print /etc/motd. */
|
||||
int print_lastlog; /* If true, print lastlog */
|
||||
int check_mail; /* If true, check for new mail */
|
||||
int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */
|
||||
int x11_display_offset; /* What DISPLAY number to start
|
||||
* searching at */
|
||||
@ -110,7 +108,6 @@ typedef struct {
|
||||
char *allow_groups[MAX_ALLOW_GROUPS];
|
||||
u_int num_deny_groups;
|
||||
char *deny_groups[MAX_DENY_GROUPS];
|
||||
unsigned int connections_period;
|
||||
|
||||
u_int num_subsystems;
|
||||
char *subsystem_name[MAX_SUBSYSTEMS];
|
||||
@ -133,6 +130,7 @@ typedef struct {
|
||||
|
||||
char *authorized_keys_file; /* File containing public keys */
|
||||
char *authorized_keys_file2;
|
||||
int pam_authentication_via_kbd_int;
|
||||
} ServerOptions;
|
||||
|
||||
void initialize_server_options(ServerOptions *);
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: serverloop.c,v 1.102 2002/06/11 05:46:20 mpech Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
@ -144,7 +143,7 @@ sigchld_handler(int sig)
|
||||
int save_errno = errno;
|
||||
debug("Received SIGCHLD.");
|
||||
child_terminated = 1;
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
mysignal(SIGCHLD, sigchld_handler);
|
||||
notify_parent();
|
||||
errno = save_errno;
|
||||
}
|
||||
@ -497,7 +496,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
||||
|
||||
/* Initialize the SIGCHLD kludge. */
|
||||
child_terminated = 0;
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
mysignal(SIGCHLD, sigchld_handler);
|
||||
|
||||
/* Initialize our global variables. */
|
||||
fdin = fdin_arg;
|
||||
@ -669,7 +668,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
||||
channel_free_all();
|
||||
|
||||
/* We no longer want our SIGCHLD handler to be called. */
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
mysignal(SIGCHLD, SIG_DFL);
|
||||
|
||||
while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0)
|
||||
if (errno != EINTR)
|
||||
@ -741,7 +740,7 @@ server_loop2(Authctxt *authctxt)
|
||||
|
||||
debug("Entering interactive session for SSH2.");
|
||||
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
mysignal(SIGCHLD, sigchld_handler);
|
||||
child_terminated = 0;
|
||||
connection_in = packet_get_connection_in();
|
||||
connection_out = packet_get_connection_out();
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: session.c,v 1.138 2002/06/20 23:05:55 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
@ -59,15 +58,10 @@ RCSID("$FreeBSD$");
|
||||
#include "session.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define _PATH_CHPASS "/usr/bin/passwd"
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#if defined(HAVE_LOGIN_CAP) || defined(USE_PAM)
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
#include <login_cap.h>
|
||||
#ifdef HAVE_CYGWIN
|
||||
#include <windows.h>
|
||||
#include <sys/cygwin.h>
|
||||
#define is_winnt (GetVersion() < 0x80000000)
|
||||
#endif
|
||||
|
||||
/* func */
|
||||
@ -81,6 +75,9 @@ void do_exec_pty(Session *, const char *);
|
||||
void do_exec_no_pty(Session *, const char *);
|
||||
void do_exec(Session *, const char *);
|
||||
void do_login(Session *, const char *);
|
||||
#ifdef LOGIN_NEEDS_UTMPX
|
||||
static void do_pre_login(Session *s);
|
||||
#endif
|
||||
void do_child(Session *, const char *);
|
||||
void do_motd(void);
|
||||
int check_quietlogin(Session *, const char *);
|
||||
@ -106,6 +103,10 @@ const char *original_command = NULL;
|
||||
#define MAX_SESSIONS 10
|
||||
Session sessions[MAX_SESSIONS];
|
||||
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
char *aixloginmsg;
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
login_cap_t *lc;
|
||||
#endif
|
||||
@ -209,6 +210,14 @@ do_authenticated(Authctxt *authctxt)
|
||||
close(startup_pipe);
|
||||
startup_pipe = -1;
|
||||
}
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
/* We don't have a pty yet, so just label the line as "ssh" */
|
||||
if (loginsuccess(authctxt->user,
|
||||
get_canonical_hostname(options.verify_reverse_mapping),
|
||||
"ssh", &aixloginmsg) < 0)
|
||||
aixloginmsg = NULL;
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
|
||||
/* setup the channel layer */
|
||||
if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
|
||||
channel_permit_all_opens();
|
||||
@ -451,8 +460,12 @@ do_exec_no_pty(Session *s, const char *command)
|
||||
|
||||
session_proctitle(s);
|
||||
|
||||
#ifdef USE_PAM
|
||||
do_pam_setcred();
|
||||
#if defined(USE_PAM)
|
||||
do_pam_session(s->pw->pw_name, NULL);
|
||||
do_pam_setcred(1);
|
||||
if (is_pam_password_change_required())
|
||||
packet_disconnect("Password change required but no "
|
||||
"TTY available");
|
||||
#endif /* USE_PAM */
|
||||
|
||||
/* Fork the child. */
|
||||
@ -508,6 +521,10 @@ do_exec_no_pty(Session *s, const char *command)
|
||||
do_child(s, command);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#ifdef HAVE_CYGWIN
|
||||
if (is_winnt)
|
||||
cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
|
||||
#endif
|
||||
if (pid < 0)
|
||||
packet_disconnect("fork failed: %.100s", strerror(errno));
|
||||
s->pid = pid;
|
||||
@ -561,10 +578,10 @@ do_exec_pty(Session *s, const char *command)
|
||||
ptyfd = s->ptyfd;
|
||||
ttyfd = s->ttyfd;
|
||||
|
||||
#ifdef USE_PAM
|
||||
do_pam_session(s->pw->pw_name, basename(s->tty));
|
||||
do_pam_setcred();
|
||||
#endif /* USE_PAM */
|
||||
#if defined(USE_PAM)
|
||||
do_pam_session(s->pw->pw_name, s->tty);
|
||||
do_pam_setcred(1);
|
||||
#endif
|
||||
|
||||
/* Fork the child. */
|
||||
if ((pid = fork()) == 0) {
|
||||
@ -589,13 +606,23 @@ do_exec_pty(Session *s, const char *command)
|
||||
close(ttyfd);
|
||||
|
||||
/* record login, etc. similar to login(1) */
|
||||
#ifndef HAVE_OSF_SIA
|
||||
if (!(options.use_login && command == NULL))
|
||||
do_login(s, command);
|
||||
# ifdef LOGIN_NEEDS_UTMPX
|
||||
else
|
||||
do_pre_login(s);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Do common processing for the child, such as execing the command. */
|
||||
do_child(s, command);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#ifdef HAVE_CYGWIN
|
||||
if (is_winnt)
|
||||
cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
|
||||
#endif
|
||||
if (pid < 0)
|
||||
packet_disconnect("fork failed: %.100s", strerror(errno));
|
||||
s->pid = pid;
|
||||
@ -628,6 +655,34 @@ do_exec_pty(Session *s, const char *command)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LOGIN_NEEDS_UTMPX
|
||||
static void
|
||||
do_pre_login(Session *s)
|
||||
{
|
||||
socklen_t fromlen;
|
||||
struct sockaddr_storage from;
|
||||
pid_t pid = getpid();
|
||||
|
||||
/*
|
||||
* Get IP address of client. If the connection is not a socket, let
|
||||
* the address be 0.0.0.0.
|
||||
*/
|
||||
memset(&from, 0, sizeof(from));
|
||||
if (packet_connection_is_on_socket()) {
|
||||
fromlen = sizeof(from);
|
||||
if (getpeername(packet_get_connection_in(),
|
||||
(struct sockaddr *) & from, &fromlen) < 0) {
|
||||
debug("getpeername: %.100s", strerror(errno));
|
||||
fatal_cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
record_utmp_only(pid, s->tty, s->pw->pw_name,
|
||||
get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
|
||||
(struct sockaddr *)&from);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is called to fork and execute a command. If another command is
|
||||
* to be forced, execute that instead.
|
||||
@ -654,24 +709,12 @@ do_exec(Session *s, const char *command)
|
||||
void
|
||||
do_login(Session *s, const char *command)
|
||||
{
|
||||
#ifndef USE_PAM
|
||||
char *time_string;
|
||||
#endif
|
||||
socklen_t fromlen;
|
||||
struct sockaddr_storage from;
|
||||
struct passwd * pw = s->pw;
|
||||
pid_t pid = getpid();
|
||||
#ifdef __FreeBSD__
|
||||
#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */
|
||||
struct timeval tv;
|
||||
time_t warntime = DEFAULT_WARN;
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#ifdef USE_PAM
|
||||
/*
|
||||
* Let PAM handle utmp / wtmp.
|
||||
*/
|
||||
#else
|
||||
/*
|
||||
* Get IP address of client. If the connection is not a socket, let
|
||||
* the address be 0.0.0.0.
|
||||
@ -685,78 +728,6 @@ do_login(Session *s, const char *command)
|
||||
fatal_cleanup();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_PAM
|
||||
/*
|
||||
* If password change is needed, do it now.
|
||||
* This needs to occur before the ~/.hushlogin check.
|
||||
*/
|
||||
if (pam_password_change_required()) {
|
||||
print_pam_messages();
|
||||
do_pam_chauthtok();
|
||||
}
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
if (pw->pw_change || pw->pw_expire)
|
||||
(void)gettimeofday(&tv, NULL);
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
warntime = login_getcaptime(lc, "warnpassword",
|
||||
DEFAULT_WARN, DEFAULT_WARN);
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
#ifndef USE_PAM
|
||||
/*
|
||||
* If the password change time is set and has passed, give the
|
||||
* user a password expiry notice and chance to change it.
|
||||
*/
|
||||
if (pw->pw_change != 0) {
|
||||
if (tv.tv_sec >= pw->pw_change) {
|
||||
(void)printf(
|
||||
"Sorry -- your password has expired.\n");
|
||||
log("%s Password expired - forcing change",
|
||||
pw->pw_name);
|
||||
if (newcommand != NULL)
|
||||
xfree(newcommand);
|
||||
newcommand = xstrdup(_PATH_CHPASS);
|
||||
} else if (pw->pw_change - tv.tv_sec < warntime &&
|
||||
!check_quietlogin(s, command))
|
||||
(void)printf(
|
||||
"Warning: your password expires on %s",
|
||||
ctime(&pw->pw_change));
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
warntime = login_getcaptime(lc, "warnexpire",
|
||||
DEFAULT_WARN, DEFAULT_WARN);
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
#ifndef USE_PAM
|
||||
if (pw->pw_expire) {
|
||||
if (tv.tv_sec >= pw->pw_expire) {
|
||||
(void)printf(
|
||||
"Sorry -- your account has expired.\n");
|
||||
log(
|
||||
"LOGIN %.200s REFUSED (EXPIRED) FROM %.200s ON TTY %.200s",
|
||||
pw->pw_name, get_remote_name_or_ip(utmp_len,
|
||||
options.verify_reverse_mapping), s->tty);
|
||||
exit(254);
|
||||
} else if (pw->pw_expire - tv.tv_sec < warntime &&
|
||||
!check_quietlogin(s, command))
|
||||
(void)printf(
|
||||
"Warning: your account expires on %s",
|
||||
ctime(&pw->pw_expire));
|
||||
}
|
||||
#endif /* !USE_PAM */
|
||||
#endif /* __FreeBSD__ */
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
if (!auth_ttyok(lc, basename(s->tty))) {
|
||||
(void)printf("Permission denied.\n");
|
||||
log(
|
||||
"LOGIN %.200s REFUSED (TTY) FROM %.200s ON TTY %.200s",
|
||||
pw->pw_name, get_remote_name_or_ip(utmp_len,
|
||||
options.verify_reverse_mapping), s->tty);
|
||||
exit(254);
|
||||
}
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
|
||||
/* Record that there was a login on that tty from the remote host. */
|
||||
if (!use_privsep)
|
||||
@ -766,23 +737,29 @@ do_login(Session *s, const char *command)
|
||||
(struct sockaddr *)&from);
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (command == NULL && options.print_lastlog &&
|
||||
!check_quietlogin(s, command) &&
|
||||
!options.use_login && !pam_password_change_required())
|
||||
print_pam_messages();
|
||||
#else /* !USE_PAM */
|
||||
/*
|
||||
* If the user has logged in before, display the time of last
|
||||
* login. However, don't display anything extra if a command
|
||||
* has been specified (so that ssh can be used to execute
|
||||
* commands on a remote machine without users knowing they
|
||||
* are going to another machine). Login(1) will do this for
|
||||
* us as well, so check if login(1) is used
|
||||
* If password change is needed, do it now.
|
||||
* This needs to occur before the ~/.hushlogin check.
|
||||
*/
|
||||
if (is_pam_password_change_required()) {
|
||||
print_pam_messages();
|
||||
do_pam_chauthtok();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (command == NULL && options.print_lastlog &&
|
||||
s->last_login_time != 0 && !check_quietlogin(s, command) &&
|
||||
!options.use_login) {
|
||||
if (check_quietlogin(s, command))
|
||||
return;
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (!is_pam_password_change_required())
|
||||
print_pam_messages();
|
||||
#endif /* USE_PAM */
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
if (aixloginmsg && *aixloginmsg)
|
||||
printf("%s\n", aixloginmsg);
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
|
||||
if (options.print_lastlog && s->last_login_time != 0) {
|
||||
time_string = ctime(&s->last_login_time);
|
||||
if (strchr(time_string, '\n'))
|
||||
*strchr(time_string, '\n') = 0;
|
||||
@ -792,35 +769,8 @@ do_login(Session *s, const char *command)
|
||||
printf("Last login: %s from %s\r\n", time_string,
|
||||
s->hostname);
|
||||
}
|
||||
#endif /* !USE_PAM */
|
||||
|
||||
if (command == NULL && !check_quietlogin(s, command) &&
|
||||
!options.use_login) {
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
const char *fname;
|
||||
char buf[256];
|
||||
FILE *f;
|
||||
|
||||
fname = login_getcapstr(lc, "copyright", NULL, NULL);
|
||||
if (fname != NULL && (f = fopen(fname, "r")) != NULL) {
|
||||
while (fgets(buf, sizeof(buf), f) != NULL)
|
||||
fputs(buf, stdout);
|
||||
fclose(f);
|
||||
} else
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
(void)printf("%s\n\t%s %s\n",
|
||||
"Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
|
||||
"The Regents of the University of California. ",
|
||||
"All rights reserved.");
|
||||
(void)printf("\n");
|
||||
/*
|
||||
* Print /etc/motd unless a command was specified or printing
|
||||
* it was disabled in server options or login(1) will be
|
||||
* used. Note that some machines appear to print it in
|
||||
* /etc/profile or similar.
|
||||
*/
|
||||
do_motd();
|
||||
}
|
||||
do_motd();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -952,76 +902,83 @@ read_environment_file(char ***env, u_int *envsize,
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
#ifdef USE_PAM
|
||||
/*
|
||||
* Sets any environment variables which have been specified by PAM
|
||||
*/
|
||||
static void
|
||||
do_pam_environment(char ***env, u_int *envsize)
|
||||
void copy_environment(char **source, char ***env, u_int *envsize)
|
||||
{
|
||||
char *equals, var_name[512], var_val[512];
|
||||
char **pam_env;
|
||||
char *var_name, *var_val;
|
||||
int i;
|
||||
|
||||
if ((pam_env = fetch_pam_environment()) == NULL)
|
||||
if (source == NULL)
|
||||
return;
|
||||
|
||||
for(i = 0; pam_env[i] != NULL; i++) {
|
||||
if ((equals = strstr(pam_env[i], "=")) == NULL)
|
||||
|
||||
for(i = 0; source[i] != NULL; i++) {
|
||||
var_name = xstrdup(source[i]);
|
||||
if ((var_val = strstr(var_name, "=")) == NULL) {
|
||||
xfree(var_name);
|
||||
continue;
|
||||
|
||||
if (strlen(pam_env[i]) < (sizeof(var_name) - 1)) {
|
||||
memset(var_name, '\0', sizeof(var_name));
|
||||
memset(var_val, '\0', sizeof(var_val));
|
||||
|
||||
strncpy(var_name, pam_env[i], equals - pam_env[i]);
|
||||
strcpy(var_val, equals + 1);
|
||||
|
||||
child_set_env(env, envsize, var_name, var_val);
|
||||
}
|
||||
*var_val++ = '\0';
|
||||
|
||||
debug3("Copy environment: %s=%s", var_name, var_val);
|
||||
child_set_env(env, envsize, var_name, var_val);
|
||||
|
||||
xfree(var_name);
|
||||
}
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
|
||||
static char **
|
||||
do_setup_env(char **env, Session *s, const char *shell)
|
||||
do_setup_env(Session *s, const char *shell)
|
||||
{
|
||||
char buf[256];
|
||||
u_int i, envsize;
|
||||
char **env;
|
||||
struct passwd *pw = s->pw;
|
||||
|
||||
if (env == NULL) {
|
||||
/* Initialize the environment. */
|
||||
envsize = 100;
|
||||
env = xmalloc(envsize * sizeof(char *));
|
||||
env[0] = NULL;
|
||||
} else {
|
||||
for (envsize = 0; env[envsize] != NULL; ++envsize)
|
||||
;
|
||||
envsize = (envsize < 100) ? 100 : envsize + 50;
|
||||
env = xrealloc(env, envsize * sizeof(char *));
|
||||
}
|
||||
/* Initialize the environment. */
|
||||
envsize = 100;
|
||||
env = xmalloc(envsize * sizeof(char *));
|
||||
env[0] = NULL;
|
||||
|
||||
#ifdef HAVE_CYGWIN
|
||||
/*
|
||||
* The Windows environment contains some setting which are
|
||||
* important for a running system. They must not be dropped.
|
||||
*/
|
||||
copy_environment(environ, &env, &envsize);
|
||||
#endif
|
||||
|
||||
if (!options.use_login) {
|
||||
/* Set basic environment. */
|
||||
child_set_env(&env, &envsize, "USER", pw->pw_name);
|
||||
child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
|
||||
child_set_env(&env, &envsize, "HOME", pw->pw_dir);
|
||||
#ifndef HAVE_LOGIN_CAP
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
(void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
|
||||
child_set_env(&env, &envsize, "PATH", getenv("PATH"));
|
||||
#else /* HAVE_LOGIN_CAP */
|
||||
# ifndef HAVE_CYGWIN
|
||||
/*
|
||||
* There's no standard path on Windows. The path contains
|
||||
* important components pointing to the system directories,
|
||||
* needed for loading shared libraries. So the path better
|
||||
* remains intact here.
|
||||
*/
|
||||
# ifdef SUPERUSER_PATH
|
||||
child_set_env(&env, &envsize, "PATH",
|
||||
s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH);
|
||||
# else
|
||||
child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
|
||||
# endif /* SUPERUSER_PATH */
|
||||
# endif /* HAVE_CYGWIN */
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
|
||||
snprintf(buf, sizeof buf, "%.200s/%.50s",
|
||||
_PATH_MAILDIR, pw->pw_name);
|
||||
child_set_env(&env, &envsize, "MAIL", buf);
|
||||
#endif /* !HAVE_LOGIN_CAP */
|
||||
|
||||
/* Normal systems set SHELL by default. */
|
||||
child_set_env(&env, &envsize, "SHELL", shell);
|
||||
}
|
||||
if (getenv("TZ"))
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
if (options.use_login)
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
child_set_env(&env, &envsize, "TZ", getenv("TZ"));
|
||||
|
||||
/* Set custom environment options from RSA authentication. */
|
||||
@ -1055,6 +1012,18 @@ do_setup_env(char **env, Session *s, const char *shell)
|
||||
if (original_command)
|
||||
child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
|
||||
original_command);
|
||||
|
||||
#ifdef _AIX
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if ((cp = getenv("AUTHSTATE")) != NULL)
|
||||
child_set_env(&env, &envsize, "AUTHSTATE", cp);
|
||||
if ((cp = getenv("KRB5CCNAME")) != NULL)
|
||||
child_set_env(&env, &envsize, "KRB5CCNAME", cp);
|
||||
read_environment_file(&env, &envsize, "/etc/environment");
|
||||
}
|
||||
#endif
|
||||
#ifdef KRB4
|
||||
if (s->authctxt->krb4_ticket_file)
|
||||
child_set_env(&env, &envsize, "KRBTKFILE",
|
||||
@ -1065,10 +1034,9 @@ do_setup_env(char **env, Session *s, const char *shell)
|
||||
child_set_env(&env, &envsize, "KRB5CCNAME",
|
||||
s->authctxt->krb5_ticket_file);
|
||||
#endif
|
||||
|
||||
#ifdef USE_PAM
|
||||
/* Pull in any environment variables that may have been set by PAM. */
|
||||
do_pam_environment(&env, &envsize);
|
||||
copy_environment(fetch_pam_environment(), &env, &envsize);
|
||||
#endif /* USE_PAM */
|
||||
|
||||
if (auth_sock_name != NULL)
|
||||
@ -1181,47 +1149,30 @@ do_nologin(struct passwd *pw)
|
||||
}
|
||||
|
||||
/* Set login name, uid, gid, and groups. */
|
||||
char **
|
||||
void
|
||||
do_setusercontext(struct passwd *pw)
|
||||
{
|
||||
char **env = NULL;
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
char buf[256];
|
||||
char **tmpenv;
|
||||
u_int envsize;
|
||||
extern char **environ;
|
||||
|
||||
/* Initialize the environment. */
|
||||
envsize = 100;
|
||||
env = xmalloc(envsize * sizeof(char *));
|
||||
env[0] = NULL;
|
||||
|
||||
child_set_env(&env, &envsize, "PATH",
|
||||
(pw->pw_uid == 0) ?
|
||||
_PATH_STDPATH : _PATH_DEFPATH);
|
||||
|
||||
snprintf(buf, sizeof buf, "%.200s/%.50s",
|
||||
_PATH_MAILDIR, pw->pw_name);
|
||||
child_set_env(&env, &envsize, "MAIL", buf);
|
||||
|
||||
if (getenv("TZ"))
|
||||
child_set_env(&env, &envsize, "TZ", getenv("TZ"));
|
||||
|
||||
/* Save parent environment */
|
||||
tmpenv = environ;
|
||||
/* Switch to env */
|
||||
environ = env;
|
||||
|
||||
if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETALL) < 0)
|
||||
fatal("setusercontext failed: %s", strerror(errno));
|
||||
|
||||
/* NOTE: Modified environment now passed to env! */
|
||||
env = environ;
|
||||
/* Restore parent environment */
|
||||
environ = tmpenv;
|
||||
|
||||
#else /* !HAVE_LOGIN_CAP */
|
||||
#ifdef HAVE_CYGWIN
|
||||
if (is_winnt) {
|
||||
#else /* HAVE_CYGWIN */
|
||||
if (getuid() == 0 || geteuid() == 0) {
|
||||
#endif /* HAVE_CYGWIN */
|
||||
#ifdef HAVE_SETPCRED
|
||||
setpcred(pw->pw_name);
|
||||
#endif /* HAVE_SETPCRED */
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
if (setusercontext(lc, pw, pw->pw_uid,
|
||||
(LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
|
||||
perror("unable to set user context");
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
# if defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
|
||||
/* Sets login uid for accounting */
|
||||
if (getluid() == -1 && setluid(pw->pw_uid) == -1)
|
||||
error("setluid: %s", strerror(errno));
|
||||
# endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */
|
||||
|
||||
if (setlogin(pw->pw_name) < 0)
|
||||
error("setlogin failed: %s", strerror(errno));
|
||||
if (setgid(pw->pw_gid) < 0) {
|
||||
@ -1234,14 +1185,23 @@ do_setusercontext(struct passwd *pw)
|
||||
exit(1);
|
||||
}
|
||||
endgrent();
|
||||
|
||||
# ifdef USE_PAM
|
||||
/*
|
||||
* PAM credentials may take the form of supplementary groups.
|
||||
* These will have been wiped by the above initgroups() call.
|
||||
* Reestablish them here.
|
||||
*/
|
||||
do_pam_setcred(0);
|
||||
# endif /* USE_PAM */
|
||||
# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
|
||||
irix_setusercontext(pw);
|
||||
# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
|
||||
/* Permanently switch to the desired uid. */
|
||||
permanently_set_uid(pw);
|
||||
#endif
|
||||
}
|
||||
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
|
||||
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
return env;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1249,8 +1209,15 @@ launch_login(struct passwd *pw, const char *hostname)
|
||||
{
|
||||
/* Launch login(1). */
|
||||
|
||||
execl("/usr/bin/login", "login", "-h", hostname,
|
||||
execl(LOGIN_PROGRAM, "login", "-h", hostname,
|
||||
#ifdef xxxLOGIN_NEEDS_TERM
|
||||
(s->term ? s->term : "unknown"),
|
||||
#endif /* LOGIN_NEEDS_TERM */
|
||||
#ifdef LOGIN_NO_ENDOPT
|
||||
"-p", "-f", pw->pw_name, (char *)NULL);
|
||||
#else
|
||||
"-p", "-f", "--", pw->pw_name, (char *)NULL);
|
||||
#endif
|
||||
|
||||
/* Login couldn't be executed, die. */
|
||||
|
||||
@ -1267,15 +1234,11 @@ void
|
||||
do_child(Session *s, const char *command)
|
||||
{
|
||||
extern char **environ;
|
||||
char **env = NULL;
|
||||
char **env;
|
||||
char *argv[10];
|
||||
const char *shell, *shell0, *hostname = NULL;
|
||||
struct passwd *pw = s->pw;
|
||||
u_int i;
|
||||
int ttyfd = s->ttyfd;
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
int lc_requirehome, lc_nocheckmail;
|
||||
#endif
|
||||
|
||||
/* remove hostkey from the child's memory */
|
||||
destroy_sensitive_data();
|
||||
@ -1289,8 +1252,17 @@ do_child(Session *s, const char *command)
|
||||
* switch, so we let login(1) to this for us.
|
||||
*/
|
||||
if (!options.use_login) {
|
||||
#ifdef HAVE_OSF_SIA
|
||||
session_setup_sia(pw->pw_name, s->ttyfd == -1 ? NULL : s->tty);
|
||||
if (!check_quietlogin(s, command))
|
||||
do_motd();
|
||||
#else /* HAVE_OSF_SIA */
|
||||
do_nologin(pw);
|
||||
env = do_setusercontext(pw);
|
||||
# ifdef _AIX
|
||||
aix_usrinfo(pw, s->tty, s->ttyfd);
|
||||
# endif /* _AIX */
|
||||
do_setusercontext(pw);
|
||||
#endif /* HAVE_OSF_SIA */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1302,7 +1274,7 @@ do_child(Session *s, const char *command)
|
||||
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
|
||||
#endif
|
||||
|
||||
env = do_setup_env(env, s, shell);
|
||||
env = do_setup_env(s, shell);
|
||||
|
||||
/* we have to stash the hostname before we close our socket. */
|
||||
if (options.use_login)
|
||||
@ -1334,19 +1306,13 @@ do_child(Session *s, const char *command)
|
||||
*/
|
||||
endpwent();
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
lc_requirehome = login_getcapbool(lc, "requirehome", 0);
|
||||
lc_nocheckmail = login_getcapbool(lc, "nocheckmail", 0);
|
||||
login_close(lc);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Close any extra open file descriptors so that we don\'t have them
|
||||
* hanging around in clients. Note that we want to do this after
|
||||
* initgroups, because at least on Solaris 2.3 it leaves file
|
||||
* descriptors open.
|
||||
*/
|
||||
for (i = 3; i < getdtablesize(); i++)
|
||||
for (i = 3; i < 64; i++)
|
||||
close(i);
|
||||
|
||||
/*
|
||||
@ -1372,7 +1338,7 @@ do_child(Session *s, const char *command)
|
||||
fprintf(stderr, "Could not chdir to home directory %s: %s\n",
|
||||
pw->pw_dir, strerror(errno));
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
if (lc_requirehome)
|
||||
if (login_getcapbool(lc, "requirehome", 0))
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
@ -1412,29 +1378,6 @@ do_child(Session *s, const char *command)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for mail if we have a tty and it was enabled
|
||||
* in server options.
|
||||
*/
|
||||
if (ttyfd != -1 && options.check_mail
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
&& !lc_nocheckmail
|
||||
#endif
|
||||
) {
|
||||
char *mailbox;
|
||||
struct stat mailstat;
|
||||
|
||||
mailbox = getenv("MAIL");
|
||||
if (mailbox != NULL) {
|
||||
if (stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0)
|
||||
;
|
||||
else if (mailstat.st_mtime < mailstat.st_atime)
|
||||
printf("You have mail.\n");
|
||||
else
|
||||
printf("You have new mail.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Execute the shell. */
|
||||
argv[0] = argv0;
|
||||
argv[1] = NULL;
|
||||
@ -1818,7 +1761,7 @@ session_pty_cleanup2(void *session)
|
||||
|
||||
/* Record that the user has logged out. */
|
||||
if (s->pid != 0)
|
||||
record_logout(s->pid, s->tty);
|
||||
record_logout(s->pid, s->tty, s->pw->pw_name);
|
||||
|
||||
/* Release the pseudo-tty. */
|
||||
if (getuid() == 0)
|
||||
@ -1860,7 +1803,11 @@ session_exit_message(Session *s, int status)
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
channel_request_start(s->chanid, "exit-signal", 0);
|
||||
packet_put_int(WTERMSIG(status));
|
||||
#ifdef WCOREDUMP
|
||||
packet_put_char(WCOREDUMP(status));
|
||||
#else /* WCOREDUMP */
|
||||
packet_put_char(0);
|
||||
#endif /* WCOREDUMP */
|
||||
packet_put_cstring("");
|
||||
packet_put_cstring("");
|
||||
packet_send();
|
||||
@ -2046,8 +1993,23 @@ session_setup_x11fwd(Session *s)
|
||||
s->display = xstrdup(display);
|
||||
s->auth_display = xstrdup(auth_display);
|
||||
} else {
|
||||
#ifdef IPADDR_IN_DISPLAY
|
||||
struct hostent *he;
|
||||
struct in_addr my_addr;
|
||||
|
||||
he = gethostbyname(hostname);
|
||||
if (he == NULL) {
|
||||
error("Can't get IP address for X11 DISPLAY.");
|
||||
packet_send_debug("Can't get IP address for X11 DISPLAY.");
|
||||
return 0;
|
||||
}
|
||||
memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr));
|
||||
snprintf(display, sizeof display, "%.50s:%d.%d", inet_ntoa(my_addr),
|
||||
s->display_number, s->screen);
|
||||
#else
|
||||
snprintf(display, sizeof display, "%.400s:%d.%d", hostname,
|
||||
s->display_number, s->screen);
|
||||
#endif
|
||||
s->display = xstrdup(display);
|
||||
s->auth_display = xstrdup(display);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: session.h,v 1.17 2002/03/29 18:59:32 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -68,5 +67,5 @@ void session_pty_cleanup2(void *);
|
||||
Session *session_new(void);
|
||||
Session *session_by_tty(char *);
|
||||
void session_close(Session *);
|
||||
char **do_setusercontext(struct passwd *);
|
||||
void do_setusercontext(struct passwd *);
|
||||
#endif
|
||||
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.5 2001/03/03 23:59:36 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= sftp-server
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/libexec
|
||||
MAN= sftp-server.8
|
||||
|
||||
SRCS= sftp-server.c sftp-common.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto
|
||||
DPADD+= ${LIBCRYPTO}
|
@ -1,19 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.5 2001/05/03 23:09:57 mouring Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= sftp
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= sftp.1
|
||||
|
||||
SRCS= sftp.c sftp-client.c sftp-int.c sftp-common.c sftp-glob.c misc.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto
|
||||
DPADD+= ${LIBCRYPTO}
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh-add.c,v 1.61 2002/06/19 00:27:55 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
@ -51,6 +50,12 @@ RCSID("$FreeBSD$");
|
||||
#include "readpass.h"
|
||||
#include "misc.h"
|
||||
|
||||
#ifdef HAVE___PROGNAME
|
||||
extern char *__progname;
|
||||
#else
|
||||
char *__progname;
|
||||
#endif
|
||||
|
||||
/* argv0 */
|
||||
extern char *__progname;
|
||||
|
||||
@ -302,6 +307,10 @@ main(int argc, char **argv)
|
||||
char *sc_reader_id = NULL;
|
||||
int i, ch, deleting = 0, ret = 0;
|
||||
|
||||
__progname = get_progname(argv[0]);
|
||||
init_rng();
|
||||
seed_rng();
|
||||
|
||||
SSLeay_add_all_algorithms();
|
||||
|
||||
/* At first, get a connection to the authentication agent. */
|
||||
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.20 2001/03/04 00:51:25 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-add
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh-add.1
|
||||
|
||||
SRCS= ssh-add.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto
|
||||
DPADD+= ${LIBCRYPTO}
|
@ -34,9 +34,8 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include <sys/queue.h>
|
||||
#include "openbsd-compat/fake-queue.h"
|
||||
RCSID("$OpenBSD: ssh-agent.c,v 1.95 2002/06/19 00:27:55 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/md5.h>
|
||||
@ -101,7 +100,11 @@ char socket_dir[1024];
|
||||
int locked = 0;
|
||||
char *lock_passwd = NULL;
|
||||
|
||||
#ifdef HAVE___PROGNAME
|
||||
extern char *__progname;
|
||||
#else
|
||||
char *__progname;
|
||||
#endif
|
||||
|
||||
static void
|
||||
idtab_init(void)
|
||||
@ -926,7 +929,12 @@ main(int ac, char **av)
|
||||
{
|
||||
int sock, c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0, ch, nalloc;
|
||||
struct sockaddr_un sunaddr;
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
struct rlimit rlim;
|
||||
#endif
|
||||
#ifdef HAVE_CYGWIN
|
||||
int prev_mask;
|
||||
#endif
|
||||
pid_t pid;
|
||||
char *shell, *format, *pidstr, pidstrbuf[1 + 3 * sizeof pid];
|
||||
char *agentsocket = NULL;
|
||||
@ -935,7 +943,15 @@ main(int ac, char **av)
|
||||
|
||||
SSLeay_add_all_algorithms();
|
||||
|
||||
__progname = get_progname(av[0]);
|
||||
init_rng();
|
||||
seed_rng();
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
while ((ch = getopt(ac, av, "+cdksa:")) != -1) {
|
||||
#else /* __GNU_LIBRARY__ */
|
||||
while ((ch = getopt(ac, av, "cdksa:")) != -1) {
|
||||
#endif /* __GNU_LIBRARY__ */
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
if (s_flag)
|
||||
@ -1025,11 +1041,19 @@ main(int ac, char **av)
|
||||
memset(&sunaddr, 0, sizeof(sunaddr));
|
||||
sunaddr.sun_family = AF_UNIX;
|
||||
strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
|
||||
sunaddr.sun_len = SUN_LEN(&sunaddr) + 1;
|
||||
if (bind(sock, (struct sockaddr *)&sunaddr, sunaddr.sun_len) < 0) {
|
||||
#ifdef HAVE_CYGWIN
|
||||
prev_mask = umask(0177);
|
||||
#endif
|
||||
if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) {
|
||||
perror("bind");
|
||||
#ifdef HAVE_CYGWIN
|
||||
umask(prev_mask);
|
||||
#endif
|
||||
cleanup_exit(1);
|
||||
}
|
||||
#ifdef HAVE_CYGWIN
|
||||
umask(prev_mask);
|
||||
#endif
|
||||
if (listen(sock, 5) < 0) {
|
||||
perror("listen");
|
||||
cleanup_exit(1);
|
||||
@ -1086,12 +1110,14 @@ main(int ac, char **av)
|
||||
close(1);
|
||||
close(2);
|
||||
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
/* deny core dumps, since memory contains unencrypted private keys */
|
||||
rlim.rlim_cur = rlim.rlim_max = 0;
|
||||
if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
|
||||
error("setrlimit RLIMIT_CORE: %s", strerror(errno));
|
||||
cleanup_exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
skip:
|
||||
fatal_add_cleanup(cleanup_socket, NULL);
|
||||
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.21 2001/06/27 19:29:16 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-agent
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh-agent.1
|
||||
|
||||
SRCS= ssh-agent.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto
|
||||
DPADD+= ${LIBCRYPTO}
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.21 2001/06/27 19:29:16 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-keygen
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh-keygen.1
|
||||
|
||||
SRCS= ssh-keygen.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto
|
||||
DPADD+= ${LIBCRYPTO}
|
@ -8,10 +8,8 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh-keyscan.c,v 1.36 2002/06/16 21:30:58 itojun Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <errno.h>
|
||||
#include "openbsd-compat/fake-queue.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
@ -31,7 +29,13 @@ RCSID("$FreeBSD$");
|
||||
#include "atomicio.h"
|
||||
#include "misc.h"
|
||||
|
||||
extern int IPv4or6;
|
||||
/* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
|
||||
Default value is AF_UNSPEC means both IPv4 and IPv6. */
|
||||
#ifdef IPV4_DEFAULT
|
||||
int IPv4or6 = AF_INET;
|
||||
#else
|
||||
int IPv4or6 = AF_UNSPEC;
|
||||
#endif
|
||||
|
||||
int ssh_port = SSH_DEFAULT_PORT;
|
||||
|
||||
@ -49,7 +53,11 @@ int timeout = 5;
|
||||
int maxfd;
|
||||
#define MAXCON (maxfd - 10)
|
||||
|
||||
#ifdef HAVE___PROGNAME
|
||||
extern char *__progname;
|
||||
#else
|
||||
char *__progname;
|
||||
#endif
|
||||
fd_set *read_wait;
|
||||
size_t read_wait_size;
|
||||
int ncon;
|
||||
@ -199,6 +207,7 @@ Linebuf_getline(Linebuf * lb)
|
||||
static int
|
||||
fdlim_get(int hard)
|
||||
{
|
||||
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
|
||||
struct rlimit rlfd;
|
||||
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
|
||||
@ -207,19 +216,30 @@ fdlim_get(int hard)
|
||||
return 10000;
|
||||
else
|
||||
return hard ? rlfd.rlim_max : rlfd.rlim_cur;
|
||||
#elif defined (HAVE_SYSCONF)
|
||||
return sysconf (_SC_OPEN_MAX);
|
||||
#else
|
||||
return 10000;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
fdlim_set(int lim)
|
||||
{
|
||||
#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
|
||||
struct rlimit rlfd;
|
||||
#endif
|
||||
if (lim <= 0)
|
||||
return (-1);
|
||||
#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
|
||||
return (-1);
|
||||
rlfd.rlim_cur = lim;
|
||||
if (setrlimit(RLIMIT_NOFILE, &rlfd) < 0)
|
||||
return (-1);
|
||||
#elif defined (HAVE_SETDTABLESIZE)
|
||||
setdtablesize(lim);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -679,6 +699,9 @@ main(int argc, char **argv)
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
__progname = get_progname(argv[0]);
|
||||
init_rng();
|
||||
seed_rng();
|
||||
TAILQ_INIT(&tq);
|
||||
|
||||
if (argc <= 1)
|
||||
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.4 2001/08/05 23:18:20 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-keyscan
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh-keyscan.1
|
||||
|
||||
SRCS= ssh-keyscan.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lz
|
||||
DPADD+= ${LIBCRYPTO} ${LIBZ}
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.3 2002/05/31 10:30:33 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-keysign
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=4555
|
||||
|
||||
BINDIR= /usr/libexec
|
||||
MAN= ssh-keysign.8
|
||||
|
||||
SRCS= ssh-keysign.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lz
|
||||
DPADD+= ${LIBCRYPTO} ${LIBZ}
|
@ -35,7 +35,6 @@
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh.1,v 1.158 2002/06/20 19:56:07 stevesk Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd September 25, 1999
|
||||
.Dt SSH 1
|
||||
.Os
|
||||
@ -100,7 +99,7 @@ depending on the protocol version used:
|
||||
First, if the machine the user logs in from is listed in
|
||||
.Pa /etc/hosts.equiv
|
||||
or
|
||||
.Pa /etc/ssh/shosts.equiv
|
||||
.Pa /etc/shosts.equiv
|
||||
on the remote machine, and the user names are
|
||||
the same on both sides, the user is immediately permitted to log in.
|
||||
Second, if
|
||||
@ -124,7 +123,7 @@ It means that if the login would be permitted by
|
||||
.Pa $HOME/.shosts ,
|
||||
.Pa /etc/hosts.equiv ,
|
||||
or
|
||||
.Pa /etc/ssh/shosts.equiv ,
|
||||
.Pa /etc/shosts.equiv ,
|
||||
and if additionally the server can verify the client's
|
||||
host key (see
|
||||
.Pa /etc/ssh/ssh_known_hosts
|
||||
@ -331,7 +330,6 @@ The user should not manually set
|
||||
.Ev DISPLAY .
|
||||
Forwarding of X11 connections can be
|
||||
configured on the command line or in configuration files.
|
||||
Take note that X11 forwarding can represent a security hazard.
|
||||
.Pp
|
||||
The
|
||||
.Ev DISPLAY
|
||||
@ -668,7 +666,7 @@ It is automatically set by
|
||||
to point to a value of the form
|
||||
.Dq hostname:n
|
||||
where hostname indicates
|
||||
the host where the shell runs, and n is an integer \*(>= 1.
|
||||
the host where the shell runs, and n is an integer >= 1.
|
||||
.Nm
|
||||
uses this special value to forward X11 connections over the secure
|
||||
channel.
|
||||
@ -895,8 +893,7 @@ or
|
||||
.Xr rsh 1 .
|
||||
.It Pa /etc/hosts.equiv
|
||||
This file is used during
|
||||
.Pa \&.rhosts
|
||||
authentication.
|
||||
.Pa \&.rhosts authentication.
|
||||
It contains
|
||||
canonical hosts names, one per line (the full format is described on
|
||||
the
|
||||
@ -908,7 +905,7 @@ same.
|
||||
Additionally, successful RSA host authentication is normally
|
||||
required.
|
||||
This file should only be writable by root.
|
||||
.It Pa /etc/ssh/shosts.equiv
|
||||
.It Pa /etc/shosts.equiv
|
||||
This file is processed exactly as
|
||||
.Pa /etc/hosts.equiv .
|
||||
This file may be useful to permit logins using
|
||||
|
@ -41,7 +41,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh.c,v 1.179 2002/06/12 01:09:52 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
@ -74,11 +73,19 @@ RCSID("$FreeBSD$");
|
||||
#include "scard.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE___PROGNAME
|
||||
extern char *__progname;
|
||||
#else
|
||||
char *__progname;
|
||||
#endif
|
||||
|
||||
/* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
|
||||
Default value is AF_UNSPEC means both IPv4 and IPv6. */
|
||||
extern int IPv4or6;
|
||||
#ifdef IPV4_DEFAULT
|
||||
int IPv4or6 = AF_INET;
|
||||
#else
|
||||
int IPv4or6 = AF_UNSPEC;
|
||||
#endif
|
||||
|
||||
/* Flag indicating whether debug mode is on. This can be set on the command line. */
|
||||
int debug_flag = 0;
|
||||
@ -213,6 +220,9 @@ main(int ac, char **av)
|
||||
extern int optind, optreset;
|
||||
extern char *optarg;
|
||||
|
||||
__progname = get_progname(av[0]);
|
||||
init_rng();
|
||||
|
||||
/*
|
||||
* Save the original real uid. It will be needed later (uid-swapping
|
||||
* may clobber the real uid).
|
||||
@ -220,6 +230,7 @@ main(int ac, char **av)
|
||||
original_real_uid = getuid();
|
||||
original_effective_uid = geteuid();
|
||||
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
/* If we are installed setuid root be careful to not drop core. */
|
||||
if (original_real_uid != original_effective_uid) {
|
||||
struct rlimit rlim;
|
||||
@ -227,10 +238,11 @@ main(int ac, char **av)
|
||||
if (setrlimit(RLIMIT_CORE, &rlim) < 0)
|
||||
fatal("setrlimit failed: %.100s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
/* Get user data. */
|
||||
pw = getpwuid(original_real_uid);
|
||||
if (!pw) {
|
||||
log("unknown user %d", original_real_uid);
|
||||
log("You don't exist, go away!");
|
||||
exit(1);
|
||||
}
|
||||
/* Take a copy of the returned structure. */
|
||||
@ -580,30 +592,21 @@ main(int ac, char **av)
|
||||
/* reinit */
|
||||
log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1);
|
||||
|
||||
seed_rng();
|
||||
|
||||
if (options.user == NULL)
|
||||
options.user = xstrdup(pw->pw_name);
|
||||
|
||||
if (options.hostname != NULL)
|
||||
host = options.hostname;
|
||||
|
||||
/* Find canonic host name. */
|
||||
if (strchr(host, '.') == 0) {
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *ai = NULL;
|
||||
int errgai;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = IPv4or6;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
errgai = getaddrinfo(host, NULL, &hints, &ai);
|
||||
if (errgai == 0) {
|
||||
if (ai->ai_canonname != NULL)
|
||||
host = xstrdup(ai->ai_canonname);
|
||||
freeaddrinfo(ai);
|
||||
}
|
||||
}
|
||||
/* Disable rhosts authentication if not running as root. */
|
||||
#ifdef HAVE_CYGWIN
|
||||
/* Ignore uid if running under Windows */
|
||||
if (!options.use_privileged_port) {
|
||||
#else
|
||||
if (original_effective_uid != 0 || !options.use_privileged_port) {
|
||||
#endif
|
||||
debug("Rhosts Authentication disabled, "
|
||||
"originating port will not be trusted.");
|
||||
options.rhosts_authentication = 0;
|
||||
@ -612,7 +615,11 @@ main(int ac, char **av)
|
||||
|
||||
if (ssh_connect(host, &hostaddr, options.port, IPv4or6,
|
||||
options.connection_attempts,
|
||||
#ifdef HAVE_CYGWIN
|
||||
options.use_privileged_port,
|
||||
#else
|
||||
original_effective_uid == 0 && options.use_privileged_port,
|
||||
#endif
|
||||
options.proxy_command) != 0)
|
||||
exit(1);
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: ssh.h,v 1.70 2002/06/03 12:04:07 deraadt Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -16,6 +15,16 @@
|
||||
#ifndef SSH_H
|
||||
#define SSH_H
|
||||
|
||||
#include <netinet/in.h> /* For struct sockaddr_in */
|
||||
#include <pwd.h> /* For struct pw */
|
||||
#include <stdarg.h> /* For va_list */
|
||||
#include <syslog.h> /* For LOG_AUTH and friends */
|
||||
#include <sys/socket.h> /* For struct sockaddr_storage */
|
||||
#include "openbsd-compat/fake-socket.h" /* For struct sockaddr_storage */
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
|
||||
/* Cipher used for encrypting authentication files. */
|
||||
#define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES
|
||||
|
||||
@ -51,6 +60,10 @@
|
||||
*/
|
||||
#define SSH_SERVICE_NAME "ssh"
|
||||
|
||||
#if defined(USE_PAM) && !defined(SSHD_PAM_SERVICE)
|
||||
# define SSHD_PAM_SERVICE __progname
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Name of the environment variable containing the pathname of the
|
||||
* authentication socket.
|
||||
@ -91,13 +104,11 @@
|
||||
* sshd will change its privileges to this user and its
|
||||
* primary group.
|
||||
*/
|
||||
#ifndef SSH_PRIVSEP_USER
|
||||
#define SSH_PRIVSEP_USER "sshd"
|
||||
#endif
|
||||
|
||||
/* Minimum modulus size (n) for RSA keys. */
|
||||
#define SSH_RSA_MINIMUM_MODULUS_SIZE 768
|
||||
|
||||
#ifdef USE_PAM
|
||||
#include "auth-pam.h"
|
||||
#endif /* USE_PAM */
|
||||
|
||||
#endif /* SSH_H */
|
||||
|
@ -1,40 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.42 2002/06/20 19:56:07 stevesk Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh
|
||||
BINOWN= root
|
||||
|
||||
#BINMODE?=4555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh.1 ssh_config.5
|
||||
LINKS= ${BINDIR}/ssh ${BINDIR}/slogin
|
||||
MLINKS= ssh.1 slogin.1
|
||||
|
||||
SRCS= ssh.c readconf.c clientloop.c sshtty.c \
|
||||
sshconnect.c sshconnect1.c sshconnect2.c
|
||||
|
||||
.include <bsd.own.mk> # for AFS
|
||||
|
||||
.if (${KERBEROS5:L} == "yes")
|
||||
CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
|
||||
LDADD+= -lkrb5 -lasn1 -lcom_err
|
||||
DPADD+= ${LIBKRB5} ${LIBASN1} ${LIBCOM_ERR}
|
||||
.endif # KERBEROS5
|
||||
|
||||
.if (${KERBEROS:L} == "yes")
|
||||
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
|
||||
LDADD+= -lkrb
|
||||
DPADD+= ${LIBKRB}
|
||||
.if (${AFS:L} == "yes")
|
||||
CFLAGS+= -DAFS
|
||||
LDADD+= -lkafs
|
||||
DPADD+= ${LIBKAFS}
|
||||
.endif # AFS
|
||||
.endif # KERBEROS
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lz -ldes
|
||||
DPADD+= ${LIBCRYPTO} ${LIBZ} ${LIBDES}
|
@ -1,5 +1,4 @@
|
||||
# $OpenBSD: ssh_config,v 1.15 2002/06/20 20:03:34 stevesk Exp $
|
||||
# $FreeBSD$
|
||||
|
||||
# This is the ssh client system-wide configuration file. See
|
||||
# ssh_config(5) for more information. This file provides defaults for
|
||||
@ -34,4 +33,3 @@
|
||||
# Cipher 3des
|
||||
# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
|
||||
# EscapeChar ~
|
||||
# VersionAddendum FreeBSD-20020402
|
||||
|
@ -35,7 +35,6 @@
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh_config.5,v 1.1 2002/06/20 19:56:07 stevesk Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd September 25, 1999
|
||||
.Dt SSH_CONFIG 5
|
||||
.Os
|
||||
@ -584,9 +583,6 @@ having to remember to give the user name on the command line.
|
||||
Specifies a file to use for the user
|
||||
host key database instead of
|
||||
.Pa $HOME/.ssh/known_hosts .
|
||||
.It Cm VersionAddendum
|
||||
Specifies a string to append to the regular version string to identify
|
||||
OS- or site-specific modifications.
|
||||
.It Cm XAuthLocation
|
||||
Specifies the location of the
|
||||
.Xr xauth 1
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshconnect.c,v 1.125 2002/06/19 00:27:55 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
@ -43,6 +42,10 @@ extern char *__progname;
|
||||
extern uid_t original_real_uid;
|
||||
extern uid_t original_effective_uid;
|
||||
|
||||
#ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */
|
||||
#define INET6_ADDRSTRLEN 46
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
sockaddr_ntop(struct sockaddr *sa, socklen_t salen)
|
||||
{
|
||||
@ -498,6 +501,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
HostStatus host_status;
|
||||
HostStatus ip_status;
|
||||
int local = 0, host_ip_differ = 0;
|
||||
int salen;
|
||||
char ntop[NI_MAXHOST];
|
||||
char msg[1024];
|
||||
int len, host_line, ip_line;
|
||||
@ -516,13 +520,16 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
case AF_INET:
|
||||
local = (ntohl(((struct sockaddr_in *)hostaddr)->
|
||||
sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
|
||||
salen = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
local = IN6_IS_ADDR_LOOPBACK(
|
||||
&(((struct sockaddr_in6 *)hostaddr)->sin6_addr));
|
||||
salen = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
local = 0;
|
||||
salen = sizeof(struct sockaddr_storage);
|
||||
break;
|
||||
}
|
||||
if (options.no_host_authentication_for_localhost == 1 && local &&
|
||||
@ -537,7 +544,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
* using a proxy command
|
||||
*/
|
||||
if (options.proxy_command == NULL) {
|
||||
if (getnameinfo(hostaddr, hostaddr->sa_len, ntop, sizeof(ntop),
|
||||
if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop),
|
||||
NULL, 0, NI_NUMERICHOST) != 0)
|
||||
fatal("check_host_key: getnameinfo failed");
|
||||
ip = xstrdup(ntop);
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $OpenBSD: sshconnect.h,v 1.17 2002/06/19 00:27:55 deraadt Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshconnect1.c,v 1.51 2002/05/23 19:24:30 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/md5.h>
|
||||
@ -24,6 +23,9 @@ RCSID("$FreeBSD$");
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
#include <krb5.h>
|
||||
#ifndef HEIMDAL
|
||||
#define krb5_get_err_text(context,code) error_message(code)
|
||||
#endif /* !HEIMDAL */
|
||||
#endif
|
||||
#ifdef AFS
|
||||
#include <kafs.h>
|
||||
@ -522,6 +524,23 @@ try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
problem = krb5_auth_con_init(*context, auth_context);
|
||||
if (problem) {
|
||||
debug("Kerberos v5: krb5_auth_con_init failed");
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifndef HEIMDAL
|
||||
problem = krb5_auth_con_setflags(*context, *auth_context,
|
||||
KRB5_AUTH_CONTEXT_RET_TIME);
|
||||
if (problem) {
|
||||
debug("Keberos v5: krb5_auth_con_setflags failed");
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
tkfile = krb5_cc_default_name(*context);
|
||||
if (strncmp(tkfile, "FILE:", 5) == 0)
|
||||
@ -598,7 +617,11 @@ try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
|
||||
if (reply != NULL)
|
||||
krb5_free_ap_rep_enc_part(*context, reply);
|
||||
if (ap.length > 0)
|
||||
#ifdef HEIMDAL
|
||||
krb5_data_free(&ap);
|
||||
#else
|
||||
krb5_free_data_contents(*context, &ap);
|
||||
#endif
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@ -611,7 +634,11 @@ send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
|
||||
krb5_data outbuf;
|
||||
krb5_ccache ccache = NULL;
|
||||
krb5_creds creds;
|
||||
#ifdef HEIMDAL
|
||||
krb5_kdc_flags flags;
|
||||
#else
|
||||
int forwardable;
|
||||
#endif
|
||||
const char *remotehost;
|
||||
|
||||
memset(&creds, 0, sizeof(creds));
|
||||
@ -619,7 +646,13 @@ send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
|
||||
|
||||
fd = packet_get_connection_in();
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
|
||||
#else
|
||||
problem = krb5_auth_con_genaddrs(context, auth_context, fd,
|
||||
KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
|
||||
KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
|
||||
#endif
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
@ -631,23 +664,35 @@ send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
remotehost = get_canonical_hostname(1);
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_build_principal(context, &creds.server,
|
||||
strlen(creds.client->realm), creds.client->realm,
|
||||
"krbtgt", creds.client->realm, NULL);
|
||||
#else
|
||||
problem = krb5_build_principal(context, &creds.server,
|
||||
creds.client->realm.length, creds.client->realm.data,
|
||||
"host", remotehost, NULL);
|
||||
#endif
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
creds.times.endtime = 0;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
flags.i = 0;
|
||||
flags.b.forwarded = 1;
|
||||
flags.b.forwardable = krb5_config_get_bool(context, NULL,
|
||||
"libdefaults", "forwardable", NULL);
|
||||
|
||||
remotehost = get_canonical_hostname(1);
|
||||
|
||||
problem = krb5_get_forwarded_creds(context, auth_context,
|
||||
ccache, flags.i, remotehost, &creds, &outbuf);
|
||||
#else
|
||||
forwardable = 1;
|
||||
problem = krb5_fwd_tgt_creds(context, auth_context, remotehost,
|
||||
creds.client, creds.server, ccache, forwardable, &outbuf);
|
||||
#endif
|
||||
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshconnect2.c,v 1.104 2002/06/19 00:27:55 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
@ -473,7 +472,7 @@ userauth_passwd(Authctxt *authctxt)
|
||||
* parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
|
||||
*/
|
||||
void
|
||||
input_userauth_passwd_changereq(int type, uint32_t seqnr, void *ctxt)
|
||||
input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
|
||||
{
|
||||
Authctxt *authctxt = ctxt;
|
||||
char *info, *lang, *password = NULL, *retype = NULL;
|
||||
|
@ -35,7 +35,6 @@
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd.8,v 1.184 2002/06/20 19:56:07 stevesk Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd September 25, 1999
|
||||
.Dt SSHD 8
|
||||
.Os
|
||||
@ -66,7 +65,7 @@ install and use as possible.
|
||||
.Nm
|
||||
is the daemon that listens for connections from clients.
|
||||
It is normally started at boot from
|
||||
.Pa /etc/rc.network .
|
||||
.Pa /etc/rc .
|
||||
It forks a new
|
||||
daemon for each incoming connection.
|
||||
The forked daemons handle
|
||||
@ -341,9 +340,8 @@ section).
|
||||
If the login is on a tty, records login time.
|
||||
.It
|
||||
Checks
|
||||
.Pa /etc/nologin and
|
||||
.Pa /var/run/nologin ;
|
||||
if one exists, it prints the contents and quits
|
||||
.Pa /etc/nologin ;
|
||||
if it exists, prints contents and quits
|
||||
(unless root).
|
||||
.It
|
||||
Changes to run with normal user privileges.
|
||||
@ -361,12 +359,11 @@ If
|
||||
exists, runs it; else if
|
||||
.Pa /etc/ssh/sshrc
|
||||
exists, runs
|
||||
it; otherwise runs
|
||||
.Xr xauth 1 .
|
||||
it; otherwise runs xauth.
|
||||
The
|
||||
.Dq rc
|
||||
files are given the X11
|
||||
authentication protocol and cookie (if applicable) in standard input.
|
||||
authentication protocol and cookie in standard input.
|
||||
.It
|
||||
Runs user's shell or command.
|
||||
.El
|
||||
@ -501,7 +498,7 @@ command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hu
|
||||
permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23.\|.\|.\|2323
|
||||
.Sh SSH_KNOWN_HOSTS FILE FORMAT
|
||||
The
|
||||
.Pa /etc/ssh/ssh_known_hosts
|
||||
.Pa /etc/ssh/ssh_known_hosts ,
|
||||
and
|
||||
.Pa $HOME/.ssh/known_hosts
|
||||
files contain host public keys for all known hosts.
|
||||
@ -579,7 +576,7 @@ really used for anything; they are provided for the convenience of
|
||||
the user so their contents can be copied to known hosts files.
|
||||
These files are created using
|
||||
.Xr ssh-keygen 1 .
|
||||
.It Pa /etc/ssh/moduli
|
||||
.It Pa /etc/moduli
|
||||
Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange".
|
||||
.It Pa /var/run/sshd.pid
|
||||
Contains the process ID of the
|
||||
@ -682,7 +679,7 @@ The only valid use for user names that I can think
|
||||
of is in negative entries.
|
||||
.Pp
|
||||
Note that this warning also applies to rsh/rlogin.
|
||||
.It Pa /etc/ssh/shosts.equiv
|
||||
.It Pa /etc/shosts.equiv
|
||||
This is processed exactly as
|
||||
.Pa /etc/hosts.equiv .
|
||||
However, this file may be useful in environments that want to run both
|
||||
@ -695,9 +692,7 @@ and assignment lines of the form name=value.
|
||||
The file should be writable
|
||||
only by the user; it need not be readable by anyone else.
|
||||
.It Pa $HOME/.ssh/rc
|
||||
If this file exists, it is run with
|
||||
.Pa /bin/sh
|
||||
after reading the
|
||||
If this file exists, it is run with /bin/sh after reading the
|
||||
environment files but before starting the user's shell or command.
|
||||
It must not produce any output on stdout; stderr must be used
|
||||
instead.
|
||||
|
@ -43,12 +43,15 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshd.c,v 1.246 2002/06/20 23:05:56 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/rand.h>
|
||||
#ifdef HAVE_SECUREWARE
|
||||
#include <sys/security.h>
|
||||
#include <prot.h>
|
||||
#endif
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
@ -63,9 +66,6 @@ RCSID("$FreeBSD$");
|
||||
#include "uidswap.h"
|
||||
#include "compat.h"
|
||||
#include "buffer.h"
|
||||
#include <poll.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "key.h"
|
||||
@ -96,7 +96,11 @@ int deny_severity = LOG_WARNING;
|
||||
#define O_NOCTTY 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE___PROGNAME
|
||||
extern char *__progname;
|
||||
#else
|
||||
char *__progname;
|
||||
#endif
|
||||
|
||||
/* Server configuration options. */
|
||||
ServerOptions options;
|
||||
@ -108,7 +112,11 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE;
|
||||
* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
|
||||
* Default value is AF_UNSPEC means both IPv4 and IPv6.
|
||||
*/
|
||||
extern int IPv4or6;
|
||||
#ifdef IPV4_DEFAULT
|
||||
int IPv4or6 = AF_INET;
|
||||
#else
|
||||
int IPv4or6 = AF_UNSPEC;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Debug mode flag. This can be set on the command line. If debug
|
||||
@ -132,6 +140,7 @@ int log_stderr = 0;
|
||||
|
||||
/* Saved arguments to main(). */
|
||||
char **saved_argv;
|
||||
int saved_argc;
|
||||
|
||||
/*
|
||||
* The sockets that the server is listening; this is used in the SIGHUP
|
||||
@ -781,7 +790,14 @@ main(int ac, char **av)
|
||||
Key *key;
|
||||
int ret, key_used = 0;
|
||||
|
||||
#ifdef HAVE_SECUREWARE
|
||||
(void)set_auth_parameters(ac, av);
|
||||
#endif
|
||||
__progname = get_progname(av[0]);
|
||||
init_rng();
|
||||
|
||||
/* Save argv. */
|
||||
saved_argc = ac;
|
||||
saved_argv = av;
|
||||
|
||||
/* Initialize configuration options to their default values. */
|
||||
@ -895,6 +911,15 @@ main(int ac, char **av)
|
||||
SYSLOG_FACILITY_AUTH : options.log_facility,
|
||||
!inetd_flag);
|
||||
|
||||
#ifdef _CRAY
|
||||
/* Cray can define user privs drop all prives now!
|
||||
* Not needed on PRIV_SU systems!
|
||||
*/
|
||||
drop_cray_privs();
|
||||
#endif
|
||||
|
||||
seed_rng();
|
||||
|
||||
/* Read server configuration options from the configuration file. */
|
||||
read_server_config(&options, config_file_name);
|
||||
|
||||
@ -993,6 +1018,16 @@ main(int ac, char **av)
|
||||
if (test_flag)
|
||||
exit(0);
|
||||
|
||||
/*
|
||||
* Clear out any supplemental groups we may have inherited. This
|
||||
* prevents inadvertent creation of files with bad modes (in the
|
||||
* portable version at least, it's certainly possible for PAM
|
||||
* to create a file, and we can't control the code in every
|
||||
* module which might be used).
|
||||
*/
|
||||
if (setgroups(0, NULL) < 0)
|
||||
debug("setgroups() failed: %.200s", strerror(errno));
|
||||
|
||||
/* Initialize the log (it is reinitialized below in case we forked). */
|
||||
if (debug_flag && !inetd_flag)
|
||||
log_stderr = 1;
|
||||
@ -1090,8 +1125,9 @@ main(int ac, char **av)
|
||||
|
||||
/* Bind the socket to the desired port. */
|
||||
if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||
error("Bind to port %s on %s failed: %.200s.",
|
||||
strport, ntop, strerror(errno));
|
||||
if (!ai->ai_next)
|
||||
error("Bind to port %s on %s failed: %.200s.",
|
||||
strport, ntop, strerror(errno));
|
||||
close(listen_sock);
|
||||
continue;
|
||||
}
|
||||
@ -1133,7 +1169,7 @@ main(int ac, char **av)
|
||||
* fail if there already is a daemon, and this will
|
||||
* overwrite any old pid in the file.
|
||||
*/
|
||||
f = fopen(options.pid_file, "w");
|
||||
f = fopen(options.pid_file, "wb");
|
||||
if (f) {
|
||||
fprintf(f, "%ld\n", (long) getpid());
|
||||
fclose(f);
|
||||
@ -1313,8 +1349,11 @@ main(int ac, char **av)
|
||||
* setlogin() affects the entire process group. We don't
|
||||
* want the child to be able to affect the parent.
|
||||
*/
|
||||
#if 0
|
||||
/* XXX: this breaks Solaris */
|
||||
if (setsid() < 0)
|
||||
error("setsid: %.100s", strerror(errno));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Disable the key regeneration alarm. We will not regenerate the
|
||||
@ -1327,7 +1366,7 @@ main(int ac, char **av)
|
||||
signal(SIGTERM, SIG_DFL);
|
||||
signal(SIGQUIT, SIG_DFL);
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGINT, SIG_DFL);
|
||||
|
||||
/*
|
||||
* Set socket options for the connection. We want the socket to
|
||||
|
@ -1,56 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.51 2002/06/20 19:56:07 stevesk Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= sshd
|
||||
BINOWN= root
|
||||
BINMODE=555
|
||||
BINDIR= /usr/sbin
|
||||
MAN= sshd.8 sshd_config.5
|
||||
CFLAGS+=-DHAVE_LOGIN_CAP -DBSD_AUTH
|
||||
|
||||
SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
|
||||
sshpty.c sshlogin.c servconf.c serverloop.c uidswap.c \
|
||||
auth.c auth1.c auth2.c auth-options.c session.c \
|
||||
auth-chall.c auth2-chall.c groupaccess.c \
|
||||
auth-skey.c auth-bsdauth.c monitor_mm.c monitor.c \
|
||||
auth2-none.c auth2-passwd.c auth2-pubkey.c \
|
||||
auth2-hostbased.c auth2-kbdint.c
|
||||
|
||||
.include <bsd.own.mk> # for KERBEROS and AFS
|
||||
|
||||
.if (${KERBEROS5:L} == "yes")
|
||||
CFLAGS+=-DKRB5 -I${DESTDIR}/usr/include/kerberosV
|
||||
SRCS+= auth-krb5.c
|
||||
LDADD+= -lkrb5 -lkafs -lasn1 -lcom_err
|
||||
DPADD+= ${LIBKRB5} ${LIBKAFS} ${LIBASN1} ${LIBCOM_ERR}
|
||||
.endif # KERBEROS5
|
||||
|
||||
.if (${KERBEROS:L} == "yes")
|
||||
.if (${AFS:L} == "yes")
|
||||
CFLAGS+= -DAFS
|
||||
LDADD+= -lkafs
|
||||
DPADD+= ${LIBKAFS}
|
||||
.endif # AFS
|
||||
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
|
||||
SRCS+= auth-krb4.c
|
||||
LDADD+= -lkrb
|
||||
DPADD+= ${LIBKRB}
|
||||
.endif # KERBEROS
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lutil -lz -ldes
|
||||
DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ} ${LIBDES}
|
||||
|
||||
.if (${TCP_WRAPPERS:L} == "yes")
|
||||
CFLAGS+= -DLIBWRAP
|
||||
LDADD+= -lwrap
|
||||
DPADD+= ${LIBWRAP}
|
||||
.endif
|
||||
|
||||
#.if (${SKEY:L} == "yes")
|
||||
#CFLAGS+= -DSKEY
|
||||
#LDADD+= -lskey
|
||||
#DPADD+= ${SKEY}
|
||||
#.endif
|
@ -1,19 +1,15 @@
|
||||
# $OpenBSD: sshd_config,v 1.56 2002/06/20 23:37:12 markus Exp $
|
||||
# $FreeBSD$
|
||||
|
||||
# This is the sshd server system-wide configuration file. See
|
||||
# sshd_config(5) for more information.
|
||||
|
||||
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# The strategy used for options in the default sshd_config shipped with
|
||||
# OpenSSH is to specify options with their default value where
|
||||
# possible, but leave them commented. Uncommented options change a
|
||||
# default value.
|
||||
|
||||
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
|
||||
# FreeBSD has a few additional options.
|
||||
|
||||
#VersionAddendum FreeBSD-20020402
|
||||
|
||||
#Port 22
|
||||
#Protocol 2,1
|
||||
#ListenAddress 0.0.0.0
|
||||
@ -36,8 +32,8 @@
|
||||
|
||||
# Authentication:
|
||||
|
||||
#LoginGraceTime 120
|
||||
#PermitRootLogin no
|
||||
#LoginGraceTime 600
|
||||
#PermitRootLogin yes
|
||||
#StrictModes yes
|
||||
|
||||
#RSAAuthentication yes
|
||||
@ -73,15 +69,18 @@
|
||||
# Kerberos TGT Passing only works with the AFS kaserver
|
||||
#KerberosTgtPassing no
|
||||
|
||||
#X11Forwarding yes
|
||||
# Set this to 'yes' to enable PAM keyboard-interactive authentication
|
||||
# Warning: enabling this may bypass the setting of 'PasswordAuthentication'
|
||||
#PAMAuthenticationViaKbdInt yes
|
||||
|
||||
#X11Forwarding no
|
||||
#X11DisplayOffset 10
|
||||
#X11UseLocalhost yes
|
||||
#PrintMotd yes
|
||||
#PrintLastLog yes
|
||||
#KeepAlive yes
|
||||
#UseLogin no
|
||||
#CheckMail yes
|
||||
#UsePrivilegeSeparation no
|
||||
#UsePrivilegeSeparation yes
|
||||
#Compression yes
|
||||
|
||||
#MaxStartups 10
|
||||
|
@ -35,7 +35,6 @@
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd_config.5,v 1.3 2002/06/20 23:37:12 markus Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd September 25, 1999
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
@ -132,9 +131,6 @@ All authentication styles from
|
||||
are supported.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that OPIE authentication is enabled only if
|
||||
.Cm PasswordAuthentication
|
||||
is allowed, too.
|
||||
.It Cm Ciphers
|
||||
Specifies the ciphers allowed for protocol version 2.
|
||||
Multiple ciphers must be comma-separated.
|
||||
@ -144,12 +140,6 @@ The default is
|
||||
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
|
||||
aes192-cbc,aes256-cbc''
|
||||
.Ed
|
||||
.It Cm CheckMail
|
||||
Specifies whether
|
||||
.Nm
|
||||
should notify the user of new mail for interactive logins.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm ClientAliveInterval
|
||||
Sets a timeout interval in seconds after which if no data has been received
|
||||
from the client,
|
||||
@ -276,7 +266,7 @@ or
|
||||
.Pp
|
||||
.Pa /etc/hosts.equiv
|
||||
and
|
||||
.Pa /etc/ssh/shosts.equiv
|
||||
.Pa /etc/shosts.equiv
|
||||
are still used.
|
||||
The default is
|
||||
.Dq yes .
|
||||
@ -315,6 +305,10 @@ To disable keepalives, the value should be set to
|
||||
.It Cm KerberosAuthentication
|
||||
Specifies whether Kerberos authentication is allowed.
|
||||
This can be in the form of a Kerberos ticket, or if
|
||||
.It Cm PAMAuthenticationViaKbdInt
|
||||
Specifies whether PAM challenge response authentication is allowed. This
|
||||
allows the use of most PAM challenge response authentication modules, but
|
||||
it will allow password authentication regardless of whether
|
||||
.Cm PasswordAuthentication
|
||||
is yes, the password provided by the user will be validated through
|
||||
the Kerberos KDC.
|
||||
@ -389,7 +383,7 @@ options must precede this option for non port qualified addresses.
|
||||
The server disconnects after this time if the user has not
|
||||
successfully logged in.
|
||||
If the value is 0, there is no time limit.
|
||||
The default is 120 (seconds).
|
||||
The default is 600 (seconds).
|
||||
.It Cm LogLevel
|
||||
Gives the verbosity level that is used when logging messages from
|
||||
.Nm sshd .
|
||||
@ -450,7 +444,7 @@ The argument must be
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.Dq yes .
|
||||
.Pp
|
||||
If this option is set to
|
||||
.Dq without-password
|
||||
@ -517,23 +511,18 @@ The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm RhostsAuthentication
|
||||
Specifies whether authentication using rhosts or
|
||||
.Pa /etc/hosts.equiv
|
||||
Specifies whether authentication using rhosts or /etc/hosts.equiv
|
||||
files is sufficient.
|
||||
Normally, this method should not be permitted because it is insecure.
|
||||
.Cm RhostsRSAAuthentication
|
||||
should be used
|
||||
instead, because it performs RSA-based host authentication in addition
|
||||
to normal rhosts or
|
||||
.Pa /etc/hosts.equiv
|
||||
authentication.
|
||||
to normal rhosts or /etc/hosts.equiv authentication.
|
||||
The default is
|
||||
.Dq no .
|
||||
This option applies to protocol version 1 only.
|
||||
.It Cm RhostsRSAAuthentication
|
||||
Specifies whether rhosts or
|
||||
.Pa /etc/hosts.equiv
|
||||
authentication together
|
||||
Specifies whether rhosts or /etc/hosts.equiv authentication together
|
||||
with successful RSA host authentication is allowed.
|
||||
The default is
|
||||
.Dq no .
|
||||
@ -546,9 +535,6 @@ This option applies to protocol version 1 only.
|
||||
.It Cm ServerKeyBits
|
||||
Defines the number of bits in the ephemeral protocol version 1 server key.
|
||||
The minimum value is 512, and the default is 768.
|
||||
.It Cm SkeyAuthentication
|
||||
Backward-compatibility alias for
|
||||
.Cm ChallengeResponseAuthentication .
|
||||
.It Cm StrictModes
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
@ -611,9 +597,6 @@ the resolved host name for the remote IP address maps back to the
|
||||
very same IP address.
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm VersionAddendum
|
||||
Specifies a string to append to the regular version string to identify
|
||||
OS- or site-specific modifications.
|
||||
.It Cm X11DisplayOffset
|
||||
Specifies the first display number available for
|
||||
.Nm sshd Ns 's
|
||||
|
@ -40,12 +40,8 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshlogin.c,v 1.3 2001/12/19 07:18:56 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <libutil.h>
|
||||
#include <utmp.h>
|
||||
#include "sshlogin.h"
|
||||
#include "log.h"
|
||||
#include "loginrec.h"
|
||||
|
||||
/*
|
||||
* Returns the time when the user last logged in. Returns 0 if the
|
||||
@ -57,27 +53,11 @@ u_long
|
||||
get_last_login_time(uid_t uid, const char *logname,
|
||||
char *buf, u_int bufsize)
|
||||
{
|
||||
struct lastlog ll;
|
||||
char *lastlog;
|
||||
int fd;
|
||||
struct logininfo li;
|
||||
|
||||
lastlog = _PATH_LASTLOG;
|
||||
buf[0] = '\0';
|
||||
|
||||
fd = open(lastlog, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
|
||||
if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
if (bufsize > sizeof(ll.ll_host) + 1)
|
||||
bufsize = sizeof(ll.ll_host) + 1;
|
||||
strncpy(buf, ll.ll_host, bufsize - 1);
|
||||
buf[bufsize - 1] = 0;
|
||||
return ll.ll_time;
|
||||
login_get_lastlog(&li, uid);
|
||||
strlcpy(buf, li.hostname, bufsize);
|
||||
return li.tv_sec;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -89,49 +69,36 @@ void
|
||||
record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
|
||||
const char *host, struct sockaddr * addr)
|
||||
{
|
||||
int fd;
|
||||
struct lastlog ll;
|
||||
char *lastlog;
|
||||
struct utmp u;
|
||||
struct logininfo *li;
|
||||
|
||||
/* Construct an utmp/wtmp entry. */
|
||||
memset(&u, 0, sizeof(u));
|
||||
strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
|
||||
u.ut_time = time(NULL);
|
||||
strncpy(u.ut_name, user, sizeof(u.ut_name));
|
||||
strncpy(u.ut_host, host, sizeof(u.ut_host));
|
||||
|
||||
login(&u);
|
||||
lastlog = _PATH_LASTLOG;
|
||||
|
||||
/* Update lastlog unless actually recording a logout. */
|
||||
if (strcmp(user, "") != 0) {
|
||||
/*
|
||||
* It is safer to bzero the lastlog structure first because
|
||||
* some systems might have some extra fields in it (e.g. SGI)
|
||||
*/
|
||||
memset(&ll, 0, sizeof(ll));
|
||||
|
||||
/* Update lastlog. */
|
||||
ll.ll_time = time(NULL);
|
||||
strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line));
|
||||
strncpy(ll.ll_host, host, sizeof(ll.ll_host));
|
||||
fd = open(lastlog, O_RDWR);
|
||||
if (fd >= 0) {
|
||||
lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
|
||||
if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
|
||||
log("Could not write %.100s: %.100s", lastlog, strerror(errno));
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
li = login_alloc_entry(pid, user, host, ttyname);
|
||||
login_set_addr(li, addr, sizeof(struct sockaddr));
|
||||
login_login(li);
|
||||
login_free_entry(li);
|
||||
}
|
||||
|
||||
#ifdef LOGIN_NEEDS_UTMPX
|
||||
void
|
||||
record_utmp_only(pid_t pid, const char *ttyname, const char *user,
|
||||
const char *host, struct sockaddr * addr)
|
||||
{
|
||||
struct logininfo *li;
|
||||
|
||||
li = login_alloc_entry(pid, user, host, ttyname);
|
||||
login_set_addr(li, addr, sizeof(struct sockaddr));
|
||||
login_utmp_only(li);
|
||||
login_free_entry(li);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Records that the user has logged out. */
|
||||
|
||||
void
|
||||
record_logout(pid_t pid, const char *ttyname)
|
||||
record_logout(pid_t pid, const char *ttyname, const char *user)
|
||||
{
|
||||
const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */
|
||||
if (logout(line))
|
||||
logwtmp(line, "", "");
|
||||
struct logininfo *li;
|
||||
|
||||
li = login_alloc_entry(pid, user, NULL, ttyname);
|
||||
login_logout(li);
|
||||
login_free_entry(li);
|
||||
}
|
||||
|
@ -13,17 +13,27 @@
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshpty.c,v 1.4 2001/12/19 07:18:56 deraadt Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <libutil.h>
|
||||
#ifdef HAVE_UTIL_H
|
||||
# include <util.h>
|
||||
#endif /* HAVE_UTIL_H */
|
||||
|
||||
#include "sshpty.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
|
||||
/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */
|
||||
#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY)
|
||||
#undef HAVE_DEV_PTMX
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTY_H
|
||||
# include <pty.h>
|
||||
#endif
|
||||
#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H)
|
||||
# include <sys/stropts.h>
|
||||
#endif
|
||||
|
||||
#ifndef O_NOCTTY
|
||||
#define O_NOCTTY 0
|
||||
#endif
|
||||
@ -40,15 +50,19 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
{
|
||||
#if defined(HAVE_OPENPTY) || defined(BSD4_4)
|
||||
/* openpty(3) exists in OSF/1 and some other os'es */
|
||||
char buf[64];
|
||||
char *name;
|
||||
int i;
|
||||
|
||||
i = openpty(ptyfd, ttyfd, buf, NULL, NULL);
|
||||
i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
|
||||
if (i < 0) {
|
||||
error("openpty: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
strlcpy(namebuf, buf, namebuflen); /* possible truncation */
|
||||
name = ttyname(*ttyfd);
|
||||
if (!name)
|
||||
fatal("openpty returns device for which ttyname fails.");
|
||||
|
||||
strlcpy(namebuf, name, namebuflen); /* possible truncation */
|
||||
return 1;
|
||||
#else /* HAVE_OPENPTY */
|
||||
#ifdef HAVE__GETPTY
|
||||
@ -73,23 +87,26 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
}
|
||||
return 1;
|
||||
#else /* HAVE__GETPTY */
|
||||
#ifdef HAVE_DEV_PTMX
|
||||
#if defined(HAVE_DEV_PTMX)
|
||||
/*
|
||||
* This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3
|
||||
* also has bsd-style ptys, but they simply do not work.)
|
||||
*/
|
||||
int ptm;
|
||||
char *pts;
|
||||
mysig_t old_signal;
|
||||
|
||||
ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
|
||||
if (ptm < 0) {
|
||||
error("/dev/ptmx: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
old_signal = mysignal(SIGCHLD, SIG_DFL);
|
||||
if (grantpt(ptm) < 0) {
|
||||
error("grantpt: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
mysignal(SIGCHLD, old_signal);
|
||||
if (unlockpt(ptm) < 0) {
|
||||
error("unlockpt: %.100s", strerror(errno));
|
||||
return 0;
|
||||
@ -107,13 +124,20 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
/* Push the appropriate streams modules, as described in Solaris pts(7). */
|
||||
#ifndef HAVE_CYGWIN
|
||||
/*
|
||||
* Push the appropriate streams modules, as described in Solaris pts(7).
|
||||
* HP-UX pts(7) doesn't have ttcompat module.
|
||||
*/
|
||||
if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
|
||||
error("ioctl I_PUSH ptem: %.100s", strerror(errno));
|
||||
if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)
|
||||
error("ioctl I_PUSH ldterm: %.100s", strerror(errno));
|
||||
#ifndef __hpux
|
||||
if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)
|
||||
error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));
|
||||
#endif
|
||||
#endif
|
||||
return 1;
|
||||
#else /* HAVE_DEV_PTMX */
|
||||
#ifdef HAVE_DEV_PTS_AND_PTC
|
||||
@ -138,25 +162,27 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
}
|
||||
return 1;
|
||||
#else /* HAVE_DEV_PTS_AND_PTC */
|
||||
/* BSD-style pty code. */
|
||||
#ifdef _CRAY
|
||||
char buf[64];
|
||||
int i;
|
||||
const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
const char *ptyminors = "0123456789abcdef";
|
||||
int num_minors = strlen(ptyminors);
|
||||
int num_ptys = strlen(ptymajors) * num_minors;
|
||||
int highpty;
|
||||
|
||||
for (i = 0; i < num_ptys; i++) {
|
||||
snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
|
||||
ptyminors[i % num_minors]);
|
||||
*ptyfd = open(buf, O_RDWR | O_NOCTTY);
|
||||
#ifdef _SC_CRAY_NPTY
|
||||
highpty = sysconf(_SC_CRAY_NPTY);
|
||||
if (highpty == -1)
|
||||
highpty = 128;
|
||||
#else
|
||||
highpty = 128;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < highpty; i++) {
|
||||
snprintf(buf, sizeof(buf), "/dev/pty/%03d", i);
|
||||
*ptyfd = open(buf, O_RDWR|O_NOCTTY);
|
||||
if (*ptyfd < 0)
|
||||
continue;
|
||||
snprintf(namebuf, namebuflen, "/dev/tty%c%c",
|
||||
ptymajors[i / num_minors], ptyminors[i % num_minors]);
|
||||
|
||||
snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i);
|
||||
/* Open the slave side. */
|
||||
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
|
||||
*ttyfd = open(namebuf, O_RDWR|O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("%.100s: %.100s", namebuf, strerror(errno));
|
||||
close(*ptyfd);
|
||||
@ -165,6 +191,56 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
/* BSD-style pty code. */
|
||||
char buf[64];
|
||||
int i;
|
||||
const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
const char *ptyminors = "0123456789abcdef";
|
||||
int num_minors = strlen(ptyminors);
|
||||
int num_ptys = strlen(ptymajors) * num_minors;
|
||||
struct termios tio;
|
||||
|
||||
for (i = 0; i < num_ptys; i++) {
|
||||
snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
|
||||
ptyminors[i % num_minors]);
|
||||
snprintf(namebuf, namebuflen, "/dev/tty%c%c",
|
||||
ptymajors[i / num_minors], ptyminors[i % num_minors]);
|
||||
|
||||
*ptyfd = open(buf, O_RDWR | O_NOCTTY);
|
||||
if (*ptyfd < 0) {
|
||||
/* Try SCO style naming */
|
||||
snprintf(buf, sizeof buf, "/dev/ptyp%d", i);
|
||||
snprintf(namebuf, namebuflen, "/dev/ttyp%d", i);
|
||||
*ptyfd = open(buf, O_RDWR | O_NOCTTY);
|
||||
if (*ptyfd < 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Open the slave side. */
|
||||
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("%.100s: %.100s", namebuf, strerror(errno));
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
/* set tty modes to a sane state for broken clients */
|
||||
if (tcgetattr(*ptyfd, &tio) < 0)
|
||||
log("Getting tty modes for pty failed: %.100s", strerror(errno));
|
||||
else {
|
||||
tio.c_lflag |= (ECHO | ISIG | ICANON);
|
||||
tio.c_oflag |= (OPOST | ONLCR);
|
||||
tio.c_iflag |= ICRNL;
|
||||
|
||||
/* Set the new modes for the terminal. */
|
||||
if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0)
|
||||
log("Setting tty modes for pty failed: %.100s", strerror(errno));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#endif /* CRAY */
|
||||
#endif /* HAVE_DEV_PTS_AND_PTC */
|
||||
#endif /* HAVE_DEV_PTMX */
|
||||
#endif /* HAVE__GETPTY */
|
||||
@ -188,6 +264,33 @@ void
|
||||
pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
{
|
||||
int fd;
|
||||
#ifdef USE_VHANGUP
|
||||
void *old;
|
||||
#endif /* USE_VHANGUP */
|
||||
|
||||
#ifdef _CRAY
|
||||
if (setsid() < 0)
|
||||
error("setsid: %.100s", strerror(errno));
|
||||
|
||||
fd = open(ttyname, O_RDWR|O_NOCTTY);
|
||||
if (fd != -1) {
|
||||
mysignal(SIGHUP, SIG_IGN);
|
||||
ioctl(fd, TCVHUP, (char *)NULL);
|
||||
mysignal(SIGHUP, SIG_DFL);
|
||||
setpgid(0, 0);
|
||||
close(fd);
|
||||
} else {
|
||||
error("Failed to disconnect from controlling tty.");
|
||||
}
|
||||
|
||||
debug("Setting controlling tty using TCSETCTTY.");
|
||||
ioctl(*ttyfd, TCSETCTTY, NULL);
|
||||
fd = open("/dev/tty", O_RDWR);
|
||||
if (fd < 0)
|
||||
error("%.100s: %.100s", ttyname, strerror(errno));
|
||||
close(*ttyfd);
|
||||
*ttyfd = fd;
|
||||
#else /* _CRAY */
|
||||
|
||||
/* First disconnect from the old controlling tty. */
|
||||
#ifdef TIOCNOTTY
|
||||
@ -215,12 +318,26 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0)
|
||||
error("ioctl(TIOCSCTTY): %.100s", strerror(errno));
|
||||
#endif /* TIOCSCTTY */
|
||||
#ifdef HAVE_NEWS4
|
||||
if (setpgrp(0,0) < 0)
|
||||
error("SETPGRP %s",strerror(errno));
|
||||
#endif /* HAVE_NEWS4 */
|
||||
#ifdef USE_VHANGUP
|
||||
old = mysignal(SIGHUP, SIG_IGN);
|
||||
vhangup();
|
||||
mysignal(SIGHUP, old);
|
||||
#endif /* USE_VHANGUP */
|
||||
fd = open(ttyname, O_RDWR);
|
||||
if (fd < 0)
|
||||
if (fd < 0) {
|
||||
error("%.100s: %.100s", ttyname, strerror(errno));
|
||||
else
|
||||
} else {
|
||||
#ifdef USE_VHANGUP
|
||||
close(*ttyfd);
|
||||
*ttyfd = fd;
|
||||
#else /* USE_VHANGUP */
|
||||
close(fd);
|
||||
|
||||
#endif /* USE_VHANGUP */
|
||||
}
|
||||
/* Verify that we now have a controlling tty. */
|
||||
fd = open(_PATH_TTY, O_WRONLY);
|
||||
if (fd < 0)
|
||||
@ -229,6 +346,7 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
else {
|
||||
close(fd);
|
||||
}
|
||||
#endif /* _CRAY */
|
||||
}
|
||||
|
||||
/* Changes the window size associated with the pty. */
|
||||
|
@ -1,12 +1,4 @@
|
||||
/* $OpenBSD: version.h,v 1.33 2002/06/21 15:41:20 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef SSH_VERSION
|
||||
#define SSH_VERSION "OpenSSH_3.3"
|
||||
|
||||
#define SSH_VERSION (ssh_version_get())
|
||||
#define SSH_VERSION_BASE "OpenSSH_3.3"
|
||||
#define SSH_VERSION_ADDENDUM "FreeBSD-20020623"
|
||||
|
||||
const char *ssh_version_get(void);
|
||||
void ssh_version_set_addendum(const char *add);
|
||||
#endif /* SSH_VERSION */
|
||||
|
Loading…
Reference in New Issue
Block a user