Ejemplo n.º 1
0
static int
kvno4(krb5_context ctx, const char *host, krb5_principal sprinc)
{
	krb5_error_code	kerr;
	KTEXT_ST	req;
	CREDENTIALS	creds;
	int		err = 0;
	char		name[ANAME_SZ];
	char		instance[INST_SZ];
	char		realm[REALM_SZ];

	VERBOSE(1, (stderr, "initiating kvno4/udp ping to %s\n", host));

	kerr = krb5_524_conv_principal(ctx, sprinc, name, instance, realm);
	if (kerr) {
		fail_msg("kvno4", SOCK_DGRAM, host, error_message(kerr));
		goto bail;
	}

	err = krb_mk_req(&req, name, instance, realm, 0);
	if (err)
		goto bail;

        err = krb_get_cred(name, instance, realm, &creds);
        if (err)
		goto bail;

	VERBOSE(2, (stderr, "%s.%s@%s kvno = %d\n", name, instance, realm,
	    creds.kvno));

bail:
	if (err)
		fail_msg("kvno4", SOCK_DGRAM, host, krb_get_err_text(err));
	return err;
}
Ejemplo n.º 2
0
Code_t
SendKerberosData(int fd,	/* file descriptor to write onto */
		 KTEXT ticket,	/* where to put ticket (return) */
		 char *service,	/* service name, foreign host */
		 char *host)

{
    int rem;
    char p[32];
    size_t written;
    size_t size_to_write;

    rem = krb_mk_req(ticket, service, host, (char *)ZGetRealm(), (u_long) 0);
    if (rem != KSUCCESS)
	return rem + krb_err_base;

    (void) sprintf(p,"%d ",ticket->length);
    size_to_write = strlen (p);
    if ((written = write(fd, p, size_to_write)) != size_to_write)
	return ((ssize_t)written < 0) ? errno : ZSRV_PKSHORT;
    if ((written = write(fd, ticket->dat, ticket->length))
	!= ticket->length)
	return ((ssize_t)written < 0) ? errno : ZSRV_PKSHORT;

    return 0;
}
Ejemplo n.º 3
0
char *
ldap_get_kerberosv4_credentials(
	LDAP *ld,
	LDAP_CONST char *who,
	LDAP_CONST char *service,
	ber_len_t *len )
{
	KTEXT_ST	ktxt;
	int		err;
	char		realm[REALM_SZ], *cred, *krbinstance;

	Debug( LDAP_DEBUG_TRACE, "ldap_get_kerberosv4_credentials\n", 0, 0, 0 );

	if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: "
			"krb_get_tf_realm failed: %s\n", krb_err_txt[err], 0, 0 );
		ld->ld_errno = LDAP_AUTH_UNKNOWN;
		return( NULL );
	}

	err = 0;
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
	if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
		/* not connected yet */
		err = ldap_open_defconn( ld );
	}
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
	if ( err < 0 ) return NULL;

	krbinstance = ld->ld_defconn->lconn_krbinstance;

	if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 ))
	    != KSUCCESS )
	{
		Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: "
			"krb_mk_req failed (%s)\n", krb_err_txt[err], 0, 0 );
		ld->ld_errno = LDAP_AUTH_UNKNOWN;
		return( NULL );
	}

	if ( ( cred = LDAP_MALLOC( ktxt.length )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return( NULL );
	}

	*len = ktxt.length;
	AC_MEMCPY( cred, ktxt.dat, ktxt.length );

	return( cred );
}
Ejemplo n.º 4
0
int mr_auth(char *prog)
{
#ifdef HAVE_KRB4
  int status;
  mr_params params, reply;
  char *args[2];
  int argl[2];
  char realm[REALM_SZ], host[BUFSIZ], *p;
  KTEXT_ST auth;

  CHECK_CONNECTED;

  if ((status = mr_host(host, sizeof(host) - 1)))
    return status;

  strcpy(realm, krb_realmofhost(host));
  for (p = host; *p && *p != '.'; p++)
    {
      if (isupper(*p))
	*p = tolower(*p);
    }
  *p = '\0';

  status = krb_mk_req(&auth, MOIRA_SNAME, host, realm, 0);
  if (status != KSUCCESS)
    {
      status += ERROR_TABLE_BASE_krb;
      return status;
    }
  params.u.mr_procno = MR_AUTH;
  params.mr_argc = 2;
  params.mr_argv = args;
  params.mr_argl = argl;
  params.mr_argv[0] = (char *)auth.dat;
  params.mr_argl[0] = auth.length;
  params.mr_argv[1] = prog;
  params.mr_argl[1] = strlen(prog) + 1;

  if ((status = mr_do_call(&params, &reply)) == MR_SUCCESS)
    status = reply.u.mr_status;

  mr_destroy_reply(reply);

  return status;
#else
  return MR_NO_KRB4;
#endif
}
Ejemplo n.º 5
0
/*
 * 
 * K4_auth_send - gets authentication bits we need to send to KDC.
 * 
 * Result is left in auth
 *
 * Returns: 0 on failure, 1 on success
 */
