xref: /haiku/src/add-ons/kernel/file_systems/netfs/authentication_server/AuthenticationServer.cpp (revision 44905bf648c407cc26593f9141c5297e18fca73b)
15a1d355fSStephan Aßmus // AuthenticationServer.cpp
25a1d355fSStephan Aßmus 
35a1d355fSStephan Aßmus #include "AuthenticationServer.h"
45a1d355fSStephan Aßmus 
55a1d355fSStephan Aßmus #include <new>
65a1d355fSStephan Aßmus 
75a1d355fSStephan Aßmus #include <HashMap.h>
85a1d355fSStephan Aßmus #include <HashString.h>
95a1d355fSStephan Aßmus #include <util/KMessage.h>
105a1d355fSStephan Aßmus 
115a1d355fSStephan Aßmus #include "AuthenticationPanel.h"
125a1d355fSStephan Aßmus #include "AuthenticationServerDefs.h"
135a1d355fSStephan Aßmus #include "DebugSupport.h"
145a1d355fSStephan Aßmus #include "TaskManager.h"
155a1d355fSStephan Aßmus 
165a1d355fSStephan Aßmus 
175a1d355fSStephan Aßmus // Authentication
185a1d355fSStephan Aßmus class AuthenticationServer::Authentication {
195a1d355fSStephan Aßmus public:
Authentication()205a1d355fSStephan Aßmus 	Authentication()
215a1d355fSStephan Aßmus 		: fUser(),
225a1d355fSStephan Aßmus 		  fPassword()
235a1d355fSStephan Aßmus 	{
245a1d355fSStephan Aßmus 	}
255a1d355fSStephan Aßmus 
Authentication(const char * user,const char * password)265a1d355fSStephan Aßmus 	Authentication(const char* user, const char* password)
275a1d355fSStephan Aßmus 		: fUser(user),
285a1d355fSStephan Aßmus 		  fPassword(password)
295a1d355fSStephan Aßmus 	{
305a1d355fSStephan Aßmus 	}
315a1d355fSStephan Aßmus 
SetTo(const char * user,const char * password)325a1d355fSStephan Aßmus 	status_t SetTo(const char* user, const char* password)
335a1d355fSStephan Aßmus 	{
345a1d355fSStephan Aßmus 		if (fUser.SetTo(user) && fPassword.SetTo(password))
355a1d355fSStephan Aßmus 			return B_OK;
365a1d355fSStephan Aßmus 		return B_NO_MEMORY;
375a1d355fSStephan Aßmus 	}
385a1d355fSStephan Aßmus 
IsValid() const395a1d355fSStephan Aßmus 	bool IsValid() const
405a1d355fSStephan Aßmus 	{
415a1d355fSStephan Aßmus 		return (fUser.GetLength() > 0);
425a1d355fSStephan Aßmus 	}
435a1d355fSStephan Aßmus 
GetUser() const445a1d355fSStephan Aßmus 	const char* GetUser() const
455a1d355fSStephan Aßmus 	{
465a1d355fSStephan Aßmus 		return fUser.GetString();
475a1d355fSStephan Aßmus 	}
485a1d355fSStephan Aßmus 
GetPassword() const495a1d355fSStephan Aßmus 	const char* GetPassword() const
505a1d355fSStephan Aßmus 	{
515a1d355fSStephan Aßmus 		return fPassword.GetString();
525a1d355fSStephan Aßmus 	}
535a1d355fSStephan Aßmus 
545a1d355fSStephan Aßmus private:
555a1d355fSStephan Aßmus 	HashString	fUser;
565a1d355fSStephan Aßmus 	HashString	fPassword;
575a1d355fSStephan Aßmus };
585a1d355fSStephan Aßmus 
595a1d355fSStephan Aßmus // ServerKey
605a1d355fSStephan Aßmus class AuthenticationServer::ServerKey {
615a1d355fSStephan Aßmus public:
ServerKey()625a1d355fSStephan Aßmus 	ServerKey()
635a1d355fSStephan Aßmus 		: fContext(),
645a1d355fSStephan Aßmus 		  fServer()
655a1d355fSStephan Aßmus 	{
665a1d355fSStephan Aßmus 	}
675a1d355fSStephan Aßmus 
ServerKey(const char * context,const char * server)685a1d355fSStephan Aßmus 	ServerKey(const char* context, const char* server)
695a1d355fSStephan Aßmus 		: fContext(context),
705a1d355fSStephan Aßmus 		  fServer(server)
715a1d355fSStephan Aßmus 	{
725a1d355fSStephan Aßmus 	}
735a1d355fSStephan Aßmus 
ServerKey(const ServerKey & other)745a1d355fSStephan Aßmus 	ServerKey(const ServerKey& other)
755a1d355fSStephan Aßmus 		: fContext(other.fContext),
765a1d355fSStephan Aßmus 		  fServer(other.fServer)
775a1d355fSStephan Aßmus 	{
785a1d355fSStephan Aßmus 	}
795a1d355fSStephan Aßmus 
GetHashCode() const805a1d355fSStephan Aßmus 	uint32 GetHashCode() const
815a1d355fSStephan Aßmus 	{
825a1d355fSStephan Aßmus 		return fContext.GetHashCode() * 17 + fServer.GetHashCode();
835a1d355fSStephan Aßmus 	}
845a1d355fSStephan Aßmus 
operator =(const ServerKey & other)855a1d355fSStephan Aßmus 	ServerKey& operator=(const ServerKey& other)
865a1d355fSStephan Aßmus 	{
875a1d355fSStephan Aßmus 		fContext = other.fContext;
885a1d355fSStephan Aßmus 		fServer = other.fServer;
895a1d355fSStephan Aßmus 		return *this;
905a1d355fSStephan Aßmus 	}
915a1d355fSStephan Aßmus 
operator ==(const ServerKey & other) const925a1d355fSStephan Aßmus 	bool operator==(const ServerKey& other) const
935a1d355fSStephan Aßmus 	{
945a1d355fSStephan Aßmus 		return (fContext == other.fContext && fServer == other.fServer);
955a1d355fSStephan Aßmus 	}
965a1d355fSStephan Aßmus 
operator !=(const ServerKey & other) const975a1d355fSStephan Aßmus 	bool operator!=(const ServerKey& other) const
985a1d355fSStephan Aßmus 	{
995a1d355fSStephan Aßmus 		return !(*this == other);
1005a1d355fSStephan Aßmus 	}
1015a1d355fSStephan Aßmus 
1025a1d355fSStephan Aßmus private:
1035a1d355fSStephan Aßmus 	HashString	fContext;
1045a1d355fSStephan Aßmus 	HashString	fServer;
1055a1d355fSStephan Aßmus };
1065a1d355fSStephan Aßmus 
1075a1d355fSStephan Aßmus // ServerEntry
1085a1d355fSStephan Aßmus class AuthenticationServer::ServerEntry {
1095a1d355fSStephan Aßmus public:
ServerEntry()1105a1d355fSStephan Aßmus 	ServerEntry()
1115a1d355fSStephan Aßmus 		: fDefaultAuthentication(),
1125a1d355fSStephan Aßmus 		  fUseDefaultAuthentication(false)
1135a1d355fSStephan Aßmus 	{
1145a1d355fSStephan Aßmus 	}
1155a1d355fSStephan Aßmus 
~ServerEntry()1165a1d355fSStephan Aßmus 	~ServerEntry()
1175a1d355fSStephan Aßmus 	{
1185a1d355fSStephan Aßmus 		// delete the authentications
1195a1d355fSStephan Aßmus 		for (AuthenticationMap::Iterator it = fAuthentications.GetIterator();
1205a1d355fSStephan Aßmus 			 it.HasNext();) {
1215a1d355fSStephan Aßmus 			delete it.Next().value;
1225a1d355fSStephan Aßmus 		}
1235a1d355fSStephan Aßmus 	}
1245a1d355fSStephan Aßmus 
SetUseDefaultAuthentication(bool useDefaultAuthentication)1255a1d355fSStephan Aßmus 	void SetUseDefaultAuthentication(bool useDefaultAuthentication)
1265a1d355fSStephan Aßmus 	{
1275a1d355fSStephan Aßmus 		fUseDefaultAuthentication = useDefaultAuthentication;
1285a1d355fSStephan Aßmus 	}
1295a1d355fSStephan Aßmus 
UseDefaultAuthentication() const1305a1d355fSStephan Aßmus 	bool UseDefaultAuthentication() const
1315a1d355fSStephan Aßmus 	{
1325a1d355fSStephan Aßmus 		return fUseDefaultAuthentication;
1335a1d355fSStephan Aßmus 	}
1345a1d355fSStephan Aßmus 
SetDefaultAuthentication(const char * user,const char * password)1355a1d355fSStephan Aßmus 	status_t SetDefaultAuthentication(const char* user, const char* password)
1365a1d355fSStephan Aßmus 	{
1375a1d355fSStephan Aßmus 		return fDefaultAuthentication.SetTo(user, password);
1385a1d355fSStephan Aßmus 	}
1395a1d355fSStephan Aßmus 
GetDefaultAuthentication() const1405a1d355fSStephan Aßmus 	const Authentication& GetDefaultAuthentication() const
1415a1d355fSStephan Aßmus 	{
1425a1d355fSStephan Aßmus 		return fDefaultAuthentication;
1435a1d355fSStephan Aßmus 	}
1445a1d355fSStephan Aßmus 
SetAuthentication(const char * share,const char * user,const char * password)1455a1d355fSStephan Aßmus 	status_t SetAuthentication(const char* share, const char* user,
1465a1d355fSStephan Aßmus 		const char* password)
1475a1d355fSStephan Aßmus 	{
1485a1d355fSStephan Aßmus 		// check, if an entry already exists for the share -- if it does,
1495a1d355fSStephan Aßmus 		// just set it
1505a1d355fSStephan Aßmus 		Authentication* authentication = fAuthentications.Get(share);
1515a1d355fSStephan Aßmus 		if (authentication)
1525a1d355fSStephan Aßmus 			return authentication->SetTo(user, password);
1535a1d355fSStephan Aßmus 		// the entry does not exist yet: create and add a new one
1545a1d355fSStephan Aßmus 		authentication = new(std::nothrow) Authentication;
1555a1d355fSStephan Aßmus 		if (!authentication)
1565a1d355fSStephan Aßmus 			return B_NO_MEMORY;
1575a1d355fSStephan Aßmus 		status_t error = authentication->SetTo(user, password);
1585a1d355fSStephan Aßmus 		if (error == B_OK)
1595a1d355fSStephan Aßmus 			error = fAuthentications.Put(share, authentication);
1605a1d355fSStephan Aßmus 		if (error != B_OK)
1615a1d355fSStephan Aßmus 			delete authentication;
1625a1d355fSStephan Aßmus 		return error;
1635a1d355fSStephan Aßmus 	}
1645a1d355fSStephan Aßmus 
GetAuthentication(const char * share) const1655a1d355fSStephan Aßmus 	Authentication* GetAuthentication(const char* share) const
1665a1d355fSStephan Aßmus 	{
1675a1d355fSStephan Aßmus 		return fAuthentications.Get(share);
1685a1d355fSStephan Aßmus 	}
1695a1d355fSStephan Aßmus 
1705a1d355fSStephan Aßmus private:
1715a1d355fSStephan Aßmus 	typedef HashMap<HashString, Authentication*> AuthenticationMap;
1725a1d355fSStephan Aßmus 
1735a1d355fSStephan Aßmus 	Authentication		fDefaultAuthentication;
1745a1d355fSStephan Aßmus 	bool				fUseDefaultAuthentication;
1755a1d355fSStephan Aßmus 	AuthenticationMap	fAuthentications;
1765a1d355fSStephan Aßmus };
1775a1d355fSStephan Aßmus 
1785a1d355fSStephan Aßmus // ServerEntryMap
1795a1d355fSStephan Aßmus struct AuthenticationServer::ServerEntryMap
1805a1d355fSStephan Aßmus 	: HashMap<ServerKey, ServerEntry*> {
1815a1d355fSStephan Aßmus };
1825a1d355fSStephan Aßmus 
1835a1d355fSStephan Aßmus // UserDialogTask
1845a1d355fSStephan Aßmus class AuthenticationServer::UserDialogTask : public Task {
1855a1d355fSStephan Aßmus public:
UserDialogTask(AuthenticationServer * authenticationServer,const char * context,const char * server,const char * share,bool badPassword,port_id replyPort,int32 replyToken)1865a1d355fSStephan Aßmus 	UserDialogTask(AuthenticationServer* authenticationServer,
1875a1d355fSStephan Aßmus 		const char* context, const char* server, const char* share,
1885a1d355fSStephan Aßmus 		bool badPassword, port_id replyPort,
1895a1d355fSStephan Aßmus 		int32 replyToken)
1905a1d355fSStephan Aßmus 		: Task("user dialog task"),
1915a1d355fSStephan Aßmus 		  fAuthenticationServer(authenticationServer),
1925a1d355fSStephan Aßmus 		  fContext(context),
1935a1d355fSStephan Aßmus 		  fServer(server),
1945a1d355fSStephan Aßmus 		  fShare(share),
1955a1d355fSStephan Aßmus 		  fBadPassword(badPassword),
1965a1d355fSStephan Aßmus 		  fReplyPort(replyPort),
1975a1d355fSStephan Aßmus 		  fReplyToken(replyToken),
1985a1d355fSStephan Aßmus 		  fPanel(NULL)
1995a1d355fSStephan Aßmus 	{
2005a1d355fSStephan Aßmus 	}
2015a1d355fSStephan Aßmus 
Execute()2025a1d355fSStephan Aßmus 	virtual status_t Execute()
2035a1d355fSStephan Aßmus 	{
2045a1d355fSStephan Aßmus 		// open the panel
2055a1d355fSStephan Aßmus 		char user[B_OS_NAME_LENGTH];
2065a1d355fSStephan Aßmus 		char password[B_OS_NAME_LENGTH];
2075a1d355fSStephan Aßmus 		bool keep = true;
2085a1d355fSStephan Aßmus 		fPanel = new(std::nothrow) AuthenticationPanel();
2095a1d355fSStephan Aßmus 		status_t error = (fPanel ? B_OK : B_NO_MEMORY);
2105a1d355fSStephan Aßmus 		bool cancelled = false;
2115a1d355fSStephan Aßmus 		HashString defaultUser;
2125a1d355fSStephan Aßmus 		HashString defaultPassword;
2135a1d355fSStephan Aßmus 		fAuthenticationServer->_GetAuthentication(fContext.GetString(),
2145a1d355fSStephan Aßmus 			fServer.GetString(), NULL, &defaultUser, &defaultPassword);
2155a1d355fSStephan Aßmus 		if (error == B_OK) {
2165a1d355fSStephan Aßmus 			cancelled = fPanel->GetAuthentication(fServer.GetString(),
2175a1d355fSStephan Aßmus 				fShare.GetString(), defaultUser.GetString(),
2185a1d355fSStephan Aßmus 				defaultPassword.GetString(), false, fBadPassword, user,
2195a1d355fSStephan Aßmus 				password, &keep);
2205a1d355fSStephan Aßmus 		}
2215a1d355fSStephan Aßmus 		fPanel = NULL;
2225a1d355fSStephan Aßmus 		// send the reply
2235a1d355fSStephan Aßmus 		if (error != B_OK) {
2245a1d355fSStephan Aßmus 			fAuthenticationServer->_SendRequestReply(fReplyPort, fReplyToken,
2255a1d355fSStephan Aßmus 				error, true, NULL, NULL);
2265a1d355fSStephan Aßmus 		} else if (cancelled) {
2275a1d355fSStephan Aßmus 			fAuthenticationServer->_SendRequestReply(fReplyPort, fReplyToken,
2285a1d355fSStephan Aßmus 				B_OK, true, NULL, NULL);
2295a1d355fSStephan Aßmus 		} else {
2305a1d355fSStephan Aßmus 			fAuthenticationServer->_AddAuthentication(fContext.GetString(),
2315a1d355fSStephan Aßmus 				fServer.GetString(), fShare.GetString(), user, password,
2325a1d355fSStephan Aßmus 				keep);
2335a1d355fSStephan Aßmus 			fAuthenticationServer->_SendRequestReply(fReplyPort, fReplyToken,
2345a1d355fSStephan Aßmus 				B_OK, false, user, password);
2355a1d355fSStephan Aßmus 		}
2365a1d355fSStephan Aßmus 		return error;
2375a1d355fSStephan Aßmus 	}
2385a1d355fSStephan Aßmus 
Stop()2395a1d355fSStephan Aßmus 	virtual void Stop()
2405a1d355fSStephan Aßmus 	{
2415a1d355fSStephan Aßmus 		if (fPanel)
2425a1d355fSStephan Aßmus 			fPanel->Cancel();
2435a1d355fSStephan Aßmus 	}
2445a1d355fSStephan Aßmus 
2455a1d355fSStephan Aßmus private:
2465a1d355fSStephan Aßmus 	AuthenticationServer*	fAuthenticationServer;
2475a1d355fSStephan Aßmus 	HashString				fContext;
2485a1d355fSStephan Aßmus 	HashString				fServer;
2495a1d355fSStephan Aßmus 	HashString				fShare;
2505a1d355fSStephan Aßmus 	bool					fBadPassword;
2515a1d355fSStephan Aßmus 	port_id					fReplyPort;
2525a1d355fSStephan Aßmus 	int32					fReplyToken;
2535a1d355fSStephan Aßmus 	AuthenticationPanel*	fPanel;
2545a1d355fSStephan Aßmus };
2555a1d355fSStephan Aßmus 
2565a1d355fSStephan Aßmus 
2575a1d355fSStephan Aßmus // constructor
AuthenticationServer()2585a1d355fSStephan Aßmus AuthenticationServer::AuthenticationServer()
259*44905bf6SStephan Aßmus 	:
260*44905bf6SStephan Aßmus 	BApplication("application/x-vnd.haiku-authentication_server"),
2615a1d355fSStephan Aßmus 	fLock(),
2625a1d355fSStephan Aßmus 	fRequestPort(-1),
2635a1d355fSStephan Aßmus 	fRequestThread(-1),
2645a1d355fSStephan Aßmus 	fServerEntries(NULL),
2655a1d355fSStephan Aßmus 	fTerminating(false)
2665a1d355fSStephan Aßmus {
2675a1d355fSStephan Aßmus }
2685a1d355fSStephan Aßmus 
2695a1d355fSStephan Aßmus // destructor
~AuthenticationServer()2705a1d355fSStephan Aßmus AuthenticationServer::~AuthenticationServer()
2715a1d355fSStephan Aßmus {
2725a1d355fSStephan Aßmus 	fTerminating = true;
2735a1d355fSStephan Aßmus 	// terminate the request thread
2745a1d355fSStephan Aßmus 	if (fRequestPort >= 0)
2755a1d355fSStephan Aßmus 		delete_port(fRequestPort);
2765a1d355fSStephan Aßmus 	if (fRequestThread >= 0) {
2775a1d355fSStephan Aßmus 		int32 result;
2785a1d355fSStephan Aßmus 		wait_for_thread(fRequestPort, &result);
2795a1d355fSStephan Aßmus 	}
2805a1d355fSStephan Aßmus 	// delete the server entries
2815a1d355fSStephan Aßmus 	for (ServerEntryMap::Iterator it = fServerEntries->GetIterator();
2825a1d355fSStephan Aßmus 		 it.HasNext();) {
2835a1d355fSStephan Aßmus 		delete it.Next().value;
2845a1d355fSStephan Aßmus 	}
2855a1d355fSStephan Aßmus }
2865a1d355fSStephan Aßmus 
2875a1d355fSStephan Aßmus // Init
2885a1d355fSStephan Aßmus status_t
Init()2895a1d355fSStephan Aßmus AuthenticationServer::Init()
2905a1d355fSStephan Aßmus {
2915a1d355fSStephan Aßmus 	// create the server entry map
2925a1d355fSStephan Aßmus 	fServerEntries = new(std::nothrow) ServerEntryMap;
2935a1d355fSStephan Aßmus 	if (!fServerEntries)
2945a1d355fSStephan Aßmus 		return B_NO_MEMORY;
2955a1d355fSStephan Aßmus 	status_t error = fServerEntries->InitCheck();
2965a1d355fSStephan Aßmus 	if (error != B_OK)
2975a1d355fSStephan Aßmus 		return error;
2985a1d355fSStephan Aßmus 	// create the request port
2995a1d355fSStephan Aßmus 	fRequestPort = create_port(10, kAuthenticationServerPortName);
3005a1d355fSStephan Aßmus 	if (fRequestPort < 0)
3015a1d355fSStephan Aßmus 		return fRequestPort;
3025a1d355fSStephan Aßmus 	// spawn the request thread
3035a1d355fSStephan Aßmus 	fRequestThread = spawn_thread(&_RequestThreadEntry, "request thread",
3045a1d355fSStephan Aßmus 		B_NORMAL_PRIORITY, this);
3055a1d355fSStephan Aßmus 	if (fRequestThread < 0)
3065a1d355fSStephan Aßmus 		return fRequestThread;
3075a1d355fSStephan Aßmus 	resume_thread(fRequestThread);
3085a1d355fSStephan Aßmus 	return B_OK;
3095a1d355fSStephan Aßmus }
3105a1d355fSStephan Aßmus 
3115a1d355fSStephan Aßmus // _RequestThreadEntry
3125a1d355fSStephan Aßmus int32
_RequestThreadEntry(void * data)3135a1d355fSStephan Aßmus AuthenticationServer::_RequestThreadEntry(void* data)
3145a1d355fSStephan Aßmus {
3155a1d355fSStephan Aßmus 	return ((AuthenticationServer*)data)->_RequestThread();
3165a1d355fSStephan Aßmus }
3175a1d355fSStephan Aßmus 
3185a1d355fSStephan Aßmus // _RequestThread
3195a1d355fSStephan Aßmus int32
_RequestThread()3205a1d355fSStephan Aßmus AuthenticationServer::_RequestThread()
3215a1d355fSStephan Aßmus {
3225a1d355fSStephan Aßmus 	TaskManager taskManager;
3235a1d355fSStephan Aßmus 	while (!fTerminating) {
3245a1d355fSStephan Aßmus 		taskManager.RemoveDoneTasks();
3255a1d355fSStephan Aßmus 		// read the request
3265a1d355fSStephan Aßmus 		KMessage request;
3275a1d355fSStephan Aßmus 		status_t error = request.ReceiveFrom(fRequestPort);
3285a1d355fSStephan Aßmus 		if (error != B_OK)
3295a1d355fSStephan Aßmus 			continue;
3305a1d355fSStephan Aßmus 		// get the parameters
3315a1d355fSStephan Aßmus 		const char* context = NULL;
3325a1d355fSStephan Aßmus 		const char* server = NULL;
3335a1d355fSStephan Aßmus 		const char* share = NULL;
3345a1d355fSStephan Aßmus 		bool badPassword = true;
3355a1d355fSStephan Aßmus 		request.FindString("context", &context);
3365a1d355fSStephan Aßmus 		request.FindString("server", &server);
3375a1d355fSStephan Aßmus 		request.FindString("share", &share);
3385a1d355fSStephan Aßmus 		request.FindBool("badPassword", &badPassword);
3395a1d355fSStephan Aßmus 		if (!context || !server || !share)
3405a1d355fSStephan Aßmus 			continue;
3415a1d355fSStephan Aßmus 		HashString foundUser;
3425a1d355fSStephan Aßmus 		HashString foundPassword;
3435a1d355fSStephan Aßmus 		if (!badPassword && _GetAuthentication(context, server, share,
3445a1d355fSStephan Aßmus 			&foundUser, &foundPassword)) {
3455a1d355fSStephan Aßmus 			_SendRequestReply(request.ReplyPort(), request.ReplyToken(),
3465a1d355fSStephan Aßmus 				error, false, foundUser.GetString(), foundPassword.GetString());
3475a1d355fSStephan Aßmus 		} else {
3485a1d355fSStephan Aßmus 			// we need to ask the user: create a task that does it
3495a1d355fSStephan Aßmus 			UserDialogTask* task = new(std::nothrow) UserDialogTask(this,
3505a1d355fSStephan Aßmus 				context, server, share, badPassword, request.ReplyPort(),
3515a1d355fSStephan Aßmus 				request.ReplyToken());
3525a1d355fSStephan Aßmus 			if (!task) {
3535a1d355fSStephan Aßmus 				ERROR("AuthenticationServer::_RequestThread(): ERROR: "
3545a1d355fSStephan Aßmus 					"failed to allocate ");
3555a1d355fSStephan Aßmus 				continue;
3565a1d355fSStephan Aßmus 			}
3575a1d355fSStephan Aßmus 			status_t error = taskManager.RunTask(task);
3585a1d355fSStephan Aßmus 			if (error != B_OK) {
3595a1d355fSStephan Aßmus 				ERROR("AuthenticationServer::_RequestThread(): Failed to "
3605a1d355fSStephan Aßmus 					"start server info task: %s\n", strerror(error));
3615a1d355fSStephan Aßmus 				continue;
3625a1d355fSStephan Aßmus 			}
3635a1d355fSStephan Aßmus 		}
3645a1d355fSStephan Aßmus 	}
3655a1d355fSStephan Aßmus 	return 0;
3665a1d355fSStephan Aßmus }
3675a1d355fSStephan Aßmus 
3685a1d355fSStephan Aßmus // _GetAuthentication
3695a1d355fSStephan Aßmus /*!
3705a1d355fSStephan Aßmus 	If share is NULL, the default authentication for the server is returned.
3715a1d355fSStephan Aßmus */
3725a1d355fSStephan Aßmus bool
_GetAuthentication(const char * context,const char * server,const char * share,HashString * user,HashString * password)3735a1d355fSStephan Aßmus AuthenticationServer::_GetAuthentication(const char* context,
3745a1d355fSStephan Aßmus 	const char* server, const char* share, HashString* user,
3755a1d355fSStephan Aßmus 	HashString* password)
3765a1d355fSStephan Aßmus {
3775a1d355fSStephan Aßmus 	if (!context || !server || !user || !password)
3785a1d355fSStephan Aßmus 		return B_BAD_VALUE;
3795a1d355fSStephan Aßmus 	// get the server entry
3805a1d355fSStephan Aßmus 	AutoLocker<BLocker> _(fLock);
3815a1d355fSStephan Aßmus 	ServerKey key(context, server);
3825a1d355fSStephan Aßmus 	ServerEntry* serverEntry = fServerEntries->Get(key);
3835a1d355fSStephan Aßmus 	if (!serverEntry)
3845a1d355fSStephan Aßmus 		return false;
3855a1d355fSStephan Aßmus 	// get the authentication
3865a1d355fSStephan Aßmus 	const Authentication* authentication = NULL;
3875a1d355fSStephan Aßmus 	if (share) {
3885a1d355fSStephan Aßmus 		serverEntry->GetAuthentication(share);
3895a1d355fSStephan Aßmus 		if (!authentication && serverEntry->UseDefaultAuthentication())
3905a1d355fSStephan Aßmus 			authentication = &serverEntry->GetDefaultAuthentication();
3915a1d355fSStephan Aßmus 	} else
3925a1d355fSStephan Aßmus 		authentication = &serverEntry->GetDefaultAuthentication();
3935a1d355fSStephan Aßmus 	if (!authentication || !authentication->IsValid())
3945a1d355fSStephan Aßmus 		return false;
3955a1d355fSStephan Aßmus 	return (user->SetTo(authentication->GetUser())
3965a1d355fSStephan Aßmus 		&& password->SetTo(authentication->GetPassword()));
3975a1d355fSStephan Aßmus }
3985a1d355fSStephan Aßmus 
3995a1d355fSStephan Aßmus // _AddAuthentication
4005a1d355fSStephan Aßmus status_t
_AddAuthentication(const char * context,const char * server,const char * share,const char * user,const char * password,bool makeDefault)4015a1d355fSStephan Aßmus AuthenticationServer::_AddAuthentication(const char* context,
4025a1d355fSStephan Aßmus 	const char* server, const char* share, const char* user,
4035a1d355fSStephan Aßmus 	const char* password, bool makeDefault)
4045a1d355fSStephan Aßmus {
4055a1d355fSStephan Aßmus 	AutoLocker<BLocker> _(fLock);
4065a1d355fSStephan Aßmus 	ServerKey key(context, server);
4075a1d355fSStephan Aßmus 	// get the server entry
4085a1d355fSStephan Aßmus 	ServerEntry* serverEntry = fServerEntries->Get(key);
4095a1d355fSStephan Aßmus 	if (!serverEntry) {
4105a1d355fSStephan Aßmus 		// server entry does not exist yet: create a new one
4115a1d355fSStephan Aßmus 		serverEntry = new(std::nothrow) ServerEntry;
4125a1d355fSStephan Aßmus 		if (!serverEntry)
4135a1d355fSStephan Aßmus 			return B_NO_MEMORY;
4145a1d355fSStephan Aßmus 		status_t error = fServerEntries->Put(key, serverEntry);
4155a1d355fSStephan Aßmus 		if (error != B_OK) {
4165a1d355fSStephan Aßmus 			delete serverEntry;
4175a1d355fSStephan Aßmus 			return error;
4185a1d355fSStephan Aßmus 		}
4195a1d355fSStephan Aßmus 	}
4205a1d355fSStephan Aßmus 	// put the authentication
4215a1d355fSStephan Aßmus 	status_t error = serverEntry->SetAuthentication(share, user, password);
4225a1d355fSStephan Aßmus 	if (error == B_OK) {
4235a1d355fSStephan Aßmus 		if (makeDefault || !serverEntry->UseDefaultAuthentication())
4245a1d355fSStephan Aßmus 			serverEntry->SetDefaultAuthentication(user, password);
4255a1d355fSStephan Aßmus 		if (makeDefault)
4265a1d355fSStephan Aßmus 			serverEntry->SetUseDefaultAuthentication(true);
4275a1d355fSStephan Aßmus 	}
4285a1d355fSStephan Aßmus 	return error;
4295a1d355fSStephan Aßmus }
4305a1d355fSStephan Aßmus 
4315a1d355fSStephan Aßmus // _SendRequestReply
4325a1d355fSStephan Aßmus status_t
_SendRequestReply(port_id port,int32 token,status_t error,bool cancelled,const char * user,const char * password)4335a1d355fSStephan Aßmus AuthenticationServer::_SendRequestReply(port_id port, int32 token,
4345a1d355fSStephan Aßmus 	status_t error, bool cancelled, const char* user, const char* password)
4355a1d355fSStephan Aßmus {
4365a1d355fSStephan Aßmus 	// prepare the reply
4375a1d355fSStephan Aßmus 	KMessage reply;
4385a1d355fSStephan Aßmus 	reply.AddInt32("error", error);
4395a1d355fSStephan Aßmus 	if (error == B_OK) {
4405a1d355fSStephan Aßmus 		reply.AddBool("cancelled", cancelled);
4415a1d355fSStephan Aßmus 		if (!cancelled) {
4425a1d355fSStephan Aßmus 			reply.AddString("user", user);
4435a1d355fSStephan Aßmus 			reply.AddString("password", password);
4445a1d355fSStephan Aßmus 		}
4455a1d355fSStephan Aßmus 	}
4465a1d355fSStephan Aßmus 	// send the reply
4475a1d355fSStephan Aßmus 	return reply.SendTo(port, token);
4485a1d355fSStephan Aßmus }
4495a1d355fSStephan Aßmus 
4505a1d355fSStephan Aßmus 
4515a1d355fSStephan Aßmus // main
4525a1d355fSStephan Aßmus int
main()4535a1d355fSStephan Aßmus main()
4545a1d355fSStephan Aßmus {
4555a1d355fSStephan Aßmus 	AuthenticationServer app;
4565a1d355fSStephan Aßmus 	status_t error = app.Init();
4575a1d355fSStephan Aßmus 	if (error != B_OK)
4585a1d355fSStephan Aßmus 		return 1;
4595a1d355fSStephan Aßmus 	app.Run();
4605a1d355fSStephan Aßmus 	return 0;
4615a1d355fSStephan Aßmus }
4625a1d355fSStephan Aßmus 
463