示例#1
0
FileNode::FileNode(char* dirname,char* plugin,std::istream &cfile,userspec_t &user) {
  plug=NULL;
  init=NULL;
  point=std::string(dirname);
  plugname=std::string(plugin);
//    handle=dlopen(plugin,RTLD_LAZY);
  handle=dlopen(plugin,RTLD_NOW);
  if(!handle) {
    logger.msg(Arc::ERROR, dlerror());
    logger.msg(Arc::ERROR, "Can't load plugin %s for access point %s", plugin, dirname);
    return;
  };
  init=(plugin_init_t)dlsym(handle,"init");
  if(init == NULL) {
    logger.msg(Arc::ERROR, "Plugin %s for access point %s is broken.", plugin, dirname);
    dlclose(handle); handle=NULL; return;
  };
  if((plug=init(cfile,user,*this)) == NULL) {
    logger.msg(Arc::ERROR, "Plugin %s for access point %s is broken.", plugin, dirname);
    dlclose(handle); handle=NULL; init=NULL; return;
  };
  if(plug->acquire() != 1) {
    logger.msg(Arc::ERROR, "Plugin %s for access point %s acquire failed (should never happen).", plugin, dirname);
    delete plug; dlclose(handle); handle=NULL; init=NULL; plug=NULL; return;
  };
}
示例#2
0
FileNode& FileNode::operator= (const FileNode &node) {
  logger.msg(Arc::VERBOSE, "FileNode: operator= (%s <- %s) %lu <- %lu", point, node.point, (unsigned long int)this, (unsigned long int)(&node));
  if(plug) if(plug->release() == 0) {
    logger.msg(Arc::VERBOSE, "Copying with dlclose");
    delete plug; dlclose(handle); handle=NULL; init=NULL; plug=NULL;
  };
  point=node.point; plugname=node.plugname;
  plug=node.plug; handle=node.handle;
  return *this;
}
示例#3
0
namespace ArcSHCLegacy {

static Arc::Logger logger(Arc::Logger::getRootLogger(),"AuthUser");

int AuthUser::match_file(const char* line) {
  std::list<std::string> tokens;
  Arc::tokenize(line, tokens, " ", "\"", "\"");
  for(std::list<std::string>::iterator s = tokens.begin();s!=tokens.end();++s) {
    std::ifstream f(s->c_str());
    if(!f.is_open()) {
      logger.msg(Arc::ERROR, "Failed to read file %s", *s);
      return AAA_FAILURE;
    };
    for(;f.good();) {
      std::string buf;
      getline(f,buf);
      int res = evaluate(buf.c_str());
      if(res != AAA_NO_MATCH) {
        f.close();
        return res;
      };
    };
    f.close();
  };
  return AAA_NO_MATCH;
}

} // namespace ArcSHCLegacy
示例#4
0
int FilePlugin::release(void) {
  count--;
  if(count < 0) {
    logger.msg(Arc::WARNING, "FilePlugin: more unload than load");
    count=0;
  };
  return count;
}
示例#5
0
int AuthUser::match_ldap(const char* line) {
#ifdef HAVE_LDAP
  for(;;) {
    std::string u("");
    int n = gridftpd::input_escaped_string(line,u,' ','"');
    if(n == 0) break;
    line+=n;
	try {
      Arc::URL url(u.c_str());
      if(url.Protocol() != "ldap") return AAA_FAILURE;
      std::string usersn("");
      gridftpd::LdapQuery ldap(url.Host(), url.Port(), false, usersn);
      logger.msg(Arc::INFO, "Connecting to %s:%i", url.Host(), url.Port());
      logger.msg(Arc::INFO, "Quering at %s", url.Path());
      std::vector<std::string> attrs; attrs.push_back("description");
      try {
        ldap.Query(url.Path(),"",attrs,gridftpd::LdapQuery::onelevel);
      } catch (gridftpd::LdapQueryError& e) {
        logger.msg(Arc::ERROR, "Failed to query LDAP server %s", u);
        return AAA_FAILURE;
      };
      result_t r(subject.c_str());
      try {
        ldap.Result(&result_callback,&r) ;
      } catch (gridftpd::LdapQueryError& e) {
        logger.msg(Arc::ERROR, "Failed to get results from LDAP server %s", u);
        return AAA_FAILURE;
      };
      if(r.decision==AAA_POSITIVE_MATCH) {  // just a placeholder
        default_voms_=NULL;
        default_vo_=NULL;
        default_role_=NULL;
        default_capability_=NULL;
        default_vgroup_=NULL;
      }; 
      return r.decision;
    } catch (std::exception& e) {
      return AAA_FAILURE;
    };
  };
  return AAA_NO_MATCH;
#else
  logger.msg(Arc::ERROR, "LDAP authorization is not supported");
  return AAA_FAILURE;
#endif
}
示例#6
0
void GridFTP_Commands::data_connect_store_callback(void* arg,globus_ftp_control_handle_t*,unsigned int /* stripendx */,globus_bool_t /* reused */,globus_object_t *error) {
  GridFTP_Commands *it = (GridFTP_Commands*)arg;
  logger.msg(Arc::VERBOSE, "data_connect_store_callback");
  globus_thread_blocking_will_block();
  globus_mutex_lock(&(it->data_lock));
  it->time_spent_disc=0;
  it->time_spent_network=0;
  it->last_action_time=time(NULL);
  logger.msg(Arc::VERBOSE, "Data channel connected (store)");
  if(it->check_abort(error)) {
    it->froot.close(false);
    globus_mutex_unlock(&(it->data_lock)); return;
  };
  it->data_eof = false;
  /* make buffers */
  it->compute_data_buffer();
  if(!(it->allocate_data_buffer())) {
    it->froot.close(false);
    it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return;
  };
  /* register all available buffers */
  it->data_callbacks=0;
  globus_result_t res = GLOBUS_SUCCESS;
  for(unsigned int i = 0;i<it->data_buffer_num;i++) {
    if(!((it->data_buffer)[i].data)) continue;
    struct timezone tz;
    gettimeofday(&(it->data_buffer[i].time_last),&tz);
    res=globus_ftp_control_data_read(&(it->handle),
            (globus_byte_t*)(it->data_buffer[i].data),
            it->data_buffer_size,
            &data_store_callback,it);
    if(res==GLOBUS_SUCCESS) { it->data_callbacks++; }
    else { break; };
  };
  if(it->data_callbacks==0) {
    logger.msg(Arc::ERROR, "Failed to register any buffer");
    if(res != GLOBUS_SUCCESS) {
      logger.msg(Arc::ERROR, "Globus error: %s", Arc::GlobusResult(res).str());
    };
    it->froot.close(false);
    it->free_data_buffer();
    it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return;
  };
  globus_mutex_unlock(&(it->data_lock)); return;
}
示例#7
0
/* *** list transfer callbacks *** */
void GridFTP_Commands::list_retrieve_callback(void* arg,globus_ftp_control_handle_t*,globus_object_t *error,globus_byte_t* /* buffer */,globus_size_t /* length */,globus_off_t /* offset */,globus_bool_t /* eof */) {
  GridFTP_Commands *it = (GridFTP_Commands*)arg;
  globus_mutex_lock(&(it->data_lock));
  it->last_action_time=time(NULL);
  if(it->check_abort(error)) {
    it->free_data_buffer();
    globus_mutex_unlock(&(it->data_lock));
    return;
  };
  globus_bool_t eodf;
  globus_size_t size;
  if(it->dir_list_pointer == it->dir_list.end()) {
    it->virt_offset=0;
    it->transfer_mode=false;
    it->free_data_buffer();
    logger.msg(Arc::VERBOSE, "Closing channel (list)");
    it->send_response("226 Transfer completed.\r\n");
    globus_mutex_unlock(&(it->data_lock));
    return;
  };
  globus_ftp_control_local_send_eof(&(it->handle),GLOBUS_TRUE);
  ++(it->dir_list_pointer);
  if(it->dir_list_pointer == it->dir_list.end()) {
    size=0; eodf=GLOBUS_TRUE;
  }
  else {
    size=make_list_string(*(it->dir_list_pointer),it->list_mode,
                        it->data_buffer[0].data,it->data_buffer_size,
                        it->list_name_prefix.c_str());
    eodf=GLOBUS_FALSE;
  };
  globus_result_t res;
  res=globus_ftp_control_data_write(&(it->handle),
                   (globus_byte_t*)(it->data_buffer[0].data),
                   size,it->list_offset,eodf,
                   &list_retrieve_callback,it);
  if(res != GLOBUS_SUCCESS) {
    it->free_data_buffer();
    it->force_abort();
    globus_mutex_unlock(&(it->data_lock));
    return;
  };
  globus_mutex_unlock(&(it->data_lock));
}
示例#8
0
void GridFTP_Commands::list_connect_retrieve_callback(void* arg,globus_ftp_control_handle_t*,unsigned int /* stripendx */,globus_bool_t /* reused */,globus_object_t *error) {
  GridFTP_Commands *it = (GridFTP_Commands*)arg;
  globus_mutex_lock(&(it->data_lock));
  it->last_action_time=time(NULL);
  if(it->check_abort(error)) {
    globus_mutex_unlock(&(it->data_lock));
    return;
  };
  it->data_buffer_size=4096;
  it->data_buffer_num=1;
  if(!it->allocate_data_buffer()) {
    it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return;
  };
  it->dir_list_pointer=it->dir_list.begin();
  globus_size_t size;
  globus_bool_t eodf;
  if(it->dir_list_pointer == it->dir_list.end()) {
    size=0; eodf=GLOBUS_TRUE;
  }
  else {
    size=make_list_string(*(it->dir_list_pointer),it->list_mode,
                         it->data_buffer[0].data,it->data_buffer_size,
                        it->list_name_prefix.c_str());
    eodf=GLOBUS_FALSE;
  };
  it->list_offset = 0;
  logger.msg(Arc::VERBOSE, "Data channel connected (list)");
  globus_ftp_control_local_send_eof(&(it->handle),GLOBUS_TRUE);
  globus_result_t res;
  res=globus_ftp_control_data_write(&(it->handle),
                   (globus_byte_t*)(it->data_buffer[0].data),
                   size,it->list_offset,eodf,
                   &list_retrieve_callback,it);
  if(res != GLOBUS_SUCCESS) {
    it->free_data_buffer();
    it->force_abort();
    globus_mutex_unlock(&(it->data_lock));
    return;
  };
  it->list_offset+=size;
  globus_mutex_unlock(&(it->data_lock));
}
示例#9
0
// TODO: In a future accept and store ALL policies. Let it fail at PDP level.
//       Currently code fails immediately if policy not recognized.
//       Alternatively behavior may be configurable.
static bool get_proxy_policy(X509* cert,DelegationMultiSecAttr* sattr) {
  bool result = false;
#ifdef HAVE_OPENSSL_PROXY
  PROXY_CERT_INFO_EXTENSION *pci = (PROXY_CERT_INFO_EXTENSION*)X509_get_ext_d2i(cert,NID_proxyCertInfo,NULL,NULL);
  if(!pci) return true; // No proxy 
  switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) {
    case NID_Independent: { // No rights granted
      // Either such situation should be disallowed or 
      // policy should be generated which granst no right for enything.
      // First option is easier to implement so using it at least yet.
      logger.msg(DEBUG,"Independent proxy - no rights granted");
    }; break; 
    case NID_id_ppl_inheritAll: {
      // All right granted. No additional policies should be enforced.
      logger.msg(DEBUG,"Proxy with all rights inherited");
      result=true;
    }; break;
    case NID_id_ppl_anyLanguage: { // Here we store ARC policy
      // Either this is ARC policy is determined by examining content
      const char* policy_str = (const char *)(pci->proxyPolicy->policy->data);
      int policy_length = pci->proxyPolicy->policy->length;
      if((policy_str == NULL) || (policy_length <= 0)) {
        logger.msg(DEBUG,"Proxy with empty policy  - fail on unrecognized policy");
        break;
      };
      {
        std::string s(policy_str,policy_length);
        logger.msg(DEBUG,"Proxy with specific policy: %s",s);
      };
      result = sattr->Add(policy_str,policy_length);
      if(result) {
        logger.msg(DEBUG,"Proxy with ARC Policy");
      } else {
        logger.msg(DEBUG,"Proxy with unknown policy  - fail on unrecognized policy");
      };
    }; break;
    default: {
      // Unsupported policy - fail
    }; break;
  };
  PROXY_CERT_INFO_EXTENSION_free(pci);