static int
k4_auth_send(kstream ks)
{
  int r;                                      /* Return value */
  char instance[INST_SZ];
  char *realm;
  char buf[256];

  memset(instance, 0, sizeof(instance));

  if (realm = krb_get_phost(szHostName))
    lstrcpy(instance, realm);

  realm = krb_realmofhost(szHostName);

  if (!realm) {
    strcpy(buf, "Can't find realm for host \"");
    strncat(buf, szHostName, sizeof(buf) - 1 - strlen(buf));
    strncat(buf, "\"", sizeof(buf) - 1 - strlen(buf));
    auth_abort(ks, buf, 0);
    return KFAILURE;
  }

  r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0);

  if (r == 0)
    r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred);

  if (r) {
    strcpy(buf, "Can't get \"");
    strncat(buf, KRB_SERVICE_NAME, sizeof(buf) - 1 - strlen(buf));
    if (instance[0] != 0) {
      strncat(buf, ".", sizeof(buf) - 1 - strlen(buf));
      lstrcat(buf, instance);
    }
    strncat(buf, "@", sizeof(buf) - 1 - strlen(buf));
    lstrcat(buf, realm);
    strncat(buf, "\" ticket", sizeof(buf) - 1 - strlen(buf));
    auth_abort(ks, buf, r);

    return r;
  }

  if (!szUserName[0])			/* Copy if not there */
    strcpy(szUserName, cred.pname);

  return(1);
}
Ejemplo n.º 6
0
static int
get_cred(struct kafs_data *data, const char *name, const char *inst, 
	 const char *realm, uid_t uid, struct kafs_token *kt)
{
    CREDENTIALS c;
    KTEXT_ST tkt;
    int ret = krb_get_cred((char*)name, (char*)inst, (char*)realm, &c);
    
    if (ret) {
	ret = krb_mk_req(&tkt, (char*)name, (char*)inst, (char*)realm, 0);
	if (ret == KSUCCESS)
	    ret = krb_get_cred((char*)name, (char*)inst, (char*)realm, &c);
    }
    if (ret == 0)
	ret = _kafs_v4_to_kt(&c, uid, kt);
    return ret;
}
Ejemplo n.º 7
0
static int get_cred(char *name, char *inst, char *realm, CREDENTIALS *c)
{
    int status;

    status = krb_get_cred(name, inst, realm, c);
    if (status != KSUCCESS)
    {
#ifdef DONT_HAVE_GET_AD_TKT
        KTEXT_ST ticket;
        status = krb_mk_req(&ticket, name, inst, realm, 0);
#else
        status = get_ad_tkt(name, inst, realm, 255);
#endif
        if (status == KSUCCESS)
            status = krb_get_cred(name, inst, realm, c);
    }       

    return (status);
}
Ejemplo n.º 8
0
char *
get_kerberosv4_credentials( LDAP *ld, char *who, char *service, int *len )
{
	KTEXT_ST	ktxt;
	int		err;
	char		realm[REALM_SZ], *cred, *krbinstance;

	Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 191, "get_kerberosv4_credentials\n"), 0, 0, 0 );

	if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) {
#ifndef NO_USERINTERFACE
		fprintf( stderr, "krb_get_tf_realm failed (%s)\n",
		    krb_err_txt[err] );
#endif /* NO_USERINTERFACE */
		ld->ld_errno = LDAP_INVALID_CREDENTIALS;
		return( NULL );
	}

