pike.git / src / post_modules / ZXID / zxid.cmod

version» Context lines:

pike.git/src/post_modules/ZXID/zxid.cmod:13:   #include "fdlib.h"   #include "fd_control.h"   #include "backend.h"   #include "module_support.h"   #include "array.h"   #include "builtin_functions.h"   #include "mapping.h"   #include "pike_types.h"   #include "threads.h"   #include "pike_threadlib.h" - #include "dmalloc.h" +       #include "zxid_config.h"      DECLARATIONS      #ifdef HAVE_ZXID      /*! @module ZXID    *!    *! ZXID is a library that implements SAML 2.0, Liberty ID-WSF 2.0    *! and XACML 2.0.    *!    *! This module implements a wrapper for ZXID. The interface is similar    *! to the C one, but using generally accepted Pike syntax.    */    -  + /* This symbol conflicts with a definition of the same in <zxid/errmac.h>. +  */ + #undef GETTIMEOFDAY +    /* These defines are needed to get the right size for the zxid_conf struct! */   #define USE_CURL   #define USE_PTHREAD   #define USE_OPENSSL      #include <zxid/zxid.h>      /* Needed for some obscure macros (like ERR, DD, MB, ME, etc). */   #include <zxid/errmac.h>      /* Needed for zxid_new_at(). */   #include <zxid/zxidpriv.h>      /* Needed for zx_md_EntityDescriptor_s. */   /* #include <zxid/zx-md-data.h> */      #include "constants.h"    - #define THIS_OBJ Pike_interpreter.frame_pointer->current_object - #define RET_THIS() do { pop_n_elems(args); ref_push_object(THIS_OBJ); return; } while(0) -  - /* Fall back to a normal index on this object, in case -  * someone inherited us. */ -  #define OBJ_INDEX() do { \ -  struct svalue res; \ -  object_index_no_free2 (&res, Pike_fp->current_object, 0, Pike_sp-1); \ -  pop_stack(); \ -  *Pike_sp++ = res; \ -  } while(0) \ -  -  - #define CHECK_CLASS(o, name, arg)\ -  if(o->prog != PIKE_CONCAT(name, _program)) { \ -  Pike_error("Invalid class for argument %d\n", arg); \ -  } -  +    #ifdef malloc   /* DMALLOC or similar. */   void *malloc_wrapper(size_t bytes)   {    return malloc(bytes);   }   void *realloc_wrapper(void *ptr, size_t bytes)   {    return realloc(ptr, bytes);   }   void free_wrapper(void *ptr)   {    free(ptr);   }   #endif    -  + #ifdef HAVE_STRUCT_ZXID_CONF_BURL + /* These fields were renamed 2013-12-05. */ + #define BURL(CONF) ((CONF).burl) + #define CPATH(CONF) ((CONF).cpath) + #define CPATH_LEN(CONF) ((CONF).cpath_len) + #else + #define BURL(CONF) ((CONF).url) + #define CPATH(CONF) ((CONF).path) + #define CPATH_LEN(CONF) ((CONF).path_len) + #endif +  + #ifndef ERRMAC_INOUT + /* These were renamed 2013-11-13. */ + #define errmac_debug zx_debug + #define ERRMAC_INOUT ZXID_INOUT + #endif +    /*! @class Configuration    *!    *! A set of configuration parameters for a ZXID context.    *!    *! This is typically overloaded with new definitions    *! for the various callback functions.    */   PIKECLASS Configuration {    CVAR zxid_conf conf;   
pike.git/src/post_modules/ZXID/zxid.cmod:247:    CHECK_ARG_STRING(MK_STRING("COUNTRY"), THIS->conf.country);    CHECK_ARG_INT(MK_STRING("CANON_INOPT"), THIS->conf.canon_inopt);    THIS->conf.ctx->canon_inopt = THIS->conf.canon_inopt;    CHECK_ARG_INT(MK_STRING("CPN_ENA"), THIS->conf.cpn_ena);    CHECK_ARG_STRING(MK_STRING("DEFAULTQS"), THIS->conf.defaultqs);    CHECK_ARG_INT(MK_STRING("DUP_A7N_FATAL"), THIS->conf.dup_a7n_fatal);    CHECK_ARG_INT(MK_STRING("DUP_MSG_FATAL"), THIS->conf.dup_msg_fatal);    CHECK_ARG_CHAR(MK_STRING("DI_ALLOW_CREATE"), THIS->conf.di_allow_create);    CHECK_ARG_INT(MK_STRING("DI_NID_FMT"), THIS->conf.di_nid_fmt);    CHECK_ARG_INT(MK_STRING("DI_A7N_ENC"), THIS->conf.di_a7n_enc); -  CHECK_ARG_INT(MK_STRING("DEBUG"), zx_debug); +  CHECK_ARG_INT(MK_STRING("DEBUG"), errmac_debug);    LOW_CHECK_ARG(MK_STRING("DEBUG_LOG"),    ((TYPEOF(*s) == PIKE_T_STRING) && !s->u.string->size_shift),    zxid_set_opt_cstr(&THIS->conf, 6, s->u.string->str));    CHECK_ARG_INT(MK_STRING("ERR"), THIS->conf.log_err);    CHECK_ARG_INT(MK_STRING("ERR_IN_ACT"), THIS->conf.log_err_in_act);    CHECK_ARG_INT(MK_STRING("ENC_TAIL_OPT"), THIS->conf.enc_tail_opt);    CHECK_ARG_INT(MK_STRING("ENCKEY_OPT"), THIS->conf.enckey_opt);    CHECK_ARG_STRING(MK_STRING("ERR_PAGE"), THIS->conf.err_page);    CHECK_ARG_STRING(MK_STRING("ERR_TEMPL_FILE"), THIS->conf.err_templ_file);    CHECK_ARG_STRING(MK_STRING("ERR_TEMPL"), THIS->conf.err_templ);
pike.git/src/post_modules/ZXID/zxid.cmod:285:    THIS->conf.idp_sel_templ_file);    CHECK_ARG_STRING(MK_STRING("IDP_SEL_TEMPL"), THIS->conf.idp_sel_templ);    CHECK_ARG_INT(MK_STRING("IDP_ENA"), THIS->conf.idp_ena);    CHECK_ARG_INT(MK_STRING("IDP_PXY_ENA"), THIS->conf.idp_pxy_ena);    CHECK_ARG_INT(MK_STRING("IMPS_ENA"), THIS->conf.imps_ena);    CHECK_ARG_STRING(MK_STRING("IDP_PREF_ACS_BINDING"),    THIS->conf.idp_pref_acs_binding);    CHECK_ARG_INT(MK_STRING("IDPATOPT"), THIS->conf.idpatopt);    CHECK_ARG_INT(MK_STRING("IDP_LIST_METH"), THIS->conf.idp_list_meth);    CHECK_ARG_MAP(MK_STRING("INMAP"), THIS->conf.inmap); +  CHECK_ARG_STRING(MK_STRING("IPPORT"), THIS->conf.ipport);    CHECK_ARG_INT(MK_STRING("LEVEL"), THIS->conf.log_level);    CHECK_ARG_INT(MK_STRING("LOGUSER"), THIS->conf.loguser);    CHECK_ARG_CSTR_LIST(MK_STRING("LOCALPDP_ROLE_PERMIT"),    THIS->conf.localpdp_role_permit);    CHECK_ARG_CSTR_LIST(MK_STRING("LOCALPDP_ROLE_DENY"),    THIS->conf.localpdp_role_deny);    CHECK_ARG_CSTR_LIST(MK_STRING("LOCALPDP_IDPNID_PERMIT"),    THIS->conf.localpdp_idpnid_permit);    CHECK_ARG_CSTR_LIST(MK_STRING("LOCALPDP_IDPNID_DENY"),    THIS->conf.localpdp_idpnid_deny);
pike.git/src/post_modules/ZXID/zxid.cmod:328:    THIS->conf.notimestamp_fatal);    CHECK_ARG_NEED(MK_STRING("NEED"), THIS->conf.need);    CHECK_ARG_STRING(MK_STRING("NEW_USER_PAGE"), THIS->conf.new_user_page);    CHECK_ARG_MAP(MK_STRING("OUTMAP"), THIS->conf.outmap);    CHECK_ARG_STRING(MK_STRING("ORG_NAME"), THIS->conf.org_name);       LOW_CHECK_ARG(MK_STRING("PATH"),    ((TYPEOF(*s) == PIKE_T_STRING) &&    !s->u.string->size_shift),    do { -  if (THIS->conf.path) { -  ZX_FREE(THIS->conf.ctx, THIS->conf.path); +  if (CPATH(THIS->conf)) { +  ZX_FREE(THIS->conf.ctx, CPATH(THIS->conf));    } -  THIS->conf.path = strdup(s->u.string->str); -  THIS->conf.path_len = s->u.string->len; +  CPATH(THIS->conf) = strdup(s->u.string->str); +  CPATH_LEN(THIS->conf) = s->u.string->len;    } while(0));       CHECK_ARG_INT(MK_STRING("PDP_ENA"), THIS->conf.pdp_ena);    CHECK_ARG_STRING(MK_STRING("PDP_URL"), THIS->conf.pdp_url);    CHECK_ARG_STRING(MK_STRING("PDP_CALL_URL"), THIS->conf.pdp_call_url);    CHECK_ARG_MAP(MK_STRING("PEPMAP"), THIS->conf.pepmap);    CHECK_ARG_MAP(MK_STRING("PEPMAP_RQOUT"), THIS->conf.pepmap_rqout);    CHECK_ARG_MAP(MK_STRING("PEPMAP_RQIN"), THIS->conf.pepmap_rqin);    CHECK_ARG_MAP(MK_STRING("PEPMAP_RSOUT"), THIS->conf.pepmap_rsout);    CHECK_ARG_MAP(MK_STRING("PEPMAP_RSIN"), THIS->conf.pepmap_rsin);
pike.git/src/post_modules/ZXID/zxid.cmod:393:    CHECK_ARG_INT(MK_STRING("SSO_SOAP_RESP_SIGN"),    THIS->conf.sso_soap_resp_sign);    CHECK_ARG_INT(MK_STRING("SHOW_CONF"), THIS->conf.show_conf);    CHECK_ARG_INT(MK_STRING("SHOW_TECH"), THIS->conf.show_tech);    CHECK_ARG_STRING(MK_STRING("STATE"), THIS->conf.state);    CHECK_ARG_INT(MK_STRING("TIMEOUT_FATAL"), THIS->conf.timeout_fatal);    CHECK_ARG_INT(MK_STRING("TIMESKEW"), THIS->conf.timeskew);    CHECK_ARG_STRING(MK_STRING("TRUSTPDP_URL"), THIS->conf.trustpdp_url);    CHECK_ARG_KEEP(MK_STRING("URL"), ((TYPEOF(*s) == PIKE_T_STRING) &&    !s->u.string->size_shift), do { -  THIS->conf.url = s->u.string->str; +  BURL(THIS->conf) = s->u.string->str;    if (THIS->conf.fedusername_suffix) {    ZX_FREE(THIS->conf.ctx, THIS->conf.fedusername_suffix);    THIS->conf.fedusername_suffix = NULL;    }    THIS->conf.fedusername_suffix =    zxid_grab_domain_name(&THIS->conf, s->u.string->str);    } while(0));    CHECK_ARG_INT(MK_STRING("USER_LOCAL"), THIS->conf.user_local);    CHECK_ARG_INT(MK_STRING("VALID_OPT"), THIS->conf.valid_opt);    CHECK_ARG_NEED(MK_STRING("WANT"), THIS->conf.want);    CHECK_ARG_INT(MK_STRING("WANT_SSO_A7N_SIGNED"),    THIS->conf.want_sso_a7n_signed);    CHECK_ARG_INT(MK_STRING("WANT_AUTHN_REQ_SIGNED"),    THIS->conf.want_authn_req_signed);    CHECK_ARG_INT(MK_STRING("WSC_SIGN"), THIS->conf.wsc_sign);    CHECK_ARG_INT(MK_STRING("WSP_SIGN"), THIS->conf.wsp_sign);    CHECK_ARG_STRING(MK_STRING("WSPCGICMD"), THIS->conf.wspcgicmd);    CHECK_ARG_INT(MK_STRING("WSP_NOSIG_FATAL"), THIS->conf.wsp_nosig_fatal);    CHECK_ARG_STRING(MK_STRING("WSC_LOCALPDP_OBL_PLEDGE"),    THIS->conf.wsc_localpdp_obl_pledge); -  + #if 0    CHECK_ARG_STRING(MK_STRING("WSP_LOCALPDP_OBL_REQ"), -  THIS->conf.wsp_localpdp_obl_req ); +  THIS->conf.wsp_localpdp_obl_req); + #endif    CHECK_ARG_STRING(MK_STRING("WSP_LOCALPDP_OBL_EMIT"), -  THIS->conf.wsp_localpdp_obl_emit ); +  THIS->conf.wsp_localpdp_obl_emit); + #if 0    CHECK_ARG_STRING(MK_STRING("WSC_LOCALPDP_OBL_ACCEPT"),    THIS->conf.wsc_localpdp_obl_accept); -  + #endif    CHECK_ARG_STRING(MK_STRING("XASP_VERS"), THIS->conf.xasp_vers);       /* The above does approximately the same as    * zxid_conf_to_cf_len(&THIS->conf,    * conf->u.string->len, conf->u.string->str);    * but avoids the HTTP-transport encoding by using a mapping,    * and also attempts not to leak...    */    }       /*! @class Session    *!    *! Represents the current session state for a user.    */    PIKECLASS Session    program_flags PROGRAM_USES_PARENT; /* Shouldn't this be automatic? */    {    CVAR zxid_ses ses; -  CVAR struct Configuration_struct *config; +  CVAR struct ZXID_Configuration_struct *config;    CVAR PIKE_MUTEX_T session_lock; /* ZXID isn't fully thread-safe yet. */       /*! @decl string(0..255) session_id    *!    *! Session id (if any).    */    PIKEVAR string session_id;       INIT    { -  THIS->config = parent_storage(1); +  THIS->config = parent_storage(1, ZXID_Configuration_program);    mt_init(&THIS->session_lock);    }       EXIT    { -  +  if (THIS->ses.at) { +  zxid_free_at(&THIS->config->conf, THIS->ses.at); +  THIS->ses.at = NULL; +  } +  if (THIS->ses.cookie) { +  ZX_FREE(THIS->config->conf.ctx, THIS->ses.cookie); +  THIS->ses.cookie = NULL; +  } +  if (THIS->ses.sesix) { +  ZX_FREE(THIS->config->conf.ctx, THIS->ses.sesix); +  THIS->ses.sesix = NULL; +  } +  if (THIS->ses.setcookie) { +  ZX_FREE(THIS->config->conf.ctx, THIS->ses.setcookie); +  THIS->ses.setcookie = NULL; +  } +  if (THIS->ses.sso_a7n_path) { +  ZX_FREE(THIS->config->conf.ctx, THIS->ses.sso_a7n_path); +  if (THIS->ses.tgt_a7n_path == THIS->ses.sso_a7n_path) { +  /* Often the same pointer. */ +  THIS->ses.tgt_a7n_path = NULL; +  } +  THIS->ses.sso_a7n_path = NULL; +  } +  if (THIS->ses.tgt_a7n_path) { +  ZX_FREE(THIS->config->conf.ctx, THIS->ses.tgt_a7n_path); +  THIS->ses.tgt_a7n_path = NULL; +  }    mt_destroy(&THIS->session_lock);    if (THIS->ses.sesbuf) {    ZX_FREE(THIS->config->conf.ctx, THIS->ses.sesbuf);    THIS->ses.sesbuf = NULL;    }    if (THIS->ses.sid) {    ZX_FREE(THIS->config->conf.ctx, THIS->ses.sid);    THIS->ses.sid = NULL;    }    }       /*! @decl void create(string|void session_id)    *!    *! Create a new or look up an existing session.    */    PIKEFUN void create(string(0..255)|void session_id)    flags ID_PROTECTED;    {    if (session_id && !session_id->size_shift) { -  struct Configuration_Session_struct *this = THIS; +  struct ZXID_Configuration_Session_struct *this = THIS;    if (this->session_id) {    free_string(this->session_id);    }    copy_shared_string(this->session_id, session_id);    THREADS_ALLOW();    mt_lock(&this->session_lock);    if (!zxid_get_ses(&this->config->conf, &this->ses, session_id->str)) {    /* New session. */    if (this->ses.sid) {    ZX_FREE(this->config->conf.ctx, this->ses.sid);    this->ses.sid = NULL;    }    this->ses.sid = zx_dup_cstr(this->config->conf.ctx, session_id->str);    }    mt_unlock(&this->session_lock);    THREADS_DISALLOW();    }    }    -  /*! @decl string(0..255) authenticate(string(0..255) query) +  /* Same as zxid_simple_cf_ses(), but without environment variables, +  * and uri_path passed as an argument instead. +  */ +  static char* pike_cf_ses(zxid_conf* cf, char *uri_path, +  int qs_len, char* qs, +  zxid_ses* ses, int* res_len, int auto_flags) +  { +  int got, ret; +  char* res = 0; +  char *sid; +  zxid_cgi cgi; +  memset(&cgi, 0, sizeof(cgi)); +  +  if (auto_flags & ZXID_AUTO_DEBUG) zxid_set_opt(cf, 1, 3); +  + #ifndef HAVE_ZXID_PARSE_CGI + #error "zxid_parse_cgi() is required." + #elif HAVE_ZXID_PARSE_CGI == 3 +  zxid_parse_cgi(cf, &cgi, qs); + #elif HAVE_ZXID_PARSE_CGI == 2 +  /* Old zxid library. */ +  zxid_parse_cgi(&cgi, qs); + #else + #error "Unsupported number of arguments to zxid_parse_cgi()." + #endif +  +  if (!cgi.op && !cf->bare_url_entityid) { +  cgi.op = 'M'; /* By default, if no ses, check CDC and offer SSO */ +  } +  + #ifdef HAVE_STRUCT_ZXID_CGI_URI_PATH +  cgi.uri_path = uri_path; +  cgi.qs = qs; + #endif +  +  if (cgi.sid) { +  if (!zxid_get_ses(cf, ses, cgi.sid)) { +  D("No session(%s) active op(%c)", cgi.sid, cgi.op); +  } else if ((res = zxid_simple_ses_active_cf(cf, &cgi, ses, res_len, +  auto_flags))) +  return res; +  } +  +  if (ses->sesbuf) { +  ZX_FREE(cf->ctx, ses->sesbuf); +  } +  sid = ses->sid; /* Keep the sid (if any), since it might be +  * used as an object identifier by the caller. */ +  memset(ses, 0, sizeof(zxid_ses)); /* No session yet! Process login form */ +  ses->sid = sid; +  res = zxid_simple_no_ses_cf(cf, &cgi, ses, res_len, auto_flags); +  +  return res; +  } +  +  /*! @decl string(0..255) authenticate(string(0..255) uri_path, @ +  *! string(0..255) query)    *!    *! Authenticate via SAML given the query-string @[query].    *! -  +  *! @param uri_path +  *! Current URI path (before '?'). +  *! +  *! @param query +  *! Query variables (after '?'). +  *!    *! @returns    *! Returns JSON-encoded data on success, and various other    *! strings otherwise.    */ -  PIKEFUN string(0..255) authenticate(string(0..255) query) +  PIKEFUN string(0..255) authenticate(string(0..255) uri_path, +  string(0..255) query)    {    struct string_builder mutable_query;    char *res;    int res_len = 0; -  struct Configuration_struct *config = parent_storage(1); +  struct ZXID_Configuration_struct *config = +  parent_storage(1, ZXID_Configuration_program);    zxid_ses *ses = &THIS->ses;    int extra = 0;    PIKE_MUTEX_T *session_lock = &THIS->session_lock;       if (THIS->session_id) {    extra = 3 + THIS->session_id->len;    }    init_string_builder_alloc(&mutable_query, query->len + extra,    query->size_shift);    string_builder_shared_strcat(&mutable_query, query);    if (extra) {    string_builder_strcat(&mutable_query, "&s=");    string_builder_shared_strcat(&mutable_query, THIS->session_id);    }       THREADS_ALLOW();    mt_lock(session_lock);       /* Let the library handle metadata. */ -  res = zxid_simple_cf_ses(&config->conf, mutable_query.s->len, +  res = pike_cf_ses(&config->conf, uri_path->str, mutable_query.s->len,    mutable_query.s->str, ses, &res_len,    ZXID_AUTO_METAC|ZXID_AUTO_FMTJ);       mt_unlock(session_lock);    THREADS_DISALLOW();       free_string_builder(&mutable_query);       push_string(make_shared_binary_string(res, res_len));       ZX_FREE(config->conf.ctx, res);       stack_pop_n_elems_keep_top(args);    }    }    /*! @endclass    */   #undef THIS - #define THIS THIS_CONFIGURATION + #define THIS THIS_ZXID_CONFIGURATION       /*! @decl mapping(string(0..255):mapping(string(0..255):string(0..255))) idp_list()    *!    *! Return a list of known identity providers.    *!    *! @returns    *! Returns a mapping from IdP EID to display name (if any).    */    PIKEFUN mapping(string(0..255):mapping(string(0..255):string(0..255))) idp_list()    {    zxid_entity *idp = zxid_load_cot_cache(&THIS->conf);    int cnt = 0;    pop_n_elems(args);    check_stack(120);    while(idp) {    int attrs = 0;    /* if (!idp->ed->IDPSSODescriptor) continue; */    push_text(idp->eid); -  push_constant_text("eid"); +  push_static_text("eid");    push_text(idp->eid);    attrs++;    if (idp->dpy_name) { -  push_constant_text("name"); +  push_static_text("name");    push_text(idp->dpy_name);    attrs++;    }    if (idp->sha1_name) { -  push_constant_text("sha1_name"); +  push_static_text("sha1_name");    push_text(idp->sha1_name);    attrs++;    }    f_aggregate_mapping(attrs*2);    cnt++;       idp = idp->n;    }    f_aggregate_mapping(cnt*2);    }   }   /*! @endclass Configuration */    -  + /*! @decl int version() +  *! +  *! Return the numeric version of the zxid library. +  */ + PIKEFUN int version() + { +  RETURN zxid_version(); + } +    PIKE_MODULE_INIT   {    INIT;   }      PIKE_MODULE_EXIT   {    EXIT;   }      /*! @endmodule ZXID */      #else /* HAVE_ZXID */      PIKE_MODULE_INIT {   }   PIKE_MODULE_EXIT {   }   #endif /* HAVE_ZXID */