forked from Mirrors/privacore-open-source-search-engine
fix security system to actually work now
This commit is contained in:
@ -604,7 +604,7 @@ bool Collectiondb::addRdbBasesForCollRec ( CollectionRec *cr ) {
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
bool Collectiondb::isAdmin ( HttpRequest *r , TcpSocket *s ) {
|
||||
if ( r->getLong("admin",1) == 0 ) return false;
|
||||
if ( g_conf.isMasterAdmin ( s , r ) ) return true;
|
||||
@ -615,7 +615,6 @@ bool Collectiondb::isAdmin ( HttpRequest *r , TcpSocket *s ) {
|
||||
//return cr->hasPermission ( r , s );
|
||||
}
|
||||
|
||||
/*
|
||||
void savingCheckWrapper1 ( int fd , void *state ) {
|
||||
WaitEntry *we = (WaitEntry *)state;
|
||||
// no state?
|
||||
|
@ -95,7 +95,7 @@ class Collectiondb {
|
||||
|
||||
// . does this requester have root admin privledges???
|
||||
// . uses the root collection record!
|
||||
bool isAdmin ( class HttpRequest *r , class TcpSocket *s );
|
||||
//bool isAdmin ( class HttpRequest *r , class TcpSocket *s );
|
||||
|
||||
//collnum_t getNextCollnum ( collnum_t collnum );
|
||||
|
||||
@ -310,10 +310,10 @@ class CollectionRec {
|
||||
// . set ourselves the cgi parms in an http request
|
||||
// . unspecified cgi parms will be assigned default values
|
||||
// . returns false and sets errno on error
|
||||
bool set ( class HttpRequest *r , TcpSocket *s );
|
||||
bool set ( class HttpRequest *r , class TcpSocket *s );
|
||||
|
||||
// calls hasPermission() below
|
||||
bool hasPermission ( class HttpRequest *r , TcpSocket *s ) ;
|
||||
bool hasPermission ( class HttpRequest *r , class TcpSocket *s ) ;
|
||||
|
||||
// . does this user have permission for editing this collection?
|
||||
// . "p" is the password for this collection in question
|
||||
@ -326,7 +326,7 @@ class CollectionRec {
|
||||
// . can this ip perform a search or add url on this collection?
|
||||
// . mamma.com provides encapsulated ips of their queriers so we
|
||||
// can ban them by ip
|
||||
bool hasSearchPermission ( TcpSocket *s , long encapIp = 0 );
|
||||
bool hasSearchPermission ( class TcpSocket *s , long encapIp = 0 );
|
||||
|
||||
// how many bytes would this record occupy in raw binary format?
|
||||
//long getStoredSize () { return m_recSize; };
|
||||
|
79
Conf.cpp
79
Conf.cpp
@ -18,6 +18,7 @@ Conf::Conf ( ) {
|
||||
// . master admin can administer ALL collections
|
||||
// . use CollectionRec::hasPermission() to see if has permission
|
||||
// to adminster one particular collection
|
||||
/*
|
||||
bool Conf::isMasterAdmin ( TcpSocket *s , HttpRequest *r ) {
|
||||
// sometimes they don't want to be admin intentionally for testing
|
||||
if ( r->getLong ( "master" , 1 ) == 0 ) return false;
|
||||
@ -64,56 +65,84 @@ bool Conf::isMasterAdmin ( TcpSocket *s , HttpRequest *r ) {
|
||||
// check admin ips
|
||||
// scan the passwords
|
||||
// MDW: no! too vulnerable to attacks!
|
||||
/*
|
||||
for ( long i = 0 ; i < m_numMasterPwds ; i++ ) {
|
||||
if ( strcmp ( m_masterPwds[i], p ) != 0 ) continue;
|
||||
// . matching one password is good enough now, default OR
|
||||
// . because just matching an IP is good enough security,
|
||||
// there is really no need for both IP AND passwd match
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
//for ( long i = 0 ; i < m_numMasterPwds ; i++ ) {
|
||||
// if ( strcmp ( m_masterPwds[i], p ) != 0 ) continue;
|
||||
// // . matching one password is good enough now, default OR
|
||||
// // . because just matching an IP is good enough security,
|
||||
// // there is really no need for both IP AND passwd match
|
||||
// return true;
|
||||
//}
|
||||
// ok, make sure they came from an acceptable IP
|
||||
if ( isAdminIp ( ip ) )
|
||||
if ( isRootIp ( ip ) )
|
||||
// they also have a matching IP, so they now have permission
|
||||
return true;
|
||||
// if no security, allow all
|
||||
// MDW: nonononono!!!!
|
||||
/*
|
||||
if ( m_numMasterPwds == 0 &&
|
||||
m_numMasterIps == 0 ) return true;
|
||||
*/
|
||||
//if ( m_numMasterPwds == 0 &&
|
||||
// m_numMasterIps == 0 ) return true;
|
||||
// if they did not match an ip or password, even if both lists
|
||||
// are empty, do not allow access... this prevents security breeches
|
||||
// by accident
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
bool Conf::isCollAdmin ( TcpSocket *socket , HttpRequest *hr ) {
|
||||
// until we have coll tokens use this...
|
||||
return isRootAdmin ( socket , hr );
|
||||
}
|
||||
|
||||
// is user a root administrator?
|
||||
// . is user a root administrator?
|
||||
// . only need to be from root IP *OR* have password, not both
|
||||
bool Conf::isRootAdmin ( TcpSocket *socket , HttpRequest *hr ) {
|
||||
|
||||
if ( m_numMasterIps == 0 &&
|
||||
m_numConnectIps == 0 ) {
|
||||
// from "local" ip?
|
||||
return hr->isLocal();
|
||||
}
|
||||
// totally open access?
|
||||
if ( m_numConnectIps <= 0 && m_numMasterPwds <= 0 )
|
||||
return true;
|
||||
|
||||
if ( isAdminIp ( socket->m_ip ) ) return true;
|
||||
// coming from root gets you in
|
||||
if ( isRootIp ( socket->m_ip ) ) return true;
|
||||
|
||||
if ( isConnectIp ( socket->m_ip ) ) return true;
|
||||
//if ( isConnectIp ( socket->m_ip ) ) return true;
|
||||
|
||||
if ( hasRootPwd ( hr ) ) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Conf::hasRootPwd ( HttpRequest *hr ) {
|
||||
|
||||
if ( m_numMasterPwds == 0 ) return false;
|
||||
|
||||
char *p = hr->getString("pwd");
|
||||
|
||||
if ( ! p ) p = hr->getString("password");
|
||||
|
||||
if ( ! p ) p = hr->getStringFromCookie("pwd");
|
||||
|
||||
if ( ! p ) return false;
|
||||
|
||||
for ( long i = 0 ; i < m_numMasterPwds ; i++ ) {
|
||||
if ( strcmp ( m_masterPwds[i], p ) != 0 ) continue;
|
||||
// we got a match
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// . check this ip in the list of admin ips
|
||||
bool Conf::isAdminIp ( unsigned long ip ) {
|
||||
for ( long i = 0 ; i < m_numMasterIps ; i++ )
|
||||
if ( m_masterIps[i] == (long)ip )
|
||||
bool Conf::isRootIp ( unsigned long ip ) {
|
||||
|
||||
//if ( m_numMasterIps == 0 ) return false;
|
||||
if ( m_numConnectIps == 0 ) return false;
|
||||
|
||||
for ( long i = 0 ; i < m_numConnectIps ; i++ )
|
||||
if ( m_connectIps[i] == (long)ip )
|
||||
return true;
|
||||
|
||||
//if ( ip == atoip("10.5.0.2",8) ) return true;
|
||||
|
||||
// no match
|
||||
return false;
|
||||
}
|
||||
|
14
Conf.h
14
Conf.h
@ -49,10 +49,13 @@ class Conf {
|
||||
|
||||
Conf();
|
||||
|
||||
bool isCollAdmin ( TcpSocket *socket , HttpRequest *hr ) ;
|
||||
|
||||
bool isRootAdmin ( TcpSocket *socket , HttpRequest *hr ) ;
|
||||
bool isMasterAdmin ( class TcpSocket *s , class HttpRequest *r );
|
||||
bool isSpamAssassin ( class TcpSocket *s , class HttpRequest *r );
|
||||
bool isAdminIp ( unsigned long ip );
|
||||
//bool isMasterAdmin ( class TcpSocket *s , class HttpRequest *r );
|
||||
//bool isSpamAssassin ( class TcpSocket *s , class HttpRequest *r );
|
||||
bool hasRootPwd ( HttpRequest *hr ) ;
|
||||
bool isRootIp ( unsigned long ip );
|
||||
bool isConnectIp ( unsigned long ip );
|
||||
|
||||
// loads conf parms from this file "{dir}/gb.conf"
|
||||
@ -664,9 +667,10 @@ class Conf {
|
||||
|
||||
long m_numMasterPwds;
|
||||
char m_masterPwds[MAX_MASTER_PASSWORDS][PASSWORD_MAX_LEN];
|
||||
long m_numMasterIps;
|
||||
long m_masterIps[MAX_MASTER_IPS];
|
||||
//long m_numMasterIps;
|
||||
//long m_masterIps[MAX_MASTER_IPS];
|
||||
|
||||
// these are the new master ips
|
||||
long m_numConnectIps;
|
||||
long m_connectIps [ MAX_CONNECT_IPS ];
|
||||
|
||||
|
@ -120,7 +120,7 @@ bool sendPageGet ( TcpSocket *s , HttpRequest *r ) {
|
||||
mnew ( st , sizeof(State2) , "PageGet1" );
|
||||
// save the socket and if Host: is local in the Http request Mime
|
||||
st->m_socket = s;
|
||||
st->m_isAdmin = g_collectiondb.isAdmin ( r , s );
|
||||
st->m_isAdmin = g_conf.isCollAdmin ( s , r );
|
||||
st->m_isLocal = r->isLocal();
|
||||
st->m_docId = docId;
|
||||
// include header ... "this page cached by Gigablast on..."
|
||||
|
@ -124,7 +124,7 @@ bool sendPageIndexdb ( TcpSocket *s , HttpRequest *r ) {
|
||||
// save the TcpSocket
|
||||
st->m_socket = s;
|
||||
// and if the request is local/internal or not
|
||||
st->m_isAdmin = g_collectiondb.isAdmin ( r , s );
|
||||
st->m_isAdmin = g_conf.isCollAdmin ( s , r );
|
||||
st->m_isLocal = r->isLocal();
|
||||
st->m_r.copy ( r );
|
||||
// . check for add/delete request
|
||||
|
@ -1286,7 +1286,7 @@ bool sendPageAddUrl ( TcpSocket *s , HttpRequest *r ) {
|
||||
|
||||
// see if they provided a url of a file of urls if they did not
|
||||
// provide a url to add directly
|
||||
bool isAdmin = g_collectiondb.isAdmin ( r , s );
|
||||
bool isAdmin = g_conf.isCollAdmin ( s , r );
|
||||
long ufuLen = 0;
|
||||
char *ufu = NULL;
|
||||
if ( isAdmin )
|
||||
|
@ -58,7 +58,7 @@ bool sendPageTitledb ( TcpSocket *s , HttpRequest *r ) {
|
||||
// copy it
|
||||
st->m_r.copy ( r );
|
||||
// remember if http request is internal/local or not
|
||||
st->m_isAdmin = g_collectiondb.isAdmin ( r , s );
|
||||
st->m_isAdmin = g_conf.isCollAdmin ( s , r );
|
||||
st->m_isLocal = r->isLocal();
|
||||
st->m_docId = docId;
|
||||
// password, too
|
||||
|
85
Pages.cpp
85
Pages.cpp
@ -1005,6 +1005,25 @@ bool Pages::printAdminTop (SafeBuf *sb ,
|
||||
//
|
||||
sb->safePrintf("</TD>\n<TD>");
|
||||
|
||||
|
||||
// logout link on far right
|
||||
sb->safePrintf("<div align=right "
|
||||
"style=\""
|
||||
"max-width:100px;"
|
||||
"right:20px;"
|
||||
"position:absolute;"
|
||||
"\">"
|
||||
"<font color=blue>"
|
||||
// clear the cookie
|
||||
"<span onclick=\"document.cookie='pwd=;';"
|
||||
"window.location.href='/';"
|
||||
"\">"
|
||||
"logout"
|
||||
"</span>"
|
||||
"</font>"
|
||||
"</div>"
|
||||
);
|
||||
|
||||
// print the hosts navigation bar
|
||||
status &= printHostLinks ( sb, page ,
|
||||
username , pwd ,
|
||||
@ -2503,7 +2522,7 @@ bool sendPageLogin ( TcpSocket *socket , HttpRequest *hr ) {
|
||||
emsg.safePrintf("Collection \"%s\" does not exist.",coll);
|
||||
|
||||
// just make cookie same format as an http request for ez parsing
|
||||
char cookieData[2024];
|
||||
//char cookieData[2024];
|
||||
|
||||
SafeBuf sb;
|
||||
|
||||
@ -2515,7 +2534,10 @@ bool sendPageLogin ( TcpSocket *socket , HttpRequest *hr ) {
|
||||
g_pages.printLogo ( &sb , coll );
|
||||
|
||||
// get password from cgi parms OR cookie
|
||||
char *pwd = hr->getString("pwd",NULL);
|
||||
char *pwd = hr->getString("pwd");
|
||||
if ( ! pwd ) pwd = hr->getStringFromCookie("pwd");
|
||||
// fix "pwd=" cookie (from logout) issue
|
||||
if ( pwd && ! pwd[0] ) pwd = NULL;
|
||||
|
||||
bool hasPermission = false;
|
||||
|
||||
@ -2523,8 +2545,9 @@ bool sendPageLogin ( TcpSocket *socket , HttpRequest *hr ) {
|
||||
if ( cr && pwd && g_conf.isRootAdmin ( socket , hr ) )
|
||||
hasPermission = true;
|
||||
|
||||
if ( emsg.length() == 0 && ! hasPermission )
|
||||
emsg.safePrintf("Admin password incorrect");
|
||||
if ( emsg.length() == 0 && ! hasPermission && pwd )
|
||||
emsg.safePrintf("Root password incorrect");
|
||||
|
||||
|
||||
// sanity
|
||||
if ( hasPermission && emsg.length() ) { char *xx=NULL;*xx=0; }
|
||||
@ -2532,42 +2555,52 @@ bool sendPageLogin ( TcpSocket *socket , HttpRequest *hr ) {
|
||||
// what page are they originally trying to get to?
|
||||
long page = g_pages.getDynamicPageNumber(hr);
|
||||
|
||||
char *cookie = NULL;
|
||||
// try to the get reference Page
|
||||
long refPage = hr->getLong("ref",-1);
|
||||
// if they cam to login page directly... to to basic page then
|
||||
if ( refPage == PAGE_LOGIN ||
|
||||
refPage == PAGE_LOGIN2 ||
|
||||
refPage < 0 )
|
||||
refPage = PAGE_BASIC_SETTINGS;
|
||||
|
||||
// if they had an original destination, redirect there NOW
|
||||
WebPage *pagePtr = g_pages.getPage(refPage);
|
||||
|
||||
/*
|
||||
char *cookie = NULL;
|
||||
if ( hasPermission ) {
|
||||
// "pwd" could be NULL... like when it is not required,
|
||||
// perhaps only the right ip address is required, but if it
|
||||
// is there then store it in a cookie with no expiration
|
||||
if ( pwd ) sprintf ( cookieData, "pwd=%s;expires=0;",pwd);
|
||||
// try to the get reference Page
|
||||
long refPage = hr->getLong("ref",-1);
|
||||
// if they cam to login page directly... to to basic page then
|
||||
if ( refPage == PAGE_LOGIN ||
|
||||
refPage == PAGE_LOGIN2 ||
|
||||
refPage < 0 )
|
||||
refPage = PAGE_BASIC_SETTINGS;
|
||||
// if they had an original destination, redirect there NOW
|
||||
WebPage *page = g_pages.getPage(refPage);
|
||||
//if ( pwd ) sprintf ( cookieData, "pwd=%s;expires=0;",pwd);
|
||||
// and redirect to it
|
||||
sb.safePrintf("<meta http-equiv=\"refresh\" content=\"0;"
|
||||
"/%s?c=%s\">", page->m_filename,coll);
|
||||
// return cookie in server reply if pwd was non-null
|
||||
cookie = cookieData;
|
||||
}
|
||||
*/
|
||||
|
||||
char *ep = emsg.getBufStart();
|
||||
if ( !ep ) ep = "";
|
||||
|
||||
char *ff = "admin/settings";
|
||||
if ( pagePtr ) ff = pagePtr->m_filename;
|
||||
|
||||
sb.safePrintf(
|
||||
" "
|
||||
"</td><td><font size=+1><b>Login</b></font></td></tr>"
|
||||
"</table>"
|
||||
"<form method=post action=\"/login\" name=f>"
|
||||
" "
|
||||
"</td><td><font size=+1><b>Login</b></font></td></tr>"
|
||||
"</table>"
|
||||
"<form method=post action=\"/%s\" name=f>"
|
||||
, ff );
|
||||
|
||||
sb.safePrintf(
|
||||
"<input type=hidden name=ref value=\"%li\">"
|
||||
"<center>"
|
||||
"<br><br>"
|
||||
"<font color=ff0000><b>%s</b></font>"
|
||||
"<br><br>"
|
||||
"<br>"
|
||||
|
||||
"<table cellpadding=2><tr><td>"
|
||||
|
||||
@ -2576,17 +2609,21 @@ bool sendPageLogin ( TcpSocket *socket , HttpRequest *hr ) {
|
||||
//"</td><td></td></tr>"
|
||||
//"<tr><td>"
|
||||
|
||||
"<b>Admin Password</td>"
|
||||
"<td><input type=password name=pwd size=30>"
|
||||
"<b>Root Password : </td>"
|
||||
"<td><input id=ppp type=password name=pwd size=30>"
|
||||
"</td><td>"
|
||||
"<input type=submit value=ok border=0></td>"
|
||||
"<input type=submit value=ok border=0 onclick=\""
|
||||
"document.cookie='pwd='+document.getElementById('ppp')"
|
||||
".value+"
|
||||
"';expires=0';"
|
||||
"\"></td>"
|
||||
"</tr></table>"
|
||||
"</center>"
|
||||
"<br><br>"
|
||||
, page, ep , coll );
|
||||
|
||||
// print the tail
|
||||
g_pages.printTail ( &sb , hr->isLocal() ); // pwd
|
||||
//g_pages.printTail ( &sb , hr->isLocal() ); // pwd
|
||||
// send the page
|
||||
return g_httpServer.sendDynamicPage ( socket ,
|
||||
sb.getBufStart(),
|
||||
@ -2595,5 +2632,5 @@ bool sendPageLogin ( TcpSocket *socket , HttpRequest *hr ) {
|
||||
false , // POSTReply?
|
||||
NULL , // contentType
|
||||
-1 ,
|
||||
cookie);// Forbidden http status
|
||||
NULL);// cookie
|
||||
}
|
||||
|
16
Parms.cpp
16
Parms.cpp
@ -8015,13 +8015,13 @@ void Parms::init ( ) {
|
||||
|
||||
|
||||
m->m_title = "Admin Passwords";
|
||||
m->m_desc = "Passwords allowed to change Gigablast's general "
|
||||
"parameters and also the parameters for any collection. "
|
||||
"If no Admin Password or Admin IP is specified then "
|
||||
"Gigablast will only allow local IPs to connect to it "
|
||||
"as the master admin.";
|
||||
m->m_cgi = "mpwd";
|
||||
m->m_xml = "masterPassword";
|
||||
m->m_desc = "Any matching password will have administrative access "
|
||||
"to Gigablast and all collections.";
|
||||
//"If no Admin Password or Admin IP is specified then "
|
||||
//"Gigablast will only allow local IPs to connect to it "
|
||||
//"as the master admin.";
|
||||
m->m_cgi = "adminpwd";
|
||||
m->m_xml = "adminPassword";
|
||||
m->m_obj = OBJ_CONF;
|
||||
m->m_max = MAX_MASTER_PASSWORDS;
|
||||
m->m_off = (char *)&g_conf.m_masterPwds - g;
|
||||
@ -8042,7 +8042,7 @@ void Parms::init ( ) {
|
||||
// "their Least Significant Byte are treated as wildcards for "
|
||||
// "IP blocks. That is, 1.2.3.0 means 1.2.3.*.";
|
||||
m->m_desc = "Any IPs in this list will have administrative access "
|
||||
"to the Gigablast search engine.";
|
||||
"to Gigablast and all collections.";
|
||||
m->m_cgi = "adminip";
|
||||
m->m_xml = "adminIp";
|
||||
m->m_page = PAGE_SECURITY;
|
||||
|
@ -339,7 +339,7 @@ bool Proxy::handleRequest (TcpSocket *s){
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isAdmin = g_conf.isMasterAdmin(s,&hr);
|
||||
bool isAdmin = g_conf.isRootAdmin(s,&hr);
|
||||
|
||||
long redirLen = hr.getRedirLen() ;
|
||||
char *redir = NULL;
|
||||
|
@ -1237,7 +1237,7 @@ long UdpServer::readSock_ass ( UdpSlot **slotPtr , long long now ) {
|
||||
else if ( m_proto->useAcks() &&
|
||||
! isLocal &&
|
||||
! g_hostdb.isIpInNetwork ( ip ) &&
|
||||
! g_conf.isAdminIp ( ip ) &&
|
||||
! g_conf.isRootIp ( ip ) &&
|
||||
! g_hostdb2.isIpInNetwork ( ip ) &&
|
||||
! g_conf.isConnectIp ( ip ) ) {
|
||||
// bitch, wait at least 5 seconds though
|
||||
|
Reference in New Issue
Block a user