Forcibly revert to mainline.

This commit is contained in:
Dag-Erling Smørgrav 2002-06-27 22:42:11 +00:00
parent f4df40b218
commit 989dd127e4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=98941
81 changed files with 1727 additions and 2549 deletions

View File

@ -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$

View File

@ -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>

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */
}

View File

@ -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"

View File

@ -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>

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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);

View File

@ -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>

View File

@ -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! @");

View 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

View File

@ -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)

View File

@ -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)

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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;
}

View File

@ -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 */

View File

@ -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"

View File

@ -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.

View File

@ -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"

View File

@ -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 */

View File

@ -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>

View File

@ -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>

View File

@ -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]);
}

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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>

View File

@ -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 */

View File

@ -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)

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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);
}

View File

@ -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);

View File

@ -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>

View File

@ -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);

View File

@ -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 *);

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -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}

View File

@ -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}

View File

@ -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. */

View File

@ -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}

View File

@ -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);

View File

@ -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}

View File

@ -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}

View File

@ -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)

View File

@ -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}

View File

@ -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}

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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. */

View File

@ -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 */