/**************************************************
OpengateM - MAC address authentication system 

header file for OpengateM management programs

Copyright (C) 2011 Opengate Project Team
Written by Yoshiaki Watanabe

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Email: watanaby@is.saga-u.ac.jp
**************************************************/

#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <sys/select.h>
#include <poll.h>
#include <strings.h>
#include <sys/ioctl.h>
#include <sys/filio.h>
#include <sys/sockio.h>
#include <pthread.h>
#include <sys/socket.h>
#include <syslog.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/signal.h>
#include <regex.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <limits.h>
#include <db.h>
#include <net/if_dl.h>
#include <ifaddrs.h>
#include <sys/utsname.h>
#include <netdb.h>

#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/md5.h>

typedef	void Sigfunc(int); /* clarify signal handlers such as 'Sigfunc* func' */

/***************** constants ***********************/

/* Configuration file for opengate */ 
#define CONFIGFILE "/etc/opengate/opengatemmng.conf"

#define PAMSERVICENAME "opengate"      /* default service name used in PAM */
#define RADIUSCONF  "/etc/radius.conf" /* default path to radius.conf */

#define ADDRMAXLN 128      /* maximum address string length */
#define USERMAXLN 128      /* maximum userid string length */
#define BUFFMAXLN 1024     /* maximum buffer string length */
#define WORDMAXLN 64       /* maximum word length */
#define FILTERMAXLN 128    /* pcap filter max length */
#define SIDMAXLN 64        /* maximum sessionID length */

#define TRUE 1
#define FALSE 0
#define DENY   0
#define ACCEPT 1
#define OPEN 1
#define CLOSE 0
#define NONE -1
#define NORMALUSER 0
#define ADMINUSER 1
#define ERROR -1
#define NONAT 0
#define NAT 1
#define ROUTER 2
#define OWNER 1
#define ADMIN 0

extern int debug;

/* error IDs send to web client (message for ID is stored in messages.c) */
/* last ID should be ENDOFLIST */
enum errs{ExistentMacAddr,DeviceCountOver,IllegalMacAddrForm,
	  IllegalCharInDevice,EmptyDeviceName,IllegalCharInMailAddr,SuspectNat,
	  NoInfoInDb,IllegalUserId,IllegalMacAddr,NoService,
	  NoDaemon,ModifyCountOver,RegisterSuccess,UpdateSuccess,IllegalCookie,
	  NotSetAdminCookie,RequestAdminAuth,UnallowableAgent,
	  ENDOFLIST};

/**********prototypes***************************************/

/* opengatemreg.c */
void CheckDaemonAndSendHupSignal(void);

/* opengatemmail.c */
int SendMail(char* mailAddress, char* limitDate, char* device);


/* proc.c */
int StartChildProc(char* macAddress);
int StopChildProc(char* macAddress);
void closeExit(int signo);
void saveLoadPath(char* loadPath);
char* getProgramName(void);

/* util.c */
void Writefmt(int fd, const char *fmt, ...);
void WritefmtSSL(SSL *fd, const char *fmt, ...);
ssize_t readln(int fd, void *vptr, size_t maxlen);
ssize_t readlnSSL(SSL *fd, void *vptr, size_t maxlen);
int Lock(int fd);
int Unlock(int fd);
FILE *Popenl(int rootPriv, const char *type, const char *path, ...);
int Systeml(int roorPriv, const char *path, ...);
int Pclose(FILE *stream);
int isNull(const char *pStr);
int Open(const char *pathname, int oflag, mode_t mode);
int Close(int fd);
pid_t Fork(void);
int Pipe(int *fds);
Sigfunc * Signal(int signo, Sigfunc *func);
void * Malloc(size_t size);
void CreateCookie(char *cookie);
char* getenvEx(char* env, int pre, int post);
int Tcp_connect(const char *host, const char *serv);

