forked from Mirrorlandia_minetest/minetest
Passwords - password entry at main menu, stored and checked by server
This commit is contained in:
parent
b5ceaf445a
commit
d4d49ee8f4
@ -95,6 +95,8 @@ set(minetest_SRCS
|
|||||||
tile.cpp
|
tile.cpp
|
||||||
game.cpp
|
game.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
|
sha1.cpp
|
||||||
|
base64.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Server sources
|
# Server sources
|
||||||
|
123
src/base64.cpp
Normal file
123
src/base64.cpp
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
base64.cpp and base64.h
|
||||||
|
|
||||||
|
Copyright (C) 2004-2008 René Nyffenegger
|
||||||
|
|
||||||
|
This source code is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the author be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this source code must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original source code. If you use this source code
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original source code.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "base64.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
static const std::string base64_chars =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"0123456789+/";
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool is_base64(unsigned char c) {
|
||||||
|
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||||
|
std::string ret;
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
unsigned char char_array_3[3];
|
||||||
|
unsigned char char_array_4[4];
|
||||||
|
|
||||||
|
while (in_len--) {
|
||||||
|
char_array_3[i++] = *(bytes_to_encode++);
|
||||||
|
if (i == 3) {
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for(i = 0; (i <4) ; i++)
|
||||||
|
ret += base64_chars[char_array_4[i]];
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
for(j = i; j < 3; j++)
|
||||||
|
char_array_3[j] = '\0';
|
||||||
|
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for (j = 0; (j < i + 1); j++)
|
||||||
|
ret += base64_chars[char_array_4[j]];
|
||||||
|
|
||||||
|
while((i++ < 3))
|
||||||
|
ret += '=';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string base64_decode(std::string const& encoded_string) {
|
||||||
|
int in_len = encoded_string.size();
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
int in_ = 0;
|
||||||
|
unsigned char char_array_4[4], char_array_3[3];
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
|
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||||
|
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||||
|
if (i ==4) {
|
||||||
|
for (i = 0; i <4; i++)
|
||||||
|
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||||
|
|
||||||
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
|
for (i = 0; (i < 3); i++)
|
||||||
|
ret += char_array_3[i];
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i) {
|
||||||
|
for (j = i; j <4; j++)
|
||||||
|
char_array_4[j] = 0;
|
||||||
|
|
||||||
|
for (j = 0; j <4; j++)
|
||||||
|
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||||
|
|
||||||
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
|
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
4
src/base64.h
Normal file
4
src/base64.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include <string>
|
||||||
|
|
||||||
|
std::string base64_encode(unsigned char const* , unsigned int len);
|
||||||
|
std::string base64_decode(std::string const& s);
|
@ -68,6 +68,7 @@ void * MeshUpdateThread::Thread()
|
|||||||
Client::Client(
|
Client::Client(
|
||||||
IrrlichtDevice *device,
|
IrrlichtDevice *device,
|
||||||
const char *playername,
|
const char *playername,
|
||||||
|
std::string password,
|
||||||
MapDrawControl &control):
|
MapDrawControl &control):
|
||||||
m_mesh_update_thread(),
|
m_mesh_update_thread(),
|
||||||
m_env(
|
m_env(
|
||||||
@ -83,7 +84,9 @@ Client::Client(
|
|||||||
m_server_ser_ver(SER_FMT_VER_INVALID),
|
m_server_ser_ver(SER_FMT_VER_INVALID),
|
||||||
m_inventory_updated(false),
|
m_inventory_updated(false),
|
||||||
m_time_of_day(0),
|
m_time_of_day(0),
|
||||||
m_map_seed(0)
|
m_map_seed(0),
|
||||||
|
m_password(password),
|
||||||
|
m_access_denied(false)
|
||||||
{
|
{
|
||||||
m_packetcounter_timer = 0.0;
|
m_packetcounter_timer = 0.0;
|
||||||
m_delete_unused_sectors_timer = 0.0;
|
m_delete_unused_sectors_timer = 0.0;
|
||||||
@ -299,11 +302,14 @@ void Client::step(float dtime)
|
|||||||
// [0] u16 TOSERVER_INIT
|
// [0] u16 TOSERVER_INIT
|
||||||
// [2] u8 SER_FMT_VER_HIGHEST
|
// [2] u8 SER_FMT_VER_HIGHEST
|
||||||
// [3] u8[20] player_name
|
// [3] u8[20] player_name
|
||||||
SharedBuffer<u8> data(2+1+PLAYERNAME_SIZE);
|
// [23] u8[28] password
|
||||||
|
SharedBuffer<u8> data(2+1+PLAYERNAME_SIZE+PASSWORD_SIZE);
|
||||||
writeU16(&data[0], TOSERVER_INIT);
|
writeU16(&data[0], TOSERVER_INIT);
|
||||||
writeU8(&data[2], SER_FMT_VER_HIGHEST);
|
writeU8(&data[2], SER_FMT_VER_HIGHEST);
|
||||||
memset((char*)&data[3], 0, PLAYERNAME_SIZE);
|
memset((char*)&data[3], 0, PLAYERNAME_SIZE);
|
||||||
snprintf((char*)&data[3], PLAYERNAME_SIZE, "%s", myplayer->getName());
|
snprintf((char*)&data[3], PLAYERNAME_SIZE, "%s", myplayer->getName());
|
||||||
|
snprintf((char*)&data[23], PASSWORD_SIZE, "%s", m_password.c_str());
|
||||||
|
|
||||||
// Send as unreliable
|
// Send as unreliable
|
||||||
Send(0, data, false);
|
Send(0, data, false);
|
||||||
}
|
}
|
||||||
@ -598,6 +604,15 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(command == TOCLIENT_ACCESS_DENIED)
|
||||||
|
{
|
||||||
|
// The server didn't like our password. Note, this needs
|
||||||
|
// to be processed even if the serialisation format has
|
||||||
|
// not been agreed yet, the same as TOCLIENT_INIT.
|
||||||
|
m_access_denied = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(ser_version == SER_FMT_VER_INVALID)
|
if(ser_version == SER_FMT_VER_INVALID)
|
||||||
{
|
{
|
||||||
dout_client<<DTIME<<"WARNING: Client: Server serialization"
|
dout_client<<DTIME<<"WARNING: Client: Server serialization"
|
||||||
|
@ -207,6 +207,7 @@ public:
|
|||||||
Client(
|
Client(
|
||||||
IrrlichtDevice *device,
|
IrrlichtDevice *device,
|
||||||
const char *playername,
|
const char *playername,
|
||||||
|
std::string password,
|
||||||
MapDrawControl &control
|
MapDrawControl &control
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -377,6 +378,11 @@ public:
|
|||||||
// Get event from queue. CE_NONE is returned if queue is empty.
|
// Get event from queue. CE_NONE is returned if queue is empty.
|
||||||
ClientEvent getClientEvent();
|
ClientEvent getClientEvent();
|
||||||
|
|
||||||
|
inline bool accessDenied()
|
||||||
|
{
|
||||||
|
return m_access_denied;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Virtual methods from con::PeerHandler
|
// Virtual methods from con::PeerHandler
|
||||||
@ -430,6 +436,9 @@ private:
|
|||||||
// The seed returned by the server in TOCLIENT_INIT is stored here
|
// The seed returned by the server in TOCLIENT_INIT is stored here
|
||||||
u64 m_map_seed;
|
u64 m_map_seed;
|
||||||
|
|
||||||
|
std::string m_password;
|
||||||
|
bool m_access_denied;
|
||||||
|
|
||||||
InventoryContext m_inventory_context;
|
InventoryContext m_inventory_context;
|
||||||
|
|
||||||
Queue<ClientEvent> m_client_event_queue;
|
Queue<ClientEvent> m_client_event_queue;
|
||||||
|
@ -150,6 +150,11 @@ enum ToClientCommand
|
|||||||
f1000 player pitch
|
f1000 player pitch
|
||||||
f1000 player yaw
|
f1000 player yaw
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
TOCLIENT_ACCESS_DENIED = 0x35,
|
||||||
|
/*
|
||||||
|
u16 command
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ToServerCommand
|
enum ToServerCommand
|
||||||
@ -161,6 +166,7 @@ enum ToServerCommand
|
|||||||
[0] u16 TOSERVER_INIT
|
[0] u16 TOSERVER_INIT
|
||||||
[2] u8 SER_FMT_VER_HIGHEST
|
[2] u8 SER_FMT_VER_HIGHEST
|
||||||
[3] u8[20] player_name
|
[3] u8[20] player_name
|
||||||
|
[23] u8[28] password
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TOSERVER_INIT2 = 0x11,
|
TOSERVER_INIT2 = 0x11,
|
||||||
|
17
src/game.cpp
17
src/game.cpp
@ -634,6 +634,7 @@ void the_game(
|
|||||||
gui::IGUIFont* font,
|
gui::IGUIFont* font,
|
||||||
std::string map_dir,
|
std::string map_dir,
|
||||||
std::string playername,
|
std::string playername,
|
||||||
|
std::string password,
|
||||||
std::string address,
|
std::string address,
|
||||||
u16 port,
|
u16 port,
|
||||||
std::wstring &error_message
|
std::wstring &error_message
|
||||||
@ -689,7 +690,7 @@ void the_game(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
std::cout<<DTIME<<"Creating client"<<std::endl;
|
std::cout<<DTIME<<"Creating client"<<std::endl;
|
||||||
Client client(device, playername.c_str(), draw_control);
|
Client client(device, playername.c_str(), password, draw_control);
|
||||||
|
|
||||||
Address connect_address(0,0,0,0, port);
|
Address connect_address(0,0,0,0, port);
|
||||||
try{
|
try{
|
||||||
@ -728,6 +729,10 @@ void the_game(
|
|||||||
could_connect = true;
|
could_connect = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(client.accessDenied())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Wait for 10 seconds
|
// Wait for 10 seconds
|
||||||
if(time_counter >= 10.0)
|
if(time_counter >= 10.0)
|
||||||
{
|
{
|
||||||
@ -756,8 +761,16 @@ void the_game(
|
|||||||
|
|
||||||
if(could_connect == false)
|
if(could_connect == false)
|
||||||
{
|
{
|
||||||
std::cout<<DTIME<<"Timed out."<<std::endl;
|
if(client.accessDenied())
|
||||||
|
{
|
||||||
|
error_message = L"Access denied. Check your password and try again.";
|
||||||
|
std::cout<<DTIME<<"Access denied."<<std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
error_message = L"Connection timed out.";
|
error_message = L"Connection timed out.";
|
||||||
|
std::cout<<DTIME<<"Timed out."<<std::endl;
|
||||||
|
}
|
||||||
gui_loadingtext->remove();
|
gui_loadingtext->remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@ void the_game(
|
|||||||
gui::IGUIFont* font,
|
gui::IGUIFont* font,
|
||||||
std::string map_dir,
|
std::string map_dir,
|
||||||
std::string playername,
|
std::string playername,
|
||||||
|
std::string password,
|
||||||
std::string address,
|
std::string address,
|
||||||
u16 port,
|
u16 port,
|
||||||
std::wstring &error_message
|
std::wstring &error_message
|
||||||
|
@ -164,30 +164,38 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
|
|||||||
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
|
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nickname
|
// Nickname + password
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 100, 20);
|
core::rect<s32> rect(0, 0, 110, 20);
|
||||||
rect += topleft_client + v2s32(40, 50+6);
|
rect += topleft_client + v2s32(35, 50+6);
|
||||||
const wchar_t *text = L"Nickname";
|
const wchar_t *text = L"Name/Password";
|
||||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 250, 30);
|
core::rect<s32> rect(0, 0, 230, 30);
|
||||||
rect += topleft_client + v2s32(160, 50);
|
rect += topleft_client + v2s32(160, 50);
|
||||||
gui::IGUIElement *e =
|
gui::IGUIElement *e =
|
||||||
Environment->addEditBox(text_name.c_str(), rect, true, this, 258);
|
Environment->addEditBox(text_name.c_str(), rect, true, this, 258);
|
||||||
if(text_name == L"")
|
if(text_name == L"")
|
||||||
Environment->setFocus(e);
|
Environment->setFocus(e);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
core::rect<s32> rect(0, 0, 120, 30);
|
||||||
|
rect += topleft_client + v2s32(size_client.X-60-100, 50);
|
||||||
|
gui::IGUIEditBox *e =
|
||||||
|
Environment->addEditBox(L"", rect, true, this, 264);
|
||||||
|
e->setPasswordBox(true);
|
||||||
|
|
||||||
|
}
|
||||||
// Address + port
|
// Address + port
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 100, 20);
|
core::rect<s32> rect(0, 0, 110, 20);
|
||||||
rect += topleft_client + v2s32(40, 100+6);
|
rect += topleft_client + v2s32(35, 100+6);
|
||||||
const wchar_t *text = L"Address + Port";
|
const wchar_t *text = L"Address/Port";
|
||||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 250, 30);
|
core::rect<s32> rect(0, 0, 230, 30);
|
||||||
rect += topleft_client + v2s32(160, 100);
|
rect += topleft_client + v2s32(160, 100);
|
||||||
gui::IGUIElement *e =
|
gui::IGUIElement *e =
|
||||||
Environment->addEditBox(text_address.c_str(), rect, true, this, 256);
|
Environment->addEditBox(text_address.c_str(), rect, true, this, 256);
|
||||||
@ -195,9 +203,9 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
|
|||||||
Environment->setFocus(e);
|
Environment->setFocus(e);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 100, 30);
|
core::rect<s32> rect(0, 0, 120, 30);
|
||||||
//rect += topleft_client + v2s32(160+250+20, 125);
|
//rect += topleft_client + v2s32(160+250+20, 125);
|
||||||
rect += topleft_client + v2s32(size_client.X-40-100, 100);
|
rect += topleft_client + v2s32(size_client.X-60-100, 100);
|
||||||
Environment->addEditBox(text_port.c_str(), rect, true, this, 257);
|
Environment->addEditBox(text_port.c_str(), rect, true, this, 257);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -208,13 +216,13 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 250, 30);
|
core::rect<s32> rect(0, 0, 250, 30);
|
||||||
rect += topleft_client + v2s32(40, 150);
|
rect += topleft_client + v2s32(35, 150);
|
||||||
Environment->addCheckBox(fancy_trees, rect, this, 263,
|
Environment->addCheckBox(fancy_trees, rect, this, 263,
|
||||||
L"Fancy trees");
|
L"Fancy trees");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 250, 30);
|
core::rect<s32> rect(0, 0, 250, 30);
|
||||||
rect += topleft_client + v2s32(40, 150+30);
|
rect += topleft_client + v2s32(35, 150+30);
|
||||||
Environment->addCheckBox(smooth_lighting, rect, this, 262,
|
Environment->addCheckBox(smooth_lighting, rect, this, 262,
|
||||||
L"Smooth Lighting");
|
L"Smooth Lighting");
|
||||||
}
|
}
|
||||||
@ -245,12 +253,12 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
|
|||||||
// Server parameters
|
// Server parameters
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 250, 30);
|
core::rect<s32> rect(0, 0, 250, 30);
|
||||||
rect += topleft_server + v2s32(40, 30);
|
rect += topleft_server + v2s32(35, 30);
|
||||||
Environment->addCheckBox(creative_mode, rect, this, 259, L"Creative Mode");
|
Environment->addCheckBox(creative_mode, rect, this, 259, L"Creative Mode");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 250, 30);
|
core::rect<s32> rect(0, 0, 250, 30);
|
||||||
rect += topleft_server + v2s32(40, 60);
|
rect += topleft_server + v2s32(35, 60);
|
||||||
Environment->addCheckBox(enable_damage, rect, this, 261, L"Enable Damage");
|
Environment->addCheckBox(enable_damage, rect, this, 261, L"Enable Damage");
|
||||||
}
|
}
|
||||||
// Map delete button
|
// Map delete button
|
||||||
@ -296,6 +304,11 @@ void GUIMainMenu::acceptInput()
|
|||||||
if(e != NULL)
|
if(e != NULL)
|
||||||
m_data->name = e->getText();
|
m_data->name = e->getText();
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
gui::IGUIElement *e = getElementFromId(264);
|
||||||
|
if(e != NULL)
|
||||||
|
m_data->password = e->getText();
|
||||||
|
}
|
||||||
{
|
{
|
||||||
gui::IGUIElement *e = getElementFromId(256);
|
gui::IGUIElement *e = getElementFromId(256);
|
||||||
if(e != NULL)
|
if(e != NULL)
|
||||||
@ -380,7 +393,7 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
|
|||||||
{
|
{
|
||||||
switch(event.GUIEvent.Caller->getID())
|
switch(event.GUIEvent.Caller->getID())
|
||||||
{
|
{
|
||||||
case 256: case 257: case 258:
|
case 256: case 257: case 258: case 264:
|
||||||
acceptInput();
|
acceptInput();
|
||||||
quitMenu();
|
quitMenu();
|
||||||
return true;
|
return true;
|
||||||
|
@ -46,6 +46,7 @@ struct MainMenuData
|
|||||||
std::wstring address;
|
std::wstring address;
|
||||||
std::wstring port;
|
std::wstring port;
|
||||||
std::wstring name;
|
std::wstring name;
|
||||||
|
std::wstring password;
|
||||||
bool fancy_trees;
|
bool fancy_trees;
|
||||||
bool smooth_lighting;
|
bool smooth_lighting;
|
||||||
// Server options
|
// Server options
|
||||||
|
27
src/main.cpp
27
src/main.cpp
@ -325,6 +325,8 @@ Making it more portable:
|
|||||||
#include "materials.h"
|
#include "materials.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "keycode.h"
|
#include "keycode.h"
|
||||||
|
#include "sha1.h"
|
||||||
|
#include "base64.h"
|
||||||
|
|
||||||
// This makes textures
|
// This makes textures
|
||||||
ITextureSource *g_texturesource = NULL;
|
ITextureSource *g_texturesource = NULL;
|
||||||
@ -1170,6 +1172,7 @@ int main(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
More parameters
|
More parameters
|
||||||
*/
|
*/
|
||||||
@ -1324,11 +1327,15 @@ int main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
std::wstring error_message = L"";
|
std::wstring error_message = L"";
|
||||||
|
|
||||||
|
// The password entered during the menu screen,
|
||||||
|
std::string password;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Menu-game loop
|
Menu-game loop
|
||||||
*/
|
*/
|
||||||
while(device->run() && kill == false)
|
while(device->run() && kill == false)
|
||||||
{
|
{
|
||||||
|
|
||||||
// This is used for catching disconnects
|
// This is used for catching disconnects
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -1428,6 +1435,25 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
playername = wide_to_narrow(menudata.name);
|
playername = wide_to_narrow(menudata.name);
|
||||||
|
|
||||||
|
// Get an sha-1 hash of the player's name combined with
|
||||||
|
// the password entered. That's what the server uses as
|
||||||
|
// their password. (Exception : if the password field is
|
||||||
|
// blank, we send a blank password - this is for backwards
|
||||||
|
// compatibility with password-less players).
|
||||||
|
if(menudata.password.length() > 0)
|
||||||
|
{
|
||||||
|
std::string slt=playername + wide_to_narrow(menudata.password);
|
||||||
|
SHA1 *sha1 = new SHA1();
|
||||||
|
sha1->addBytes(slt.c_str(), slt.length());
|
||||||
|
unsigned char *digest = sha1->getDigest();
|
||||||
|
password = base64_encode(digest, 20);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
password = "";
|
||||||
|
}
|
||||||
|
|
||||||
address = wide_to_narrow(menudata.address);
|
address = wide_to_narrow(menudata.address);
|
||||||
int newport = stoi(wide_to_narrow(menudata.port));
|
int newport = stoi(wide_to_narrow(menudata.port));
|
||||||
if(newport != 0)
|
if(newport != 0)
|
||||||
@ -1474,6 +1500,7 @@ int main(int argc, char *argv[])
|
|||||||
font,
|
font,
|
||||||
map_dir,
|
map_dir,
|
||||||
playername,
|
playername,
|
||||||
|
password,
|
||||||
address,
|
address,
|
||||||
port,
|
port,
|
||||||
error_message
|
error_message
|
||||||
|
@ -87,6 +87,7 @@ Player::Player():
|
|||||||
m_position(0,0,0)
|
m_position(0,0,0)
|
||||||
{
|
{
|
||||||
updateName("<not set>");
|
updateName("<not set>");
|
||||||
|
updatePassword("");
|
||||||
resetInventory();
|
resetInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +146,7 @@ void Player::serialize(std::ostream &os)
|
|||||||
Settings args;
|
Settings args;
|
||||||
args.setS32("version", 1);
|
args.setS32("version", 1);
|
||||||
args.set("name", m_name);
|
args.set("name", m_name);
|
||||||
|
args.set("password", m_password);
|
||||||
args.setFloat("pitch", m_pitch);
|
args.setFloat("pitch", m_pitch);
|
||||||
args.setFloat("yaw", m_yaw);
|
args.setFloat("yaw", m_yaw);
|
||||||
args.setV3F("position", m_position);
|
args.setV3F("position", m_position);
|
||||||
@ -179,6 +181,10 @@ void Player::deSerialize(std::istream &is)
|
|||||||
//args.getS32("version");
|
//args.getS32("version");
|
||||||
std::string name = args.get("name");
|
std::string name = args.get("name");
|
||||||
updateName(name.c_str());
|
updateName(name.c_str());
|
||||||
|
std::string password = "";
|
||||||
|
if(args.exists("password"))
|
||||||
|
password = args.get("password");
|
||||||
|
updatePassword(password.c_str());
|
||||||
m_pitch = args.getFloat("pitch");
|
m_pitch = args.getFloat("pitch");
|
||||||
m_yaw = args.getFloat("yaw");
|
m_yaw = args.getFloat("yaw");
|
||||||
m_position = args.getV3F("position");
|
m_position = args.getV3F("position");
|
||||||
|
13
src/player.h
13
src/player.h
@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "collision.h"
|
#include "collision.h"
|
||||||
|
|
||||||
#define PLAYERNAME_SIZE 20
|
#define PLAYERNAME_SIZE 20
|
||||||
|
#define PASSWORD_SIZE 28 // Maximum password length. Allows for
|
||||||
|
// base64-encoded SHA-1.
|
||||||
|
|
||||||
#define PLAYERNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.,"
|
#define PLAYERNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.,"
|
||||||
|
|
||||||
@ -121,6 +123,16 @@ public:
|
|||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void updatePassword(const char *password)
|
||||||
|
{
|
||||||
|
snprintf(m_password, PASSWORD_SIZE, "%s", password);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * getPassword()
|
||||||
|
{
|
||||||
|
return m_password;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool isLocal() const = 0;
|
virtual bool isLocal() const = 0;
|
||||||
|
|
||||||
virtual void updateLight(u8 light_at_pos) {};
|
virtual void updateLight(u8 light_at_pos) {};
|
||||||
@ -157,6 +169,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
char m_name[PLAYERNAME_SIZE];
|
char m_name[PLAYERNAME_SIZE];
|
||||||
|
char m_password[PASSWORD_SIZE];
|
||||||
f32 m_pitch;
|
f32 m_pitch;
|
||||||
f32 m_yaw;
|
f32 m_yaw;
|
||||||
v3f m_speed;
|
v3f m_speed;
|
||||||
|
@ -1734,8 +1734,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
// [0] u16 TOSERVER_INIT
|
// [0] u16 TOSERVER_INIT
|
||||||
// [2] u8 SER_FMT_VER_HIGHEST
|
// [2] u8 SER_FMT_VER_HIGHEST
|
||||||
// [3] u8[20] player_name
|
// [3] u8[20] player_name
|
||||||
|
// [23] u8[28] password <--- can be sent without this, from old versions
|
||||||
|
|
||||||
if(datasize < 3)
|
if(datasize < 2+1+PLAYERNAME_SIZE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
derr_server<<DTIME<<"Server: Got TOSERVER_INIT from "
|
derr_server<<DTIME<<"Server: Got TOSERVER_INIT from "
|
||||||
@ -1767,17 +1768,41 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Get player name
|
// Get player name
|
||||||
const u32 playername_size = 20;
|
char playername[PLAYERNAME_SIZE];
|
||||||
char playername[playername_size];
|
for(u32 i=0; i<PLAYERNAME_SIZE-1; i++)
|
||||||
for(u32 i=0; i<playername_size-1; i++)
|
|
||||||
{
|
{
|
||||||
playername[i] = data[3+i];
|
playername[i] = data[3+i];
|
||||||
}
|
}
|
||||||
playername[playername_size-1] = 0;
|
playername[PLAYERNAME_SIZE-1] = 0;
|
||||||
|
|
||||||
|
// Get password
|
||||||
|
char password[PASSWORD_SIZE];
|
||||||
|
if(datasize == 2+1+PLAYERNAME_SIZE)
|
||||||
|
{
|
||||||
|
// old version - assume blank password
|
||||||
|
*password = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(u32 i=0; i<PASSWORD_SIZE-1; i++)
|
||||||
|
{
|
||||||
|
password[i] = data[23+i];
|
||||||
|
}
|
||||||
|
password[PASSWORD_SIZE-1] = 0;
|
||||||
|
}
|
||||||
|
Player *checkplayer = m_env.getPlayer(playername);
|
||||||
|
if(checkplayer != NULL && strcmp(checkplayer->getPassword(),password))
|
||||||
|
{
|
||||||
|
derr_server<<DTIME<<"Server: peer_id="<<peer_id
|
||||||
|
<<": supplied invalid password for "
|
||||||
|
<<playername<<std::endl;
|
||||||
|
SendAccessDenied(m_con, peer_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get player
|
// Get player
|
||||||
Player *player = emergePlayer(playername, "", peer_id);
|
Player *player = emergePlayer(playername, password, peer_id);
|
||||||
//Player *player = m_env.getPlayer(peer_id);
|
|
||||||
|
|
||||||
/*{
|
/*{
|
||||||
// DEBUG: Test serialization
|
// DEBUG: Test serialization
|
||||||
@ -3138,6 +3163,20 @@ void Server::SendHP(con::Connection &con, u16 peer_id, u8 hp)
|
|||||||
con.Send(peer_id, 0, data, true);
|
con.Send(peer_id, 0, data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::SendAccessDenied(con::Connection &con, u16 peer_id)
|
||||||
|
{
|
||||||
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
|
||||||
|
writeU16(os, TOCLIENT_ACCESS_DENIED);
|
||||||
|
|
||||||
|
// Make data buffer
|
||||||
|
std::string s = os.str();
|
||||||
|
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
|
||||||
|
// Send as reliable
|
||||||
|
con.Send(peer_id, 0, data, true);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Non-static send methods
|
Non-static send methods
|
||||||
*/
|
*/
|
||||||
@ -4052,8 +4091,7 @@ v3f findSpawnPos(ServerMap &map)
|
|||||||
), BS);
|
), BS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Player *Server::emergePlayer(const char *name, const char *password,
|
Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id)
|
||||||
u16 peer_id)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Try to get an existing player
|
Try to get an existing player
|
||||||
@ -4099,6 +4137,7 @@ Player *Server::emergePlayer(const char *name, const char *password,
|
|||||||
//player->peer_id = PEER_ID_INEXISTENT;
|
//player->peer_id = PEER_ID_INEXISTENT;
|
||||||
player->peer_id = peer_id;
|
player->peer_id = peer_id;
|
||||||
player->updateName(name);
|
player->updateName(name);
|
||||||
|
player->updatePassword(password);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set player position
|
Set player position
|
||||||
|
@ -436,6 +436,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
|
static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
|
||||||
|
static void SendAccessDenied(con::Connection &con, u16 peer_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Non-static send methods
|
Non-static send methods
|
||||||
@ -476,11 +477,12 @@ private:
|
|||||||
/*
|
/*
|
||||||
Get a player from memory or creates one.
|
Get a player from memory or creates one.
|
||||||
If player is already connected, return NULL
|
If player is already connected, return NULL
|
||||||
|
The password is not checked here - it is only used to
|
||||||
|
set the password if a new player is created.
|
||||||
|
|
||||||
Call with env and con locked.
|
Call with env and con locked.
|
||||||
*/
|
*/
|
||||||
Player *emergePlayer(const char *name, const char *password,
|
Player *emergePlayer(const char *name, const char *password, u16 peer_id);
|
||||||
u16 peer_id);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update water pressure.
|
Update water pressure.
|
||||||
|
191
src/sha1.cpp
Normal file
191
src/sha1.cpp
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/* sha1.cpp
|
||||||
|
|
||||||
|
Copyright (c) 2005 Michael D. Leonhard
|
||||||
|
|
||||||
|
http://tamale.net/
|
||||||
|
|
||||||
|
This file is licensed under the terms described in the
|
||||||
|
accompanying LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "sha1.h"
|
||||||
|
|
||||||
|
// print out memory in hexadecimal
|
||||||
|
void SHA1::hexPrinter( unsigned char* c, int l )
|
||||||
|
{
|
||||||
|
assert( c );
|
||||||
|
assert( l > 0 );
|
||||||
|
while( l > 0 )
|
||||||
|
{
|
||||||
|
printf( " %02x", *c );
|
||||||
|
l--;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// circular left bit rotation. MSB wraps around to LSB
|
||||||
|
Uint32 SHA1::lrot( Uint32 x, int bits )
|
||||||
|
{
|
||||||
|
return (x<<bits) | (x>>(32 - bits));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Save a 32-bit unsigned integer to memory, in big-endian order
|
||||||
|
void SHA1::storeBigEndianUint32( unsigned char* byte, Uint32 num )
|
||||||
|
{
|
||||||
|
assert( byte );
|
||||||
|
byte[0] = (unsigned char)(num>>24);
|
||||||
|
byte[1] = (unsigned char)(num>>16);
|
||||||
|
byte[2] = (unsigned char)(num>>8);
|
||||||
|
byte[3] = (unsigned char)num;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Constructor *******************************************************
|
||||||
|
SHA1::SHA1()
|
||||||
|
{
|
||||||
|
// make sure that the data type is the right size
|
||||||
|
assert( sizeof( Uint32 ) * 5 == 20 );
|
||||||
|
|
||||||
|
// initialize
|
||||||
|
H0 = 0x67452301;
|
||||||
|
H1 = 0xefcdab89;
|
||||||
|
H2 = 0x98badcfe;
|
||||||
|
H3 = 0x10325476;
|
||||||
|
H4 = 0xc3d2e1f0;
|
||||||
|
unprocessedBytes = 0;
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor ********************************************************
|
||||||
|
SHA1::~SHA1()
|
||||||
|
{
|
||||||
|
// erase data
|
||||||
|
H0 = H1 = H2 = H3 = H4 = 0;
|
||||||
|
for( int c = 0; c < 64; c++ ) bytes[c] = 0;
|
||||||
|
unprocessedBytes = size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// process ***********************************************************
|
||||||
|
void SHA1::process()
|
||||||
|
{
|
||||||
|
assert( unprocessedBytes == 64 );
|
||||||
|
//printf( "process: " ); hexPrinter( bytes, 64 ); printf( "\n" );
|
||||||
|
int t;
|
||||||
|
Uint32 a, b, c, d, e, K, f, W[80];
|
||||||
|
// starting values
|
||||||
|
a = H0;
|
||||||
|
b = H1;
|
||||||
|
c = H2;
|
||||||
|
d = H3;
|
||||||
|
e = H4;
|
||||||
|
// copy and expand the message block
|
||||||
|
for( t = 0; t < 16; t++ ) W[t] = (bytes[t*4] << 24)
|
||||||
|
+(bytes[t*4 + 1] << 16)
|
||||||
|
+(bytes[t*4 + 2] << 8)
|
||||||
|
+ bytes[t*4 + 3];
|
||||||
|
for(; t< 80; t++ ) W[t] = lrot( W[t-3]^W[t-8]^W[t-14]^W[t-16], 1 );
|
||||||
|
|
||||||
|
/* main loop */
|
||||||
|
Uint32 temp;
|
||||||
|
for( t = 0; t < 80; t++ )
|
||||||
|
{
|
||||||
|
if( t < 20 ) {
|
||||||
|
K = 0x5a827999;
|
||||||
|
f = (b & c) | ((b ^ 0xFFFFFFFF) & d);//TODO: try using ~
|
||||||
|
} else if( t < 40 ) {
|
||||||
|
K = 0x6ed9eba1;
|
||||||
|
f = b ^ c ^ d;
|
||||||
|
} else if( t < 60 ) {
|
||||||
|
K = 0x8f1bbcdc;
|
||||||
|
f = (b & c) | (b & d) | (c & d);
|
||||||
|
} else {
|
||||||
|
K = 0xca62c1d6;
|
||||||
|
f = b ^ c ^ d;
|
||||||
|
}
|
||||||
|
temp = lrot(a,5) + f + e + W[t] + K;
|
||||||
|
e = d;
|
||||||
|
d = c;
|
||||||
|
c = lrot(b,30);
|
||||||
|
b = a;
|
||||||
|
a = temp;
|
||||||
|
//printf( "t=%d %08x %08x %08x %08x %08x\n",t,a,b,c,d,e );
|
||||||
|
}
|
||||||
|
/* add variables */
|
||||||
|
H0 += a;
|
||||||
|
H1 += b;
|
||||||
|
H2 += c;
|
||||||
|
H3 += d;
|
||||||
|
H4 += e;
|
||||||
|
//printf( "Current: %08x %08x %08x %08x %08x\n",H0,H1,H2,H3,H4 );
|
||||||
|
/* all bytes have been processed */
|
||||||
|
unprocessedBytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// addBytes **********************************************************
|
||||||
|
void SHA1::addBytes( const char* data, int num )
|
||||||
|
{
|
||||||
|
assert( data );
|
||||||
|
assert( num > 0 );
|
||||||
|
// add these bytes to the running total
|
||||||
|
size += num;
|
||||||
|
// repeat until all data is processed
|
||||||
|
while( num > 0 )
|
||||||
|
{
|
||||||
|
// number of bytes required to complete block
|
||||||
|
int needed = 64 - unprocessedBytes;
|
||||||
|
assert( needed > 0 );
|
||||||
|
// number of bytes to copy (use smaller of two)
|
||||||
|
int toCopy = (num < needed) ? num : needed;
|
||||||
|
// Copy the bytes
|
||||||
|
memcpy( bytes + unprocessedBytes, data, toCopy );
|
||||||
|
// Bytes have been copied
|
||||||
|
num -= toCopy;
|
||||||
|
data += toCopy;
|
||||||
|
unprocessedBytes += toCopy;
|
||||||
|
|
||||||
|
// there is a full block
|
||||||
|
if( unprocessedBytes == 64 ) process();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// digest ************************************************************
|
||||||
|
unsigned char* SHA1::getDigest()
|
||||||
|
{
|
||||||
|
// save the message size
|
||||||
|
Uint32 totalBitsL = size << 3;
|
||||||
|
Uint32 totalBitsH = size >> 29;
|
||||||
|
// add 0x80 to the message
|
||||||
|
addBytes( "\x80", 1 );
|
||||||
|
|
||||||
|
unsigned char footer[64] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
// block has no room for 8-byte filesize, so finish it
|
||||||
|
if( unprocessedBytes > 56 )
|
||||||
|
addBytes( (char*)footer, 64 - unprocessedBytes);
|
||||||
|
assert( unprocessedBytes <= 56 );
|
||||||
|
// how many zeros do we need
|
||||||
|
int neededZeros = 56 - unprocessedBytes;
|
||||||
|
// store file size (in bits) in big-endian format
|
||||||
|
storeBigEndianUint32( footer + neededZeros , totalBitsH );
|
||||||
|
storeBigEndianUint32( footer + neededZeros + 4, totalBitsL );
|
||||||
|
// finish the final block
|
||||||
|
addBytes( (char*)footer, neededZeros + 8 );
|
||||||
|
// allocate memory for the digest bytes
|
||||||
|
unsigned char* digest = (unsigned char*)malloc( 20 );
|
||||||
|
// copy the digest bytes
|
||||||
|
storeBigEndianUint32( digest, H0 );
|
||||||
|
storeBigEndianUint32( digest + 4, H1 );
|
||||||
|
storeBigEndianUint32( digest + 8, H2 );
|
||||||
|
storeBigEndianUint32( digest + 12, H3 );
|
||||||
|
storeBigEndianUint32( digest + 16, H4 );
|
||||||
|
// return the digest
|
||||||
|
return digest;
|
||||||
|
}
|
35
src/sha1.h
Normal file
35
src/sha1.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* sha1.h
|
||||||
|
|
||||||
|
Copyright (c) 2005 Michael D. Leonhard
|
||||||
|
|
||||||
|
http://tamale.net/
|
||||||
|
|
||||||
|
This file is licensed under the terms described in the
|
||||||
|
accompanying LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHA1_HEADER
|
||||||
|
typedef unsigned int Uint32;
|
||||||
|
|
||||||
|
class SHA1
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// fields
|
||||||
|
Uint32 H0, H1, H2, H3, H4;
|
||||||
|
unsigned char bytes[64];
|
||||||
|
int unprocessedBytes;
|
||||||
|
Uint32 size;
|
||||||
|
void process();
|
||||||
|
public:
|
||||||
|
SHA1();
|
||||||
|
~SHA1();
|
||||||
|
void addBytes( const char* data, int num );
|
||||||
|
unsigned char* getDigest();
|
||||||
|
// utility methods
|
||||||
|
static Uint32 lrot( Uint32 x, int bits );
|
||||||
|
static void storeBigEndianUint32( unsigned char* byte, Uint32 num );
|
||||||
|
static void hexPrinter( unsigned char* c, int l );
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SHA1_HEADER
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user