#endif
  return result;
}
示例#10
0
FileNode::~FileNode(void) {
  if(plug) if(plug->release() == 0) {
    logger.msg(Arc::VERBOSE, "Destructor with dlclose (%s)", point);
    delete plug; dlclose(handle); handle=NULL; init=NULL; plug=NULL;
  };
}
示例#11
0
namespace ArcMCCTLSSec {

using namespace Arc;
using namespace ArcMCCTLS;

static Arc::Logger logger(Arc::Logger::getRootLogger(),"DelegationCollector");

DelegationCollector::DelegationCollector(Config *cfg,PluginArgument* parg):SecHandler(cfg,parg) {
}

DelegationCollector::~DelegationCollector(void) {
}


// TODO: In a future accept and store ALL policies. Let it fail at PDP level.
//       Currently code fails immediately if policy not recognized.
//       Alternatively behavior may be configurable.
static bool get_proxy_policy(X509* cert,DelegationMultiSecAttr* sattr) {
  bool result = false;
#ifdef HAVE_OPENSSL_PROXY
  PROXY_CERT_INFO_EXTENSION *pci = (PROXY_CERT_INFO_EXTENSION*)X509_get_ext_d2i(cert,NID_proxyCertInfo,NULL,NULL);
  if(!pci) return true; // No proxy 
  switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) {
    case NID_Independent: { // No rights granted
      // Either such situation should be disallowed or 
      // policy should be generated which granst no right for enything.
      // First option is easier to implement so using it at least yet.
      logger.msg(DEBUG,"Independent proxy - no rights granted");
    }; break; 
    case NID_id_ppl_inheritAll: {
      // All right granted. No additional policies should be enforced.
      logger.msg(DEBUG,"Proxy with all rights inherited");
      result=true;
    }; break;
    case NID_id_ppl_anyLanguage: { // Here we store ARC policy
      // Either this is ARC policy is determined by examining content
      const char* policy_str = (const char *)(pci->proxyPolicy->policy->data);
      int policy_length = pci->proxyPolicy->policy->length;
      if((policy_str == NULL) || (policy_length <= 0)) {
        logger.msg(DEBUG,"Proxy with empty policy  - fail on unrecognized policy");
        break;
      };
      {
        std::string s(policy_str,policy_length);
        logger.msg(DEBUG,"Proxy with specific policy: %s",s);
      };
      result = sattr->Add(policy_str,policy_length);
      if(result) {
        logger.msg(DEBUG,"Proxy with ARC Policy");
      } else {
        logger.msg(DEBUG,"Proxy with unknown policy  - fail on unrecognized policy");
      };
    }; break;
    default: {
      // Unsupported policy - fail
    }; break;
  };
  PROXY_CERT_INFO_EXTENSION_free(pci);
#endif
  return result;
}

