From: Sungbae Yoo Date: Thu, 17 Jan 2019 03:26:57 +0000 (+0900) Subject: Add klay-legacy classes into this repository X-Git-Tag: accepted/tizen/5.0/unified/20190304.054838~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=11449eb98d42385e9567f34891f67ce898b67f67;p=platform%2Fcore%2Fsecurity%2Fkrate.git Add klay-legacy classes into this repository It moves several classes such as Cgroup, Namespace, xml. Change-Id: I67bcd993230f8cbaf01012aba003d7bd8b7a734f Signed-off-by: Sungbae Yoo --- diff --git a/CMakeLists.txt b/CMakeLists.txt index e7b2b3e..0a9d6f5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ SET(KRATE_SERVER ${PROJECT_SOURCE_DIR}/server) SET(KRATE_DATA ${PROJECT_SOURCE_DIR}/data) SET(KRATE_MODULE ${PROJECT_SOURCE_DIR}/module) SET(KRATE_VOLUME ${PROJECT_SOURCE_DIR}/volume) +SET(KRATE_COMMON ${PROJECT_SOURCE_DIR}/common) IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) SET(CXX_STD "c++0x") diff --git a/common/cgroup.cpp b/common/cgroup.cpp new file mode 100644 index 0000000..8276f46 --- /dev/null +++ b/common/cgroup.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "cgroup.h" + +#define NAME_PATTERN "^[A-Za-z_][A-Za-z0-9_-]*" +#define PATH_PATTERN "(/*[A-Za-z_][A-Za-z0-9_-]*)*" + +bool Cgroup::existSubsystem(const std::string& name) +{ + try { + if (!std::regex_match(name, std::regex(NAME_PATTERN))) { + return false; + } + } catch (std::runtime_error &e) { + throw klay::Exception("Unexpected regex error"); + } + + klay::File dir("/sys/fs/cgroup/" + name); + if (dir.exists()) { + if (dir.isDirectory()) { + return true; + } + throw klay::Exception("Invalid subsystem name"); + } + + return false; +} + +void Cgroup::createSubsystem(const std::string& name) +{ + try { + if (!std::regex_match(name, std::regex(NAME_PATTERN))) { + throw klay::Exception("Invalid subsystem name"); + } + } catch (std::runtime_error &e) { + throw klay::Exception("Unexpected regex error"); + } + + if (existSubsystem(name)) { + return; + } + + klay::File subsystem("/sys/fs/cgroup/" + name); + if (::mount(NULL, "/sys/fs/cgroup/", NULL, MS_REMOUNT | + MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, + "mode=755")) { + throw klay::Exception("Failed to remount cgroupfs as the writable"); + } + + if (!subsystem.exists()) { + subsystem.makeDirectory(true); + } + + if (::mount(name.c_str(), subsystem.getPath().c_str(), + "cgroup", MS_NODEV | MS_NOSUID | MS_NOEXEC, + ("none,name=" + name).c_str())) { + subsystem.remove(false); + throw klay::Exception("Failed to mount cgroup subsystem"); + } + + if (::mount(NULL, "/sys/fs/cgroup/", NULL, MS_REMOUNT | MS_RDONLY | + MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, + "mode=755")) { + throw klay::Exception("Failed to remount cgroupfs as the read-only"); + } +} + +void Cgroup::destroySubsystem(const std::string& name) +{ + if (!existSubsystem(name)) { + throw klay::Exception("No such subsystem"); + } + + if (::mount(NULL, "/sys/fs/cgroup/", NULL, MS_REMOUNT | + MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, + "mode=755")) { + throw klay::Exception("Failed to remount cgroupfs as the writable"); + } + + klay::File subsystem("/sys/fs/cgroup/" + name); + ::umount2(subsystem.getPath().c_str(), MNT_EXPIRE); + + subsystem.remove(false); + + if (::mount(NULL, "/sys/fs/cgroup/", NULL, MS_REMOUNT | MS_RDONLY | + MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, + "mode=755")) { + throw klay::Exception("Failed to remount cgroupfs as the read-only"); + } +} + +bool Cgroup::exist(const std::string& subsystem, const std::string& path) +{ + try { + if (!std::regex_match(path, std::regex(PATH_PATTERN))) { + return false; + } + } catch (std::runtime_error &e) { + throw klay::Exception("Unexpected regex error"); + } + + klay::File dir("/sys/fs/cgroup/" + subsystem + "/" + path); + if (dir.exists()) { + if (dir.isDirectory()) { + return true; + } + throw klay::Exception("Invalid path"); + } + + return false; +} + +void Cgroup::create(const std::string& subsystem, const std::string& path) +{ + try { + if (!std::regex_match(path, std::regex(PATH_PATTERN))) { + throw klay::Exception("Invalid path"); + } + } catch (std::runtime_error &e) { + throw klay::Exception("Unexpected regex error"); + } + + if (exist(subsystem, path)) { + return; + } + + klay::File dir("/sys/fs/cgroup/" + subsystem + "/" + path); + dir.makeDirectory(true); +} + +void Cgroup::destroy(const std::string& subsystem, const std::string& path) +{ + if (!exist(subsystem, path)) { + throw klay::Exception("No such path in subsystem"); + } + + klay::File dir("/sys/fs/cgroup/" + subsystem + "/" + path); + dir.remove(false); +} + +void Cgroup::addProcess(const std::string& subsystem, const std::string& path, const pid_t pid) +{ + if (!exist(subsystem, path)) { + throw klay::Exception("No such path in subsystem"); + } + + std::ofstream ofs("/sys/fs/cgroup/" + subsystem + "/" + path + + "/tasks"); + + ofs << pid << std::endl; +} + +std::vector Cgroup::getProcessList(const std::string& subsystem, const std::string& path) +{ + std::vector ret; + std::ifstream ifs("/sys/fs/cgroup/" + subsystem + "/" + path + + "/tasks"); + + pid_t pid; + + ifs >> pid; + + while (ifs.good()) { + ret.push_back(pid); + ifs >> pid; + } + + return ret; +} + +const std::string Cgroup::getPath(const std::string& subsystem, const pid_t pid) +{ + std::ifstream ifs("/proc/" + std::to_string(pid) + "/cgroup"); + std::string ret = "/", line; + + while (std::getline(ifs, line)) { + std::stringstream lineStream(line); + std::string name; + + //the first getline is for removing the first argument + std::getline(lineStream, name, ':'); + std::getline(lineStream, name, ':'); + + if (name == subsystem || name == "name=" + subsystem) { + ret = line.substr(line.find('/')); + } + } + return ret; +} diff --git a/common/cgroup.h b/common/cgroup.h new file mode 100644 index 0000000..63994cd --- /dev/null +++ b/common/cgroup.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#ifndef __COMMON_CGROUP_H__ +#define __COMMON_CGROUP_H__ + +#include +#include + +class Cgroup final { +public: + Cgroup() = delete; + + static bool existSubsystem(const std::string& name); + static void createSubsystem(const std::string& name); + static void destroySubsystem(const std::string& name); + + static bool exist(const std::string& subsystem, const std::string& path); + static void create(const std::string& subsystem, const std::string& path); + static void destroy(const std::string& subsystem, const std::string& path); + + static void addProcess(const std::string& subsystem, + const std::string& path, const pid_t pid); + static std::vector getProcessList(const std::string& subsystem, + const std::string& path); + + static const std::string getPath(const std::string& subsystem, const pid_t pid); +}; + +#endif //!__RUNTIME_CGROUP_H__ diff --git a/common/namespace.cpp b/common/namespace.cpp new file mode 100644 index 0000000..fdcd1b5 --- /dev/null +++ b/common/namespace.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +#include + +#include +#include +#include + +#include + +#include "namespace.h" + +namespace { + +typedef std::pair NamespacePair; +std::vector namespaces = { + {"mnt", CLONE_NEWNS}, + {"net", CLONE_NEWNET}, + {"ipc", CLONE_NEWIPC}, + {"pid", CLONE_NEWPID}, + {"uts", CLONE_NEWUTS}, + {"user", CLONE_NEWUSER}, +#ifdef CLONE_NEWCGROUP + {"cgroup", CLONE_NEWCGROUP}, +#endif +}; + +} // namespace + +void Namespace::attach(const pid_t pid) +{ + for (const NamespacePair& ns : namespaces) { + std::string nspath = "/proc/" + std::to_string(pid) + "/ns/" + ns.first; + + int fd; + do { + fd = ::open(nspath.c_str(), O_RDONLY); + } while (fd == -1 && errno == EINTR); + + if (fd == -1) { + if (errno != ENOENT) { + throw klay::Exception("Failed to open namesapce: " + nspath); + } + } else { + if (::setns(fd, ns.second)) { + ::close(fd); + throw klay::Exception("Failed to set namespace: " + nspath); + } + ::close(fd); + } + } +} + +void Namespace::unshare(int flags) +{ + if (::unshare(flags)) { + throw klay::Exception("Failed to unshare namespace"); + } + + if (flags & CLONE_NEWNS && + ::mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) == -1) { + throw klay::Exception("Failed to mount root filesystem"); + } +} diff --git a/common/namespace.h b/common/namespace.h new file mode 100644 index 0000000..bc9368c --- /dev/null +++ b/common/namespace.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#ifndef __RUNTIME_NAMESPACE_H__ +#define __RUNTIME_NAMESPACE_H__ + +#include + +class Namespace final { +public: + Namespace() = delete; + + static void unshare(int flags); + static void attach(const pid_t pid); +}; + +#endif //!__RUNTIME_NAMESPACE_H__ diff --git a/common/xml/document.cpp b/common/xml/document.cpp new file mode 100644 index 0000000..6056b09 --- /dev/null +++ b/common/xml/document.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#include + +#include + +#include + +#include "document.h" +#include "keepblanks.h" + +namespace xml { + +Document::Document(const std::string& root, const std::string& version) : + implementation(xmlNewDoc((const xmlChar*)version.c_str())) +{ + if (implementation == nullptr) { + throw klay::Exception("Failed to create document"); + } + + implementation->_private = this; + + xmlNode* rootPtr = xmlNewNode(NULL, xmlStrdup((const xmlChar*)root.c_str())); + xmlDocSetRootElement(implementation, rootPtr); + + rootNode = new Node(rootPtr); +} + +Document::Document(xmlDoc* doc) + : implementation(doc) +{ + implementation->_private = this; + + rootNode = new Node(xmlDocGetRootElement(implementation)); +} + +Document::~Document() +{ + if (rootNode != nullptr) { + delete rootNode; + } + + xmlFreeDoc(implementation); +} + +Node& Document::getRootNode() +{ + if (rootNode == nullptr) { + throw klay::Exception("Empty document"); + } + + return *rootNode; +} + +Node::NodeList Document::evaluate(const std::string& xpath) +{ + auto ctxt = xmlXPathNewContext(implementation); + if (ctxt == nullptr) { + throw klay::Exception("Failed to create XPath context for " + xpath); + } + + auto result = xmlXPathEval((const xmlChar*)xpath.c_str(), ctxt); + if (result == nullptr) { + xmlXPathFreeContext(ctxt); + throw klay::Exception("Invalid XPath: " + xpath); + } + + if (result ->type != XPATH_NODESET) { + xmlXPathFreeObject(result); + xmlXPathFreeContext(ctxt); + + throw klay::Exception("Only nodeset result types are supported"); + } + + auto nodeset = result->nodesetval; + + Node::NodeList nodes; + if ((nodeset == nullptr) || (xmlXPathNodeSetIsEmpty(nodeset))) { + xmlXPathFreeContext(ctxt); + return nodes; + } + + const int count = xmlXPathNodeSetGetLength(nodeset); + + nodes.reserve(count); + for (int i = 0; i != count; i++) { + auto cnode = xmlXPathNodeSetItem(nodeset, i); + if (!cnode) { + continue; + } + + if (cnode->type == XML_NAMESPACE_DECL) { + continue; + } + + nodes.emplace_back(cnode); + } + + xmlXPathFreeObject(result); + xmlXPathFreeContext(ctxt); + + return nodes; +} + +void Document::write(const std::string& filename, const std::string& encoding, bool formatted) +{ + KeepBlanks keepBlanks(KeepBlanks::Default); + xmlIndentTreeOutput = formatted; + + xmlResetLastError(); + + const int result = xmlSaveFormatFileEnc(filename.c_str(), + implementation, + encoding.c_str(), + formatted); + if (result == 0) { + throw klay::Exception("Failed to write XML document"); + } +} + +} // namespace xml diff --git a/common/xml/document.h b/common/xml/document.h new file mode 100644 index 0000000..08dd1b5 --- /dev/null +++ b/common/xml/document.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#ifndef __XML_DOCUMENT_H__ +#define __XML_DOCUMENT_H__ + +#include +#include + +#include + +#include + +namespace xml { + +class Document { +public: + Document(const std::string& root, const std::string& version = XML_DEFAULT_VERSION); + Document(xmlDoc* doc); + + ~Document(); + + Node& getRootNode(); + + Node::NodeList evaluate(const std::string& xpath); + void write(const std::string& filename, const std::string& encoding, bool formatted); + +private: + Node* rootNode; + xmlDoc* implementation; +}; + +} // namespace xml + + +#endif //__XML_DOCUMENT_H__ diff --git a/common/xml/keepblanks.cpp b/common/xml/keepblanks.cpp new file mode 100644 index 0000000..906aa75 --- /dev/null +++ b/common/xml/keepblanks.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +#include "keepblanks.h" + +namespace xml { + +KeepBlanks::KeepBlanks(bool value) +{ + preservedIndentTreeOutput = xmlIndentTreeOutput; + preservedKeepBlanksDefault = xmlKeepBlanksDefault(value ? 1 : 0); +} + +KeepBlanks::~KeepBlanks() +{ + xmlKeepBlanksDefault(preservedKeepBlanksDefault); + xmlIndentTreeOutput = preservedIndentTreeOutput; +} + +} // namespace xml diff --git a/common/xml/keepblanks.h b/common/xml/keepblanks.h new file mode 100644 index 0000000..d227051 --- /dev/null +++ b/common/xml/keepblanks.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#ifndef __XML_KEEPBLANKS_H__ +#define __XML_KEEPBLANKS_H__ + +#include + +namespace xml { + +class KeepBlanks { +public: + KeepBlanks(bool value); + ~KeepBlanks(); + + static const bool Default = true; + +private: + int preservedKeepBlanksDefault; + int preservedIndentTreeOutput; +}; + +} // namespace xml + +#endif //__XML_KEEPBLANKS_H__ diff --git a/common/xml/node.cpp b/common/xml/node.cpp new file mode 100644 index 0000000..0c0609e --- /dev/null +++ b/common/xml/node.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +#include + +#include "node.h" + +namespace xml { + +Node::Node(xmlNode* node) : + implementation(node) +{ +} + +Node::Node(Node&& node) : + implementation(node.implementation) +{ +} + +Node::~Node() +{ +} + +Node::NodeList Node::getChildren() const +{ + NodeList nodeList; + + auto child = implementation->xmlChildrenNode; + while (child != nullptr) { + nodeList.emplace_back(child); + child = child->next; + } + + return nodeList; +} + +Node Node::addNewChild(const std::string& name) +{ + xmlNode* nodePtr = xmlNewNode(NULL, xmlStrdup((const xmlChar*)name.c_str())); + if (nodePtr == nullptr) { + throw klay::Exception("Can not create a new node"); + } + xmlAddChild(implementation, nodePtr); + + return Node(nodePtr); +} + +std::string Node::getName() const +{ + return implementation->name ? (const char*)implementation->name : ""; +} + +void Node::setName(const std::string& name) +{ + xmlNodeSetName(implementation, (const xmlChar*)name.c_str()); +} + +std::string Node::getContent() const +{ + xmlChar* content = xmlNodeGetContent(implementation); + if (content == NULL) { + return ""; + } + std::string ret((const char*)content); + xmlFree(content); + return ret; +} + +void Node::setContent(const std::string& content) +{ + xmlNodeSetContent(implementation, (xmlChar*)content.c_str()); +} + +std::string Node::getProp(const std::string& name) const +{ + if (implementation->type != XML_ELEMENT_NODE) { + throw klay::Exception("This node type does not have properties"); + } + + xmlChar* prop = xmlGetProp(implementation, (xmlChar*)name.c_str()); + if (prop) { + std::string ret((const char*)prop); + xmlFree(prop); + return ret; + } + + return ""; +} + +void Node::setProp(const std::string& name, const std::string& val) +{ + if (implementation->type != XML_ELEMENT_NODE) { + throw klay::Exception("Can not set properties for this node type"); + } + + xmlSetProp(implementation, (xmlChar*)name.c_str(), (xmlChar*)val.c_str()); +} + +bool Node::isBlank() const +{ + return xmlIsBlankNode(const_cast(implementation)); +} + +} // namespace xml diff --git a/common/xml/node.h b/common/xml/node.h new file mode 100644 index 0000000..259164c --- /dev/null +++ b/common/xml/node.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#ifndef __XML_NODE_H__ +#define __XML_NODE_H__ + +#include +#include + +#include +#include + +namespace xml { + +class Node { +public: + typedef std::vector NodeList; + + explicit Node(xmlNode* node); + Node(Node&&); + Node(const Node&) = delete; + + ~Node(); + + Node& operator=(const Node&) = delete; + + NodeList getChildren() const; + Node addNewChild(const std::string& name); + + std::string getName() const; + void setName(const std::string& name); + + std::string getContent() const; + void setContent(const std::string& content); + + std::string getProp(const std::string& name) const; + void setProp(const std::string& name, const std::string& val); + + bool isBlank() const; + +private: + xmlNode* implementation; +}; + +} // namespace xml + +#endif //__XML_NODE_H__ diff --git a/common/xml/parser.cpp b/common/xml/parser.cpp new file mode 100644 index 0000000..a878d30 --- /dev/null +++ b/common/xml/parser.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +#include + +#include + +#include "parser.h" +#include "keepblanks.h" + +namespace xml { + +Document* Parser::parseContext(xmlParserCtxt* context, bool validate) +{ + if (context == nullptr) { + throw klay::Exception("Could not create parser context"); + } + + KeepBlanks(false); + + int options = 0; + + if (validate) { + options |= XML_PARSE_DTDVALID; + } else { + options &= ~XML_PARSE_DTDVALID; + } + + xmlCtxtUseOptions(context, options); + + if (xmlParseDocument(context) < 0) { + xmlFreeParserCtxt(context); + throw klay::Exception("Parsing failed"); + } + + xmlDoc* document = context->myDoc; + + // We took the ownership on the doc + context->myDoc = nullptr; + + xmlFreeParserCtxt(context); + + return new Document(document); +} + +Document* Parser::parseFile(const std::string& filename, bool validate) +{ + xmlParserCtxt* context = xmlCreateFileParserCtxt(filename.c_str()); + if (context == nullptr) { + throw klay::Exception("Could not create parser context"); + } + + if (context->directory == nullptr) { + context->directory = xmlParserGetDirectory(filename.c_str()); + } + + return parseContext(context, validate); +} + +Document* Parser::parseString(const std::string& xml, bool validate) +{ + xmlParserCtxt* context = xmlCreateMemoryParserCtxt(xml.c_str(), xml.size() + 1); + + if (context == nullptr) { + throw klay::Exception("Could not create parser context"); + } + + return parseContext(context, validate); +} + +} // namespace xml diff --git a/common/xml/parser.h b/common/xml/parser.h new file mode 100644 index 0000000..f6f3eb9 --- /dev/null +++ b/common/xml/parser.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#ifndef __XML_DOMPARSER_H__ +#define __XML_DOMPARSER_H__ + +#include + +#include + +#include + +namespace xml { + +class Parser { +public: + static Document* parseFile(const std::string& filename, bool validate = false); + static Document* parseString(const std::string& xml, bool validate = false); + +private: + static Document* parseContext(xmlParserCtxt* context, bool validate = false); +}; + +} // namespace xml + +#endif //__XML_DOMPARSER_H__ diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt index 2c3cd43..c3a603e 100644 --- a/module/CMakeLists.txt +++ b/module/CMakeLists.txt @@ -15,7 +15,14 @@ # SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack") -FILE(GLOB BUILDER_SRCS krate-builder.cpp) +FILE(GLOB BUILDER_SRCS krate-builder.cpp + ${KRATE_COMMON}/cgroup.cpp + ${KRATE_COMMON}/namespace.cpp + ${KRATE_COMMON}/xml/node.cpp + ${KRATE_COMMON}/xml/parser.cpp + ${KRATE_COMMON}/xml/document.cpp + ${KRATE_COMMON}/xml/keepblanks.cpp +) PKG_CHECK_MODULES(BUILDER_DEPS REQUIRED klay @@ -40,7 +47,7 @@ MARK_AS_ADVANCED(PAM_INCLUDE_DIR PAM_LIBRARY) INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(PAM DEFAULT_MSG PAM_LIBRARY PAM_INCLUDE_DIR) -INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR} ${BUILDER_DEPS_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR} ${BUILDER_DEPS_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}) TARGET_LINK_LIBRARIES(${PAM_NAME} ${PAM_LIBRARY} ${BUILDER_DEPS_LIBRARIES}) diff --git a/module/krate-builder.cpp b/module/krate-builder.cpp index 3e13cc7..4b423cc 100644 --- a/module/krate-builder.cpp +++ b/module/krate-builder.cpp @@ -22,9 +22,10 @@ #include "krate-builder.h" #include -#include #include +#include + #define CGROUP_SUBSYSTEM "krate" KrateBuilder::KrateBuilder(const runtime::User& user) : @@ -82,28 +83,28 @@ void KrateBuilder::enterKrate() std::string path = CGROUP_SUBSYSTEM "/" + user.getName(); pid_t pid = 0; - if (runtime::Cgroup::exist(CGROUP_SUBSYSTEM, path)) { - auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, path); + if (Cgroup::exist(CGROUP_SUBSYSTEM, path)) { + auto pids = Cgroup::getProcessList(CGROUP_SUBSYSTEM, path); if (pids.size() > 0) { pid = pids[0]; } } else { - runtime::Cgroup::create(CGROUP_SUBSYSTEM, path); + Cgroup::create(CGROUP_SUBSYSTEM, path); } if (pid == 0) { - runtime::Cgroup::addProcess(CGROUP_SUBSYSTEM, path, ::getpid()); - runtime::Namespace::unshare(CLONE_NEWNS | CLONE_NEWIPC); + Cgroup::addProcess(CGROUP_SUBSYSTEM, path, ::getpid()); + Namespace::unshare(CLONE_NEWNS | CLONE_NEWIPC); } else { - runtime::Namespace::attach(pid); + Namespace::attach(pid); } } void KrateBuilder::exitKrate() { std::string path = CGROUP_SUBSYSTEM "/" + user.getName(); - auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, path); + auto pids = Cgroup::getProcessList(CGROUP_SUBSYSTEM, path); if (pids.size() <= 1) { - runtime::Cgroup::destroy(CGROUP_SUBSYSTEM, path); + Cgroup::destroy(CGROUP_SUBSYSTEM, path); } } diff --git a/module/krate-builder.h b/module/krate-builder.h index 1563c3e..724b9ea 100644 --- a/module/krate-builder.h +++ b/module/krate-builder.h @@ -20,11 +20,12 @@ #include #include -#include -#include -#include #include +#include +#include +#include + class KrateBuilder final { public: KrateBuilder(const runtime::User& user); diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 7651c57..f75b6d6 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -21,6 +21,11 @@ SET(SERVER_SRCS main.cpp manager.cpp app-proxy.cpp package-proxy.cpp + ${KRATE_COMMON}/cgroup.cpp + ${KRATE_COMMON}/xml/node.cpp + ${KRATE_COMMON}/xml/parser.cpp + ${KRATE_COMMON}/xml/document.cpp + ${KRATE_COMMON}/xml/keepblanks.cpp ) SET(DEPENDENCY klay diff --git a/server/manager.cpp b/server/manager.cpp index d3b0aa5..4a95afa 100755 --- a/server/manager.cpp +++ b/server/manager.cpp @@ -28,17 +28,18 @@ #include #include #include -#include #include #include #include -#include -#include + #include #include #include "packman.h" #include "launchpad.h" +#include +#include +#include #include "rmi/manager.h" @@ -531,8 +532,8 @@ Manager::Manager(KrateControlContext& ctx) : context.createNotification("Manager::created"); context.createNotification("Manager::removed"); - runtime::Cgroup::createSubsystem(CGROUP_SUBSYSTEM); - runtime::Cgroup::create(CGROUP_SUBSYSTEM, CGROUP_SUBSYSTEM); + Cgroup::createSubsystem(CGROUP_SUBSYSTEM); + Cgroup::create(CGROUP_SUBSYSTEM, CGROUP_SUBSYSTEM); KRATE_DEFAULT_OWNER = ::tzplatform_getenv(TZ_SYS_DEFAULT_USER);