/* error.c */
void err_ret(const char *fmt, ...);
void err_sys(const char *fmt, ...);
void err_dump(const char *fmt, ...);
void err_msg(const char *fmt, ...);
void err_quit(const char *fmt, ...);
void errToSyslog(int i);
void terminateProg(int ret);

/* getparam.c */
int OpenConfFile(void);
void CloseConfFile(void);
void SetupConfExtra(char *userId, char *extraId);
char *GetConfValue(char *name);
char *GetConfValueExtra(char *name);
char *GetConfAuthServer(char *name);
int SelectNextAuthServer(void);
void InitConf(void);
int RegExMatch(const char *inStr, const char *regEx, int caseSensitive);
void ResetAuthServerPointer(void);
char *GetFirstConfValue(char* name);
char *GetNextConfValue(void);

/* managementdb.c */
int InitMngDb(void);
void CloseMngDb(void);
int RegistMacAddrToMngDb(char* macAddr, char* deviceName, char* userId, char* extraId, char* mailAddress);
int GetNextMacAddrFromMngDb(char* userId, char* extraId, char* macAddress, char* deviceName, char* entryDate, char* limitDate, char* status, char* mailAddress);
int IsMacAddrFoundInMngDb(char* macAddr);
int CountMacAddrsForUserInMngDb(char* userId, char* extraId);
int PutMacModifyLogToMngDb(char* userId, char* extraId, char* macAddr, char modifyType);
int GetNicVendorFromMngDb(char* macAddress, char* vendor, int bufferLength);
int CountMacModifyPerDayInMngDb(char* userId, char* extraId, char* macAddress);
int DelMacAddrFromMngDb(char* macAddr);
int RenewMacAddrInMngDb(char* macAddr);
int PauseMacAddrInMngDb(char* macAddr);
int IsSessionFoundInMngDb(char* macAddr);
int GetNextUsageLogFromMngDb(char* userId, char* extraId, char* macAddr, char* deviceName, char* openTime, char* closeTime, char* gatewayName);
int GetNextMailAddressFromMngDb(char* mailAddress, char* limitDate, char*device);
int GetTimeRangeToShowLog(char* beginTime, char* endTime, int* dateCount);
int RenameDeviceNameInMngDb(char* macAddr, char* nameStr);
int RenameMailAddressInMngDb(char* macAddr, char* mailStr);
int RegOrUpNobodyMacAddr(char* macAddress);
int IsMacAddrStatusInactiveInMngDb(char* macAddress);

/* workdb.c */
int SetupSqliteBusyTimeoutValue(void);
int InitWorkDb(void);
int CreateMacCheckTableInWorkDb(void);
int AddIpv4ToMacCheckTable(void);
int AddIpv6ToMacCheckTable(void);
int GetNextRowInMacCheckTable(char* macAddress, char* ipv4, char* ipv6);
int GetIpFromMacCheckTable(char* macAddress, char* ipv4, char* ipv6);
int GetPidFromMacCheckTable(char* macAddress, int* pid, int* ruleIpv4, int* ruleIpv6);
  int SavePidToMacCheckTable(char* macAddress, int pid, int ruleIpv4, int ruleIpv6);
int GetDetectTimeFromMacinfoTable(char* macAddress);
int IsSessionFoundInSessionTable(char* macAddress);
int SaveCookieToWorkDb(char* cookie, char* userId, char* extraId, int userType);
int IsCookieFoundInWorkDb(char* cookie, char* userId, char* extraId, int userType);
int GetMailDefaultFromWorkDb(char* cookie, char* mailDefault);
int IsNatSuspectedInWorkDb(char* macAddr);
int SaveMacForCookieToWorkDb(char* cookie, char* macAddress);
int SaveMailDefalutForCookieToWorkDb(char* cookie, char* mailDefault);
int LoadMacForCookieFromWorkDb(char* cookie, char* macAddress);
int IsActiveSessionFoundInOpengateSessionTable(char* macAddress);