SecHandlerStatus DelegationCollector::Handle(Arc::Message* msg) const {
  DelegationMultiSecAttr* sattr = NULL;
  try {
    MessagePayload* mpayload = msg->Payload();
    if(!mpayload) return false; // No payload in this message
    PayloadTLSStream* tstream = dynamic_cast<PayloadTLSStream*>(msg->Payload());
    // Currently only TLS payloads are supported
    if(!tstream) return false;
    SecAttr* sattr_ = msg->Auth()->get("DELEGATION POLICY");
    if(sattr_) sattr=dynamic_cast<DelegationMultiSecAttr*>(sattr_);
    if(!sattr) sattr=new DelegationMultiSecAttr;
    X509* cert = tstream->GetPeerCert();
    if (cert != NULL) {
      if(!get_proxy_policy(cert,sattr)) {
        X509_free(cert);
        throw std::exception();
      };
      X509_free(cert);
    };
    STACK_OF(X509)* peerchain = tstream->GetPeerChain();
    if(peerchain != NULL) {
      for(int idx = 0;;++idx) {
        if(idx >= sk_X509_num(peerchain)) break;
        X509* cert = sk_X509_value(peerchain,idx);
        if(cert) {
          if(!get_proxy_policy(cert,sattr)) throw std::exception();
        };
      };
    };
    if(!sattr_) msg->Auth()->set("DELEGATION POLICY",sattr);
    return true;
  } catch(std::exception&) { };
  if(sattr) delete sattr;
  return false;
}


