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; }
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; }
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"); }
// // 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; } }
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; }
/* 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; }
/* 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; }