/* cgi.c */
int GetPostData(char *content, int contentMaxLength);
int GetLangFromQueryString(char* language);
int GetRedirectedUrlFromQueryString(char* redirectedUrl);
int GetMacAddrFromQueryString(char* macAddress);
int AnalyzeCheckRequest(char *content, int* status, char* macAddress);
int AnalyzeRegisterRequest(char *content, char* macAddress, char* deviceName, char* mailAddress);
int PutDenyToClient(char *language);
int PutCheckPageToClient(char *language, char* userId, char* extraId);
int PutRegisterPageToClient(char *language, char* macAddress, char* deviceName, char* mailAddress, char* userId, char* extraId, int ownReg, char* redirectedUrl);
void PutMacCheckListToClient(void);
void PutMacRegListToClient(char* userId, char* extraId);
void PutMessageToClient(char *message);
void ReturnToRedirectedPage(char* redirectedUrl, char* language);
int PutAuthRequestPageToClient(char *language, char* cgiName, char* docName, char* redirectedUrl);
int ConvertMacAddr(char* macAddr);
int IsSafeString(char* str, int length);
int HtmlReplace(char* buff,char *beforeStr,char *afterStr);
char* StrSplit(char* str,const char* delimStr);
int GetUserIdFromEnv(char *userid);
int GetUserIdFromPostData(char* requestStr, char* userid, char* password);
int GetHttpCookie(char *cookie, char* cookieName);
int IsCorrectCookie(char* cookie, int userType);
int AnalyzeUpdateRequestAndExecute(char *content, char* userId, char* extraId);
int PutUpdatePageToClient(char *language, char* userId, char* extraId, int ownUpdate, char* redirectedUrl);
void PutMacListToClient(char *userId, char* extraId);
void PutUsageLogToClient(char *userId, char* extraId, char* language);
int IsAccessedFromAllowableAgent(void);

/* messages.c */
void SetMessage(int errNo);
void ResetMessage(void);
void InsertMessageToPage(char* language);
char* messagesInJa(int errNo);
char* messagesInEn(int errNo);
char* WeekdayStr(int weekday, char* str, char* language);

/* getmac.c */
int GetMacAddrListFromArp(char* interface);
int GetMacAddrListFromNdp(char* interface);
int ReFormatMacAddr(char* macAddr);

/* queue.c */
int Initqueue(void);
int Enqueue(char* keyStr, char* dataStr);
int Dequeue(char* keyStr, char* dataStr);
int Listqueue(void);
void Freequeue(void);

/* ipfw.c */
int GetRuleNumber(char *clientAddr, int forced);
int OpenClientGate(char *clientAddr, int forced, char* userId, char* extraId,char* macAddress);
void CloseClientGate(int ruleNumber);
int CountRuleNumber(int ruleNumber);

/* auth.c */
int GetUserId(char* requestStr, char* userId, char* extraId, char* language, int userType, char* cgiName, char* mailDefault, char* redirectedUrl);
int AuthenticateUser(char *userid, char *password);
void SplitId(char* userid, char* useridshort, char* extraId);
char* ConcatUserId(char*  useridfull, char* userId, char* extraId);
int IsUserIdFoundInAcceptUsersList(char* userId);
int IsShibOrBasicAuthDuplicated(void);
int MakeMailDefault(char* userId, char* extraId, char* mailDefault);
int IsSplashOnlyManagement(void);

/* alarms.c */
int AddAlarm(char *name, int timeout, int preceding, Sigfunc *func);
int RemoveAlarm(char *name);
int EnableAlarm(void);
int DisableAlarm(void);

/* udpcli.c */
int PutDataToUdpPort(char* udpServerAddr, char* udpServerPort, char* buff);
int PutMacAddressToServers(char* macAddress);
char *GetServicePortStr(char *servName);

/* signal.c */
Sigfunc* signalx(int signo, Sigfunc* func);