Arc::Plugin* DelegationCollector::get_sechandler(Arc::PluginArgument* arg) {
    ArcSec::SecHandlerPluginArgument* shcarg =
            arg?dynamic_cast<ArcSec::SecHandlerPluginArgument*>(arg):NULL;
    if(!shcarg) return NULL;
    return new DelegationCollector((Arc::Config*)(*shcarg),shcarg);
}

}
示例#12
0
int main(int argc, char **argv) {

  setlocale(LC_ALL, "");

  Arc::LogStream logcerr(std::cerr);
  logcerr.setFormat(Arc::ShortFormat);
  Arc::Logger::getRootLogger().addDestination(logcerr);
  Arc::Logger::getRootLogger().setThreshold(Arc::WARNING);

  Arc::ArcLocation::Init(argv[0]);

  Arc::OptionParser options(istring("url"),
                            istring("The arcls command is used for listing "
                                    "files in grid storage elements "
                                    "and file\nindex catalogues."));

  bool longlist = false;
  options.AddOption('l', "long", istring("long format (more information)"),
                    longlist);

  bool locations = false;
  options.AddOption('L', "locations", istring("show URLs of file locations"),
                    locations);

  bool metadata = false;
  options.AddOption('m', "metadata", istring("display all available metadata"),
        metadata);

  bool infinite_recursion = false;
  options.AddOption('r', "recursive",
                    istring("operate recursively"),
                    infinite_recursion);

  int recursion = 0;
  options.AddOption('D', "depth",
                    istring("operate recursively up to specified level"),
                    istring("level"), recursion);

  bool nolist = false;
  options.AddOption('n', "nolist", istring("show only description of requested object, do not list content of directories"),
        nolist);

  bool forcelist = false;
  options.AddOption('f', "forcelist", istring("treat requested object as directory and always try to list content"),
        forcelist);

  bool checkaccess = false;
  options.AddOption('c', "checkaccess", istring("check readability of object, does not show any information about object"),
        checkaccess);

  bool show_plugins = false;
  options.AddOption('P', "listplugins",
                    istring("list the available plugins (protocols supported)"),
                    show_plugins);

  int timeout = 20;
  options.AddOption('t', "timeout", istring("timeout in seconds (default 20)"),
                    istring("seconds"), timeout);

  std::string conffile;
  options.AddOption('z', "conffile",
                    istring("configuration file (default ~/.arc/client.conf)"),
                    istring("filename"), conffile);

  std::string debug;
  options.AddOption('d', "debug",
                    istring("FATAL, ERROR, WARNING, INFO, VERBOSE or DEBUG"),
                    istring("debuglevel"), debug);

  bool version = false;
  options.AddOption('v', "version", istring("print version information"),
                    version);

  std::list<std::string> params = options.Parse(argc, argv);

  if (version) {
    std::cout << Arc::IString("%s version %s", "arcls", VERSION) << std::endl;
    return 0;
  }

  // If debug is specified as argument, it should be set before loading the configuration.
  if (!debug.empty())
    Arc::Logger::getRootLogger().setThreshold(Arc::string_to_level(debug));

  if (show_plugins) {
    std::list<Arc::ModuleDesc> modules;
    Arc::PluginsFactory pf(Arc::BaseConfig().MakeConfig(Arc::Config()).Parent());
    pf.scan(Arc::FinderLoader::GetLibrariesList(), modules);
    Arc::PluginsFactory::FilterByKind("HED:DMC", modules);

    std::cout << Arc::IString("Protocol plugins available:") << std::endl;
    for (std::list<Arc::ModuleDesc>::iterator itMod = modules.begin();
         itMod != modules.end(); itMod++) {
      for (std::list<Arc::PluginDesc>::iterator itPlug = itMod->plugins.begin();
           itPlug != itMod->plugins.end(); itPlug++) {
        std::cout << "  " << itPlug->name << " - " << itPlug->description << std::endl;
      }
    }
    return 0;
  }

  // credentials will be initialised later if necessary
  Arc::UserConfig usercfg(conffile, Arc::initializeCredentialsType::TryCredentials);
  if (!usercfg) {
    logger.msg(Arc::ERROR, "Failed configuration initialization");
    return 1;
  }
  usercfg.UtilsDirPath(Arc::UserConfig::ARCUSERDIRECTORY);

  if (debug.empty() && !usercfg.Verbosity().empty())
    Arc::Logger::getRootLogger().setThreshold(Arc::string_to_level(usercfg.Verbosity()));

  // Analyze options

  if (params.size() != 1) {
    logger.msg(Arc::ERROR, "Wrong number of parameters specified");
    return 1;
  }

  if(forcelist && nolist) {
    logger.msg(Arc::ERROR, "Incompatible options --nolist and --forcelist requested");
    return 1;
  }

  if(recursion && nolist) {
    logger.msg(Arc::ERROR, "Requesting recursion and --nolist has no sense");
    return 1;
  }
  if(infinite_recursion) recursion = INT_MAX;

  std::list<std::string>::iterator it = params.begin();

  if(!arcls(*it, usercfg, longlist, locations, metadata,
            nolist, forcelist, checkaccess, recursion, timeout)) return 1;

  return 0;
}
示例#13
0
static bool arcls(const Arc::URL& dir_url,
           Arc::UserConfig& usercfg,
           bool show_details, // longlist
           bool show_urls,    // locations
           bool show_meta,    // metadata
           bool no_list,      // don't list dirs
           bool force_list,   // force dir list
           bool check_access, // checkaccess
           int recursion,     // recursion 
           int timeout) {     // timeout

  if (!dir_url) {
    logger.msg(Arc::ERROR, "Invalid URL: %s", dir_url.fullstr());
    return false;
  }
  if (dir_url.Protocol() == "urllist") {
    std::list<Arc::URL> dirs = Arc::ReadURLList(dir_url);
    if (dirs.empty()) {
      logger.msg(Arc::ERROR, "Can't read list of locations from file %s",
                 dir_url.Path());
      return false;
    }
    bool r = true;
    for (std::list<Arc::URL>::iterator dir = dirs.begin();
         dir != dirs.end(); dir++) {
      if(!arcls(*dir, usercfg, show_details, show_urls, show_meta,
               no_list, force_list, check_access, recursion, timeout)) r = false;
    }
    return r;
  }

  Arc::DataHandle url(dir_url, usercfg);
  if (!url) {
    logger.msg(Arc::ERROR, "Unsupported URL given");
    return false;
  }
  if (url->RequiresCredentials()) {
    if (usercfg.ProxyPath().empty() ) {
      logger.msg(Arc::ERROR, "Unable to list content of %s: No valid credentials found", dir_url.str());
      return false;
    }
    Arc::Credential holder(usercfg.ProxyPath(), "", "", "");
    if (holder.GetEndTime() < Arc::Time()){
      logger.msg(Arc::ERROR, "Proxy expired");
      logger.msg(Arc::ERROR, "Unable to list content of %s: No valid credentials found", dir_url.str());
      return false;
    }
  }
  url->SetSecure(false);

  if(check_access) {
    std::cout << dir_url << " - ";
    if(url->Check(false)) {
      std::cout << "passed" << std::endl;
      return true;
    } else {
      std::cout << "failed" << std::endl;
      return false;
    }
  }

  Arc::DataPoint::DataPointInfoType verb = (Arc::DataPoint::DataPointInfoType)
                                           (Arc::DataPoint::INFO_TYPE_MINIMAL |
                                            Arc::DataPoint::INFO_TYPE_NAME);
  if(show_urls) verb = (Arc::DataPoint::DataPointInfoType)
                       (verb | Arc::DataPoint::INFO_TYPE_STRUCT);
  if(show_meta) verb = (Arc::DataPoint::DataPointInfoType)
                       (verb | Arc::DataPoint::INFO_TYPE_ALL);
  if(show_details) verb = (Arc::DataPoint::DataPointInfoType)
                          (verb |
                           Arc::DataPoint::INFO_TYPE_TYPE |
                           Arc::DataPoint::INFO_TYPE_TIMES |
                           Arc::DataPoint::INFO_TYPE_CONTENT |
                           Arc::DataPoint::INFO_TYPE_ACCESS); 
  if(recursion > 0) verb = (Arc::DataPoint::DataPointInfoType)
                           (verb | Arc::DataPoint::INFO_TYPE_TYPE);

  Arc::DataStatus res;
  Arc::FileInfo file;
  std::list<Arc::FileInfo> files;

  if(no_list) { // only requested object is queried
    res = url->Stat(file, verb);
    if(res) files.push_back(file);
  } else if(force_list) { // assume it is directory, fail otherwise
    res = url->List(files, verb);
  } else { // try to guess what to do
    res = url->Stat(file, (Arc::DataPoint::DataPointInfoType)(verb | Arc::DataPoint::INFO_TYPE_TYPE));
    if(res && (file.GetType() == Arc::FileInfo::file_type_file)) {
      // If it is file and we are sure, then just report it.
      files.push_back(file);
    } else {
      // If it is dir then we must list it. But if stat failed or
      // if type is undefined there is still chance it is directory.
      Arc::DataStatus res_ = url->List(files, verb);
      if(!res_) {
        // If listing failed maybe simply report previous result if any.
        if(res) {
          files.push_back(file);
        }
      } else {
        res = res_;
      }
    }
  }
  if (!res) {
    if (files.empty()) {
      logger.msg(Arc::ERROR, std::string(res));
      if (res.Retryable())
        logger.msg(Arc::ERROR, "This seems like a temporary error, please try again later");
      return false;
    }
    logger.msg(Arc::INFO, "Warning: "
               "Failed listing files but some information is obtained");
  }

  files.sort(); // Sort alphabetically by name
  if (show_details) {
    print_details(files, show_urls, show_meta);
  } else {
    for (std::list<Arc::FileInfo>::iterator i = files.begin();
       i != files.end(); i++) {
      std::cout << i->GetName() << std::endl;
      if (show_urls) print_urls(*i);
      if (show_meta) print_meta(*i);
    }
  }
  // Do recursion. Recursion has no sense if listing is forbidden.
  if ((recursion > 0) && (!no_list)) {
    for (std::list<Arc::FileInfo>::iterator i = files.begin();
       i != files.end(); i++) {
      if (i->GetType() == Arc::FileInfo::file_type_dir) {
        Arc::URL suburl = dir_url;
        if(suburl.Protocol() != "file") {
          if (suburl.Path()[suburl.Path().length() - 1] != '/')
            suburl.ChangePath(suburl.Path() + "/" + i->GetName());
          else
            suburl.ChangePath(suburl.Path() + i->GetName());
        } else {
          if (suburl.Path()[suburl.Path().length() - 1] != G_DIR_SEPARATOR)
            suburl.ChangePath(suburl.Path() + G_DIR_SEPARATOR_S + i->GetName());
          else
            suburl.ChangePath(suburl.Path() + i->GetName());
        }
        std::cout << std::endl;
        std::cout << suburl.str() << ":" << std::endl;
        arcls(suburl, usercfg, show_details, show_urls, show_meta,
              no_list, force_list, check_access, recursion - 1, timeout);
        std::cout << std::endl;
      }
    }
  }
  return true;
}
示例#14
0
int main(int argc,char* argv[]) {
  Arc::LogStream err(std::cerr);
  err.setFormat(Arc::EmptyFormat);
  Arc::Logger::rootLogger.addDestination(err);
  std::string lcmaps_library;
  std::string lcmaps_db_file;
  std::string lcmaps_dir;
  std::string subject;
  std::string filename;

  if(argc > 1) subject = argv[1];
  if(subject.empty()) {
    logger.msg(Arc::ERROR, "Missing subject name");
    return -1;
  };
  if(argc > 2) filename = argv[2];
  if(filename.empty()) {
    logger.msg(Arc::ERROR, "Missing path of credentials file");
    return -1;
  };
  if(argc > 3) lcmaps_library = argv[3];
  if(lcmaps_library.empty()) {
    logger.msg(Arc::ERROR, "Missing name of LCMAPS library");
    return -1;
  };
  if(argc > 4) lcmaps_dir = argv[4];
  if(argc > 5) lcmaps_db_file = argv[5];

  if(lcmaps_dir == "*") lcmaps_dir.resize(0);
  if(lcmaps_db_file == "*") lcmaps_db_file.resize(0);

  if((lcmaps_library[0] != G_DIR_SEPARATOR) && (lcmaps_library[0] != '.')) {
    if(lcmaps_dir.length() != 0) lcmaps_library=lcmaps_dir+G_DIR_SEPARATOR_S+lcmaps_library;
  };

  if(argc <= 6) {
    logger.msg(Arc::ERROR, "Can't read policy names");
    return -1;
  };
  char** policynames = argv+6;
  int npols = 0;
  for(;policynames[npols];npols++) { };

  set_lcmaps_env(lcmaps_db_file,lcmaps_dir);
  Glib::Module lcmaps_handle(lcmaps_library,Glib::ModuleFlags(0));
  if(!lcmaps_handle) {
    recover_lcmaps_env();
    logger.msg(Arc::ERROR, "Can't load LCMAPS library %s: %s", lcmaps_library, Glib::Module::get_last_error());
    return -1;
  };
  void *lcmaps_init_p = NULL;
  void *lcmaps_run_and_return_username_p = NULL;
  void *lcmaps_run_p = NULL;
  void *lcmaps_term_p = NULL;
  void *getCredentialData_p = NULL;
  if((!lcmaps_handle.get_symbol("lcmaps_init",lcmaps_init_p)) ||
     (!lcmaps_handle.get_symbol("lcmaps_run_and_return_username",lcmaps_run_and_return_username_p)) ||
     (!lcmaps_handle.get_symbol("lcmaps_term",lcmaps_term_p))) {
    recover_lcmaps_env();
    logger.msg(Arc::ERROR, "Can't find LCMAPS functions in a library %s", lcmaps_library);
    return -1;
  };
  lcmaps_handle.get_symbol("lcmaps_run",lcmaps_run_p);
  lcmaps_handle.get_symbol("getCredentialData",getCredentialData_p);
  lcmaps_init_t lcmaps_init_f = (lcmaps_init_t)lcmaps_init_p;
  lcmaps_run_and_return_username_t lcmaps_run_and_return_username_f =
    (lcmaps_run_and_return_username_t)lcmaps_run_and_return_username_p;
  lcmaps_run_t lcmaps_run_f = (lcmaps_run_t)lcmaps_run_p;
  lcmaps_term_t lcmaps_term_f = (lcmaps_term_t)lcmaps_term_p;
  getCredentialData_t getCredentialData_f =
    (getCredentialData_t)getCredentialData_p;
  if(lcmaps_run_f) logger.msg(Arc::ERROR,"LCMAPS has lcmaps_run");
  if(getCredentialData_f) logger.msg(Arc::ERROR,"LCMAPS has getCredentialData");
  FILE* lcmaps_log = fdopen(STDERR_FILENO,"a");
  if((*lcmaps_init_f)(lcmaps_log) != 0) {
    recover_lcmaps_env();
    logger.msg(Arc::ERROR, "Failed to initialize LCMAPS");
    return -1;
  };
  // In case anything is not initialized yet
  globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE);
  globus_module_activate(GLOBUS_GSI_CREDENTIAL_MODULE);
  globus_module_activate(GLOBUS_GSI_CERT_UTILS_MODULE);
  // User without credentials is useless for LCMAPS ?
  //Arc::GSSCredential cred(filename,"","");
  gss_cred_id_t cred = read_globus_credentials(filename);
  char* username = NULL;
  int res = 1;
  if((!getCredentialData_f) || (!lcmaps_run_f)) {
    if((*lcmaps_run_and_return_username_f)(
             (char*)(subject.c_str()),cred,(char*)"",&username,npols,policynames
       ) == 0) {
      if(username != NULL) {
        res=0;
        std::cout<<username<<std::flush;
      };
    };
#ifdef WIN32
  };
