1
#include "np_connections_server.h"
2
#include "named_pipe_server.h"
5
# include <sys/types.h>
6
# include <sys/socket.h>
12
static PIPE_HANDLE createNamedPipe(const char* pipeName, SECURITY_ATTRIBUTES sa)
14
return CreateNamedPipe( pipeName,
15
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
16
PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_READMODE_BYTE,
17
PIPE_UNLIMITED_INSTANCES,
22
static PACL prepareNamedPipeAcl(SECURITY_DESCRIPTOR* sd, SECURITY_ATTRIBUTES* sa)
25
char everyone_buf[32], owner_buf[32];
26
PSID sid_everyone, sid_owner;
27
SID_IDENTIFIER_AUTHORITY
28
siaWorld = SECURITY_WORLD_SID_AUTHORITY,
29
siaCreator = SECURITY_CREATOR_SID_AUTHORITY;
32
sid_everyone = (PSID)&everyone_buf;
33
sid_owner = (PSID)&owner_buf;
35
req_acl_size = sizeof(ACL) +
36
(2 * ((sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + GetSidLengthRequired(1)));
38
acl = (PACL) malloc(req_acl_size);
44
if (!InitializeSid(sid_everyone, &siaWorld, 1)) {
47
*GetSidSubAuthority(sid_everyone, 0) = SECURITY_WORLD_RID;
49
if (!InitializeSid(sid_owner, &siaCreator, 1)) {
52
*GetSidSubAuthority(sid_owner, 0) = SECURITY_CREATOR_OWNER_RID;
54
if (!InitializeAcl(acl, req_acl_size, ACL_REVISION)) {
58
if (!AddAccessAllowedAce(acl, ACL_REVISION, FILE_GENERIC_READ | FILE_GENERIC_WRITE, sid_everyone)) {
62
if (!AddAccessAllowedAce(acl, ACL_REVISION, FILE_ALL_ACCESS, sid_owner)) {
66
if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
70
if (!SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE)) {
74
sa->lpSecurityDescriptor = sd;
85
clNamedPipeConnectionsServer::clNamedPipeConnectionsServer(const char* pipeName)
86
: _listenHandle(INVALID_PIPE_HANDLE)
88
_pipePath = strdup(pipeName);
91
clNamedPipeConnectionsServer::~clNamedPipeConnectionsServer()
97
_listenHandle = INVALID_PIPE_HANDLE;
100
PIPE_HANDLE clNamedPipeConnectionsServer::initNewInstance()
104
SECURITY_DESCRIPTOR sd = {0};
106
SECURITY_ATTRIBUTES sa = {0};
107
memset(&sa, 0, sizeof(sa));
108
sa.nLength = sizeof(sa);
109
sa.bInheritHandle = TRUE;
110
sa.lpSecurityDescriptor = NULL;
112
HANDLE hPipe = createNamedPipe(_pipePath, sa);
114
this->setLastError(NP_SERVER_UNKNOWN_ERROR);
115
return INVALID_PIPE_HANDLE;
119
if(_listenHandle == INVALID_PIPE_HANDLE) {
122
struct sockaddr_un server;
124
_listenHandle = socket(AF_UNIX, SOCK_STREAM, 0);
125
if (_listenHandle < 0) {
126
perror("ERROR: socket");
127
return INVALID_PIPE_HANDLE;
130
server.sun_family = AF_UNIX;
131
strcpy(server.sun_path, _pipePath);
132
if (bind(_listenHandle, (struct sockaddr *) &server, sizeof(struct sockaddr_un))) {
133
perror("ERROR: binding stream socket");
134
return INVALID_PIPE_HANDLE;
137
listen(_listenHandle, 10);
138
return _listenHandle;
142
bool clNamedPipeConnectionsServer::shutdown()
150
close(_listenHandle);
153
_listenHandle = INVALID_PIPE_HANDLE;
157
clNamedPipe *clNamedPipeConnectionsServer::waitForNewConnection( int timeout )
159
PIPE_HANDLE hConn = this->initNewInstance();
163
HANDLE ev = CreateEvent(NULL, TRUE, TRUE, NULL);
166
bool fConnected = ConnectNamedPipe(hConn, &ov);
167
if (fConnected != 0) {
168
this->setLastError(NP_SERVER_UNKNOWN_ERROR);
172
switch (GetLastError()) {
174
// The overlapped connection in progress.
175
case ERROR_IO_PENDING: {
176
DWORD res = WaitForSingleObject(ov.hEvent, timeout) ;
178
case WAIT_OBJECT_0 : {
179
clNamedPipeServer *conn = new clNamedPipeServer(_pipePath);
180
conn->setHandle(hConn);
183
case WAIT_TIMEOUT : {
184
this->setLastError(NP_SERVER_TIMEOUT);
188
this->setLastError(NP_SERVER_UNKNOWN_ERROR);
195
case ERROR_PIPE_CONNECTED: {
196
clNamedPipeServer *conn = new clNamedPipeServer(_pipePath);
197
conn->setHandle(hConn);
200
// If an error occurs during the connect operation...
202
this->setLastError(NP_SERVER_UNKNOWN_ERROR);
207
// accept new connection
208
if(hConn != INVALID_PIPE_HANDLE){
209
PIPE_HANDLE fd = ::accept(hConn, 0, 0);
211
clNamedPipeServer *conn = new clNamedPipeServer(_pipePath);
215
perror("ERROR: accept");