/// Provide access to files as allowed by process definitions. void HttpFileAccess::processRequest(const HttpRequestContext& requestContext, const HttpMessage& request, HttpMessage*& response ) { UtlString message; response = new HttpMessage(); UtlString peerName; if (mSipxRpc->isAllowedPeer(requestContext, peerName)) { if (requestContext.methodIs(HTTP_GET_METHOD)) { UtlString path; requestContext.getMappedPath(path); FileResource* resource = FileResourceManager::getInstance()->find(path); if (resource) { if (resource->isReadable()) { sendFile(path, peerName, requestContext, request, response); } else { message.append("resource "); resource->appendDescription(message); message.append(" does not allow write access to '"); message.append(path); message.append("'"); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "HttpFileAccess::processRequest from %s %s", peerName.data(), message.data()); response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION, HTTP_FORBIDDEN_CODE, "Access denied by process definition"); response->setBody(new HttpBody(message.data(),message.length())); response->setContentType(CONTENT_TYPE_TEXT_PLAIN); response->setContentLength(message.length()); } } else { message.append("File resource '"); message.append(path); message.append("' not known to sipXsupervisor."); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "HttpFileAccess::processRequest from %s %s", peerName.data(), message.data()); response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION, HTTP_FILE_NOT_FOUND_CODE, HTTP_FILE_NOT_FOUND_TEXT); response->setBody(new HttpBody(message.data(),message.length())); response->setContentType(CONTENT_TYPE_TEXT_PLAIN); response->setContentLength(message.length()); } } else if (requestContext.methodIs(HTTP_DELETE_METHOD)) { UtlString path; requestContext.getMappedPath(path); FileResource* resource = FileResourceManager::getInstance()->find(path); if (resource) { if (resource->isWriteable()) { OsPath filePath(path); if (OsFileSystem::exists(filePath)) { if (OS_SUCCESS == OsFileSystem::remove(filePath, TRUE /* recursive */, TRUE /* force */)) { message.append("File '"); message.append(path); message.append("' deleted"); OsSysLog::add(FAC_SUPERVISOR, PRI_INFO, "HttpFileAccess::processRequest from %s %s", peerName.data(), message.data()); response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION_1_1, HTTP_OK_CODE, "Deleted"); response->setContentLength(0); // tell anyone who cares that this has changed resource->modified(); } else { int httpStatusCode; UtlString httpStatusText; switch (errno) { case EACCES: httpStatusCode = HTTP_FORBIDDEN_CODE; httpStatusText = "File Access Denied"; break; default: httpStatusCode = HTTP_SERVER_ERROR_CODE; httpStatusText.append("Unknown error "); httpStatusText.appendNumber(errno); break; } message.append("File '"); message.append(path); message.append("' errno "); message.appendNumber(errno); message.append(" "); char errnoMsg[1024]; strerror_r(errno, errnoMsg, sizeof(errnoMsg)); message.append(errnoMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "HttpFileAccess::processRequest from %s %s", peerName.data(), message.data()); response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION, httpStatusCode, httpStatusText); response->setBody(new HttpBody(message.data(),message.length())); response->setContentType(CONTENT_TYPE_TEXT_PLAIN); response->setContentLength(message.length()); } } else { message.append("File to be deleted '"); message.append(path); message.append("' does not exist"); OsSysLog::add(FAC_SUPERVISOR, PRI_INFO, "HttpFileAccess::processRequest from %s %s", peerName.data(), message.data()); response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION_1_1, HTTP_OK_CODE, "File does not exist"); response->setContentLength(0); } } else { message.append("resource "); resource->appendDescription(message); message.append(" does not allow write access to '"); message.append(path); message.append("'"); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "HttpFileAccess::processRequest from %s %s", peerName.data(), message.data()); response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION, HTTP_FORBIDDEN_CODE, "Access denied by process definition"); response->setBody(new HttpBody(message.data(),message.length())); response->setContentType(CONTENT_TYPE_TEXT_PLAIN); response->setContentLength(message.length()); } } else { message.append("File resource '"); message.append(path); message.append("' not known to sipXsupervisor."); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "HttpFileAccess::processRequest from %s %s", peerName.data(), message.data()); response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION, HTTP_FILE_NOT_FOUND_CODE, HTTP_FILE_NOT_FOUND_TEXT); response->setBody(new HttpBody(message.data(),message.length())); response->setContentType(CONTENT_TYPE_TEXT_PLAIN); response->setContentLength(message.length()); } } else { OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "HttpFileAccess::processRequest %s from %s", HTTP_UNSUPPORTED_METHOD_TEXT, peerName.data()); response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION, HTTP_UNSUPPORTED_METHOD_CODE, HTTP_UNSUPPORTED_METHOD_TEXT); } } else { message.append("Request not supported from untrusted peer."); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "HttpFileAccess::processRequest %s", message.data()); response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION, HTTP_FORBIDDEN_CODE, HTTP_FORBIDDEN_TEXT); response->setBody(new HttpBody(message.data(),message.length())); response->setContentType(CONTENT_TYPE_TEXT_PLAIN); response->setContentLength(message.length()); } }
bool FileRpcReplaceFile::execute(const HttpRequestContext& requestContext, UtlSList& params, void* userData, XmlRpcResponse& response, ExecutionStatus& status) { const int minPermissions = 0100; const int maxPermissions = 0777; bool result = false; status = XmlRpcMethod::FAILED; if (4 != params.entries()) { handleExtraExecuteParam(name(), response, status); } else { if (!params.at(0) || !params.at(0)->isInstanceOf(UtlString::TYPE)) { handleMissingExecuteParam(name(), PARAM_NAME_CALLING_HOST, response, status); } else { UtlString* pCallingHostname = dynamic_cast<UtlString*>(params.at(0)); if (!params.at(1) || !params.at(1)->isInstanceOf(UtlString::TYPE)) { handleMissingExecuteParam(name(), PARAM_NAME_FILE_NAME, response, status); } else { UtlString* pfileName = dynamic_cast<UtlString*>(params.at(1)); if (!params.at(2) || !params.at(2)->isInstanceOf(UtlInt::TYPE)) { handleMissingExecuteParam(name(), PARAM_NAME_FILE_PERMISSIONS, response, status); } else { UtlInt* pfilePermissions = dynamic_cast<UtlInt*>(params.at(2)); if (!params.at(3) || !params.at(3)->isInstanceOf(UtlString::TYPE)) { handleMissingExecuteParam(name(), PARAM_NAME_FILE_DATA, response, status); } else { UtlBool method_result(true); SipxRpc* pSipxRpcImpl = ((SipxRpc *)userData); if(validCaller(requestContext, *pCallingHostname, response, *pSipxRpcImpl, name())) { // Check the resource permissions. To be added when available. FileResource* fileResource = FileResourceManager::getInstance()->find(pfileName->data()); if (!fileResource) { UtlString faultMsg; faultMsg.append("File '"); faultMsg.append(*pfileName); faultMsg.append("' not declared as a resource by any sipXecs process"); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "FileRpc::replaceFile %s", faultMsg.data()); result=false; response.setFault(FileRpcMethod::InvalidParameter, faultMsg); } else if (!fileResource->isWriteable()) { UtlString faultMsg; faultMsg.append("File '"); faultMsg.append(*pfileName); faultMsg.append("' is not writeable (configAccess='read-only')"); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "FileRpc::replaceFile %s", faultMsg.data()); result=false; response.setFault(FileRpcMethod::InvalidParameter, faultMsg); } else if ( ( pfilePermissions->getValue() <= minPermissions ) || ( pfilePermissions->getValue() > maxPermissions )) { UtlString faultMsg; faultMsg.appendNumber(pfilePermissions->getValue(),"File permissions %04o"); faultMsg.appendNumber(minPermissions,"not within valid range (%04o - "); faultMsg.appendNumber(maxPermissions,"%04o)"); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "FileRpc::replaceFile %s", faultMsg.data()); result = false; response.setFault(FileRpcMethod::InvalidParameter, faultMsg); } else { // Write out the file. UtlString* pfileData = dynamic_cast<UtlString*>(params.at(3)); UtlString faultMsg; if((result=replicateFile(*pfileName,*pfilePermissions,*pfileData,faultMsg ))) { // Construct and set the response. response.setResponse(&method_result); status = XmlRpcMethod::OK; // Tell anyone who cares that this changed fileResource->modified(); } else { // Replication failed. response.setFault(FileRpcMethod::InvalidParameter, faultMsg); } } } } } } } } return result; }