nfs4: Add call generation code including authentication

RPC::Call generates a RPC call using provided RPC::Auth objects.
RPC::Auth supports AUTH_NONE and AUTH_SYS authentication protocols.
This commit is contained in:
Pawel Dziepak
2012-06-29 02:14:08 +02:00
parent 42b2ae1c80
commit 313da82b9f
5 changed files with 260 additions and 0 deletions
@@ -5,5 +5,7 @@ UsePrivateHeaders kernel ;
KernelAddon nfs4 : KernelAddon nfs4 :
Connection.cpp Connection.cpp
kernel_interface.cpp kernel_interface.cpp
RPCAuth.cpp
RPCCall.cpp
XDR.cpp XDR.cpp
; ;
@@ -0,0 +1,89 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, [email protected]
*/
#include "RPCAuth.h"
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <SupportDefs.h>
#include <util/kernel_cpp.h>
using namespace RPC;
Auth::Auth()
{
}
const Auth*
Auth::CreateNone()
{
Auth* auth = new(std::nothrow) Auth;
if (auth == NULL)
return NULL;
auth->fStream.AddInt(AUTH_NONE);
auth->fStream.AddOpaque(NULL, 0);
if (auth->fStream.GetError() != B_OK) {
delete auth;
return NULL;
}
return auth;
}
const Auth*
Auth::CreateSys()
{
Auth* auth = new(std::nothrow) Auth;
if (auth == NULL)
return NULL;
XDR::WriteStream xdr;
xdr.AddUInt(time(NULL));
char hostname[255];
//if (gethostname(hostname, 255) < 0)
strcpy(hostname, "unknown");
xdr.AddString(hostname, 255);
xdr.AddUInt(getuid());
xdr.AddUInt(getgid());
int count = getgroups(0, NULL);
gid_t* groups = (gid_t*)malloc(count * sizeof(gid_t));
int len = getgroups(count, groups);
if (len > 0) {
len = min_c(len, 16);
xdr.AddUInt(len);
for (int i = 0; i < len; i++)
xdr.AddUInt((uint32)groups[i]);
} else
xdr.AddUInt(0);
free(groups);
if (xdr.GetError() != B_OK) {
delete auth;
return NULL;
}
auth->fStream.AddInt(AUTH_SYS);
auth->fStream.AddOpaque(xdr);
if (auth->fStream.GetError() != B_OK) {
delete auth;
return NULL;
}
return auth;
}
@@ -0,0 +1,46 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, [email protected]
*/
#ifndef RPCAUTH_H
#define RPCAUTH_H
#include "XDR.h"
namespace RPC {
enum auth_flavour {
AUTH_NONE = 0,
AUTH_SYS = 1
};
class Auth {
public:
inline const XDR::WriteStream& GetStream() const;
static const Auth* CreateNone();
static const Auth* CreateSys();
private:
Auth();
XDR::WriteStream fStream;
};
inline const XDR::WriteStream&
Auth::GetStream() const
{
return fStream;
}
} // namespace RPC
#endif // RPCAUTH_H
@@ -0,0 +1,77 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, [email protected]
*/
#include "RPCCall.h"
#include <util/kernel_cpp.h>
using namespace RPC;
enum {
CALL = 0
};
#define VERSION 2
enum {
PROGRAM_NFS = 100003
};
#define NFS_VERSION 4
Call::Call()
{
}
Call*
Call::Create(uint32 proc, const Auth* creds, const Auth* ver)
{
Call* call = new(std::nothrow) Call;
if (call == NULL)
return NULL;
// XID will be determined and set by RPC::Server
call->fXIDPosition = call->fStream.GetCurrent();
call->fStream.AddUInt(0);
call->fStream.AddInt(CALL);
call->fStream.AddUInt(VERSION);
call->fStream.AddUInt(PROGRAM_NFS);
call->fStream.AddUInt(NFS_VERSION);
call->fStream.AddUInt(proc);
call->fStream.Append(creds->GetStream());
delete creds;
call->fStream.Append(ver->GetStream());
delete ver;
if (call->fStream.GetError() != B_OK) {
delete call;
return NULL;
}
return call;
}
Call::~Call()
{
}
void
Call::SetXID(uint32 xid)
{
fStream.InsertUInt(fXIDPosition, xid);
}
@@ -0,0 +1,46 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, [email protected]
*/
#ifndef RPCCALL_H
#define RPCCALL_H
#include "RPCAuth.h"
#include "XDR.h"
namespace RPC {
class Call {
public:
static Call* Create(uint32 proc, const Auth* creds,
const Auth* ver);
~Call();
void SetXID(uint32 x);
inline XDR::WriteStream& GetStream();
private:
Call();
XDR::Stream::Position fXIDPosition;
XDR::WriteStream fStream;
};
inline XDR::WriteStream&
Call::GetStream()
{
return fStream;
}
} // namespace RPC
#endif // RPCCALL_H