1// InsecureConnectionListener.cpp
2
3#include <new>
4
5#include <errno.h>
6#include <netdb.h>
7#include <stdio.h>
8#include <string.h>
9#include <unistd.h>
10
11#include "Compatibility.h"
12#include "DebugSupport.h"
13#include "InsecureChannel.h"
14#include "InsecureConnection.h"
15#include "InsecureConnectionListener.h"
16#include "NetFSDefs.h"
17#include "Utils.h"
18
19using namespace InsecureConnectionDefs;
20
21// constructor
22InsecureConnectionListener::InsecureConnectionListener()
23	: ConnectionListener(),
24	  fSocket(-1)
25{
26}
27
28// destructor
29InsecureConnectionListener::~InsecureConnectionListener()
30{
31	safe_closesocket(fSocket);
32}
33
34// Init
35status_t
36InsecureConnectionListener::Init(const char* parameters)
37{
38	// parse the parameters
39	// parameter format is "[port]"
40	uint16 port = kDefaultInsecureConnectionPort;
41	if (parameters && strlen(parameters) > 0) {
42		int result = sscanf(parameters, "%hu", &port);
43		if (result < 1)
44			return B_BAD_VALUE;
45	}
46	// create a listener socket
47	fSocket = socket(AF_INET, SOCK_STREAM, 0);
48	if (fSocket < 0)
49		return errno;
50	// bind it to the port
51	sockaddr_in addr;
52	addr.sin_family = AF_INET;
53	addr.sin_port = htons(port);
54	addr.sin_addr.s_addr = INADDR_ANY;
55	if (bind(fSocket, (sockaddr*)&addr, sizeof(addr)) < 0)
56		return errno;
57	// start listening
58	if (listen(fSocket, 5) < 0)
59		return errno;
60	return B_OK;
61}
62
63// Listen
64status_t
65InsecureConnectionListener::Listen(Connection** _connection)
66{
67	if (!_connection || fSocket < 0)
68		return B_BAD_VALUE;
69	// accept a connection
70	int fd = -1;
71	do {
72		fd = accept(fSocket, NULL, 0);
73		if (fd < 0) {
74			status_t error = errno;
75			if (error != B_INTERRUPTED)
76				return error;
77		}
78	} while (fd < 0);
79	// create a connection
80	InsecureConnection* connection = new(std::nothrow) InsecureConnection;
81	if (!connection) {
82		closesocket(fd);
83		return B_NO_MEMORY;
84	}
85	status_t error = connection->Init(fd);
86	if (error != B_OK) {
87		delete connection;
88		return error;
89	}
90	*_connection = connection;
91	return B_OK;
92}
93
94// StopListening
95void
96InsecureConnectionListener::StopListening()
97{
98	safe_closesocket(fSocket);
99}
100
101// FinishInitialization
102status_t
103InsecureConnectionListener::FinishInitialization(Connection* _connection,
104	SecurityContext* securityContext, User** user)
105{
106	InsecureConnection* connection
107		= dynamic_cast<InsecureConnection*>(_connection);
108	if (!connection)
109		return B_BAD_VALUE;
110	*user = NULL;
111	return connection->FinishInitialization();
112}
113
114