TrinityCore
TCSoap.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "TCSoap.h"
19#include "soapH.h"
20#include "soapStub.h"
21#include "Realm.h"
22#include "World.h"
23#include "AccountMgr.h"
24#include "Log.h"
25
26void TCSoapThread(const std::string& host, uint16 port)
27{
28 struct soap soap;
29 soap_init(&soap);
30 soap_set_imode(&soap, SOAP_C_UTFSTRING);
31 soap_set_omode(&soap, SOAP_C_UTFSTRING);
32
33#if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS
34 soap.bind_flags = SO_REUSEADDR;
35#endif
36
37 // check every 3 seconds if world ended
38 soap.accept_timeout = 3;
39 soap.recv_timeout = 5;
40 soap.send_timeout = 5;
41 if (!soap_valid_socket(soap_bind(&soap, host.c_str(), port, 100)))
42 {
43 TC_LOG_ERROR("network.soap", "Couldn't bind to {}:{}", host, port);
44 exit(-1);
45 }
46
47 TC_LOG_INFO("network.soap", "Bound to http://{}:{}", host, port);
48
49 while (!World::IsStopped())
50 {
51 if (!soap_valid_socket(soap_accept(&soap)))
52 continue; // ran into an accept timeout
53
54 TC_LOG_DEBUG("network.soap", "Accepted connection from IP={}.{}.{}.{}", (int)(soap.ip>>24)&0xFF, (int)(soap.ip>>16)&0xFF, (int)(soap.ip>>8)&0xFF, (int)soap.ip&0xFF);
55 struct soap* thread_soap = soap_copy(&soap);// make a safe copy
56 process_message(thread_soap);
57 }
58
59 soap_destroy(&soap);
60 soap_end(&soap);
61 soap_done(&soap);
62}
63
64void process_message(struct soap* soap_message)
65{
66 TC_LOG_TRACE("network.soap", "SOAPWorkingThread::process_message");
67
68 soap_serve(soap_message);
69 soap_destroy(soap_message); // dealloc C++ data
70 soap_end(soap_message); // dealloc data and clean up
71 soap_free(soap_message); // detach soap struct and free up the memory
72}
73/*
74Code used for generating stubs:
75
76int ns1__executeCommand(char* command, char** result);
77*/
78int ns1__executeCommand(soap* soap, char* command, char** result)
79{
80 // security check
81 if (!soap->userid || !soap->passwd)
82 {
83 TC_LOG_INFO("network.soap", "Client didn't provide login information");
84 return 401;
85 }
86
87 uint32 accountId = AccountMgr::GetId(soap->userid);
88 if (!accountId)
89 {
90 TC_LOG_INFO("network.soap", "Client used invalid username '{}'", soap->userid);
91 return 401;
92 }
93
94 if (!AccountMgr::CheckPassword(accountId, soap->passwd))
95 {
96 TC_LOG_INFO("network.soap", "Invalid password for account '{}'", soap->userid);
97 return 401;
98 }
99
101 {
102 TC_LOG_INFO("network.soap", "{}'s gmlevel is too low", soap->userid);
103 return 403;
104 }
105
106 if (!command || !*command)
107 return soap_sender_fault(soap, "Command can not be empty", "The supplied command was an empty string");
108
109 TC_LOG_INFO("network.soap", "Received command '{}'", command);
110 SOAPCommand connection;
111
112 // commands are executed in the world thread. We have to wait for them to be completed
113 {
114 // CliCommandHolder will be deleted from world, accessing after queueing is NOT safe
116 sWorld->QueueCliCommand(cmd);
117 }
118
119 // Wait until the command has finished executing
120 connection.finishedPromise.get_future().wait();
121
122 // The command has finished executing already
123 char* printBuffer = soap_strdup(soap, connection.m_printBuffer.c_str());
124 if (connection.hasCommandSucceeded())
125 {
126 *result = printBuffer;
127 return SOAP_OK;
128 }
129 else
130 return soap_sender_fault(soap, printBuffer, printBuffer);
131}
132
133void SOAPCommand::commandFinished(void* soapconnection, bool success)
134{
135 SOAPCommand* con = (SOAPCommand*)soapconnection;
136 con->setCommandSuccess(success);
137}
138
140//
141// Namespace Definition Table
142//
144
145struct Namespace namespaces[] =
146{ { "SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", nullptr, nullptr }, // must be first
147 { "SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", nullptr, nullptr }, // must be second
148 { "xsi", "http://www.w3.org/1999/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", nullptr },
149 { "xsd", "http://www.w3.org/1999/XMLSchema", "http://www.w3.org/*/XMLSchema", nullptr },
150 { "ns1", "urn:TC", nullptr, nullptr }, // "ns1" namespace prefix
151 { nullptr, nullptr, nullptr, nullptr }
152};
@ SEC_ADMINISTRATOR
Definition: Common.h:43
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_TRACE(filterType__,...)
Definition: Log.h:153
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:159
struct Namespace namespaces[]
Definition: TCSoap.cpp:145
void process_message(struct soap *soap_message)
Definition: TCSoap.cpp:64
void TCSoapThread(const std::string &host, uint16 port)
Definition: TCSoap.cpp:26
int ns1__executeCommand(soap *soap, char *command, char **result)
Definition: TCSoap.cpp:78
static uint32 GetSecurity(uint32 accountId, int32 realmId)
Definition: AccountMgr.cpp:298
static bool CheckPassword(std::string username, std::string password)
Definition: AccountMgr.cpp:349
static uint32 GetId(std::string_view username)
Definition: AccountMgr.cpp:289
static void commandFinished(void *callbackArg, bool success)
Definition: TCSoap.cpp:133
bool hasCommandSucceeded() const
Definition: TCSoap.h:51
static void print(void *callbackArg, std::string_view msg)
Definition: TCSoap.h:56
std::string m_printBuffer
Definition: TCSoap.h:64
void setCommandSuccess(bool val)
Definition: TCSoap.h:45
std::promise< void > finishedPromise
Definition: TCSoap.h:65
static bool IsStopped()
Definition: World.h:671
#define sWorld
Definition: World.h:931
Realm realm
Definition: World.cpp:3966
Storage class for commands issued for delayed execution.
Definition: World.h:542
Battlenet::RealmHandle Id
Definition: Realm.h:82