예제 #1
0
static pj_status_t new_auth_for_req( pjsip_tx_data *tdata,
				     pjsip_auth_clt_sess *sess,
				     pjsip_cached_auth *auth,
				     pjsip_authorization_hdr **p_h_auth)
{
    const pjsip_cred_info *cred;
    pjsip_authorization_hdr *hauth;
    pj_status_t status;

    PJ_ASSERT_RETURN(tdata && sess && auth, PJ_EINVAL);
    PJ_ASSERT_RETURN(auth->last_chal != NULL, PJSIP_EAUTHNOPREVCHAL);

    cred = auth_find_cred( sess, &auth->realm, &auth->last_chal->scheme );
    if (!cred)
	return PJSIP_ENOCREDENTIAL;

    status = auth_respond( tdata->pool, auth->last_chal,
			   tdata->msg->line.req.uri,
			   cred, &tdata->msg->line.req.method,
			   sess->pool, auth, &hauth);
    if (status != PJ_SUCCESS)
	return status;
    
    pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)hauth);

    if (p_h_auth)
	*p_h_auth = hauth;

    return PJ_SUCCESS;
}
예제 #2
0
파일: auth.c 프로젝트: 99years/plan9
static Auth *
auth_lm_and_ntlm(char *windom, char *keyp, uchar *chal, int len)
{
	int err;
	char user[64];
	Auth *ap;
	MSchapreply mcr;

	err = auth_respond(chal, len, user, sizeof user, &mcr, sizeof mcr,
		auth_getkey, "windom=%s proto=mschap role=client service=cifs %s",
		windom, keyp);
	if(err == -1)
		sysfatal("cannot get key - %r");

	ap = emalloc9p(sizeof(Auth));
	memset(ap, 0, sizeof(ap));
	ap->user = estrdup9p(user);
	ap->windom = estrdup9p(windom);

	/* LM response */
	ap->len[0] = sizeof(mcr.LMresp);
	ap->resp[0] = emalloc9p(ap->len[0]);
	memcpy(ap->resp[0], mcr.LMresp, ap->len[0]);

	/* NTLM response */
	ap->len[1] = sizeof(mcr.NTresp);
	ap->resp[1] = emalloc9p(ap->len[1]);
	memcpy(ap->resp[1], mcr.NTresp, ap->len[1]);

	return ap;
}
예제 #3
0
파일: respond.c 프로젝트: 00001/plan9port
void
main(int argc, char **argv)
{
	char buf[128];
	int n;

	ARGBEGIN{
	default:
		usage();
	}ARGEND

	if(argc != 2)
		usage();

	memset(buf, 0, sizeof buf);
	n = auth_respond(argv[1], strlen(argv[1]), buf, sizeof buf-1, auth_getkey, "%s", argv[0]);
	if(n < 0)
		sysfatal("auth_respond: %r");
	write(1, buf, n);
	print("\n");
}
예제 #4
0
파일: pop3.c 프로젝트: AustenConrad/plan-9
//
// log in using APOP if possible, password if allowed by user
//
static char*
pop3login(Pop *pop)
{
	int n;
	char *s, *p, *q;
	char ubuf[128], user[128];
	char buf[500];
	UserPasswd *up;

	s = pop3resp(pop);
	if(!isokay(s))
		return "error in initial handshake";

	if(pop->user)
		snprint(ubuf, sizeof ubuf, " user=%q", pop->user);
	else
		ubuf[0] = '\0';

	// look for apop banner
	if(pop->ppop==0 && (p = strchr(s, '<')) && (q = strchr(p+1, '>'))) {
		*++q = '\0';
		if((n=auth_respond(p, q-p, user, sizeof user, buf, sizeof buf, auth_getkey, "proto=apop role=client server=%q%s",
			pop->host, ubuf)) < 0)
			return "factotum failed";
		if(user[0]=='\0')
			return "factotum did not return a user name";

		if(s = pop3capa(pop))
			return s;

		pop3cmd(pop, "APOP %s %.*s", user, n, buf);
		if(!isokay(s = pop3resp(pop)))
			return s;

		return nil;
	} else {
		if(pop->ppop == 0)
			return "no APOP hdr from server";

		if(s = pop3capa(pop))
			return s;

		if(pop->needtls && !pop->encrypted)
			return "could not negotiate TLS";

		up = auth_getuserpasswd(auth_getkey, "proto=pass service=pop dom=%q%s",
			pop->host, ubuf);
		if(up == nil)
			return "no usable keys found";

		pop3cmd(pop, "USER %s", up->user);
		if(!isokay(s = pop3resp(pop))){
			free(up);
			return s;
		}
		pop3cmd(pop, "PASS %s", up->passwd);
		free(up);
		if(!isokay(s = pop3resp(pop)))
			return s;

		return nil;
	}
}
예제 #5
0
파일: auth.c 프로젝트: bhanug/harvey
int
vncauth(Vnc *v, char *keypattern)
{
	char pw[128], *reason;
	uint8_t chal[VncChalLen];
	uint32_t auth;
	char *p, *server;

	if(keypattern == nil)
		keypattern = "";
	auth = vncrdlong(v);
	switch(auth){
	default:
		werrstr("unknown auth type 0x%lux", auth);
		if(verbose)
			fprint(2, "unknown auth type 0x%lux", auth);
		return -1;

	case AFailed:
		reason = vncrdstring(v);
		werrstr("%s", reason);
		if(verbose)
			fprint(2, "auth failed: %s\n", reason);
		return -1;

	case ANoAuth:
		if(verbose)
			fprint(2, "no auth needed");
		break;

	case AVncAuth:
		vncrdbytes(v, chal, VncChalLen);
		server = strdup(serveraddr);
		p = strrchr(server, ':');
		if(p)
			*p = 0;
		if(auth_respond(chal, VncChalLen, nil, 0, chal, VncChalLen, auth_getkey,
			"proto=vnc role=client server=%s %s", server, keypattern) != VncChalLen){
			/* BUG This is for drawterm users who don't start their own factotums */
			readln("password: "******"unknown server response 0x%lux", auth);
			return -1;
		case VncAuthFailed:
			werrstr("server says authentication failed");
			return -1;
		case VncAuthTooMany:
			werrstr("server says too many tries");
			return -1;
		case VncAuthOK:
			break;
		}
		break;
	}
	return 0;
}
예제 #6
0
/* Process authorization challenge */
static pj_status_t process_auth( pj_pool_t *req_pool,
				 const pjsip_www_authenticate_hdr *hchal,
				 const pjsip_uri *uri,
				 pjsip_tx_data *tdata,
				 pjsip_auth_clt_sess *sess,
				 pjsip_cached_auth *cached_auth,
				 pjsip_authorization_hdr **h_auth)
{
    const pjsip_cred_info *cred;
    pjsip_authorization_hdr *sent_auth = NULL;
    pjsip_hdr *hdr;
    pj_status_t status;

    /* See if we have sent authorization header for this realm */
    hdr = tdata->msg->hdr.next;
    while (hdr != &tdata->msg->hdr) {
	if ((hchal->type == PJSIP_H_WWW_AUTHENTICATE &&
	     hdr->type == PJSIP_H_AUTHORIZATION) ||
	    (hchal->type == PJSIP_H_PROXY_AUTHENTICATE &&
	     hdr->type == PJSIP_H_PROXY_AUTHORIZATION))
	{
	    sent_auth = (pjsip_authorization_hdr*) hdr;
	    if (pj_stricmp(&hchal->challenge.common.realm, 
			   &sent_auth->credential.common.realm )==0)
	    {
		/* If this authorization has empty response, remove it. */
		if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&
		    sent_auth->credential.digest.response.slen == 0)
		{
		    /* This is empty authorization, remove it. */
		    hdr = hdr->next;
		    pj_list_erase(sent_auth);
		    continue;
		} else {
		    /* Found previous authorization attempt */
		    break;
		}
	    }
	}
	hdr = hdr->next;
    }

    /* If we have sent, see if server rejected because of stale nonce or
     * other causes.
     */
    if (hdr != &tdata->msg->hdr) {
	pj_bool_t stale;

	/* Detect "stale" state */
	stale = hchal->challenge.digest.stale;
	if (!stale) {
	    /* If stale is false, check is nonce has changed. Some servers
	     * (broken ones!) want to change nonce but they fail to set
	     * stale to true.
	     */
	    stale = pj_strcmp(&hchal->challenge.digest.nonce,
			      &sent_auth->credential.digest.nonce);
	}

	if (stale == PJ_FALSE) {
	    /* Our credential is rejected. No point in trying to re-supply
	     * the same credential.
	     */
	    PJ_LOG(4, (THIS_FILE, "Authorization failed for %.*s@%.*s: "
		       "server rejected with stale=false",
		       sent_auth->credential.digest.username.slen,
		       sent_auth->credential.digest.username.ptr,
		       sent_auth->credential.digest.realm.slen,
		       sent_auth->credential.digest.realm.ptr));
	    return PJSIP_EFAILEDCREDENTIAL;
	}

	cached_auth->stale_cnt++;
	if (cached_auth->stale_cnt >= PJSIP_MAX_STALE_COUNT) {
	    /* Our credential is rejected. No point in trying to re-supply
	     * the same credential.
	     */
	    PJ_LOG(4, (THIS_FILE, "Authorization failed for %.*s@%.*s: "
		       "maximum number of stale retries exceeded",
		       sent_auth->credential.digest.username.slen,
		       sent_auth->credential.digest.username.ptr,
		       sent_auth->credential.digest.realm.slen,
		       sent_auth->credential.digest.realm.ptr));
	    return PJSIP_EAUTHSTALECOUNT;
	}

	/* Otherwise remove old, stale authorization header from the mesasge.
	 * We will supply a new one.
	 */
	pj_list_erase(sent_auth);
    }

    /* Find credential to be used for the challenge. */
    cred = auth_find_cred( sess, &hchal->challenge.common.realm, 
			   &hchal->scheme);
    if (!cred) {
	const pj_str_t *realm = &hchal->challenge.common.realm;
	PJ_LOG(4,(THIS_FILE, 
		  "Unable to set auth for %s: can not find credential for %.*s/%.*s",
		  tdata->obj_name, 
		  realm->slen, realm->ptr,
		  hchal->scheme.slen, hchal->scheme.ptr));
	return PJSIP_ENOCREDENTIAL;
    }

    /* Respond to authorization challenge. */
    status = auth_respond( req_pool, hchal, uri, cred, 
			   &tdata->msg->line.req.method, 
			   sess->pool, cached_auth, h_auth);
    return status;
}
예제 #7
0
/* Initialize outgoing request. */
PJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
					     pjsip_tx_data *tdata )
{
    const pjsip_method *method;
    pjsip_cached_auth *auth;
    pjsip_hdr added;

    PJ_ASSERT_RETURN(sess && tdata, PJ_EINVAL);
    PJ_ASSERT_RETURN(sess->pool, PJSIP_ENOTINITIALIZED);
    PJ_ASSERT_RETURN(tdata->msg->type==PJSIP_REQUEST_MSG,
		     PJSIP_ENOTREQUESTMSG);

    /* Init list */
    pj_list_init(&added);

    /* Get the method. */
    method = &tdata->msg->line.req.method;

    auth = sess->cached_auth.next;
    while (auth != &sess->cached_auth) {
	/* Reset stale counter */
	auth->stale_cnt = 0;

	if (auth->qop_value == PJSIP_AUTH_QOP_NONE) {
#	    if defined(PJSIP_AUTH_HEADER_CACHING) && \
	       PJSIP_AUTH_HEADER_CACHING!=0
	    {
		pjsip_cached_auth_hdr *entry = auth->cached_hdr.next;
		while (entry != &auth->cached_hdr) {
		    if (pjsip_method_cmp(&entry->method, method)==0) {
			pjsip_authorization_hdr *hauth;
			hauth = pjsip_hdr_shallow_clone(tdata->pool, entry->hdr);
			//pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);
			pj_list_push_back(&added, hauth);
			break;
		    }
		    entry = entry->next;
		}

#		if defined(PJSIP_AUTH_AUTO_SEND_NEXT) && \
			   PJSIP_AUTH_AUTO_SEND_NEXT!=0
		{
		    if (entry == &auth->cached_hdr)
			new_auth_for_req( tdata, sess, auth, NULL);
		}
#		endif

	    }
#	    elif defined(PJSIP_AUTH_AUTO_SEND_NEXT) && \
		 PJSIP_AUTH_AUTO_SEND_NEXT!=0
	    {
		new_auth_for_req( tdata, sess, auth, NULL);
	    }
#	    endif

	} 
#	if defined(PJSIP_AUTH_QOP_SUPPORT) && \
	   defined(PJSIP_AUTH_AUTO_SEND_NEXT) && \
	   (PJSIP_AUTH_QOP_SUPPORT && PJSIP_AUTH_AUTO_SEND_NEXT)
	else if (auth->qop_value == PJSIP_AUTH_QOP_AUTH) {
	    /* For qop="auth", we have to re-create the authorization header. 
	     */
	    const pjsip_cred_info *cred;
	    pjsip_authorization_hdr *hauth;
	    pj_status_t status;

	    cred = auth_find_cred(sess, &auth->realm, 
				  &auth->last_chal->scheme);
	    if (!cred) {
		auth = auth->next;
		continue;
	    }

	    status = auth_respond( tdata->pool, auth->last_chal, 
				   tdata->msg->line.req.uri, 
				   cred,
				   &tdata->msg->line.req.method,
				   sess->pool, auth, &hauth);
	    if (status != PJ_SUCCESS)
		return status;
	    
	    //pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);
	    pj_list_push_back(&added, hauth);
	}
#	endif	/* PJSIP_AUTH_QOP_SUPPORT && PJSIP_AUTH_AUTO_SEND_NEXT */

	auth = auth->next;
    }

    if (sess->pref.initial_auth == PJ_FALSE) {
	pjsip_hdr *h;

	/* Don't want to send initial empty Authorization header, so
	 * just send whatever available in the list (maybe empty).
	 */

	h = added.next;
	while (h != &added) {
	    pjsip_hdr *next = h->next;
	    pjsip_msg_add_hdr(tdata->msg, h);
	    h = next;
	}
    } else {
	/* For each realm, add either the cached authorization header
	 * or add an empty authorization header.
	 */
	unsigned i;
	char *uri_str;
	int len;

	uri_str = (char*)pj_pool_alloc(tdata->pool, PJSIP_MAX_URL_SIZE);
	len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, tdata->msg->line.req.uri,
			      uri_str, PJSIP_MAX_URL_SIZE);
	if (len < 1 || len >= PJSIP_MAX_URL_SIZE)
	    return PJSIP_EURITOOLONG;

	for (i=0; i<sess->cred_cnt; ++i) {
	    pjsip_cred_info *c = &sess->cred_info[i];
	    pjsip_authorization_hdr *h;

	    h = get_header_for_realm(&added, &c->realm);
	    if (h) {
		pj_list_erase(h);
		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)h);
	    } else {
		pjsip_authorization_hdr *hs;

		hs = pjsip_authorization_hdr_create(tdata->pool);
		pj_strdup(tdata->pool, &hs->scheme, &c->scheme);
		pj_strdup(tdata->pool, &hs->credential.digest.username,
			  &c->username);
		pj_strdup(tdata->pool, &hs->credential.digest.realm,
			  &c->realm);
		pj_strdup2(tdata->pool, &hs->credential.digest.uri,
			   uri_str);
		pj_strdup(tdata->pool, &hs->credential.digest.algorithm,
			  &sess->pref.algorithm);

		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hs);
	    }
	}
    }

    return PJ_SUCCESS;
}