#ifdef LDAP_REFERRALS
	krbinstance = ld->ld_defconn->lconn_krbinstance;
#else /* LDAP_REFERRALS */
	krbinstance = ld->ld_host;
#endif /* LDAP_REFERRALS */

	if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 ))
	    != KSUCCESS ) {
#ifndef NO_USERINTERFACE
		fprintf( stderr, "krb_mk_req failed (%s)\n", krb_err_txt[err] );
#endif /* NO_USERINTERFACE */
		ld->ld_errno = LDAP_INVALID_CREDENTIALS;
		return( NULL );
	}

	if ( ( cred = malloc( ktxt.length )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return( NULL );
	}

	*len = ktxt.length;
	memcpy( cred, ktxt.dat, ktxt.length );

	return( cred );
}
Ejemplo n.º 9
0
static int
mk_auth(struct krb4_data *d, KTEXT adat, 
	char *service, char *host, int checksum)
{
    int ret;
    CREDENTIALS cred;
    char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ];

    strlcpy(sname, service, sizeof(sname));
    strlcpy(inst, krb_get_phost(host), sizeof(inst));
    strlcpy(realm, krb_realmofhost(host), sizeof(realm));
    ret = krb_mk_req(adat, sname, inst, realm, checksum);
    if(ret)
	return ret;
    strlcpy(sname, service, sizeof(sname));
    strlcpy(inst, krb_get_phost(host), sizeof(inst));
    strlcpy(realm, krb_realmofhost(host), sizeof(realm));
    ret = krb_get_cred(sname, inst, realm, &cred);
    memmove(&d->key, &cred.session, sizeof(des_cblock));
    des_key_sched(&d->key, d->schedule);
    memset(&cred, 0, sizeof(cred));
    return ret;
}
Ejemplo n.º 10
0
int do_GetSecret(char *hostname, const char **identity, int *ilen, 
                 const char **secret, int *slen)
{
    struct ktext *authenticator = NULL;
    struct credentials *cred = NULL;
    char *host = NULL;
    int rc = -1;

    host = krb_canonicalize_host(hostname);
    if (!host) return -1;

    cred = malloc(sizeof(struct credentials));
    if (!cred) {
	fprintf(stderr, "krb4: malloc(credentials) failed\n");
	goto out;
    }

    authenticator = malloc(sizeof(struct ktext));
    if (!authenticator) {
	fprintf(stderr, "krb4: malloc(ktext) failed\n");
	goto out;
    }

    /* construct a new authenticator, or find an old one */
    rc = krb_mk_req(authenticator, kerberos4service, host, kerberos4realm, 0);
    if (rc) {
	fprintf(stderr, "krb4: %s (%d)\n", krb_err_txt[rc], rc);
	rc = 1;
	goto out;
    }

    /* authenticator now contains authenticator */
    /* pull out the shared secret for RPC2 to use in the bind */

    rc = krb_get_cred(kerberos4service, host, kerberos4realm, cred);
    if (rc) {
	fprintf(stderr, "krb4: %s (%d)\n", krb_err_txt[rc], rc);
	rc = 1;
	goto out;
    }

    /* we now have the key in session_key */
    HashSecret(cred->session, 8, *secret);
    *slen = RPC2_KEYSIZE;

    *identity = (char *)authenticator;
    *ilen = sizeof(struct ktext);

    rc = 0;

    authenticator = NULL; /* XXX ok, who is supposed to be freeing the
			     authenticator now? -JH */
out:
    if (host)
	free(host);

    if (authenticator)
	free(authenticator);

    if (cred)
	free(cred);

    return rc;
}
Ejemplo n.º 11
0
int krb_sendauth_udp(long options, int fd, KTEXT_FP ticket,
	const LPSTR service, const LPSTR inst, LPSTR realm, LONG checksum,
	MSG_DAT *msg_data, CREDENTIALS *cred, Key_schedule *schedule,
	struct sockaddr_in *laddr, struct sockaddr_in *faddr, LPSTR version,
	LPSTR buffer, int sz)
{
	int rem, i, cc;
	char srv_inst[INST_SZ];
	char krb_realm[REALM_SZ];
	char buf[BUFSIZ];
	long tkt_len;
	u_char priv_buf[1024];
	u_long cksum;
	
	rem = KSUCCESS;
	
	/* get current realm if not passed in */
	if (!realm) {
		rem = krb_get_lrealm(krb_realm,1);
		if (rem != KSUCCESS)
			return (rem);
		realm = krb_realm;
	}
	
	/* Copy instance into local storage, canonicalizing if desired */
	if (options & KOPT_DONT_CANON)
		(void) strncpy(srv_inst, inst, INST_SZ);
	else
		(void) strncpy((LPSTR)srv_inst, (LPSTR)krb_get_phost(inst), INST_SZ);
		
	/* Get the ticket if desired */
	if (!(options & KOPT_DONT_MK_REQ)) {
		rem = krb_mk_req(ticket, service, srv_inst, realm, checksum);
		if (rem != KSUCCESS)
			return (rem);
	}
	
#ifdef ATHENA_COMPAT
	/* this is only for compatibility with old servers */
	if (options & KOPT_DO_OLDSTYLE) {
		(void) sprintf(buf, "%d ", ticket->length);
		(void) write(fd, buf, strlen(buf));
		(void) write(fd, (char *) ticket->dat, ticket->length);
		return (rem);
	}
#endif /* ATHENA_COMPAT */
	/* if the mutual auth, get credentials so we have service session
	 * keys for decryption below
	 */
	if (options & KOPT_DO_MUTUAL)
	{
		/*if (cc == 1)
		 *{
		 *      krb_get_cred(service, srv_inst, realm, cred);
		 *      return (cc);
		 *}
		 */
		krb_get_cred(service, srv_inst, realm, cred);
	}
			
	/* Zero the buffer */
	(void) bzero(buf, BUFSIZ);
	
	/* insert version strings */
	(void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN);
	
	/* increment past version strings */
	i = 2*KRB_SENDAUTH_VLEN;
	
	/* put ticket length into buffer */
	tkt_len = htonl((unsigned long) ticket->length);
	(void) bcopy((char *) &tkt_len, buf+i, ticket->length);
	i += ticket->length;
	
	/* Normally, we write the request to the server
	** For udp, esp. TechNotify type protocols, we
	** just return the buffer.  
	*/
	if (sz < i)
		return HEY_PAUL_WHAT_ERROR;     /* Buffer not big enough */
	bcopy(buf, buffer, i);
	return (KSUCCESS);
}
Ejemplo n.º 12
0
char *					/* R: allocated response string */
auth_krb4 (
  /* PARAMETERS */
  const char *login,			/* I: plaintext authenticator */
  const char *password,			/* I: plaintext password */
  const char *service,
  const char *realm_in
  /* END PARAMETERS */
  )
{
    /* VARIABLES */
    char aname[ANAME_SZ];		/* Kerberos principal */
    const char *realm;		        /* Kerberos realm to authenticate in */
    int rc;				/* return code */
    char tf_name[TF_NAME_LEN];		/* Ticket file name */
    char *instance, *user_specified;
    KTEXT_ST ticket;
    AUTH_DAT kdata;
    /* END VARIABLES */

    /*
     * Make sure we have a password. If this is NULL the call
     * to krb_get_pw_in_tkt below would try to prompt for
     * one interactively.
     */
    if (password == NULL) {
	syslog(LOG_ERR, "auth_krb4: NULL password?");
	return strdup("NO saslauthd internal error");
    }

    if (krbtf_name(tf_name, sizeof(tf_name)) != 0) {
      syslog(LOG_ERR, "auth_krb4: could not generate ticket file name");
      return strdup("NO saslauthd internal error");
    }
    krb_set_tkt_string(tf_name);

    strncpy(aname, login, ANAME_SZ-1);
    aname[ANAME_SZ-1] = '\0';

    instance = "";

    if (config) {
      char keyname[1024];

      snprintf(keyname, sizeof(keyname), "krb4_%s_instance", service);
      instance = cfile_getstring(config, keyname, "");
    }

    user_specified = strchr(aname, '.');
    if (user_specified) {
      if (instance && instance[0]) {
	/* sysadmin specified a (mandatory) instance */
	if (strcmp(user_specified + 1, instance)) {
	  return strdup("NO saslauthd principal name error");
	}
	/* nuke instance from "aname"-- matches what's already in "instance" */
	*user_specified = '\0';
      } else {
	/* sysadmin has no preference, so we shift
	 * instance name from "aname" to "instance"
	 */
	*user_specified = '\0';
	instance = user_specified + 1;
      }
    }

    if(realm_in && *realm_in != '\0') {
	realm = realm_in;
    } else {
	realm = default_realm;
    }

    rc = krb_get_pw_in_tkt(aname, instance, realm,
			   KRB_TICKET_GRANTING_TICKET,
			   realm, 1, password);

    if (rc == INTK_BADPW || rc == KDC_PR_UNKNOWN) {
	return strdup("NO");
    } else if (rc != KSUCCESS) {
      syslog(LOG_ERR, "ERROR: auth_krb4: krb_get_pw_in_tkt: %s",
	     krb_get_err_text(rc));

      return strdup("NO saslauthd internal error");
    }

    /* if the TGT wasn't spoofed, it should entitle us to an rcmd ticket... */
    rc = krb_mk_req(&ticket, verify_principal, myhostname, default_realm, 0);

    if (rc != KSUCCESS) {
      syslog(LOG_ERR, "ERROR: auth_krb4: krb_get_pw_in_tkt: %s",
	     krb_get_err_text(rc));
      dest_tkt();
      return strdup("NO saslauthd internal error");
    }

    /* .. and that ticket should match our secret host key */
    rc = krb_rd_req(&ticket, verify_principal, myhostname, 0, &kdata, srvtabname);

    if (rc != RD_AP_OK) {
      syslog(LOG_ERR, "ERROR: auth_krb4: krb_rd_req:%s",
	     krb_get_err_text(rc));
      dest_tkt();
      return strdup("NO saslauthd internal error");
    }

    dest_tkt();

    return strdup("OK");
}
Ejemplo n.º 13
0
static int
kerberos4_send(char *name, Authenticator *ap)
{
    KTEXT_ST auth;
    char instance[INST_SZ];
    char *realm;
    CREDENTIALS cred;
    int r;

    printf("[ Trying %s ... ]\r\n", name);
    if (!UserNameRequested) {
	if (auth_debug_mode) {
	    printf("Kerberos V4: no user name supplied\r\n");
	}
	return(0);
    }

    memset(instance, 0, sizeof(instance));

    if ((realm = krb_get_phost(RemoteHostName)))
	strncpy(instance, realm, sizeof(instance));

    instance[sizeof(instance)-1] = '\0';

    realm = dest_realm ? dest_realm : krb_realmofhost(RemoteHostName);

    if (!realm) {
	printf("Kerberos V4: no realm for %s\r\n", RemoteHostName);
	return(0);
    }
    r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0L);
    if (r) {
	printf("mk_req failed: %s\r\n", krb_get_err_text(r));
	return(0);
    }
    r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred);
    if (r) {
	printf("get_cred failed: %s\r\n", krb_get_err_text(r));
	return(0);
    }
    if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
	if (auth_debug_mode)
	    printf("Not enough room for user name\r\n");
	return(0);
    }
    if (auth_debug_mode)
	printf("Sent %d bytes of authentication data\r\n", auth.length);
    if (!Data(ap, KRB_AUTH, (void *)auth.dat, auth.length)) {
	if (auth_debug_mode)
	    printf("Not enough room for authentication data\r\n");
	return(0);
    }