#else
  } else {
示例#15
0
gss_cred_id_t read_globus_credentials(const std::string& filename) {
  Arc::Credential cred(filename, "", "", "", "", true);
  X509* cert = cred.GetCert();
  STACK_OF(X509)* cchain = cred.GetCertChain();
  EVP_PKEY* key = cred.GetPrivKey();
  globus_gsi_cred_handle_t chandle;
  globus_gsi_cred_handle_init(&chandle, NULL);
  if(cert) globus_gsi_cred_set_cert(chandle, cert);
  if(key) globus_gsi_cred_set_key(chandle, key);
  if(cchain) globus_gsi_cred_set_cert_chain(chandle, cchain);

  gss_cred_id_desc* ccred = (gss_cred_id_desc*)::malloc(sizeof(gss_cred_id_desc));
  if(ccred) {
    ::memset(ccred,0,sizeof(gss_cred_id_desc));
    ccred->cred_handle = chandle; chandle = NULL;
    // cred_usage
    // ssl_context
    X509* identity_cert = NULL;
    if(cert) {
      globus_gsi_cert_utils_cert_type_t ctype = GLOBUS_GSI_CERT_UTILS_TYPE_DEFAULT;
      globus_gsi_cert_utils_get_cert_type(cert,&ctype);
      if(ctype == GLOBUS_GSI_CERT_UTILS_TYPE_EEC) {
        identity_cert = cert;
      };
    };
    if(!identity_cert && cchain) {
      // For compatibility with older globus not using
      //globus_gsi_cert_utils_get_identity_cert(cchain,&identity_cert);
      for(int n = 0; n < sk_X509_num(cchain); ++n) {
        X509* tmp_cert = sk_X509_value(cchain, n);
        if(tmp_cert) {
          globus_gsi_cert_utils_cert_type_t ctype = GLOBUS_GSI_CERT_UTILS_TYPE_DEFAULT;
          globus_gsi_cert_utils_get_cert_type(tmp_cert,&ctype);
          if(ctype == GLOBUS_GSI_CERT_UTILS_TYPE_EEC) {
            identity_cert = tmp_cert;
            break;
          };
        };
      };
    };
    gss_buffer_desc peer_buffer;
    peer_buffer.value = identity_cert;
    peer_buffer.length = identity_cert?sizeof(X509):0;
    OM_uint32 majstat, minstat;
    majstat = gss_import_name(&minstat, &peer_buffer,
                              identity_cert?GLOBUS_GSS_C_NT_X509:GSS_C_NT_ANONYMOUS,
                              &ccred->globusid);
    if (GSS_ERROR(majstat)) {
      logger.msg(Arc::ERROR, "Failed to convert GSI credential to "
         "GSS credential (major: %d, minor: %d)", majstat, minstat);
      majstat = gss_release_cred(&minstat, &ccred);
    };
  } else {
    ccred = GSS_C_NO_CREDENTIAL;
  };
  if(cert) X509_free(cert);
  if(key) EVP_PKEY_free(key);
  if(cchain) sk_X509_pop_free(cchain, X509_free);
  if(chandle) globus_gsi_cred_handle_destroy(chandle);
  return ccred;
}
示例#16
0
void GridFTP_Commands::data_store_callback(void* arg,globus_ftp_control_handle_t*,globus_object_t *error,globus_byte_t *buffer,globus_size_t length,globus_off_t offset,globus_bool_t eof) {
  globus_thread_blocking_will_block();
  GridFTP_Commands *it = (GridFTP_Commands*)arg;
  struct timezone tz;
  struct timeval tv;
  gettimeofday(&tv,&tz);
  globus_mutex_lock(&(it->data_lock));
  it->last_action_time=time(NULL);
  logger.msg(Arc::VERBOSE, "Data channel (store) %i %i %i", (int)offset, (int)length, (int)eof);
  it->data_callbacks--;
  if(it->check_abort(error)) {
    if(it->data_callbacks==0){it->free_data_buffer();it->froot.close(false);};
    globus_mutex_unlock(&(it->data_lock)); return;
  };
  if(eof) it->data_eof=true;
  /* find this buffer */
  unsigned int i;
  for(i = 0;i<it->data_buffer_num;i++) {
    if((it->data_buffer)[i].data == (unsigned char*)buffer) break;
  };
  if(i >= it->data_buffer_num) { /* lost buffer - probably memory corruption */
    logger.msg(Arc::ERROR, "data_store_callback: lost buffer");
    it->force_abort();
    if(it->data_callbacks==0){it->free_data_buffer();it->froot.close(false);};
    globus_mutex_unlock(&(it->data_lock)); return;
  };
  unsigned long long int time_diff = 
     (tv.tv_sec-(it->data_buffer[i].time_last.tv_sec))*1000000+
     (tv.tv_usec-(it->data_buffer[i].time_last.tv_usec));
  it->time_spent_network+=time_diff;
  /* write data to file 
     NOTE: it->data_lock is not unlocked here because it->froot.write 
     is not thread safe */
  struct timeval tv_last;
  gettimeofday(&tv_last,&tz);
  if(it->froot.write(it->data_buffer[i].data,
                (it->virt_offset)+offset,length) != 0) {
    logger.msg(Arc::ERROR, "Closing channel (store) due to error: %s", it->froot.error);
    it->force_abort();
    if(it->data_callbacks==0){it->free_data_buffer();it->froot.close(false);};
    globus_mutex_unlock(&(it->data_lock)); return;
  }; 
  gettimeofday(&tv,&tz);
  time_diff=(tv.tv_sec-tv_last.tv_sec)*1000000+(tv.tv_usec-tv_last.tv_usec);
  it->time_spent_disc+=time_diff;
  if(it->data_eof) {
    if(it->data_callbacks==0) {
      logger.msg(Arc::VERBOSE, "Closing channel (store)");
      it->free_data_buffer();
      it->virt_offset=0;
      it->virt_restrict=false;
      it->transfer_mode=false;
      if(it->froot.close() != 0) {
        if(it->froot.error.length()) {
          it->send_response("451 "+it->froot.error+"\r\n");
        } else {
          it->send_response("451 Local error\r\n");
        };
      }
      else {
        logger.msg(Arc::VERBOSE, "Time spent waiting for network: %.3f ms", (float)(it->time_spent_network/1000.0));
        logger.msg(Arc::VERBOSE, "Time spent waiting for disc: %.3f ms", (float)(it->time_spent_disc/1000.0));
        it->send_response("226 Requested file transfer completed\r\n");
      };
    };
    globus_mutex_unlock(&(it->data_lock)); return;
  };
  /* register buffer */
  globus_result_t res;
  gettimeofday(&(it->data_buffer[i].time_last),&tz);
  res=globus_ftp_control_data_read(&(it->handle),
            (globus_byte_t*)(it->data_buffer[i].data),
            it->data_buffer_size,
            &data_store_callback,it);
  if(res != GLOBUS_SUCCESS) {
    /* Because this error can be caused by EOF, abort should not be
       called unless this is last buffer */
    if(it->data_callbacks==0) {
      logger.msg(Arc::ERROR, "Globus error: %s", Arc::GlobusResult(res).str());
      it->force_abort();
      it->free_data_buffer();it->froot.close(false);
    };
    globus_mutex_unlock(&(it->data_lock)); return;
  };
  it->data_callbacks++;
  globus_mutex_unlock(&(it->data_lock)); return;
}