Esempio n. 1
0
int 
store_cred_handler(Service * /*service*/, int /*i*/, Stream *stream) {
  void * data = NULL;
  int rtnVal = FALSE;
  int rc;
  char * temp_file_name = NULL;
  bool found_cred;
  CredentialWrapper * temp_cred = NULL;
  int data_size = -1;
  classad::ClassAd * _classad = NULL;
  classad::ClassAd classad;
  std::string classad_cstr;
  char * classad_str = NULL;
  classad::ClassAdParser parser;
  ReliSock * socket = (ReliSock*)stream;
  const char * user = NULL;

  CredentialWrapper * cred_wrapper = NULL;

  if (!socket->triedAuthentication()) { 
    CondorError errstack;
    if( ! SecMan::authenticate_sock(socket, WRITE, &errstack) ) {
      dprintf (D_ALWAYS, "Unable to authenticate, qutting\n");
      goto EXIT;
    }
  }

  user = socket->getFullyQualifiedUser();
  dprintf (D_FULLDEBUG, "Request by: %s, %s\n", socket->getOwner(), user);

  socket->decode();

  if (!socket->code (classad_str)) {
    dprintf (D_ALWAYS, "Error receiving credential metadata\n"); 
    goto EXIT;
  }

  classad_cstr = classad_str;
  free (classad_str);

  _classad = parser.ParseClassAd(classad_cstr);
  if (!_classad) {
	  dprintf (D_ALWAYS, "Error: invalid credential metadata %s\n", classad_cstr.c_str());
	  goto EXIT;
  }

  classad = *_classad;
  delete _classad;
  
 
  
  int type;
  if (!classad.EvaluateAttrInt ("Type", type)) {
    dprintf (D_ALWAYS, "Missing Type attribute in classad!\n");
    goto EXIT;
  }


  if (type == X509_CREDENTIAL_TYPE) {
	cred_wrapper = new X509CredentialWrapper (classad);
    dprintf (D_ALWAYS, "Name=%s Size=%d\n", 
			 cred_wrapper->cred->GetName(), 
			 cred_wrapper->cred->GetDataSize());

  } else {
	  dprintf (D_ALWAYS, "Unsupported credential type %d\n", type);
	  goto EXIT;
  }

  cred_wrapper->cred->SetOrigOwner (socket->getOwner()); // original remote uname
  cred_wrapper->cred->SetOwner (user);                   // mapped uname

  // Receive credential data
  data_size = cred_wrapper->cred->GetDataSize();
  if (data_size > MAX_CRED_DATA_SIZE) {
	  dprintf (D_ALWAYS, "ERROR: Credential data size %d > maximum allowed (%d)\n", data_size, MAX_CRED_DATA_SIZE);
	  goto EXIT;
  }

  data = malloc (data_size);
  if (data == NULL) {
	  EXCEPT("Out of memory. Aborting.");
  }
  if (!socket->code_bytes(data,data_size)) {
    dprintf (D_ALWAYS, "Error receiving credential data\n");
    goto EXIT;
  }
  cred_wrapper->cred->SetData (data, data_size);
  

  // Check whether credential under this name already exists
  found_cred=false;
  credentials.Rewind();
  while (credentials.Next(temp_cred)) {
	  if ((strcmp(cred_wrapper->cred->GetName(), 
				  temp_cred->cred->GetName()) == 0) && 
		  (strcmp(cred_wrapper->cred->GetOwner(), 
				  temp_cred->cred->GetOwner()) == 0)) {
		  found_cred=true;
		  break; // found it
	  }
  }

  if (found_cred) {
	  dprintf (D_ALWAYS, "Credential %s for owner %s already exists!\n", 
			   cred_wrapper->cred->GetName(), 
			   cred_wrapper->cred->GetOwner());
	  socket->encode();
	  int rcred=CREDD_ERROR_CREDENTIAL_ALREADY_EXISTS;
	  socket->code(rcred);
	  goto EXIT;
  }

  
  // Write data to a file
  temp_file_name = dircat (cred_store_dir, "credXXXXXX");
  condor_mkstemp (temp_file_name);
  cred_wrapper->SetStorageName (temp_file_name);
  
  init_user_id_from_FQN (user);
  if (!StoreData(temp_file_name,data,data_size)) {
    socket->encode();
    int rcred = CREDD_UNABLE_TO_STORE;
    socket->code(rcred);
    goto EXIT;
  }

  ((X509CredentialWrapper*)cred_wrapper)->cred->SetRealExpirationTime (
			   x509_proxy_expiration_time(temp_file_name));

  // Write metadata to a file
  credentials.Append (cred_wrapper);
  SaveCredentialList();

  // Write response to the client
  socket->encode();
  rc = CREDD_SUCCESS;
  socket->code(rc);

  dprintf( D_ALWAYS, "Credential name %s owner %s successfully stored\n",
			 cred_wrapper->cred->GetName(), cred_wrapper->cred->GetOwner() );

  if (type == X509_CREDENTIAL_TYPE) {
	((X509Credential*)cred_wrapper->cred)->display( D_FULLDEBUG );
  }
  rtnVal = TRUE;

EXIT:
  if ( data != NULL ) {
	  free (data);
  }
  if ( temp_file_name != NULL ) {
	  delete [] temp_file_name;
  }
  if ( cred_wrapper != NULL) {
	  delete cred_wrapper;
  }
  return rtnVal;
}
Esempio n. 2
0
int 
get_cred_handler(Service * /*service*/, int /*i*/, Stream *stream) {
  char * name = NULL;
  int rtnVal = FALSE;
  bool found_cred=false;
  CredentialWrapper * cred = NULL;
  char * owner = NULL;
  const char * user = NULL;
  void * data = NULL;

  ReliSock * socket = (ReliSock*)stream;

  // Authenticate
  if (!socket->triedAuthentication()) {
    CondorError errstack;
    if( ! SecMan::authenticate_sock(socket, READ, &errstack) ) {
      dprintf (D_ALWAYS, "Unable to authenticate, qutting\n");
      goto EXIT;
    }
  }

  socket->decode();

  if (!socket->code(name)) {
    dprintf (D_ALWAYS, "Error receiving credential name\n"); 
    goto EXIT;
  }

  user = socket->getFullyQualifiedUser();
  dprintf (D_ALWAYS, "Authenticated as %s\n", user);

  if (strchr (name, ':')) {
    // The name is of the form user:name
    // This better be a super-user!
    // TODO: Check super-user's list

    // Owner is the first part
    owner = strdup (name);
    char * pColon = strchr (owner, ':');
    *pColon = '\0';
    
    // Name is the second part
    sprintf (name, "%s", (char*)(pColon+sizeof(char)));
  
    if (strcmp (owner, user) != 0) { 
      dprintf (D_ALWAYS, "Requesting another user's (%s) credential %s\n", owner, name);

      if (!isSuperUser (user)) {
	dprintf (D_ALWAYS, "User %s is NOT super user, request DENIED\n", user);
	goto EXIT;
      } else {
	dprintf (D_FULLDEBUG, "User %s is super user, request GRANTED\n", user);
      }
    }

  } else {
    owner = strdup (user);
  }

  dprintf (D_ALWAYS, "sending cred %s for user %s\n", name, owner);

  credentials.Rewind();
  while (credentials.Next(cred)) {
	  if (cred->cred->GetType() == X509_CREDENTIAL_TYPE) {
		  if ((strcmp(cred->cred->GetName(), name) == 0) && 
			  (strcmp(cred->cred->GetOwner(), owner) == 0)) {
			  found_cred=true;
			  break; // found it
      }
    }
  }
  
  socket->encode();

  if (found_cred) {
    dprintf (D_FULLDEBUG, "Found cred %s\n", cred->GetStorageName());
    
    int data_size;

    
    int rc = LoadData (cred->GetStorageName(), data, data_size);
    dprintf (D_FULLDEBUG, "Credential::LoadData returned %d\n", rc);
    if (rc == 0) {
      goto EXIT;
    }
    
    socket->code (data_size);
    socket->code_bytes (data, data_size);
    dprintf (D_ALWAYS, "Credential name %s for owner %s returned to user %s\n",
			name, owner, user);
  }
  else {
    dprintf (D_ALWAYS, "Cannot find cred %s\n", name);
    int rc = CREDD_CREDENTIAL_NOT_FOUND;
    socket->code (rc);
  }

  rtnVal = TRUE;
EXIT:
  if ( name != NULL) {
	  free (name);
  }
  if ( owner != NULL) {
	  free (owner);
  }
  if ( data != NULL) {
	  free (data);
  }
  return rtnVal;
}