1.29
date 95.06.27.02.20.33; author p-pomes; state Exp;
branches;
next 1.28;
1.28
date 95.06.26.19.58.14; author p-pomes; state Exp;
branches;
next 1.27;
1.27
date 95.06.23.19.26.57; author p-pomes; state Exp;
branches;
next 1.26;
1.26
date 95.06.23.12.58.03; author p-pomes; state Exp;
branches;
next 1.25;
1.25
date 95.06.23.02.52.53; author p-pomes; state Exp;
branches;
next 1.24;
1.24
date 95.06.10.04.04.53; author p-pomes; state Exp;
branches;
next 1.23;
1.23
date 95.06.09.23.16.49; author p-pomes; state Exp;
branches;
next 1.22;
1.22
date 95.06.09.17.44.38; author p-pomes; state Exp;
branches;
next 1.21;
1.21
date 95.06.08.21.53.41; author p-pomes; state Exp;
branches;
next 1.20;
1.20
date 95.06.08.21.19.58; author p-pomes; state Exp;
branches;
next 1.19;
1.19
date 95.06.07.19.17.56; author p-pomes; state Exp;
branches;
next 1.18;
1.18
date 95.03.03.01.06.25; author p-pomes; state Exp;
branches;
next 1.17;
1.17
date 95.03.01.20.34.11; author p-pomes; state Exp;
branches;
next 1.16;
1.16
date 95.03.01.20.09.29; author p-pomes; state Exp;
branches;
next 1.15;
1.15
date 95.02.22.02.57.51; author p-pomes; state Exp;
branches;
next 1.14;
1.14
date 94.11.18.16.03.13; author p-pomes; state Exp;
branches;
next 1.13;
1.13
date 94.09.09.20.13.11; author p-pomes; state Exp;
branches;
next 1.12;
1.12
date 94.08.18.16.21.22; author p-pomes; state Exp;
branches;
next 1.11;
1.11
date 94.05.05.21.09.05; author paul; state Exp;
branches;
next 1.10;
1.10
date 94.05.05.20.45.26; author paul; state Exp;
branches;
next 1.9;
1.9
date 94.05.05.20.39.00; author paul; state Exp;
branches;
next 1.8;
1.8
date 94.03.12.04.27.19; author paul; state Exp;
branches;
next 1.7;
1.7
date 94.03.11.22.45.56; author paul; state Exp;
branches;
next 1.6;
1.6
date 94.03.06.21.48.56; author paul; state Exp;
branches;
next 1.5;
1.5
date 94.01.05.15.50.17; author paul; state Exp;
branches;
next 1.4;
1.4
date 93.12.21.21.42.43; author paul; state Exp;
branches;
next 1.3;
1.3
date 93.12.19.18.41.33; author paul; state Exp;
branches;
next 1.2;
1.2
date 93.12.16.23.00.52; author paul; state Exp;
branches;
next 1.1;
1.1
date 93.11.24.22.32.24; author paul; state Exp;
branches;
next ;
desc
@@
1.29
log
@bug fixes.
@
text
@/*
* Copyright (c) 1985 Corporation for Research and Educational Networking
* Copyright (c) 1988 University of Illinois Board of Trustees, Steven
* Dorner, and Paul Pomes
* 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 Corporation for
* Research and Educational Networking (CREN), the University of
* Illinois at Urbana, and their contributors.
* 4. Neither the name of CREN, 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 TRUSTEES 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 TRUSTEES 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.
*/
/*
* Login and Logout functions, using the many flavors of password
* protocols (original recipe, Kerberos, email etc.)
*
*
* LoginQi - Login to QI server, optionally prompting for username/password.
*
* Parameters:
* UseHost - name of Qi server host
* ToQI - stream descriptor to write to
* FromQI - stream descriptor to read from
* Options - see qiapi.h/LQ_* defines
* Username - pointer to name to login as (alias) or NULL
* Password - pointer to password or NULL
*
* Returns:
* alias logged in as or NULL.
*
* Side Effects:
* possibly obtains and caches Kerberos tickets.
* username/password prompts are written/read to/from stdin/out,
* iff Options&LQ_INTERACTIVE.
*
* (most of this code lifted out of ph 6.5)
*/
/*
* try each kind of login protocol in turn 'til one succeeds or we run
* out of choices. To avoid reprompting for Username or Password, it
* is the responsiblity of each routine to malloc up the result of
* obtaining the username/password, and the responsibility of this
* routine to clean them up -- unless they were passed in from caller of
* course.
*/
char *
LoginQi(UseHost, ToQI, FromQI, Options, Username, Password)
const char *UseHost;
FILE *ToQI, *FromQI;
int Options;
const char *Username, *Password;
{
char *U = (char *) Username, *P = (char *) Password;
static char MyAlias[MAXSTR];
int LoggedIn, code;
char *pnt;
case LQ_PASSWORD:
if (Options & LQ_PASSWORD &&
LoginOriginal(UseHost, ToQI, FromQI, Options, MyAlias, &U, &P) == LR_OK)
LoggedIn++;
break;
case LQ_EMAIL:
if (Options & LQ_EMAIL &&
LoginEmail(UseHost, ToQI, FromQI, Options, MyAlias, &U, &P) == LR_OK)
LoggedIn++;
break;
case LQ_CLEAR:
break;
default:
syslog(LOG_ERR, "LoginQi:Unknown authentication method %d ignored", code);
fprintf(stderr, "LoginQi:Unknown authentication method %d ignored\n", code);
break;
}
pnt = strchr(pnt, ':');
if (pnt && *pnt)
pnt++;
}
if (!Username && U) /* username was not passed in */
free(U); /* so free malloc'd string */
if (!Password && P) { /* ditto for password */
memset(P, 0, strlen(P));
free(P);
}
fputs(MsgBuf, stdout);
return ((*MyAlias) ? MyAlias : NULL);
}
/*
* Original recipe login, based on shared secret (password) between QI
* server and user. If autologin is selected, .netrc is tried first.
* If LoginQiEmailAuth is true, then email auth is attempted.
*/
static int LoginQiEmailAuth = 0; /* a dirty little secret */
static int
LoginOriginal(UseHost, ToQI, FromQI, Options, MyAlias, Up, Pp)
const char *UseHost;
FILE *ToQI, *FromQI;
int Options;
char *MyAlias, **Up, **Pp;
{
int code;
char *pnt, scratch[MAXSTR];
/*
* If LQ_AUTO option selection and a username is not supplied,
* try getting the login info from .netrc
*/
if (Options & LQ_AUTO && !*Up) { /* try autologin w/.netrc */
GetAutoLogin(Up, Pp);
if (QiAuthDebug)
fprintf(stderr, "autologin: .netrc user=%s, pass=%s\n",
(*Up) ? *Up : "(none)", (*Pp) ? *Pp : "(none)");
}
if (!*Up) { /* username not supplied */
if (!(Options & LQ_INTERACTIVE)) /* sorry, I can't ask you. */
return (LR_ERROR);
printf(NAMEPROMPT); /* ask for missing alias */
fgets(scratch, sizeof (scratch), stdin);
scratch[strlen(scratch) - 1] = '\0'; /* zap the \n */
if (!*scratch)
return (LR_ERROR);
*Up = strdup(scratch);
}
if (*Pp && **Pp == '\0')
*Pp = NULL;
if (!*Pp && !LoginQiEmailAuth && !(Options & LQ_INTERACTIVE))
return (LR_ERROR); /* I can't ask your password */
if (QiAuthDebug)
fprintf(stderr, "sent=login %s\n", *Up); /*send login request */
if (fprintf(ToQI, "login %s\n", *Up) == EOF) {
syslog(LOG_ERR, "LoginOriginal: fprintf: %m");
fprintf(stderr, "LoginOriginal: Whoops--the nameserver died.\n");
return LR_ERROR;
}
fflush(ToQI);
for (;;) { /*read the response */
if (!GetGood(MsgBuf, MAXSTR, FromQI)) {
fprintf(stderr, "LoginOriginal: Whoops--the nameserver died.\n");
return LR_ERROR;
}
code = atoi(MsgBuf);
/* intermediate or strange response */
if (code != LR_LOGIN && code != LR_XLOGIN)
fputs(MsgBuf, stdout);
if (code >= LR_OK) /*final response */
break;
}
if (code == LR_LOGIN || code == LR_XLOGIN) {
if (LoginQiEmailAuth) { /* try email login */
pnt = getpwuid(getuid())->pw_name;
if (QiAuthDebug)
fprintf(stderr, "sent=email %s\n", pnt);
fprintf(ToQI, "email %s\n", pnt);
}
else
{
if (!*Pp) { /* password not supplied */
char *newp;
while (*cp)
*cp++ = '\0'; /* null out *all* the extras */
}
#ifdef PRE_ENCRYPT
crypt_start(crypt(*Pp,*Pp));
#else
crypt_start(*Pp);
#endif
/*encrypt the challenge with the password */
MsgBuf[strlen(MsgBuf) - 1] = '\0'; /*strip linefeed */
scratch[encryptit(scratch, (char *) strchr(MsgBuf, ':') + 1)] = '\0';
/*send the encrypted text to qi */
if (QiAuthDebug)
fprintf(stderr, "sent=answer %s\n", scratch);
fprintf(ToQI, "answer %s\n", scratch);
}
}
fflush(ToQI);
/*get the final response */
for (;;) {
if (!GetGood(MsgBuf, MAXSTR, FromQI)) {
fprintf(stderr, "LoginOriginal: Whoops--the nameserver died.\n");
return LR_ERROR;
}
code = atoi(MsgBuf);
if (code >= LR_OK) /*final response */
break;
}
if (code == LR_OK) { /*logged in */
strcpy(MyAlias, (char *) strchr(MsgBuf, ':') + 1);
*(char *) strchr(MyAlias, ':') = '\0';
}
else
*MyAlias = '\0';
return (code);
}
/*
* check .netrc to for username and password to try to login with.
*/
static void
GetAutoLogin(alias, pw)
char **alias, **pw; /* filled in from .netrc */
{
FILE *netrc; /*the .netrc file */
char path[1024]; /*pathname of .netrc file */
struct stat statbuf; /*permissions, etc. of .netrc file */
char key[80], val[80]; /*line from the .netrc file */
char *token; /*token (word) from the line from the .netrc file */
/*
* manufacture the pathname of the user's .netrc file
*/
sprintf(path, "%s/.netrc", getenv("HOME"));
/*
* make sure its permissions are ok
*/
if (stat(path, &statbuf) < 0)
return;
if (statbuf.st_mode & 077)
return; /*refuse insecure files */
/*
* try to open it
*/
if (!(netrc = fopen(path, "r")))
return;
/*
* look for a ``machine'' named ``ph''
*/
while (2 == fscanf(netrc, "%s %s", key, val)) {
if (!strcmp(key, "machine") && !strcmp(val, CLIENT)) {
/*
* found an entry for ph. look now for other items
*/
while (2 == fscanf(netrc, "%s %s", key, val)) {
if (!strcmp(key, "machine")) /*new machine */
goto out;
else if (!strcmp(key, "login"))
*alias = strdup(val);
else if (!strcmp(key, "password"))
*pw = strdup(val);
else if (!strcmp(key, "macdef"))
SkipMacdef(netrc);
}
}
else if (!strcmp(key, "macdef"))
SkipMacdef(netrc);
}
out:
return;
}
/*
* skip a macdef in the .netrc file
*/
static void
SkipMacdef(netrc)
FILE *netrc;
{
int c, wasNl;
for (wasNl = 0; (c = getc(netrc)) != EOF; wasNl = (c == '\n'))
if (wasNl && c == '\n')
break;
}
#ifdef FWTK_AUTH
/*
* Use the authentication server from the TIS Firewall Toolkit. Properly
* built it provides SNK/4, SecureId, S/Key, and other methods.
*/
static int
LoginFwtk(UseHost, ToQI, FromQI, Options, MyAlias, Up, Pp)
const char *UseHost;
FILE *ToQI, *FromQI;
int Options;
char *MyAlias, **Up, **Pp;
{
int code;
char *pnt, *newp;
char scratch[MAXSTR];
/* if LQ_AUTO option selection and a username is not supplied,
* try getting the login info from .netrc
*/
if (!(Options & LQ_INTERACTIVE)) /* only interactive use is possible */
return (LR_ERROR);
if (!*Up) { /* username not supplied */
printf(NAMEPROMPT); /* ask for missing alias */
fgets(scratch, sizeof (scratch), stdin);
scratch[strlen(scratch) - 1] = '\0'; /* zap the \n */
if (!*scratch)
return (LR_ERROR);
*Up = strdup(scratch);
}
if (QiAuthDebug)
fprintf(stderr, "sent=xlogin %d %s\n", LQ_FWTK, *Up);
if (fprintf(ToQI, "xlogin %d %s\n", LQ_FWTK, *Up) == EOF) {
syslog(LOG_ERR, "LoginFwtk: fprintf: %m");
fprintf(stderr, "LoginFwtk: Whoops--the nameserver died.\n");
return LR_ERROR;
}
fflush(ToQI);
for (;;) { /*read the response */
if (!GetGood(MsgBuf, MAXSTR, FromQI)) {
fprintf(stderr, "LoginFwtk: Whoops--the nameserver died.\n");
return LR_ERROR;
}
code = atoi(MsgBuf);
/* intermediate or strange response */
if (code != LR_LOGIN && code != LR_XLOGIN)
fputs(MsgBuf, stdout);
if (code >= LR_OK) /*final response */
break;
}
/*
* Ignore passed in password because SNK/4, SecureId, S/Key all require
* a password calculated from a challenge. Well, that's not exactly
* true with S/Key, however S/Key doesn't use reuseable passwords.
*/
if (code == LR_XLOGIN) {
if ((pnt = strchr(MsgBuf, '\n')) != NULL)
*pnt = '\0';
pnt = strchr(MsgBuf, ':') + 1;
}
else
pnt = PASSPROMPT;
newp = getpass(pnt);
/* send the response to qi */
if (QiAuthDebug)
fprintf(stderr, "sent=answer %s\n", newp);
fprintf(ToQI, "answer %s\n", newp);
fflush(ToQI);
/*get the final response */
for (;;) {
if (!GetGood(MsgBuf, MAXSTR, FromQI)) {
fprintf(stderr, "LoginFwtk: Whoops--the nameserver died.\n");
return LR_ERROR;
}
code = atoi(MsgBuf);
if (code >= LR_OK) /*final response */
break;
}
/* find out who I am */
namelen = sizeof (lsin);
if (getsockname(sock, (struct sockaddr *) &lsin, &namelen) < 0) {
return (LR_ERROR);
}
/* find out who the other side is */
namelen = sizeof (sin);
if (getpeername(sock, (struct sockaddr *) &sin, &namelen) < 0) {
return (LR_ERROR);
}
/*
* Did the user specify a username? Has autologin been requested?
* If not, and if we're not logged in to Kerberos, prompt for one.
*/
if (!*Up) {
struct stat dummy;
if (!(Options & LQ_AUTO)) /* no user, no autologin */
return (LR_ERROR); /* no deal */
if (stat(TKT_FILE, &dummy)) { /* no ticket cache */
if (!(Options & LQ_INTERACTIVE)) /* can't ask */
return (LR_ERROR);
printf(NAMEPROMPT);
fgets(scratch, sizeof (scratch), stdin);
if (!*scratch)
return (LR_ERROR);
else {
/* zap newline */
scratch[strlen(scratch) - 1] = 0;
*Up = strdup(scratch);
}
}
}
/* If we're not already logged in with Kerberos then do so (get a TGT).
* (NULL username at this point implies we already have a TGT).
*/
if (*Up) {
if ((pnt = strchr(*Up, '/')) != NULL)
*pnt = '.'; /* convert V5 principal/instance to V4 format */
retval = kname_parse(principal, instance, realm, *Up);
if (pnt && *pnt)
*pnt = '/';
if (retval != KSUCCESS) {
fprintf(stderr, "LoginKrb4: %s\n", krb_err_txt[retval]);
return LR_ERROR;
}
if (!*realm && krb_get_lrealm(realm, 1)) {
fprintf(stderr, "LoginKrb4: Unable to get realm.\n");
return LR_ERROR;
}
/* set tkt file we'll use */
strcpy(okrbtkfile, TKT_FILE);
sprintf(krbtkfile, "/tmp/tkt_ph4_%d", getpid());
krb_set_tkt_string(krbtkfile);
if (*Pp && **Pp == '\0')
*Pp = NULL;
if (!*Pp) { /* no password supplied */
if (!(Options & LQ_INTERACTIVE)) /* I can't ask */
return LR_ERROR;
/* Read principal name from ticket cache if needed */
if (!*principal) {
if ((retval = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS) {
syslog(LOG_ERR, "LoginKrb4: tf_init(%s): %s",
TKT_FILE, krb_err_txt[retval]);
fprintf(stderr, "LoginKrb4: tf_init(%s): %s",
TKT_FILE, krb_err_txt[retval]);
return LR_ERROR;
}
if ((retval = tf_get_pname(principal)) != KSUCCESS) {
syslog(LOG_ERR, "LoginKrb4: tf_get_pname(): %s",
krb_err_txt[retval]);
fprintf(stderr, "LoginKrb4: tf_get_pname(): %s",
krb_err_txt[retval]);
return LR_ERROR;
}
}
if (QiAuthDebug)
fprintf(stderr, "sent=xlogin %d %s\n", LQ_KRB4, principal);
if (fprintf(ToQI, "xlogin %d %s\n", LQ_KRB4, principal) == EOF) {
syslog(LOG_ERR, "LoginKrb4: fprintf: %m");
fprintf(stderr, "LoginKrb4: Whoops--the nameserver died.\n");
return LR_ERROR;
}
fflush(ToQI);
for (;;) { /* read the response */
if (!GetGood(MsgBuf, MAXSTR, FromQI)) {
fprintf(stderr, "LoginKrb4: Whoops--the nameserver died.\n");
if (*Up)
dest_tkt(); /* destroy temp tickets for
* specified username */
return (LR_ERROR);
}
code = atoi(MsgBuf);
/* intermediate or strange response */
if (code != LR_LOGIN && code != LR_XLOGIN)
fputs(MsgBuf, stdout);
if (code >= LR_OK) /* final response */
break;
}
if (code == LR_LOGIN || code == LR_XLOGIN) {
/*
* call Kerberos library routine to obtain an authenticator,
* pass it over the socket to the server, and obtain mutual
* authentication.
*/
#ifdef KRBNSREALM
hrealm = KRBNSREALM;
#else
hrealm = krb_realmofhost(UseHost);
#endif
authopts = KOPT_DO_MUTUAL;
retval = krb_sendauth(authopts, sock, &ticket,
KRB4SRV, SrvHost, hrealm,
0, &msg_data, &cred,
sched, &lsin, &sin, "VERSION9");
if (QiAuthDebug)
fprintf(stderr, "%s doing V4 Kerberos mutual authentication of %s.%s@@%s with %s.%s@@%s\n",
(retval == KSUCCESS) ? "Success" : "Failure",
cred.pname, (*cred.pinst) ? cred.pinst : "(nil)", cred.realm,
KRB4SRV, SrvHost, hrealm);
if (*Up) /* ???? */
dest_tkt(); /* destroy special tickets as soon as
* possible */
/* get the final response (even if mutual failed) */
for (;;) {
if (!GetGood(MsgBuf, MAXSTR, FromQI)) {
fprintf(stderr, "LoginKrb4: Whoops--the nameserver died.\n");
return LR_ERROR;
}
code = atoi(MsgBuf);
if (code >= LR_OK) /* final response */
break;
}
/*
* Strategy: determine if ticket cache exists. If it does and the
* tickets are valid, use them to log in. If ticket cache doesn't
* exist, create a temporary cache, prompt for username and password if
* need be, and send Kerberos authentication.
*/
/*
* If user has previously done a kinit, then krb5_cc_get_principal()
* will succeed. The ticket obtained may have timed out so be prepared
* to handle that after krb5_get_credentials().
*/
if (retval = krb5_cc_get_principal(cache, &my_creds.client)) {
if (*Pp && **Pp == '\0')
*Pp = NULL;
if (!*Pp) { /* no password supplied */
if (!(Options & LQ_INTERACTIVE)) { /* I can't ask */
krb5_free_principal(my_creds.server);
krb5_free_principal(me);
krb5_free_addresses(my_addresses);
return LR_ERROR;
}
if (krb5_read_password("Enter Kerberos password: ", 0,
kpass, &kpasslen) != 0) {
fprintf(stderr, "Unable to read password.\n");
krb5_free_principal(my_creds.server);
krb5_free_principal(me);
krb5_free_addresses(my_addresses);
return LR_ERROR;
}
if (*kpass)
*Pp = strdup(kpass);
memset(kpass, 0, sizeof(kpass));
(void) sprintf(kpass, "%d", my_creds.times.endtime);
}
/* Iterate through the pre-auth methods until we succeed or fail */
for (i=0; preauth_search_list[i] >= 0; i++) {
retval = krb5_get_in_tkt_with_password(options, my_addresses,
preauth_search_list[i],
ETYPE_DES_CBC_CRC,
KEYTYPE_DES,
(*Pp == NULL || **Pp == '\0') ? kpass : *Pp,
cache,
&my_creds, 0);
if (retval != KRB5KDC_ERR_PREAUTH_FAILED &&
code != KRB5KRB_ERR_GENERIC)
break;
}
if (!QiAuthDebug)
(void) krb5_cc_destroy(cache);
cache = NULL;
krb5_free_addresses(my_addresses);
if (QiAuthDebug) {
fprintf(stderr, "%s obtaining V5 Kerberos ticket for %s to use %s.\n",
(retval == 0) ? "Success" : "Failure", pname, cname);
}
if (retval) {
krb5_free_principal(my_creds.server);
krb5_free_principal(me);
if (retval != KRB5KRB_AP_ERR_BAD_INTEGRITY)
fprintf(stderr, "LoginKrb5: krb5_get_in_tkt_with_password(): %s\n",
error_message(retval));
return (LR_ERROR);
}
}
/* Get service ticket from cache or use TGT with KDC */
else if (retval = krb5_get_credentials(0, cache, &my_creds)) {
fprintf(stderr, "LoginKrb5: krb5_get_credentials(): %s\n",
error_message(retval));
krb5_free_principal(my_creds.server);
krb5_free_principal(me);
return (LR_ERROR);
}
for (;;) { /* read the response */
if (!GetGood(MsgBuf, MAXSTR, FromQI)) {
fprintf(stderr, "LoginKrb5: Whoops--the nameserver died.\n");
krb5_free_principal(my_creds.server);
krb5_free_principal(me);
memset ((char*)&my_creds, 0, sizeof(my_creds));
return (LR_ERROR);
}
code = atoi(MsgBuf);
/* intermediate or strange response */
if (code != LR_LOGIN && code != LR_XLOGIN)
fputs(MsgBuf, stdout);
if (code >= LR_OK) /* final response */
break;
}
if (code == LR_LOGIN || code == LR_XLOGIN) {
/*
* call Kerberos library routine to obtain an authenticator,
* pass it over the socket to the server, and obtain mutual
* authentication.
*/
retval = krb5_sendauth((krb5_pointer) &sock,
KQI_VERSION,
my_creds.client,
my_creds.server,
AP_OPTS_MUTUAL_REQUIRED,
0,
&my_creds,
cache,
0, 0, /* don't need seqno or subkey */
&err_ret,
&rep_ret);
if (QiAuthDebug) {
fprintf(stderr, "%s doing V5 Kerberos mutual authentication of %s with %s.\n",
(retval == 0) ? "Success" : "Failure", pname, cname);
}
/* krb5_free_principal(me); */ /* can't do if already had TGT */
krb5_free_principal(my_creds.server);
memset ((char*)&my_creds, 0, sizeof(my_creds));
if (retval && err_ret)
fprintf(stderr, "LoginKrb5: %s\n", error_message(retval));
/* get the final response (even if mutual failed) */
for (;;) {
if (!GetGood(MsgBuf, MAXSTR, FromQI)) {
fprintf(stderr, "LoginKrb5: Whoops--the nameserver died.\n");
return LR_ERROR;
}
code = atoi(MsgBuf);
if (code >= LR_OK) /* final response */
break;
}
/*
* Bean sprout recipe, using Berkeley r-command ingredients.
* (actually just calls LoginOriginal since I stole this code
* out of ph....)
*/
static int
LoginEmail(UseHost, ToQI, FromQI, Options, MyAlias, Up, Pp)
const char *UseHost;
FILE *ToQI, *FromQI;
int Options;
char *MyAlias, **Up, **Pp;
{
int rc;
/*
* LogoutQi - Logout from QI server.
*
* Parameters:
* ToQI - stream descriptor to write to
* FromQI - stream descriptor to read from
*
* Returns:
* success(LR_OK) or failure indication
*
*/
int
LogoutQi(ToQI, FromQI)
FILE *ToQI, *FromQI;
{
QIR *r;
int n;
fprintf(ToQI, "logout\n");
fflush(ToQI);
if ((r = ReadQi(FromQI, &n)) == NULL)
return LR_ERROR;
n = r->code;
/* Accept the memory leak to simplify standalone compilation of ph */
/* FreeQIR(r); */
return n;
}
static int
CheckAuth(ToQI, FromQI)
FILE *ToQI, *FromQI;
{
int code;
char *pnt, sbuf[10], buf[MAXSTR];
/* See if the server has preferences for authentication methods */
if (QiAuthDebug)
fprintf(stderr, "sent=siteinfo\n");
if (fprintf(ToQI, "siteinfo\n") == EOF) {
syslog(LOG_ERR, "LoginQi: fprintf: %m");
fprintf(stderr, "LoginQi: Whoops--the nameserver died.\n");
return LR_ERROR;
}
fflush(ToQI);
for (;;) { /*read the response */
if (!GetGood(MsgBuf, MAXSTR, FromQI)) {
fprintf(stderr, "LoginOriginal: Whoops--the nameserver died.\n");
return LR_ERROR;
}
code = atoi(MsgBuf);
if (pnt = strstr(MsgBuf, "authenticate")) {
/* skip to next ':' */
if (pnt = strchr(pnt, ':')) {
if (pnt && *++pnt)
AuthMethods = strdup(pnt);
}
}
if (code >= LR_OK) /*final response */
break;
}
if (AuthMethods || code != LR_OK)
return (code);
/*
* If siteinfo was uninformative, build our own based on what we were
* compiled with. N.B., ordering here reflects policy of which login
* methods are preferred at each site.
*/
*buf = '\0';
#ifdef KRB5_AUTH
(void) sprintf(sbuf, ":%d", LQ_KRB5);
strcat(buf, sbuf);
#endif /* KRB5_AUTH */
#ifdef KRB4_AUTH
(void) sprintf(sbuf, ":%d", LQ_KRB4);
strcat(buf, sbuf);
#endif /* KRB4_AUTH */
#ifdef GSS_AUTH
(void) sprintf(sbuf, ":%d", LQ_GSS);
strcat(buf, sbuf);
#endif /* GSS_AUTH */
(void) sprintf(sbuf, ":%d", LQ_PASSWORD);
strcat(buf, sbuf);
(void) sprintf(sbuf, ":%d", LQ_EMAIL);
strcat(buf, sbuf);
#ifdef FWTK_AUTH
(void) sprintf(sbuf, ":%d", LQ_FWTK);
strcat(buf, sbuf);
#endif /* FWTK_AUTH */
AuthMethods = strdup(buf+1);
return (LR_OK);
}
/*
* get a non-comment line from a stream
* a comment is a line beginning with a # sign
*/
int
GetGood(str, maxc, fp)
char *str; /*space to put the chars */
int maxc; /*max # of chars we want */
#ifdef VMS
int fp; /*stream to read them from */
{
static char Qbuf[MAXSTR + 4] = {'\0'};
static int pos = {0},
end = {0},
len = {0};
char *linp;
for (;;) {
if (pos >= len) {
len = netread(fp, Qbuf, maxc);
if (len <= 0)
return (0);
Qbuf[len] = '\0';
pos = 0;
}
linp = strchr(Qbuf + pos, '\n'); /*find next newline char */
if (linp == NULL)
end = len; /*no newline chars left */
else
end = linp - Qbuf; /*convert pointer to index */
strncpy(str, Qbuf + pos, end - pos + 1);
*(str + end - pos + 1) = '\0';
pos = end + 1; /*save new position for next time */
if (!*str)
#else
FILE *fp; /*stream to read them from */
{
errno = 0;
for (;;) {
if (!fgets(str, maxc, fp))
#endif
{
fputs("Oops; lost connection to server.\n", stderr);
exit(1);
}
else if (*str != '#') {
if (QiDebug)
fprintf(stderr, "read =%s", str);
return (1); /*not a comment; success! */
}
}
/* NOTREACHED */
}
1.21
log
@For now, this looks like a working V5 version.
@
text
@d38 1
a38 1
static char RcsId[] = "@@(#)$Id: LoginQi.c,v 1.20 1995/06/08 21:19:58 p-pomes Exp p-pomes $";
d700 1
d713 3
a715 1
if (!*Up && !(Options & LQ_INTERACTIVE)) /* can't ask */
d717 1
d721 3
a723 1
if (!*scratch)
d725 1
d737 2
d748 3
d761 3
d774 4
d787 4
d806 4
d817 1
a817 1
if (!(Options & LQ_INTERACTIVE)) /* I can't ask */
d819 1
@
1.20
log
@That paranoid feeling that a check-in would be a good idea.
@
text
@d38 1
a38 1
static char RcsId[] = "@@(#)$Id: LoginQi.c,v 1.19 1995/06/07 19:17:56 p-pomes Exp p-pomes $";
d786 1
a786 1
my_creds.times.endtime = now + (QiAuthDebug) ? 3600 : 60;
@
1.19
log
@Another checkpoint while I recover all the things I was thinking about
last time I looked at this.
@
text
@d38 1
a38 1
static char RcsId[] = "@@(#)$Id: LoginQi.c,v 1.18 1995/03/03 01:06:25 p-pomes Exp p-pomes $";
d106 1
a119 3
#ifndef NSSERVICE
#define NSSERVICE "ns"
#endif
a184 9
case LQ_KRB4:
#if defined(KRB4_AUTH)
if (Options & LQ_KRB4 &&
LoginKrb4(UseHost, ToQI, FromQI, Options, MyAlias, &U, &P)
== LR_OK)
LoggedIn++;
#endif /* KRB4_AUTH */
break;
d202 9
d213 2
a214 2
if (Options & LQ_PASSWORD)
(void) LoginOriginal(UseHost, ToQI, FromQI, Options, MyAlias, &U, &P);
d534 1
a563 1
memset(kpass, 0, sizeof (kpass)); /* paranoia */
d587 1
a587 1
NSSERVICE, UseHost, hrealm,
d591 2
a592 2
fprintf(stderr, "%s doing v4 Kerberos mutual authentication of %s with %s in realm %s.\n",
(retval == KSUCCESS) ? "success" : "failure", NSSERVICE, UseHost, hrealm);
a612 1
memset(kpass, 0, sizeof (kpass)); /* Don't need to fall thru */
d624 17
d652 1
d655 7
a661 3
krb5_ccache occ, cc;
krb5_creds creds;
krb5_data rdata;
d663 1
a663 1
int options = KRB5_DEFAULT_OPTIONS;
d667 1
a667 1
if (retval = krb5_cc_default(&cc)) {
d675 9
a683 1
memset ((char*)&creds, 0, sizeof(creds));
d686 1
a686 1
* Strategy: determine in ticket cache exists. If it does and the
d688 1
a688 2
* exist, or tickets are invalid (too old, etc), then ignore cache.
* Create a temporary cache, prompt for username and password if
d692 3
d702 1
a703 5
rdata.length = strlen(realm);
rdata.data = (char *) malloc(rdata.length+1);
strcpy(rdata.data, realm);
krb5_princ_set_realm(creds.server, &rdata);
if (!*Up) {
printf(NAMEPROMPT);
fgets(scratch, sizeof (scratch), stdin);
if (!*scratch)
return (LR_ERROR);
/* zap newline */
scratch[strlen(scratch) - 1] = 0;
*Up = strdup(scratch);
}
if (retval = krb5_parse_name(scratch, &creds.client)) {
d746 1
a746 1
scratch, error_message(retval));
d748 1
a748 1
scratch, error_message(retval));
a750 13
}
/*
* Did the user specify a username? Has autologin been requested?
* If not, and if we're not logged in to Kerberos, prompt for one.
*/
if (!*Up) {
if (!(Options & LQ_AUTO)) /* no user, no autologin */
return (LR_ERROR); /* no deal */
}
else {
/* See if credentials are still valid */
d752 7
a758 9
/* If we're not already logged in with Kerberos then do so (get a TGT).
* (NULL username at this point implies we already have a TGT).
*/
if (*Up) {
if (retval = krb5_parse_name(*Up, &creds.client)) {
syslog(LOG_ERR, "LoginKrb5: krb5_parse_name(%s): %s",
*Up, error_message(retval));
fprintf(stderr, "LoginKrb5: krb5_parse_name(%s): %s\n",
*Up, error_message(retval));
d762 6
a767 7
/* find out who I am */
namelen = sizeof (lsin);
if (getsockname(sock, (struct sockaddr *) &lsin, &namelen) < 0) {
d656 15
a670 3
/* find out who the other side is */
namelen = sizeof (sin);
if (getpeername(sock, (struct sockaddr *) &sin, &namelen) < 0) {
d674 5
d680 2
a681 2
* Did the user specify a username? Has autologin been requested?
* If not, and if we're not logged in to kerberos, prompt for one.
d683 36
a719 7
struct stat dummy;
if (!(Options & LQ_AUTO)) /* no user, no autologin */
return (LR_ERROR); /* no deal */
if (stat(TKT_FILE, &dummy)) { /* no ticket cache */
if (!(Options & LQ_INTERACTIVE)) /* can't ask */
return (LR_ERROR);
d724 10
a733 5
else {
/* zap newline */
scratch[strlen(scratch) - 1] = 0;
*Up = strdup(scratch);
}
d736 14
a749 1
/* If we're not already logged in with kerberos then do so (get a TGT).
d753 6
a758 5
*principal = *instance = *realm = '\0';
status = kname_parse(principal, instance, realm, *Up);
if (status != KSUCCESS) {
fprintf(stderr, "%s\n", krb_err_txt[status]);
return LR_ERROR;
d760 9
a768 3
if (!*realm && krb_get_lrealm(realm, 1)) {
fprintf(stderr, "Unable to get realm.\n");
return LR_ERROR;
a769 4
/* set tkt file we'll use */
strcpy(okrbtkfile, TKT_FILE);
sprintf(krbtkfile, "/tmp/tkt_ph_%d", getpid());
krb_set_tkt_string(krbtkfile);
d771 8
d782 1
a782 1
if (des_read_pw_string(kpass, sizeof (kpass), PASSPROMPT, 0) != 0) {
d789 1
a789 2
status = krb_get_pw_in_tkt(principal, instance, realm,
"krbtgt", realm, 96, *Pp);
d791 3
a793 3
fprintf(stderr, "%s getting kerberos ticket granting ticket.\n",
(status == KSUCCESS) ? "success" : "failure");
if (status != KSUCCESS) {
d801 2
a802 2
fprintf(stderr, "sent=klogin %d\n", LQ_KRB4); /* send login request */
if (fprintf(ToQI, "klogin %d\n", LQ_KRB4) == EOF) {
d838 1
a838 1
status = krb_sendauth(authopts, sock, &ticket,
d843 2
a844 2
fprintf(stderr, "%s doing kerberos mutual authentication of %s with %s in realm %s.\n",
(status == KSUCCESS) ? "success" : "failure", NSSERVICE, UseHost, hrealm);
d864 1
a864 1
if (status == KSUCCESS && code == LR_OK) { /* logged in */
d873 1
d875 2
a876 2
#endif /* KRB4_AUTH */
1.16
log
@Working version checkpoint
@
text
@d4 1
a4 1
* Dorner, and Paul Pomes
d17 3
a19 3
* This product includes software developed by the Corporation for
* Research and Educational Networking (CREN), the University of
* Illinois at Urbana, and their contributors.
d38 2
a39 1
static char RcsId[] = "@@(#)$Id: LoginQi.c,v 1.15 1995/02/22 02:57:51 p-pomes Exp p-pomes $";
d43 24
a66 24
** Login and Logout functions, using the many flavors of password
** protocols (original recipe, Kerberos, email etc.)
**
**
** LoginQi - Login to QI server, optionally prompting for username/password.
**
** Parameters:
** UseHost - name of Qi server host
** ToQI - stream descriptor to write to
** FromQI - stream descriptor to read from
** Options - see qiapi.h/LQ_* defines
** Username - pointer to name to login as (alias) or NULL
** Password - pointer to password or NULL
**
** Returns:
** alias logged in as or NULL.
**
** Side Effects:
** possibly obtains and caches Kerberos tickets.
** username/password prompts are written/read to/from stdin/out,
** iff Options&LQ_INTERACTIVE.
**
** (most of this code lifted out of ph 6.5)
*/
d71 3
a73 3
# include <unistd.h>
# include <stdlib.h>
# include <string.h>
d75 5
a79 4
# include <strings.h>
char *malloc();
char *getenv();
char *strtok();
d105 1
a105 1
char *getpass __P((const char *));
d108 1
a108 1
# define NAMEPROMPT "Enter nameserver alias: "
d111 2
a112 2
# define PASSPROMPT "Enter nameserver password: "
#endif
d114 2
a115 2
# define CLIENT "ph"
#endif
d117 1
a117 1
# define NSSERVICE "ns"
d122 3
a124 3
int QiDebug = 0;
int QiAuthDebug = 0;
static char MsgBuf[MAXSTR]; /*messages from qi*/
d128 2
a129 1
#endif /*KRB4_AUTH*/
d132 2
a133 1
#endif /*EMAIL_AUTH*/
d136 1
d138 1
a138 1
static void GetAutoLogin __P((char **,char **));
d151 4
a154 4
const char *UseHost;
FILE *ToQI, *FromQI;
int Options;
const char *Username, *Password;
d156 2
a157 2
char *U = (char *)Username, *P = (char *)Password;
static char MyAlias[MAXSTR];
d159 1
a159 1
memset(MyAlias,0,sizeof MyAlias);
d161 3
a163 3
if (Options&LQ_EMAIL &&
LoginEmail(UseHost, ToQI, FromQI, Options, MyAlias, &U, &P) == LR_OK)
goto LoggedIn;
d166 3
a168 3
if (Options&LQ_KRB4 &&
LoginKrb4(UseHost, ToQI, FromQI, Options, MyAlias, &U, &P) == LR_OK)
goto LoggedIn;
d170 11
a180 11
if (Options&LQ_PASSWORD)
(void) LoginOriginal(UseHost, ToQI, FromQI, Options, MyAlias, &U, &P);
LoggedIn:
if (!Username && U) /* username was not passed in */
free(U); /* so free malloc'd string */
if (!Password && P) { /* ditto for password */
memset(P,0,strlen(P));
free(P);
}
fputs(MsgBuf, stdout);
return (*MyAlias)? MyAlias : NULL;
d182 1
a183 1
d189 1
a189 1
static int LoginQiEmailAuth = 0; /* a dirty little secret */
d193 4
a196 4
const char *UseHost;
FILE *ToQI, *FromQI;
int Options;
char *MyAlias, **Up, **Pp;
d198 24
a221 7
int code;
char scratch[MAXSTR];
/* if LQ_AUTO option selection and a username is not supplied,
try getting the login info from .netrc */
if (Options&LQ_AUTO && !*Up) { /* try autologin w/.netrc */
GetAutoLogin(Up,Pp);
d223 52
a274 31
fprintf(stderr,"autologin: .netrc user=%s, pass=%s\n",
(*Up)?*Up:"(none)", (*Pp)?*Pp:"(none)");
}
if (!*Up) { /* username not supplied */
if (!(Options&LQ_INTERACTIVE)) /* sorry, I can't ask you. */
return (LR_ERROR);
printf(NAMEPROMPT); /* ask for missing alias */
fgets(scratch, sizeof (scratch), stdin);
scratch[strlen(scratch) - 1] = '\0'; /* zap the \n */
if (!*scratch)
return (LR_ERROR);
*Up = strdup(scratch);
}
if (!*Pp &&!LoginQiEmailAuth && !(Options&LQ_INTERACTIVE))
return (LR_ERROR); /* I can't ask your password */
if (QiAuthDebug)
fprintf(stderr, "sent=login %s\n", *Up); /*send login request */
if (fprintf(ToQI, "login %s\n", *Up) == EOF) {
syslog(LOG_ERR, "LoginOriginal: fprintf: %m");
fprintf(stderr, "LoginOriginal: Whoops--the nameserver died.\n");
return LR_ERROR;
}
fflush(ToQI);
for (;;) /*read the response */
{
if (!GetGood(MsgBuf, MAXSTR, FromQI))
{
fprintf(stderr, "LoginOriginal: Whoops--the nameserver died.\n");
return LR_ERROR;
d276 8
a283 47
code = atoi(MsgBuf);
if (code != LR_LOGIN) /*intermediate or strange response */
fputs(MsgBuf, stdout);
if (code >= LR_OK) /*final response */
break;
}
if (code == LR_LOGIN)
{
if (LoginQiEmailAuth) { /* try email login */
char *me = getpwuid(getuid())->pw_name;
if (QiAuthDebug)
fprintf(stderr, "sent=email %s\n",me);
fprintf(ToQI, "email %s\n", me);
} else {
if (!*Pp) { /* password not supplied */
char *newp;
newp = getpass(PASSPROMPT);
*Pp = strdup(newp);
}
if (strlen(*Pp) > PH_PW_LEN) {
char *cp = &(*Pp)[PH_PW_LEN];
while (*cp)
*cp++ = '\0'; /* null out *all* the extras */
}
crypt_start(*Pp);
/*encrypt the challenge with the password */
MsgBuf[strlen(MsgBuf) - 1] = '\0'; /*strip linefeed */
scratch[encryptit(scratch, (char *)strchr(MsgBuf, ':') + 1)] = '\0';
/*send the encrypted text to qi */
if (QiAuthDebug)
fprintf(stderr, "sent=answer %s\n", scratch);
fprintf(ToQI, "answer %s\n", scratch);
}
}
fflush(ToQI);
/*get the final response */
for (;;)
{
if (!GetGood(MsgBuf, MAXSTR, FromQI))
{
fprintf(stderr, "LoginOriginal: Whoops--the nameserver died.\n");
return LR_ERROR;
d285 3
a287 3
code = atoi(MsgBuf);
if (code >= LR_OK) /*final response */
break;
d290 7
a296 7
if (code == LR_OK) /*logged in */
{
strcpy(MyAlias, (char *)strchr(MsgBuf, ':') + 1);
*(char *)strchr(MyAlias, ':') = '\0';
} else
*MyAlias = '\0';
return (code);
d301 3
a303 3
static void
GetAutoLogin(alias,pw)
char **alias, **pw; /* filled in from .netrc */
d305 42
a346 45
FILE *netrc; /*the .netrc file */
char path[1024]; /*pathname of .netrc file */
struct stat statbuf; /*permissions, etc. of .netrc file */
char key[80], val[80]; /*line from the .netrc file */
char *token; /*token (word) from the line from the .netrc file */
/*
* manufacture the pathname of the user's .netrc file
*/
sprintf(path, "%s/.netrc", getenv("HOME"));
/*
* make sure its permissions are ok
*/
if (stat(path, &statbuf) < 0)
return;
if (statbuf.st_mode & 077)
return; /*refuse insecure files */
/*
* try to open it
*/
if (!(netrc = fopen(path, "r")))
return;
/*
* look for a ``machine'' named ``ph''
*/
while (2 == fscanf(netrc, "%s %s", key, val))
{
if (!strcmp(key, "machine") && !strcmp(val, CLIENT))
{
/*
* found an entry for ph. look now for other items
*/
while (2 == fscanf(netrc, "%s %s", key, val))
{
if (!strcmp(key, "machine")) /*new machine */
goto out;
else if (!strcmp(key, "login"))
*alias = strdup(val);
else if (!strcmp(key, "password"))
*pw = strdup(val);
else if (!strcmp(key, "macdef"))
SkipMacdef(netrc);
d348 3
a350 2
} else if (!strcmp(key, "macdef"))
SkipMacdef(netrc);
d352 2
a353 2
out:
return;
d359 1
a359 1
static void
d361 1
a361 1
FILE *netrc;
d363 1
a363 1
int c, wasNl;
d365 3
a367 3
for (wasNl = 0; (c = getc(netrc)) != EOF; wasNl = (c == '\n'))
if (wasNl && c == '\n')
break;
d376 4
a379 4
const char *UseHost;
FILE *ToQI, *FromQI;
int Options;
char *MyAlias, **Up, **Pp;
d381 50
a430 55
struct sockaddr_in sin, lsin;
int status;
int sock = fileno(ToQI);
int namelen;
KTEXT_ST ticket;
INT32 authopts;
MSG_DAT msg_data;
CREDENTIALS cred;
Key_schedule sched;
static char scratch[MAXSTR];
char principal[ANAME_SZ];
char instance[INST_SZ];
char realm[REALM_SZ], *hrealm;
int code;
char krbtkfile[MAXPATHLEN];
char okrbtkfile[MAXPATHLEN];
static char kpass[BUFSIZ];
/* find out who I am */
namelen = sizeof (lsin);
if (getsockname(sock, (struct sockaddr *) & lsin, &namelen) < 0)
{
return (LR_ERROR);
}
/* find out who the other side is */
namelen = sizeof (sin);
if (getpeername(sock, (struct sockaddr *) & sin, &namelen) < 0)
{
return (LR_ERROR);
}
/*
* Did the user specify a username? Has autologin been requested?
* If not, and if we're not logged in to kerberos, prompt for one.
*/
if (!*Up)
{
struct stat dummy;
if (!(Options&LQ_AUTO)) /* no user, no autologin */
return (LR_ERROR); /* no deal */
if (stat(TKT_FILE, &dummy)) /* no ticket cache */
{
if (!(Options&LQ_INTERACTIVE)) /* can't ask */
return (LR_ERROR);
printf(NAMEPROMPT);
fgets(scratch, sizeof (scratch), stdin);
if (!*scratch)
return (LR_ERROR);
else
{
/* zap newline*/
scratch[strlen(scratch) - 1] = 0;
*Up = strdup(scratch);
d434 27
a460 10
/* If we're not already logged in with kerberos then do so (get a TGT).
(NULL username at this point implies we already have a TGT). */
if (*Up)
{
*principal = *instance = *realm = '\0';
status = kname_parse(principal, instance, realm, *Up);
if (status != KSUCCESS)
{
fprintf(stderr, "%s\n", krb_err_txt[status]);
return LR_ERROR;
d462 9
a470 30
if (!*realm && krb_get_lrealm(realm, 1))
{
fprintf(stderr, "Unable to get realm.\n");
return LR_ERROR;
}
/* set tkt file we'll use */
strcpy(okrbtkfile, TKT_FILE);
sprintf(krbtkfile, "/tmp/tkt_ph_%d", getpid());
krb_set_tkt_string(krbtkfile);
if (!*Pp) { /* no password supplied */
if (!(Options&LQ_INTERACTIVE)) /* I can't ask */
return LR_ERROR;
if (des_read_pw_string(kpass,sizeof(kpass),PASSPROMPT,0) != 0) {
fprintf(stderr, "Unable to read password.\n");
return LR_ERROR;
}
*Pp = strdup(kpass);
}
/* login */
status = krb_get_pw_in_tkt(principal, instance, realm,
"krbtgt", realm, 96, *Pp);
if (QiAuthDebug)
fprintf(stderr, "%s getting kerberos ticket granting ticket.\n",
(status == KSUCCESS)?"success":"failure");
if (status != KSUCCESS)
{
if (*Up)
{
krb_set_tkt_string(okrbtkfile);
d472 1
a472 1
return LR_ERROR;
d475 3
a477 4
if (QiAuthDebug)
fprintf(stderr, "sent=klogin\n"); /* send login request */
if (fprintf(ToQI, "klogin\n") == EOF)
{
d481 25
a505 2
}
fflush(ToQI);
a506 26
for (;;) /* read the response */
{
if (!GetGood(MsgBuf, MAXSTR, FromQI))
{
fprintf(stderr, "LoginKrb4: Whoops--the nameserver died.\n");
if (*Up)
dest_tkt(); /* destroy temp tickets for
specified username */
memset(kpass,0,sizeof(kpass)); /* paranoia */
return(LR_ERROR);
}
code = atoi(MsgBuf);
if (code != LR_LOGIN) /* intermediate or strange response */
fputs(MsgBuf, stdout);
if (code >= LR_OK) /* final response */
break;
}
if (code == LR_LOGIN)
{
/*
* call Kerberos library routine to obtain an authenticator,
* pass it over the socket to the server, and obtain mutual
* authentication.
*/
d508 1
a508 1
hrealm = KRBNSREALM;
d510 1
a510 1
hrealm = krb_realmofhost(UseHost);
d512 17
a528 19
authopts = KOPT_DO_MUTUAL;
status = krb_sendauth(authopts, sock, &ticket,
NSSERVICE, UseHost, hrealm,
0, &msg_data, &cred,
sched, &lsin, &sin, "VERSION9");
if (QiAuthDebug)
fprintf(stderr, "%s doing kerberos mutual authentication of %s with %s in realm %s.\n",
(status == KSUCCESS)?"success":"failure", NSSERVICE, UseHost, hrealm);
if (*Up) /* ???? */
dest_tkt(); /* destroy special tickets as soon as
possible */
/* get the final response (even if mutual failed)*/
for (;;)
{
if (!GetGood(MsgBuf, MAXSTR, FromQI))
{
fprintf(stderr, "LoginKrb4: Whoops--the nameserver died.\n");
return LR_ERROR;
d530 3
a532 3
code = atoi(MsgBuf);
if (code >= LR_OK) /* final response */
break;
d534 3
a536 4
1.9
log
@Zap perror().
@
text
@d38 1
a38 1
static char RcsId[] = "@@(#)$Id: LoginQi.c,v 1.8 1994/03/12 04:27:19 paul Exp paul $";
a656 2
if (errno)
perror("");
@
1.8
log
@Changed NSSERVICE back to "ns" from "csnet-ns" as I can't get the
latter to decode authenticators properly when used with Kerberos.
@
text
@d38 1
a38 1
static char RcsId[] = "@@(#)$Id: LoginQi.c,v 1.7 1994/03/11 22:45:56 paul Exp paul $";
a393 1
perror("getsockname");
a400 1
perror("getpeername");
@
1.7
log
@New copyright statement. Re-arranged some #include's for use with
debugging malloc library. Changed default service name from "ns" to
"csnet-ns".
@
text
@d38 1
a38 1
static char RcsId[] = "@@(#)$Id$";
d116 1
a116 1
# define NSSERVICE "csnet-ns"
@
1.6
log
@converted to use MsgBug instead of scratch.
@
text
@d2 33
a34 2
* Login and Logout functions, using the many flavors of password
* protocols (original recipe, Kerberos, email etc.)
d36 5
d42 4
a66 2
#include "conf.h"
#include "qiapi.h"
a78 3
char *getpass __P((const char *));
char *strdup __P((const char *));
1.2
log
@Use NSSERVICE instead of hardwiring "ns" as the Kerberos instance.
Removed test of effective uid in LoginEmail() as ContactQi() has
already reset that to the user.
@
text
@d54 1
a54 1
#include <sys/fcntl.h>
d83 1
a83 1
static char RcsId[] = "@@(#)$Id: LoginQi.c,v 1.1 1993/11/24 22:32:24 paul Exp paul $";
@
1.1
log
@Initial revision
@
text
@d74 3
d83 1
a83 1
static char RcsId[] = "@@(#)$Id: LoginQi.c,v 1.2 93/11/11 22:12:27 alan Exp $";
d404 1
d478 1
a478 1
"ns", UseHost,
d483 2
a484 2
fprintf(stderr, "%s doing kerberos mutual authentication.\n",
(status == KSUCCESS)?"success":"failure");
a532 1
if (geteuid() == 0) { /* then we must have a reserved port */
a539 2
} else
return (LR_ERROR);
@