#ifdef ENCRYPTION
    /* create challenge */
    if ((ap->way & AUTH_HOW_MASK)==AUTH_HOW_MUTUAL) {
	int i;

	des_key_sched(&cred.session, sched);
	des_init_random_number_generator(&cred.session);
	des_new_random_key(&session_key);
	des_ecb_encrypt(&session_key, &session_key, sched, 0);
	des_ecb_encrypt(&session_key, &challenge, sched, 0);

	/*
	  old code
	  Some CERT Advisory thinks this is a bad thing...
	    
	  des_init_random_number_generator(&cred.session);
	  des_new_random_key(&challenge);
	  des_ecb_encrypt(&challenge, &session_key, sched, 1);
	  */
	  
	/*
	 * Increment the challenge by 1, and encrypt it for
	 * later comparison.
	 */
	for (i = 7; i >= 0; --i) 
	    if(++challenge[i] != 0) /* No carry! */
		break;
	des_ecb_encrypt(&challenge, &challenge, sched, 1);
    }

#endif

    if (auth_debug_mode) {
	printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length));
	printd(auth.dat, auth.length);
	printf("\r\n");
	printf("Sent Kerberos V4 credentials to server\r\n");
    }
    return(1);
}
Ejemplo n.º 14
0
/*
 * try krb4 authentication,
 * return 1 on success, 0 on failure, -1 if krb4 is not available
 */
