#include #include #include #include #include #include #include #include #include #include "dialout.h" #include "netconf.h" #include #include "../paths.h" #include "dialout.m" #include "pppdial.h" #include #include #include #include #include #include HELP_FILE help_ppp ("dialout","ppp"); /* #Specification: PPP & SLIP / management All configuration information is store in a file /etc/ppp/_____.dconf. One configuration file per configuration. This file is a CONFDB file, with the same format as /etc/conf.linuxconf. # name1.login login name1.passwd password name1.phone phone # and so on. Initially, there were a single file for all ppp channels. With the advent of per-channel firewalling and accounting rules, linuxconf has moved to one file per configuration. This allows also the concept of dropins for PPP configuration. For example, an ISP may provide to Linux user a prebuild configuration file. The user has just to drop this file in /etc/ppp and it becomes available. */ # /* Add a baud rate field in a dialog with standard values */ void baud_setfield ( int baud, SSTRING &baudstr, DIALOG &dia) { char msg[10]; baudstr.setfrom (baud); FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_BAUD,"Baud rate"),baudstr); static short int tb[]={ 3,6,12,24,48,96, 192,384,576,1152 }; for (unsigned i=0; iaddopt (msg); } } void serial_setfield ( SSTRING &device, DIALOG &dia) { FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_SERIALDEF ,"Serial device"),device); comb->addopt ("/dev/ttyS0",MSG_U(F_COM1M,"COM1")); comb->addopt ("/dev/ttyS1",MSG_U(F_COM2M,"COM2")); comb->addopt ("/dev/ttyS2",MSG_U(F_COM3M,"COM3")); comb->addopt ("/dev/ttyS3",MSG_U(F_COM4M,"COM4")); } /* Parse the lcpecho field (delay,retry). Return -1 if any error, 0 if empty, 1 if a value pair is supplied */ PRIVATE int PPPONE::lcpecho_parse(int &delay, int &retry) { int ret = -1; delay = retry = 0; if (lcpecho.is_empty()){ ret = 0; }else{ const char *str = lcpecho.get(); delay = atoi(str); const char *pt = strchr(str,','); if (pt != NULL){ retry = atoi(pt+1); if (delay != 0 && retry != 0) ret = 1; } } return ret; } PRIVATE int PPPONE::lcpecho_valid() { int d,r; return lcpecho_parse (d,r)!=-1; } PRIVATE int PPPONE::validate_edit ( SSTRING &baudstr, SSTRING &oldname, int &nof, int field_name, int field_device, int field_lcpecho, int field_ssh) { char buferr[2000]; buferr[0] = '\0'; baud = baudstr.getval(); if (name.strchr(' ')!=NULL){ strcpy (buferr ,MSG_U(E_NOSPACE,"No spaces allowed in the configuration name\n")); nof = 0; }else if (!oldname.is_empty() && name.cmp(oldname)!=0){ char path[PATH_MAX]; sprintf (path,"%s/%s.dconf",ETC_PPP,name.get()); if (file_exist (path)){ sprintf (buferr ,MSG_U(E_DUPCONF,"The configuration %s\n" "already exist\n" "Use another name\n\n") ,name.get()); nof = 0; } } if (name.is_empty()){ strcat (buferr,MSG_U(E_NEEDNAME,"You must supply\n" "a configuration name\n\n")); nof = 0; } if (device.is_empty() && type != TYPE_PPP_SSH && type != TYPE_PLIP1 && type != TYPE_PLIP2){ strcat (buferr,MSG_U(E_NEEDDEV,"You must supply " "a device (/dev/xxxx)\n\n")); nof = field_device; } if (!lcpecho_valid ()){ strcat (buferr,MSG_U(E_LCPECHO,"You must supply a value pair\n" " delay,retry for the LCP echo protocol")); nof = field_lcpecho; } if (type == TYPE_PPP_SSH){ #if 0 if (ourip.is_empty() || remoteip.is_empty()){ strcat (buferr,MSG_U(E_PPPNEEDIP ,"You must enter an IP number for each side\n" " of the connexion\n")); } #endif if (ssh.host.is_empty() || ssh.user.is_empty() || ssh.pppd_path.is_empty()){ strcat (buferr,MSG_U(E_SSHSECT ,"You must fill all fields (except encryption)\n" "of the PPP over SSH section\n")); nof = field_ssh; } } int ret = 0; if (buferr[0] != '\0'){ xconf_error (buferr); ret = -1; } return ret; } /* Add one IP route definition in the dialog */ PRIVATE void PPPONE::setdia_iproute (DIALOG &dia, int no) { PPPIPROUTE *ir = iproutes.getitem(no); dia.newf_str (MSG_U(F_IPDST,"Network or host"),ir->dest); dia.newf_str (MSG_U(F_IPMSK,"Netmask(opt)"),ir->mask); } static char privi_changed = 0; /* Trigger a probe of a modem */ static int ppp_probeserial (SSTRING &dev) { int ret = -1; DEVCONF_API *tbapi[MAX_API_PROVIDERS]; int nbapi = devconf_apis_init ("gurus/network",tbapi); for (int i=0; iprobe (DEVCONF_MODEM,tbs)>0){ ret = 0; dev.setfrom (tbs.getitem(0)->get()); break; } } devconf_apis_end(tbapi,nbapi); if (ret == -1){ xconf_error (MSG_U(E_NOMODEM,"No modem found")); } return ret; } PUBLIC int PPPONE::edit () { int ret = -1; DIALOG dia; SSTRING oldname (name); dia.newf_title (MSG_U(N_BASE,"Base info"),1,"",MSG_R(N_BASE)); int field_name = dia.getnb(); dia.newf_str (MSG_U(F_PPPNAME,"Configuration name"),name); dia.newf_radio (MSG_U(F_CONNECTTYPE,"Connection type"),type ,TYPE_PPP_SERIAL ,MSG_U(F_PPPSERIAL,"PPP using serial port/modem")); dia.newf_radio ("",type,TYPE_PPP_SSH ,MSG_U(F_PPPSSH,"PPP over a secure shell (ssh)")); dia.newf_radio ("",type,TYPE_SLIP,MSG_U(F_SLIP,"SLIP")); dia.newf_radio ("",type,TYPE_PLIP1 ,MSG_U(F_PLIP1,"PLIP1 (IP over printer port 1)")); dia.newf_radio ("",type,TYPE_PLIP2 ,MSG_U(F_PLIP2,"PLIP2 (IP over printer port 2)")); static const char *tbauth[]={ MSG_U(F_PPP_LOGIN,"Login"), MSG_U(F_PPP_PAP,"PAP"), MSG_U(F_PPP_CHAP,"CHAP"), MSG_U(F_PPP_NONE,"None"), NULL }; dia.newf_chkm (MSG_U(F_PPPAUTH,"PPP authentication"),pppauth,tbauth); static const char *tbuse[]={ MSG_U(F_PPP_MANUAL,"Manual"), MSG_U(F_PPP_DEMAND,"On demand"), MSG_U(F_PPP_24on24,"On boot"), NULL }; dia.newf_chkm (MSG_U(F_PPPTYPE,"Operation mode"),usetype,tbuse); dia.newf_str (MSG_U(F_OURIP,"Our IP number(opt)"),ourip); dia.newf_str (MSG_U(F_REMOTEIP,"Remote IP number(opt)"),remoteip); dia.newf_str (MSG_U(F_LOGIN,"login"),login); SSTRING newpasswd,newpasswd2; int field_newpass = dia.getnb(); dia.newf_pass (MSG_U(F_PASSWORD,"Password"),newpasswd); dia.newf_pass (MSG_U(F_PASSWORD2,"Password (Confirm)"),newpasswd2); dia.newf_title (MSG_U(T_LOGINCHAT,"Chat"),1,"",MSG_R(T_LOGINCHAT)); dia.newf_str (MSG_U(F_LOGINKEY,"Expected login key"),loginkey); dia.newf_str (MSG_U(F_PASSWDKEY,"Expected password key"),passwdkey); dia.newf_str (MSG_U(F_LOGINOK,"Expected welcome (opt)"),loginok); dia.newf_str (MSG_U(F_TRIGGER,"Trigger command (opt)"),trigger); dia.newf_str (MSG_U(F_LOGINFAIL,"Login fail key (opt)"),loginfail); dia.newf_str (MSG_U(F_LOGINCHAT,"Custom login chat (opt)"),loginchat); dia.newf_str (MSG_U(F_ALTCHAT,"Alternat chat script"),chatscript); dia.newf_title (MSG_U(N_MODEM,"Modem"),1,"" ,MSG_U(T_MODEM,"Modem specifications")); int field_device = dia.getnb(); serial_setfield (device,dia); PRIVATE_MESSAGE msg_probe; dia.new_button (MSG_U(B_PROBE,"Detect modem"),"",msg_probe); dia.newf_str (MSG_U(F_MODEMCHAT,"Modem initialisation"),modeminit); dia.newf_str (MSG_U(F_PHONE,"Phone"),phone); dia.newf_chk ("",modem,MSG_U(F_MODEMCTRL,"Modem controls")); dia.newf_chk ("",lock,MSG_U(F_LOCKFILE,"Lock file")); SSTRING baudstr; baud_setfield (baud,baudstr,dia); dia.newf_title (MSG_U(T_FEATURES,"Features"),1,"",MSG_R(T_FEATURES)); { static const char *tbidle[]={MSG_U(I_NOTIMEOUT,"No timeout"),NULL}; static const char *tbdef[]={MSG_U(I_USEDEFAULT,"Use default"),NULL}; static const int tbv[]={0,0}; dia.newf_chkm_num (MSG_U(F_IDLETIME,"Idle time"),idletime,tbv,tbidle); dia.newf_chkm_num (MSG_U(F_PPPMRU,"PPP MRU"),mru,tbv,tbdef); dia.newf_chkm_num (MSG_U(F_PPPMTU,"PPP MTU(opt)"),mtu,tbv,tbdef); } dia.newf_chk ("",dbgppp,MSG_U(F_RUNPPPD,"Run pppd in debug mode")); dia.newf_chk ("",dbgchat,MSG_U(F_RUNCHAT,"Run chat in debug mode")); dia.newf_str (MSG_U(F_ASYNCMAP,"Async map"),asyncmap); int field_lcpecho = dia.getnb(); FIELD_COMBO *cecho = dia.newf_combo (MSG_U(F_LCPECHO,"LCP echo"),lcpecho); cecho->addopt ("",MSG_U(F_NOLCPECHO,"Don't use LCP echo protocol")); cecho->addopt ("15,3",MSG_U(F_ECHO15_3,"Send lcp echo every 15, hangup after 3 failures")); dia.newf_str (MSG_U(F_OTHERPPP,"Other PPP options"),options); dia.newf_chk (MSG_U(F_FIREWALL,"Update"),firewall ,MSG_U(I_FIREWALL,"the firewall rules")); dia.newf_title (MSG_U(T_SCRIPTS,"Scripts"),1,"",MSG_R(T_SCRIPTS)); dia.newf_str (MSG_U(F_PRECONCMD,"Pre-connect cmd(opt)"),preconcmd); dia.newf_str (MSG_U(F_CONCMD,"Post-connect cmd(opt)"),postconcmd); dia.newf_str (MSG_U(F_PREDISCMD,"Pre-disconnect cmd(opt)"),prediscmd); dia.newf_str (MSG_U(F_DISCMD,"Post-disconnect cmd(opt)"),postdiscmd); dia.newf_title (MSG_U(N_PPPIPXCONF,"Ipx"),1,"" ,MSG_U(T_PPPIPXCONF,"IPX options")); dia.newf_chk ("",ipx.enable,MSG_U(F_PPPIPXENABLE,"Enable IPX over PPP")); dia.newf_hexnum (MSG_U(F_PPPIPXNETNUM,"Network number"),ipx.netnum); dia.newf_hexnum (MSG_U(F_PPPIPXLOCALNUM,"Local node number"),ipx.localnum); dia.newf_hexnum (MSG_U(F_PPPIPXREMOTENUM,"Remote node number"),ipx.remotenum); dia.newf_chk ("",ipx.routingrip,MSG_U(F_PPPIPXRIPSAP,"Enable RIP and SAP routing")); dia.newf_chk ("",ipx.routingnlsp,MSG_U(F_PPPIPXNLSP,"Enable NLSP routing")); dia.newf_str (MSG_U(F_PPPIPXOPTIONS,"Other ipx options"),ipx.options); dia.newf_title (MSG_U(N_PPPSSH,"SSH"),1,"" ,MSG_U(T_PPPSSH,"PPP over SSH")); int field_ssh = dia.getnb(); dia.newf_str (MSG_U(F_SSHHOST,"Ssh server"),ssh.host); dia.newf_str (MSG_U(F_SSHUSER,"Account"),ssh.user); static const char *tbacctype[]={ MSG_U(F_ACCTPPP,"PPP account"), MSG_U(F_ACCTSHELL,"Shell account"), NULL }; dia.newf_chkm (MSG_U(F_ACCTYPE,"Account type"),ssh.via_shell,tbacctype); FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_ENCRYPT,"Encryption type") ,ssh.encrypt); static const char *tbcrypt[][2]={ {"", MSG_U(O_CRYPTDEF,"Use the default available")}, {"none", MSG_U(O_CRYPTNONE,"No encryption")}, {"idea", MSG_U(O_CRYPTIDEA,"")}, {"des", MSG_U(O_CRYPTDES,"")}, {"3des", MSG_U(O_CRYPT3DES,"")}, {"arcfour", MSG_U(O_CRYPTFOUR,"")}, {"tss", MSG_U(O_CRYPTTSS,"")}, }; for (unsigned i=0; iaddopt (tbcrypt[i][0],tbcrypt[i][1]); } dia.newf_chk (MSG_U(F_COMPRESS,"Compression"),ssh.compress ,MSG_U(F_ENABLE,"Enabled")); dia.newf_str (MSG_U(F_OTHERPPPD,"Path of the remote pppd"),ssh.pppd_path); static const char *tbusepatch[]={ MSG_U(F_NO,"No"), MSG_U(F_YES,"Yes"), NULL }; dia.newf_chkm (MSG_U(F_USEPATCH,"Using patched SSH?"),ssh.use_patch,tbusepatch); dia.newf_title (MSG_U(T_IPROUTING,"Routing"),1,"",MSG_R(T_IPROUTING)); dia.newf_chk ("",defaultroute,MSG_U(F_DEFROUTE,"Default route")); dia.newf_chk ("",proxyarp ,MSG_U(F_PROXYARP,"Proxy Arp (fake remote on local net)")); iproutes.add (new PPPIPROUTE); iproutes.add (new PPPIPROUTE); for (int r=0; rget(); char id[PATH_MAX]; sprintf (id,"dialout_%s",dname); tb.add (new PRIVILEGE (id,dname ,MSG_U(T_PPPPRIV,"Dialout (PPP)"))); } } } static PRIVILEGE_DECLARATOR ppp_decl(ppp_setprivi); PRIVILEGE *ppp_lookuppriv (const char *config) { ppp_setprivi(); char id[PATH_MAX]; sprintf (id,"dialout_%s",config); return privilege_lookup (id); } /* Return the list of all PPP/dialup configuration files */ int ppp_getlist (SSTRINGS &lst) { dir_getlist (ETC_PPP,".dconf",lst); pppdial_getlist (lst); return lst.getnb(); } /* Format the dialog allowing PPP config selection */ static int ppp_setupdia (DIALOG &dia, SSTRINGS &lst) { int nb = ppp_getlist (lst); lst.sort(); if (dia.getnb()==0){ dia.newf_head ("",MSG_U(T_PPPHEAD,"Config\tType\tOperation mode\tStatus")); } for (int i=0; iget(); PPPONE one (name); const char *conmsg = ""; char status[20]; if (ppphook_status != NULL){ conmsg = status; (*ppphook_status) (name,status); }else if (one.getpppd_pid()!=-1){ conmsg = MSG_U(F_CONNECTED,"Connected"); } static const char *tbauth[]={ MSG_R(F_PPP_LOGIN), MSG_R(F_PPP_PAP), MSG_R(F_PPP_CHAP), MSG_R(F_PPP_NONE), NULL }; static const char *tbuse[]={ MSG_R(F_PPP_MANUAL), MSG_R(F_PPP_DEMAND), MSG_R(F_PPP_24on24), NULL }; char buf[100]; sprintf (buf,"%s\t%s\t%s",tbauth[one.pppauth],tbuse[one.usetype] ,conmsg); dia.set_menuitem (i,name,buf); } dia.remove_last (nb+1); return nb; } /* Edit the PPP/dialup configurations */ void ppp_edit () { static const char *msg = MSG_U(P_CONFPPP,"configure PPP and SLIP"); if (perm_rootaccess(msg)){ int choice = 0; DIALOG_LISTE dia; dia.addwhat (MSG_U(I_ADDCONF,"Select [Add] to add a new configuration")); while (1){ SSTRINGS lst; ppp_setupdia (dia,lst); MENU_STATUS code = dia.editmenu( MSG_U(T_PPPCONF,"PPP/SLIP configuration") ,MSG_U(I_PPPCONF,"You are allowed to edit/add\n" "PPP and SLIP configuration\n" "which will allow your computer to connect\n" "to PPP and SLIP server") ,help_ppp ,choice ,MENUBUT_ADD); SSTRING *sel = lst.getitem(choice); if (code == MENU_ESCAPE || code == MENU_QUIT){ break; }else if (perm_rootaccess(msg)){ int edcode = -1; if (code == MENU_ADD){ PPPONE one (NULL); edcode = one.edit (); }else if (sel != NULL){ if (code == MENU_OK){ PPPONE one (sel->get()); edcode = one.edit (); } } } } } } PPPONE *ppp_getconfig (const char *name) { PPPONE *ret = NULL; if (perm_access(ppp_lookuppriv(name) ,MSG_U(P_ACTLINK,"activate a network link"))){ ret = new PPPONE (name); if (!ret->exist){ xconf_error (MSG_U(E_NOCONF,"No configuration %s"),name); delete ret; ret = NULL; } } return ret; } static PPPONE *ppp_getconfig (int argc, char *argv[]) { PPPONE *ret = NULL; if (argc == 1) ret = ppp_getconfig(argv[0]); return ret; } /* Establish a PPP/SLIP connnection */ int ppp_connect (int argc, char *argv[]) { int ret = -1; int fore = 0; if (argc == 2){ argc--; if (strcmp(argv[1],"--fore")==0){ fore = 1; }else{ xconf_error (MSG_U(E_IVLOPTION ,"Invalid option\n" "netconf --connect site [ --fore ]")); } } PPPONE *one = ppp_getconfig (argc,argv); if (one != NULL){ ret = one->connect (fore); delete one; } return ret; } static int ppp_disconnect(const char *config) { int ret = -1; PPPONE *one = ppp_getconfig (config); if (one != NULL){ if (one->getpppd_pid()!=-1){ ret = one->disconnect (); } delete one; } return ret; } /* Kill a PPP/SLIP connnection */ int ppp_disconnect (int argc, char *argv[]) { int ret = -1; for (int i=0; iget()); } }else{ ret |= ppp_disconnect (config); } } return ret; } /* Complete a PPP/SLIP connection */ int ppp_postconnect (int argc, char *argv[]) { int ret = -1; if (getuid()!=0){ fprintf (stderr,MSG_U(E_POSTCONUID,"netconf --postconnect can only be used by root\n")); }else if (argc == 3){ const char *verb = argv[0]; const char *config = argv[1]; const char *dev = argv[2]; if (strcmp(verb,linuxconf_dialout)==0){ PPPONE *one = ppp_getconfig (config); if (one != NULL){ ret = one->postconnect (dev); delete one; } }else if (strcmp(verb,linuxconf_dialin)==0){ } }else{ fprintf (stderr,MSG_U(E_POSTCONUSAGE ,"Invalid usage\n" "netconf --postconnect linuxconf_dialout ppp_config ppp_device\n" "netconf --postconnect linuxconf_dialin user_account ppp_device\n")); } return ret; } /* Do some tasks before the end of a PPP/SLIP connection */ int ppp_predisconnect (int argc, char *argv[]) { int ret = -1; if (getuid()!=0){ fprintf (stderr,MSG_U(E_PRECONUID,"netconf --predisconnect can only be used by root\n")); }else if (argc == 3){ const char *verb = argv[0]; const char *config = argv[1]; const char *dev = argv[2]; if (strcmp(verb,linuxconf_dialout)==0){ PPPONE *one = ppp_getconfig (config); if (one != NULL){ ret = one->predisconnect (dev); delete one; } }else if (strcmp(verb,linuxconf_dialin)==0){ } }else{ fprintf (stderr,MSG_U(E_PREDISCONUSAGE ,"Invalid usage\n" "netconf --predisconnect linuxconf_dialout ppp_config ppp_device\n" "netconf --predisconnect linuxconf_dialin user_account ppp_device\n")); } return ret; } #if 0 PUBLIC PPPONE *PPPONES::getitem(int no) { return (PPPONE*)ARRAY::getitem(no); } #endif /* Let the user start or stop the link */ PUBLIC void PPPONE::control() { if (getpppd_pid() == -1){ if (dialog_yesno(MSG_U(Q_DOCONN,"Activate PPP link") ,MSG_U(I_DOCONN ,"Do you want to activate the network link ?") ,help_nil)==MENU_YES){ connect(0); } }else{ if (dialog_yesno(MSG_U(Q_DODISCONN,"Terminate PPP link") ,MSG_U(I_DODISCONN ,"Do you want to terminate the network link ?") ,help_nil)==MENU_YES){ disconnect(); for (int i=0; i<4; i++){ sleep(1); if (getpppd_pid() == -1){ break; } } } } } /* Control panel allowing connection and disconnection of PPP dialout */ void ppp_control () { int choice = 0; DIALOG_LISTE dia; while (1){ SSTRINGS lst; int nb = ppp_setupdia(dia,lst); MENU_STATUS code = dia.editmenu( MSG_U(T_PPPCONCTRL,"PPP/SLIP connection control") ,MSG_U(I_PPPCONCTRL,"You are allowed to activate/deactivate\n" "PPP and SLIP link\n") ,help_ppp ,choice ,0); if (code == MENU_ESCAPE || code == MENU_QUIT){ break; }else if (choice >= 0 && choice < nb){ const char *sel = lst.getitem(choice)->get(); PRIVILEGE *privi = ppp_lookuppriv (sel); if (perm_access(privi,MSG_U(P_CTLDIALOUT,"control dialout"))){ PPPONE one (sel); one.control(); } } } } /* Erase some work file used by ppp dialout at boot time */ void ppp_bootcleanup () { SSTRINGS lst; int nb = ppp_getlist (lst); lst.sort(); net_prtlog (NETLOG_TITLE,MSG_U(T_PPPCLEANUP ,"Cleaning up PPP pid file\n")); for (int i=0; iget(); PPPONE one (name); one.delpidfile(); // Remove the control file for "on boot" configuration char pathwatch[PATH_MAX]; sprintf (pathwatch,"%s.%s",VAR_RUN_PPPRESTART,name); unlink (pathwatch); } } const char ppp_dialout[]="dialout"; /* Create CONFIG_FILE object for each PPP dialout configs */ static void ppp_listcfg() { SSTRINGS lst; int n = ppp_getlist (lst); for (int i=0; iget()); new CONFIG_FILE (path,help_ppp,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,ppp_dialout); } } static CONFIG_FILE_LISTER lister (ppp_listcfg); static LINUXCONF_SUBSYS subb (ppp_dialout ,P_MSG_U(M_PPPDIALOUT,"PPP/Slip dialout")); class CONFIG_FILE_PPPLIST: public CONFIG_FILE{ /*~PROTOBEG~ CONFIG_FILE_PPPLIST */ public: CONFIG_FILE_PPPLIST (void); int archive (SSTREAM&ss)const; int extract (SSTREAM&ss); /*~PROTOEND~ CONFIG_FILE_PPPLIST */ }; PUBLIC CONFIG_FILE_PPPLIST::CONFIG_FILE_PPPLIST() : CONFIG_FILE (ETC_PPP "/dconf.list",help_nil,CONFIGF_VIRTUAL,ppp_dialout) { } PUBLIC int CONFIG_FILE_PPPLIST::archive(SSTREAM &ss) const { configf_sendexist (ss,true); SSTRINGS lst; int n = ppp_getlist (lst); for (int i=0; iget()); } return 0; } PUBLIC int CONFIG_FILE_PPPLIST::extract(SSTREAM &ss) { SSTRINGS tb; char path[PATH_MAX]; while (ss.gets(path,sizeof(path)-1) != NULL){ strip_end (path); tb.add (new SSTRING (path)); } for (int i=0; iget(); CONFIG_FILE conf (path,help_nil,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,ppp_dialout); conf.extract(); } return 0; } static CONFIG_FILE_PPPLIST ppplist; static HELP_FILE help_privi ("dialout","privileges"); static REGISTER_PRIVI_HELP p (help_privi ,P_MSG_U(T_USERPRIVI,"Privileges: Dialout (PPP)")); static bool ppp_devexist (const char *devname) { bool ret = false; if (strncmp(devname,"dialout/",8)==0){ devname += 8; SSTRINGS lst; int n = ppp_getlist (lst); for (int i=0; icmp(devname)==0){ ret = true; break; } } } return ret; } static int ppp_getdevlist (SSTRINGS &devs, SSTRINGS &descs) { SSTRINGS lst; int n = ppp_getlist (lst); for (int i=0; iget(); s->setfromf ("dialout/%s",c); d->setfromf (MSG_U(I_DIALDEVDESC,"Dialout configuration %s"),c); devs.add (s); descs.add (d); } return n; } static int ppp_getdevinfo (const char *devname, SSTRINGS &kerneldevs) { int ret = -1; if (strncmp(devname,"dialout/",8)==0){ PPPONE one (devname+8); char pppdev[8]; if (one.getpppd_info (pppdev) != -1){ kerneldevs.add (new SSTRING(pppdev)); ret = 0; } } return ret; } /* A logical host correspond to the local IP of the ppp connection */ static bool ppp_hostexist (const char *hostname) { return ppp_devexist(hostname); } static int ppp_gethostlist (SSTRINGS &devs, SSTRINGS &descs) { return ppp_getdevlist (devs,descs); } static int ppp_gethostinfo (const char *host, SSTRINGS &tb) { int ret = -1; if (strncmp(host,"dialout/",8)==0){ PPPONE one (host+8); char pppdev[8]; IFCONFIG_INFO info; if (one.getpppd_info (pppdev) != -1 && ifconfig_getinfo (pppdev,info)!=-1){ tb.add (new SSTRING(info.ip_addr)); ret = 0; } } return ret; } void *dialout_fwinfo_api_get() { FWINFO_API *api = new FWINFO_API; api->devexist = ppp_devexist; api->getdevlist = ppp_getdevlist; api->getdevinfo = ppp_getdevinfo; api->hostexist = ppp_hostexist; api->gethostlist = ppp_gethostlist; api->gethostinfo = ppp_gethostinfo; return api; } void dialout_fwinfo_api_release(void *api) { delete (FWINFO_API*)api; } static void ppp_editone(const char *config, bool setting) { char path[PATH_MAX]; sprintf (path,"%s/%s.dconf",ETC_PPP,config); if (file_exist(path) || setting){ PPPONE one (config); one.edit(); } } static void ppp_listconfig (SSTRINGS &tb) { dir_getlist (ETC_PPP,".dconf",tb); } static PUBLISH_VARIABLES_MSG dialout_var_list[]={ {"phone",P_MSG_R(F_PHONE)}, {"device",P_MSG_R(F_SERIALDEF)}, {"login",P_MSG_R(F_LOGIN)}, {"password",P_MSG_R(F_PASSWORD)}, {"connectmode",P_MSG_R(F_PPPAUTH)}, {"operationmode",P_MSG_R(F_PPPTYPE)}, {"loginkey",P_MSG_R(F_LOGINKEY)}, {"passwordkey",P_MSG_R(F_PASSWDKEY)}, {"welcomekey",P_MSG_R(F_LOGINOK)}, {"trigger",P_MSG_R(F_TRIGGER)}, {"loginfail",P_MSG_R(F_LOGINFAIL)}, {"customchat",P_MSG_R(F_LOGINCHAT)}, {"alternatchat",P_MSG_R(F_ALTCHAT)}, {"modeminit",P_MSG_R(F_MODEMCHAT)}, {"modemcontrol",P_MSG_R(F_MODEMCTRL)}, {"lockfile",P_MSG_R(F_LOCKFILE)}, {"baudrate",P_MSG_R(F_BAUD)}, {"idletime",P_MSG_R(F_IDLETIME)}, {"pppmru",P_MSG_R(F_PPPMRU)}, {"pppmtu",P_MSG_R(F_PPPMTU)}, {"debugpppd",P_MSG_R(F_RUNPPPD)}, {"debugchat",P_MSG_R(F_RUNCHAT)}, {"asyncmap",P_MSG_R(F_ASYNCMAP)}, {"lcpecho",P_MSG_R(F_LCPECHO)}, {"pppdoptions",P_MSG_R(F_OTHERPPP)}, {"updatefirewall",P_MSG_R(F_FIREWALL)}, {"preconcmd",P_MSG_R(F_PRECONCMD)}, {"postconcmd",P_MSG_R(F_CONCMD)}, {"prediscmd",P_MSG_R(F_PREDISCMD)}, {"postdiscmd",P_MSG_R(F_DISCMD)}, {"sshhost",P_MSG_R(F_SSHHOST)}, {"sshuser",P_MSG_R(F_SSHUSER)}, {"accttype",P_MSG_R(F_ACCTYPE)}, {"encrypttype",P_MSG_R(F_ENCRYPT)}, {"compress",P_MSG_R(F_COMPRESS)}, {"pppdpath",P_MSG_R(F_OTHERPPPD)}, {"usingpatchedssh",P_MSG_R(F_USEPATCH)}, {"defaultroute",P_MSG_R(F_DEFROUTE)}, {"proxyarp",P_MSG_R(F_PROXYARP)}, { NULL, NULL } }; static REGISTER_VARIABLES dialout_registry("dialout","config" ,dialout_var_list,NULL,ppp_editone,ppp_listconfig);