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; }
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; }