int
auth_krb4_password(Authctxt *authctxt, const char *password)
{
	AUTH_DAT adata;
	KTEXT_ST tkt;
	struct hostent *hp;
	struct passwd *pw;
	char localhost[MAXHOSTNAMELEN], phost[INST_SZ], realm[REALM_SZ];
	u_int32_t faddr;
	int r;

	if ((pw = authctxt->pw) == NULL)
		return (0);

	/*
	 * Try Kerberos password authentication only for non-root
	 * users and only if Kerberos is installed.
	 */
	if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
		/* Set up our ticket file. */
		if (!krb4_init(authctxt)) {
			log("Couldn't initialize Kerberos ticket file for %s!",
			    pw->pw_name);
			goto failure;
		}
		/* Try to get TGT using our password. */
		r = krb_get_pw_in_tkt((char *) pw->pw_name, "", realm,
		    "krbtgt", realm, DEFAULT_TKT_LIFE, (char *)password);
		if (r != INTK_OK) {
			debug("Kerberos v4 password authentication for %s "
			    "failed: %s", pw->pw_name, krb_err_txt[r]);
			goto failure;
		}
		/* Successful authentication. */
		chown(tkt_string(), pw->pw_uid, pw->pw_gid);

		/*
		 * Now that we have a TGT, try to get a local
		 * "rcmd" ticket to ensure that we are not talking
		 * to a bogus Kerberos server.
		 */
		gethostname(localhost, sizeof(localhost));
		strlcpy(phost, (char *)krb_get_phost(localhost),
		    sizeof(phost));
		r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);

		if (r == KSUCCESS) {
			if ((hp = gethostbyname(localhost)) == NULL) {
				log("Couldn't get local host address!");
				goto failure;
			}
			memmove((void *)&faddr, (void *)hp->h_addr,
			    sizeof(faddr));

			/* Verify our "rcmd" ticket. */
			r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
			    faddr, &adata, "");
			if (r == RD_AP_UNDEC) {
				/*
				 * Probably didn't have a srvtab on
				 * localhost. Disallow login.
				 */
				log("Kerberos v4 TGT for %s unverifiable, "
				    "no srvtab installed? krb_rd_req: %s",
				    pw->pw_name, krb_err_txt[r]);
				goto failure;
			} else if (r != KSUCCESS) {
				log("Kerberos v4 %s ticket unverifiable: %s",
				    KRB4_SERVICE_NAME, krb_err_txt[r]);
				goto failure;
			}
		} else if (r == KDC_PR_UNKNOWN) {
			/*
			 * Disallow login if no rcmd service exists, and
			 * log the error.
			 */
			log("Kerberos v4 TGT for %s unverifiable: %s; %s.%s "
			    "not registered, or srvtab is wrong?", pw->pw_name,
			    krb_err_txt[r], KRB4_SERVICE_NAME, phost);
			goto failure;
		} else {
			/*
			 * TGT is bad, forget it. Possibly spoofed!
			 */
			debug("WARNING: Kerberos v4 TGT possibly spoofed "
			    "for %s: %s", pw->pw_name, krb_err_txt[r]);
			goto failure;
		}
		/* Authentication succeeded. */
		return (1);
	} else
		/* Logging in as root or no local Kerberos realm. */
		debug("Unable to authenticate to Kerberos.");

 failure:
	krb4_cleanup_proc(authctxt);

	if (!options.kerberos_or_local_passwd)
		return (0);

	/* Fall back to ordinary passwd authentication. */
	return (-1);
}
Ejemplo n.º 15
0
static int
try_krb4_authentication(void)
{
	KTEXT_ST auth;		/* Kerberos data */
	char *reply;
	char inst[INST_SZ];
	char *realm;
	CREDENTIALS cred;
	int r, type;
	socklen_t slen;
	Key_schedule schedule;
	u_long checksum, cksum;
	MSG_DAT msg_data;
	struct sockaddr_in local, foreign;
	struct stat st;

	/* Don't do anything if we don't have any tickets. */
	if (stat(tkt_string(), &st) < 0)
		return 0;

	strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)),
	    INST_SZ);

	realm = (char *)krb_realmofhost(get_canonical_hostname(1));
	if (!realm) {
		debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));
		return 0;
	}
	/* This can really be anything. */
	checksum = (u_long)getpid();

	r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
	if (r != KSUCCESS) {
		debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]);
		return 0;
	}
	/* Get session key to decrypt the server's reply with. */
	r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);
	if (r != KSUCCESS) {
		debug("get_cred failed: %s", krb_err_txt[r]);
		return 0;
	}
	des_key_sched((des_cblock *) cred.session, schedule);

	/* Send authentication info to server. */
	packet_start(SSH_CMSG_AUTH_KERBEROS);
	packet_put_string((char *) auth.dat, auth.length);
	packet_send();
	packet_write_wait();

	/* Zero the buffer. */
	(void) memset(auth.dat, 0, MAX_KTXT_LEN);

	slen = sizeof(local);
	memset(&local, 0, sizeof(local));
	if (getsockname(packet_get_connection_in(),
	    (struct sockaddr *)&local, &slen) < 0)
		debug("getsockname failed: %s", strerror(errno));

	slen = sizeof(foreign);
	memset(&foreign, 0, sizeof(foreign));
	if (getpeername(packet_get_connection_in(),
	    (struct sockaddr *)&foreign, &slen) < 0) {
		debug("getpeername failed: %s", strerror(errno));
		cleanup_exit(255);
	}
	/* Get server reply. */
	type = packet_read();
	switch (type) {
	case SSH_SMSG_FAILURE:
		/* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
		debug("Kerberos v4 authentication failed.");
		return 0;
		break;

	case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
		/* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
		debug("Kerberos v4 authentication accepted.");

		/* Get server's response. */
		reply = packet_get_string((u_int *) &auth.length);
		if (auth.length >= MAX_KTXT_LEN)
			fatal("Kerberos v4: Malformed response from server");
		memcpy(auth.dat, reply, auth.length);
		free(reply);

		packet_check_eom();

		/*
		 * If his response isn't properly encrypted with the session
		 * key, and the decrypted checksum fails to match, he's
		 * bogus. Bail out.
		 */
		r = krb_rd_priv(auth.dat, auth.length, (void *)schedule,
		    &cred.session, &foreign, &local, &msg_data);
		if (r != KSUCCESS) {
			debug("Kerberos v4 krb_rd_priv failed: %s",
			    krb_err_txt[r]);
			packet_disconnect("Kerberos v4 challenge failed!");
		}
		/* Fetch the (incremented) checksum that we supplied in the request. */
		memcpy((char *)&cksum, (char *)msg_data.app_data,
		    sizeof(cksum));
		cksum = ntohl(cksum);

		/* If it matches, we're golden. */
		if (cksum == checksum + 1) {
			debug("Kerberos v4 challenge successful.");
			return 1;
		} else
			packet_disconnect("Kerberos v4 challenge failed!");
		break;

	default:
		packet_disconnect("Protocol error on Kerberos v4 response: %d", type);
	}
	return 0;
}
Ejemplo n.º 16
0
Code_t
ZMakeAuthentication(register ZNotice_t *notice,
		    char *buffer,
		    int buffer_len,
		    int *len)
{
#ifdef HAVE_KRB5
    return ZMakeZcodeAuthentication(notice, buffer, buffer_len, len/*?XXX*/);
#else
#ifdef HAVE_KRB4
    int result;
    KTEXT_ST authent;
    char *cstart, *cend;
    ZChecksum_t checksum;
    CREDENTIALS cred;
    C_Block *session;

    result = krb_mk_req(&authent, SERVER_SERVICE,
			SERVER_INSTANCE, __Zephyr_realm, 0);
    if (result != MK_AP_OK)
	return (result+krb_err_base);
    result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE,
			  __Zephyr_realm, &cred);
    if (result != KSUCCESS)
	return (result+krb_err_base);

    session = (C_Block *)cred.session;

    notice->z_auth = 1;
    notice->z_authent_len = authent.length;
    notice->z_ascii_authent = (char *)malloc((unsigned)authent.length*3);
    /* zero length authent is an error, so malloc(0) is not a problem */
    if (!notice->z_ascii_authent)
	return (ENOMEM);
    if ((result = ZMakeAscii(notice->z_ascii_authent,
			     authent.length*3,
			     authent.dat,
			     authent.length)) != ZERR_NONE) {
	free(notice->z_ascii_authent);
	return (result);
    }
    result = Z_FormatRawHeader(notice, buffer, buffer_len, len, &cstart,
			       &cend);
    free(notice->z_ascii_authent);
    notice->z_authent_len = 0;
    if (result)
	return(result);

    /* Compute a checksum over the header and message. */
    checksum = des_quad_cksum((unsigned char *)buffer, NULL, cstart - buffer, 0, session);
    checksum ^= des_quad_cksum((unsigned char *)cend, NULL, buffer + *len - cend, 0,
			       session);
    checksum ^= des_quad_cksum((unsigned char *)notice->z_message, NULL, notice->z_message_len,
			       0, session);
    notice->z_checksum = checksum;
    ZMakeAscii32(cstart, buffer + buffer_len - cstart, checksum);

    return (ZERR_NONE);
#else
    notice->z_checksum = 0;
    notice->z_auth = 1;
    notice->z_authent_len = 0;
    notice->z_ascii_authent = "";
    return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL));
#endif
#endif
}