⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myproxy_authorization.c

📁 代理服务器源代码 供大家学习使用,希望大家喜欢
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "myproxy_common.h"	/* all needed headers included here */#include "pubcookie.h"#if defined(HAVE_LIBPAM)#include "auth_pam.h"#endifstruct authorization_func {   author_status_t (*get_status) (struct myproxy_creds *creds,				  char *client_name,				  myproxy_server_context_t* config);   char * (*create_server_data) (void);   char * (*create_client_data) (authorization_data_t *data, 	                         void *extra_data, 				 size_t extra_data_len,				 size_t *client_data_len);   int (*check_client) (authorization_data_t *client_auth_data,			struct myproxy_creds *creds,			char *client_name, myproxy_server_context_t* config);   author_method_t method;   char *name; /* arbitrary ASCII string without a colon (':') */};static struct authorization_func * _find_func(author_method_t method);static authorization_data_t * _find_data(author_method_t method, authorization_data_t **data);/* * Implementation of password-based authorization */author_status_tauth_passwd_get_status(struct myproxy_creds *creds, char *client_name,		       myproxy_server_context_t* config){    assert(creds);    assert(config);        if (myproxy_creds_exist(creds->username, creds->credname) == 1 &&	myproxy_creds_encrypted(creds) == 1) {	return AUTHORIZEMETHOD_REQUIRED;    }#if defined(HAVE_LIBPAM)    if (config->pam_policy) {	if (strcmp(config->pam_policy, "required") == 0) {	    return AUTHORIZEMETHOD_REQUIRED;	}	if (strcmp(config->pam_policy, "sufficient") == 0) {	    return AUTHORIZEMETHOD_SUFFICIENT;	}    }#endif   if (config->pubcookie_cert && config->pubcookie_key) {       return AUTHORIZEMETHOD_SUFFICIENT;   }    return AUTHORIZEMETHOD_DISABLED;}char * auth_passwd_create_server_data(void){   return strdup("Enter MyProxy pass phrase:");}char * auth_passwd_create_client_data(authorization_data_t *data,                                void *extra_data, size_t extra_data_len,			       size_t *client_data_len){    char *tmp;   tmp = malloc(extra_data_len + 1);   if (tmp == NULL)      return NULL;   memcpy(tmp, extra_data, extra_data_len);   tmp[extra_data_len] = '\0';   *client_data_len = extra_data_len + 1;   return tmp;}/*************************************************************************//**                                                                     **//**  code to decrypt and verify pubcookie (http://www.pubcookie.org/)   **//**                                                                     **/ /**        Steve Losen, UVA ITC                                         **//**                                                                     **//**                                                                     **//*************************************************************************//* * decrypt_cookie() accepts a base64 encoded input string that * consists of a DES encrypted and signed cookie.  We decrypt * the input and verify the cookie data with the signature. * * inbuf  points to the base64 encoded input * * inlen  is the length of the input in bytes * * cookie points to a struct to receive the cookie data * * keybuf is a 2048 byte symmetric encryption key from which we *        obtain the DES key and initial vector * * cert   is the X509 cert for verifying the signature * * We base64 decode the input.  The last two decoded bytes are random * offsets into keybuf.  The first offset is the start of the DES key. * The second offset is the start of the initial vector.  Using the DES * key and initial vector, we decrypt the signature and the cookie data. * We verify the cookie data with the signature and the cert.  If correct, * then we return 0.  We return -1 on any failure. *//* Note we (temporarily) use des_ functions instead of the DES_   functions introduced in OpenSSL 0.9.7 for backwards compatibility   with OpenSSL 0.9.6.  At some point we should switch (back) to the   DES_ versions, at which point, beware the old functions take   des_key_schedule arguments whereas the new ones take   (DES_key_schedule *) arguments. */intdecrypt_cookie(const unsigned char *inbuf, int inlen,    struct cookie_data *cookie, const unsigned char *keybuf,    X509 *cert){    unsigned char tmpbuf[2048];    unsigned char signature[1024];    int siglen;    BIO *bio, *b64;    des_cblock deskey, ivec;	/* see note about des_ vs. DES_ above */    des_key_schedule ks;    EVP_PKEY *pubkey = NULL;    EVP_MD_CTX ctx;    int offset, i;    int return_value = -1;    /* base64 decode the input */    if (4 * sizeof(tmpbuf) < 3 * inlen) {        return -1;    }    b64 = BIO_new(BIO_f_base64());    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);    bio = BIO_new_mem_buf((void *)inbuf, inlen);    bio = BIO_push(b64, bio);    inlen = BIO_read(bio, tmpbuf, sizeof(tmpbuf));    BIO_free_all(bio);    inbuf = tmpbuf;    /* get public key from cert and length of signature */    if ((pubkey = X509_extract_key(cert)) == 0) {	goto cleanup;    }    siglen = EVP_PKEY_size(pubkey);    if (siglen > sizeof(signature) ||        inlen != siglen + sizeof(*cookie) + 2)    {	goto cleanup;    }    /* get the DES key from keybuf */    offset = inbuf[inlen - 2];    memcpy (deskey, keybuf + offset, sizeof(deskey));    des_set_odd_parity(&deskey);    if (des_set_key_checked(&deskey, ks) != 0) {	goto cleanup;    }    /* get the DES initial vector from keybuf */    offset = inbuf[inlen - 1];    for (i = 0; i < sizeof(ivec); i++) {        ivec[i] = keybuf[offset + i] ^ 0x4c;    }    /* decrypt signature and cookie data */    i = 0;    des_cfb64_encrypt(inbuf, signature, siglen, ks, &ivec, &i,        DES_DECRYPT);    des_cfb64_encrypt (inbuf + siglen, (unsigned char *)cookie,        sizeof(*cookie), ks, &ivec, &i, DES_DECRYPT);    /* verify signature */    EVP_VerifyInit(&ctx, EVP_md5());    EVP_VerifyUpdate(&ctx, (unsigned char *)cookie, sizeof(*cookie));    if (EVP_VerifyFinal(&ctx, signature, siglen, pubkey) != 1) {	goto cleanup;    }    myproxy_debug("valid pubcookie signature");    /* convert to host byte order */    cookie->pre_sess_token = ntohl(cookie->pre_sess_token);    cookie->create_ts      = ntohl(cookie->create_ts);    cookie->last_ts        = ntohl(cookie->last_ts);    return_value = 0; cleanup:    EVP_MD_CTX_cleanup(&ctx);    if (pubkey) EVP_PKEY_free(pubkey);    return return_value;}int auth_pubcookie_check_client (authorization_data_t *auth_data,				 struct myproxy_creds *creds, 				 char *client_name,				 myproxy_server_context_t* config){   int return_status;  FILE *fp;  struct cookie_data cookie;  unsigned char keybuf[2048];  X509 *cert = NULL;  return_status = 1;  if (!config->pubcookie_cert || !config->pubcookie_key) {      return 0; /* Pubcookie support not enabled. */  }  /* read symmetric key file for decrypting cookie */  if ((fp = fopen(config->pubcookie_key, "r")) == 0 ||      fread(keybuf, 1, sizeof(keybuf), fp) != sizeof(keybuf)) {      verror_put_string("ERROR opening %s", config->pubcookie_key);      verror_put_errno(errno);      return_status=0;      if (fp)	fclose(fp);  }    /* read cert file for verifying cookie signature */  if(return_status==1) {    if ((fp = fopen(config->pubcookie_cert, "r")) == 0 ||        (cert = PEM_read_X509(fp, 0, 0, 0)) == 0)      {	verror_put_string("ERROR opening %s", config->pubcookie_cert);	verror_put_errno(errno);        return_status=0;	if (fp)	  fclose(fp);      }  }  /* decrypt cookie and verify  -- TO DO: make this time-dependent on the cookie, but we can't      do it right now (it's NOT the create_ts -- which looks like it could be up to a week?) */  if(return_status==1) {    int decrypt_result;    int cookie_type;    time_t cookie_deadline, now;        decrypt_result =   decrypt_cookie((unsigned char *)auth_data->client_data, auth_data->client_data_len, &cookie,                                      keybuf, cert);        if (decrypt_result == 0) {      cookie_type = cookie.type;      cookie_deadline = cookie.create_ts + 24 * 3600;            if (cookie_type != '1') { /* yes, fix this hard-code.. I realize... */        verror_prepend_string("Wrong cookie type");        return_status=0;      }      if(return_status==1) {	now = time (0);	myproxy_debug("Pubcookie presented: now is %d, cookie create_ts: %d, cookie last_ts: %d",		     (int) time(0), (int) cookie.create_ts, (int) cookie.last_ts);#ifdef NOT_CORRECT        if (cookie_deadline < now) {          verror_prepend_string("Cookie is older than 1 day (cookie creation timestamp: %d (%s), one day from cookie timestamp (deadline): %d (%s), now: %d (%s))", 				cookie.create_ts, ctime(&(cookie.create_ts)),				cookie_deadline, ctime(&cookie_deadline), 				now, ctime(&now));          return_status=0;        }#endif       }    }    else {      verror_prepend_string("Could not decrypt and verify pubcookie");      return_status=0;    }  }  /* test #2: verify username */  if(return_status==1) {    if(strcmp((char *)cookie.user, creds->username)) {      verror_put_string("Pubcookie username (%s) and request username (%s) do not match", (char *)cookie.user, creds->username);       return_status=0;    }  }  /* may want to verify other info at some point */  if (return_status==1) {      myproxy_log("Pubcookie verified username: %s", (char *)cookie.user);  }  if (cert) X509_free(cert);  return return_status;}/* end of Pubcookie-specific code */int auth_passwd_check_client(authorization_data_t *client_auth_data,                             struct myproxy_creds *creds, char *client_name,			     myproxy_server_context_t* config){    int exist=0, encrypted=0, cred_passphrase_match=0;#if defined(HAVE_LIBPAM)   char* pam_policy = NULL;   char* pam_id = NULL;   int pam_required, pam_sufficient, pam_disabled;#endif   /* 1. Gather some initial information. */   exist = myproxy_creds_exist(creds->username, creds->credname);   if (exist < 0) {       return 0;   }   if (exist) {       encrypted = myproxy_creds_encrypted(creds);       if (encrypted < 0) {	   return 0;       }   }   /* 2. Check whether the password the user gave matches the    *    credential passphrase */   if (exist && (encrypted || creds->passphrase))   {      if (client_auth_data->client_data_len >= MIN_PASS_PHRASE_LEN &&	  client_auth_data->client_data != NULL &&	  myproxy_creds_verify_passphrase(creds,					  client_auth_data->client_data) == 1){	 cred_passphrase_match = 1;	 myproxy_log("credential passphrase matched");      } else {	  /* We always have to match the credential passphrase if it exists. */	  verror_put_string("invalid credential passphrase");	  return 0;      }   }      if (config->pubcookie_cert && config->pubcookie_key) {       myproxy_debug("attempting pubcookie verification");       if (!cred_passphrase_match) {	   cred_passphrase_match =	       (auth_pubcookie_check_client(client_auth_data, creds,					    client_name, config) == 1) ? 1 : 0;       }   }#if defined(HAVE_LIBPAM)   /* Tangent: figure out PAM configuration. */   pam_policy = config ? config->pam_policy : NULL;   pam_id     = config ? config->pam_id : NULL;   /* Default value is "disabled". */   if (pam_policy == NULL) pam_policy = "disabled";   pam_required   = (strcmp(pam_policy, "required"  ) == 0 ? 1 : 0);   pam_sufficient = (strcmp(pam_policy, "sufficient") == 0 ? 1 : 0);   pam_disabled   = (strcmp(pam_policy, "disabled"  ) == 0 ? 1 : 0);   /* Note: if pam_policy is not recognized, it will fall through to    * the disabled case below, and a debug message will be printed. */   /* 3. If the passphrase matches the credentials, and PAM config is    *    "sufficient", then we're done, and we don't need to check    *    PAM, as long as a passphrase was actually entered. */   if (pam_sufficient && cred_passphrase_match)   {      myproxy_debug("Passphrase matches credentials, and PAM config is \"%s\"; "		    "authentication succeeds without checking PAM.", pam_policy);      return cred_passphrase_match;   }   /* 4. If PAM is "required", *always* check it, regardless of    *    whether the credential passphrase matches, so that any    *    logging, pausing, etc. can occur.  Also, if PAM is sufficient    *    and we've gotten this far, it means that the credential    *    passphrase is blank and therefore we need to check PAM. */   else if (pam_required || pam_sufficient)   {      char* auth_pam_result = NULL;      int pam_success = 0;      if (pam_id == NULL) pam_id = "myproxy";      myproxy_debug	 ("Checking passphrase via PAM.  PAM policy: \"%s\"; PAM ID: \"%s\"",	  pam_policy, pam_id);      auth_pam_result = auth_pam(creds->username,				 client_auth_data->client_data, pam_id, NULL);      if (auth_pam_result && strcmp("OK", auth_pam_result) == 0) {	 pam_success = 1;	 myproxy_log("PAM authentication succeeded for %s",		     creds->username);      } else {	 if (auth_pam_result) {	    /* The Cyrus SASL convention is to prepend the error	       message with "NO ".  We can chop that off. */	    if (strlen(auth_pam_result) > 3 		&& strncmp(auth_pam_result, "NO ", 3) == 0) 	    {	       verror_put_string(auth_pam_result + 3);	    }	    else verror_put_string(auth_pam_result);	 }	 else 	    verror_put_string("PAM authentication failed");      }      if (auth_pam_result != NULL) {	 free(auth_pam_result);      }      return pam_success;   }   /* 5. If PAM is disabled, check only the credential passphrase. */   else   {      if (!pam_disabled) {	 myproxy_log("Unknown PAM policy: \"%s\"; not using PAM.\n", pam_policy);      }      return cred_passphrase_match;   }#else /* defined(HAVE_LIBPAM) */   return cred_passphrase_match;#endif /* defined(HAVE_LIBPAM) */}struct authorization_func authorization_passwd = {   auth_passwd_get_status,   auth_passwd_create_server_data,   auth_passwd_create_client_data,   auth_passwd_check_client,   AUTHORIZETYPE_PASSWD,   "password"};/*  * Implementation of certificate-based authorization */author_status_tauth_cert_get_status(struct myproxy_creds *creds, char *client_name,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -