Annotation of embedaddon/mpd/src/web.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * web.c
                      4:  *
                      5:  * Written by Alexander Motin <mav@FreeBSD.org>
                      6:  */
                      7: 
                      8: #include "ppp.h"
                      9: #include "web.h"
                     10: #include "util.h"
                     11: 
                     12: 
                     13: /*
                     14:  * DEFINITIONS
                     15:  */
                     16: 
                     17:   /* Set menu options */
                     18:   enum {
                     19:     SET_OPEN,
                     20:     SET_CLOSE,
                     21:     SET_SELF,
                     22:     SET_DISABLE,
                     23:     SET_ENABLE
                     24:   };
                     25: 
                     26: 
                     27: /*
                     28:  * INTERNAL FUNCTIONS
                     29:  */
                     30: 
                     31:   static int   WebSetCommand(Context ctx, int ac, char *av[], void *arg);
                     32: 
                     33:   static int   WebServletRun(struct http_servlet *servlet,
                     34:                          struct http_request *req, struct http_response *resp);
                     35:   static void  WebServletDestroy(struct http_servlet *servlet);
                     36: 
                     37:   static void  WebLogger(int sev, const char *fmt, ...);
                     38: 
                     39:   static void  WebConsoleSessionWrite(ConsoleSession cs, const char *fmt, ...);
                     40:   static void  WebConsoleSessionWriteV(ConsoleSession cs, const char *fmt, va_list vl);
                     41:   static void  WebConsoleSessionShowPrompt(ConsoleSession cs);
                     42: 
                     43:   static void  WebRunBinCmd(FILE *f, const char *query, int priv);
                     44:   static void  WebRunCmd(FILE *f, const char *query, int priv);
                     45:   static void  WebShowSummary(FILE *f, int priv);
                     46: 
                     47: /*
                     48:  * GLOBAL VARIABLES
                     49:  */
                     50: 
                     51:   const struct cmdtab WebSetCmds[] = {
                     52:     { "open",                  "Open the web" ,
                     53:        WebSetCommand, NULL, 2, (void *) SET_OPEN },
                     54:     { "close",                 "Close the web" ,
                     55:        WebSetCommand, NULL, 2, (void *) SET_CLOSE },
                     56:     { "self {ip} [{port}]",    "Set web ip and port" ,
                     57:        WebSetCommand, NULL, 2, (void *) SET_SELF },
                     58:     { "enable [opt ...]",      "Enable web option" ,
                     59:        WebSetCommand, NULL, 2, (void *) SET_ENABLE },
                     60:     { "disable [opt ...]",     "Disable web option" ,
                     61:        WebSetCommand, NULL, 2, (void *) SET_DISABLE },
                     62:     { NULL },
                     63:   };
                     64: 
                     65: 
                     66: /*
                     67:  * INTERNAL VARIABLES
                     68:  */
                     69: 
                     70:   static const struct confinfo gConfList[] = {
                     71:     { 0,       WEB_AUTH,       "auth"  },
                     72:     { 0,       0,              NULL    },
                     73:   };
                     74: 
                     75:   static struct pevent_ctx *gWebCtx = NULL;
                     76:     
                     77: /*
                     78:  * WebInit()
                     79:  */
                     80: 
                     81: int
                     82: WebInit(Web w)
                     83: {
                     84:   /* setup web-defaults */
                     85:   memset(w, 0, sizeof(*w));
                     86: 
                     87:   Enable(&w->options, WEB_AUTH);  
                     88:   
                     89:   ParseAddr(DEFAULT_WEB_IP, &w->addr, ALLOW_IPV4|ALLOW_IPV6);
                     90:   w->port = DEFAULT_WEB_PORT;
                     91: 
                     92:   return 0;
                     93: }
                     94: 
                     95: /*
                     96:  * WebOpen()
                     97:  */
                     98: 
                     99: int
                    100: WebOpen(Web w)
                    101: {
                    102:   char         addrstr[INET6_ADDRSTRLEN];
                    103: 
                    104:   if (w->srv) {
                    105:     Log(LG_ERR, ("web: web already running"));
                    106:     return -1;
                    107:   }
                    108: 
                    109:   gWebCtx = pevent_ctx_create(MB_WEB, NULL);
                    110:   if (!gWebCtx) {
                    111:     Log(LG_ERR, ("%s: error pevent_ctx_create: %d", __FUNCTION__, errno));
                    112:     return(-1);
                    113:   }
                    114:   
                    115:   if (!(w->srv = http_server_start(gWebCtx, w->addr.u.ip4,
                    116:            w->port, NULL, "mpd web server", WebLogger))) {
                    117:     Log(LG_ERR, ("%s: error http_server_start: %d", __FUNCTION__, errno));
                    118:     return(-1);
                    119:   }
                    120: 
                    121:   w->srvlet.arg=NULL;
                    122:   w->srvlet.hook=NULL;
                    123:   w->srvlet.run=WebServletRun;
                    124:   w->srvlet.destroy=WebServletDestroy;
                    125:           
                    126:   if (http_server_register_servlet(w->srv, &w->srvlet, NULL, ".*", 10) < 0) {
                    127:     Log(LG_ERR, ("%s: error http_server_register_servlet: %d", __FUNCTION__, errno));
                    128:     return(-1);
                    129:   }
                    130:   
                    131:   Log(LG_ERR, ("web: listening on %s %d", 
                    132:        u_addrtoa(&w->addr,addrstr,sizeof(addrstr)), w->port));
                    133:   return 0;
                    134: }
                    135: 
                    136: /*
                    137:  * WebClose()
                    138:  */
                    139: 
                    140: int
                    141: WebClose(Web w)
                    142: {
                    143:   if (!w->srv) {
                    144:     Log(LG_ERR, ("web: web is not running"));
                    145:     return -1;
                    146:   }
                    147: 
                    148:   http_server_stop(&w->srv);
                    149:   if (gWebCtx) pevent_ctx_destroy(&gWebCtx);
                    150:   
                    151:   return 0;
                    152: }
                    153: 
                    154: /*
                    155:  * WebStat()
                    156:  */
                    157: 
                    158: int
                    159: WebStat(Context ctx, int ac, char *av[], void *arg)
                    160: {
                    161:   Web          w = &gWeb;
                    162:   char         addrstr[64];
                    163: 
                    164:   Printf("Web configuration:\r\n");
                    165:   Printf("\tState         : %s\r\n", w->srv ? "OPENED" : "CLOSED");
                    166:   Printf("\tIP-Address    : %s\r\n", u_addrtoa(&w->addr,addrstr,sizeof(addrstr)));
                    167:   Printf("\tPort          : %d\r\n", w->port);
                    168: 
                    169:   Printf("Web options:\r\n");
                    170:   OptStat(ctx, &w->options, gConfList);
                    171: 
                    172:   return 0;
                    173: }
                    174: 
                    175: /*
                    176:  * ConsoleSessionWriteV()
                    177:  */
                    178: 
                    179: static void 
                    180: WebConsoleSessionWriteV(ConsoleSession cs, const char *fmt, va_list vl)
                    181: {
                    182:   vfprintf((FILE *)(cs->cookie), fmt, vl);
                    183: }
                    184: 
                    185: /*
                    186:  * WebConsoleSessionWrite()
                    187:  */
                    188: 
                    189: static void 
                    190: WebConsoleSessionWrite(ConsoleSession cs, const char *fmt, ...)
                    191: {
                    192:   va_list vl;
                    193: 
                    194:   va_start(vl, fmt);
                    195:   WebConsoleSessionWriteV(cs, fmt, vl);
                    196:   va_end(vl);
                    197: }
                    198: 
                    199: /*
                    200:  * WebConsoleShowPrompt()
                    201:  */
                    202: 
                    203: static void
                    204: WebConsoleSessionShowPrompt(ConsoleSession cs)
                    205: {
                    206:     if (cs->context.lnk)
                    207:        cs->write(cs, "[%s] ", cs->context.lnk->name);
                    208:     else if (cs->context.bund)
                    209:        cs->write(cs, "[%s] ", cs->context.bund->name);
                    210:     else if (cs->context.rep)
                    211:        cs->write(cs, "[%s] ", cs->context.rep->name);
                    212:     else
                    213:        cs->write(cs, "[] ");
                    214: }
                    215: 
                    216: static void
                    217: WebShowCSS(FILE *f)
                    218: {
                    219:   fprintf(f, "body {font-family: Arial, Helvetica, Sans-Serif; background-color: #EEEEEE; }\n");
                    220:   fprintf(f, "table {background-color: #FFFFFF; }\n");
                    221:   fprintf(f, "th, td {padding: 0 2pt 0 2pt; }\n");
                    222:   fprintf(f, "th {background-color: #00B000; }\n");
                    223:   fprintf(f, "td {background-color: #EEEEEE; }\n");
                    224:   fprintf(f, "td.r {background-color: #EECCCC; }\n");
                    225:   fprintf(f, "td.y {background-color: #EEEEBB; }\n");
                    226:   fprintf(f, "td.g {background-color: #BBEEBB; }\n");
                    227:   fprintf(f, "td.d {background-color: #CCCCCC; }\n");
                    228:   fprintf(f, "pre {background-color: #FFFFFF; }\n");
                    229:   fprintf(f, "a, a:visited, a:link { color: blue; }\n");
                    230: }
                    231: 
                    232: static void
                    233: WebShowSummary(FILE *f, int priv)
                    234: {
                    235:   int          b,l;
                    236:   Bund         B;
                    237:   Link         L;
                    238:   Rep          R;
                    239:   char         buf[64],buf2[64];
                    240: 
                    241:   fprintf(f, "<H2>Current status summary</H2>\n");
                    242:   fprintf(f, "<table>\n");
                    243:   fprintf(f, "<TR><TH>Bund</TH><TH colspan=2>Iface</TH><TH>IPCP</TH><TH>IPV6CP</TH><TH>CCP</TH><TH>ECP</TH>"
                    244:             "<TH>Link</TH><TH>LCP</TH><TH>User</TH><TH colspan=2>Device</TH><TH>Peer</TH><TH>IP</TH><TH colspan=3></TH>%s</TR>",
                    245:             priv?"<TH>State</TH>":"");
                    246: #define FSM_COLOR(s) (((s)==ST_OPENED)?"g":(((s)==ST_INITIAL)?"r":"y"))
                    247: #define PHYS_COLOR(s) (((s)==PHYS_STATE_UP)?"g":(((s)==PHYS_STATE_DOWN)?"r":"y"))
                    248:     for (b = 0; b<gNumLinks; b++) {
                    249:        if ((L=gLinks[b]) != NULL && L->bund == NULL && L->rep == NULL) {
                    250:            fprintf(f, "<TR>\n");
                    251:            fprintf(f, "<TD colspan=\"7\">&nbsp;</a></TD>\n");
                    252:            fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20link\">%s</a></TD>\n", 
                    253:                L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->name);
                    254:            fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20lcp\">%s</a></TD>\n", 
                    255:                L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, FsmStateName(L->lcp.fsm.state));
                    256:            fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20auth\">%s</a></TD>\n", 
                    257:                L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->lcp.auth.params.authname);
                    258:            fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
                    259:                L->tmpl?"d":PHYS_COLOR(L->state), L->name, L->type?L->type->name:"");
                    260:            fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
                    261:                L->tmpl?"d":PHYS_COLOR(L->state), L->name, gPhysStateNames[L->state]);
                    262:            if (L->state != PHYS_STATE_DOWN) {
                    263:                PhysGetPeerAddr(L, buf, sizeof(buf));
                    264:                fprintf(f, "<TD>%s</TD>\n", buf);
                    265:                fprintf(f, "<TD></TD>\n");
                    266:                PhysGetCallingNum(L, buf, sizeof(buf));
                    267:                PhysGetCalledNum(L, buf2, sizeof(buf2));
                    268:                if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
                    269:                    fprintf(f, "<TD>%s</TD><TD><=</TD><TD>%s</TD>\n", 
                    270:                        buf2, buf);
                    271:                } else {
                    272:                    fprintf(f, "<TD>%s</TD><TD>=></TD><TD>%s</TD>\n", 
                    273:                        buf, buf2);
                    274:                }
                    275:            } else {
                    276:                fprintf(f, "<TD></TD>\n");
                    277:                fprintf(f, "<TD></TD>\n");
                    278:                fprintf(f, "<TD colspan=3></TD>\n");
                    279:            }
                    280:            if (priv) {
                    281:                if (!L->tmpl) {
                    282:                    switch (L->state) {
                    283:                        case PHYS_STATE_DOWN:
                    284:                            fprintf(f, "<TD><A href=\"/cmd?link%%20%s&amp;open\">[Open]</A></TD>\n",
                    285:                                L->name);
                    286:                            break;
                    287:                        case PHYS_STATE_UP:
                    288:                            fprintf(f, "<TD><A href=\"/cmd?link%%20%s&amp;close\">[Close]</A></TD>\n",
                    289:                                L->name);
                    290:                            break;
                    291:                        default:
                    292:                            fprintf(f, "<TD><A href=\"/cmd?link%%20%s&amp;open\">[Open]</a>&nbsp;<A href=\"/cmd?link%%20%s&amp;close\">[Close]</a></TD>\n", 
                    293:                                L->name, L->name);
                    294:                    }
                    295:                } else {
                    296:                    fprintf(f, "<TD></TD>\n");
                    297:                }
                    298:            }
                    299:            fprintf(f, "</TR>\n");
                    300:        }
                    301:     }
                    302:   for (b = 0; b<gNumBundles; b++) {
                    303:     if ((B=gBundles[b]) != NULL) {
                    304:        int rows = B->n_links?B->n_links:1;
                    305:        int first = 1;
                    306:        fprintf(f, "<TR>\n");
                    307:        fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&amp;show%%20bund\">%s</a></TD>\n", 
                    308:            rows, B->tmpl?"d":(B->iface.up?"g":"r"), B->name, B->name);
                    309:        fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&amp;show%%20iface\">%s</a></TD>\n", 
                    310:            rows, B->tmpl?"d":(B->iface.up?"g":"r"), B->name, B->iface.ifname);
                    311:        fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&amp;show%%20iface\">%s</a></TD>\n", 
                    312:            rows, B->tmpl?"d":(B->iface.up?"g":"r"), B->name, (B->iface.up?"Up":"Down"));
                    313:        fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&amp;show%%20ipcp\">%s</a></TD>\n", 
                    314:            rows, B->tmpl?"d":FSM_COLOR(B->ipcp.fsm.state), B->name,FsmStateName(B->ipcp.fsm.state));
                    315:        fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&amp;show%%20ipv6cp\">%s</a></TD>\n", 
                    316:            rows, B->tmpl?"d":FSM_COLOR(B->ipv6cp.fsm.state), B->name,FsmStateName(B->ipv6cp.fsm.state));
                    317:        fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&amp;show%%20ccp\">%s</a></TD>\n", 
                    318:            rows, B->tmpl?"d":FSM_COLOR(B->ccp.fsm.state), B->name,FsmStateName(B->ccp.fsm.state));
                    319:        fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&amp;show%%20ecp\">%s</a></TD>\n", 
                    320:            rows, B->tmpl?"d":FSM_COLOR(B->ecp.fsm.state), B->name,FsmStateName(B->ecp.fsm.state));
                    321:        if (B->n_links == 0) {
                    322:            fprintf(f, "<TD colspan=\"11\">&nbsp;</a></TD>\n</TR>\n");
                    323:        }
                    324:        for (l = 0; l < NG_PPP_MAX_LINKS; l++) {
                    325:            if ((L=B->links[l]) != NULL) {
                    326:                if (first)
                    327:                    first = 0;
                    328:                else
                    329:                    fprintf(f, "<TR>\n");
                    330:                fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20link\">%s</a></TD>\n", 
                    331:                    L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->name);
                    332:                fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20lcp\">%s</a></TD>\n", 
                    333:                    L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, FsmStateName(L->lcp.fsm.state));
                    334:                fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20auth\">%s</a></TD>\n", 
                    335:                    L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->lcp.auth.params.authname);
                    336:                fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
                    337:                    L->tmpl?"d":PHYS_COLOR(L->state), L->name, L->type?L->type->name:"");
                    338:                fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
                    339:                    L->tmpl?"d":PHYS_COLOR(L->state), L->name, gPhysStateNames[L->state]);
                    340:                if (L->state != PHYS_STATE_DOWN) {
                    341:                    PhysGetPeerAddr(L, buf, sizeof(buf));
                    342:                    fprintf(f, "<TD>%s</TD>\n", buf);
                    343:                    if (L->bund != NULL)
                    344:                        fprintf(f, "<TD>%s</TD>\n", inet_ntoa(L->bund->ipcp.peer_addr));
                    345:                    else
                    346:                        fprintf(f, "<TD></TD>\n");
                    347:                    PhysGetCallingNum(L, buf, sizeof(buf));
                    348:                    PhysGetCalledNum(L, buf2, sizeof(buf2));
                    349:                    if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
                    350:                            fprintf(f, "<TD>%s</TD><TD><=</TD><TD>%s</TD>\n", 
                    351:                                buf2, buf);
                    352:                    } else {
                    353:                            fprintf(f, "<TD>%s</TD><TD>=></TD><TD>%s</TD>\n", 
                    354:                                buf, buf2);
                    355:                    }
                    356:                } else {
                    357:                        fprintf(f, "<TD></TD>\n");
                    358:                        fprintf(f, "<TD></TD>\n");
                    359:                        fprintf(f, "<TD colspan=3></TD>\n");
                    360:                }
                    361:                if (priv) {
                    362:                    switch (L->state) {
                    363:                        case PHYS_STATE_DOWN:
                    364:                            fprintf(f, "<TD><A href=\"/cmd?link%%20%s&amp;open\">[Open]</A></TD>\n",
                    365:                                L->name);
                    366:                            break;
                    367:                        case PHYS_STATE_UP:
                    368:                            fprintf(f, "<TD><A href=\"/cmd?link%%20%s&amp;close\">[Close]</A></TD>\n",
                    369:                                L->name);
                    370:                            break;
                    371:                        default:
                    372:                            fprintf(f, "<TD><A href=\"/cmd?link%%20%s&amp;open\">[Open]</a>&nbsp;<A href=\"/cmd?link%%20%s&amp;close\">[Close]</a></TD>\n", 
                    373:                                L->name, L->name);
                    374:                    }
                    375:                }
                    376:                fprintf(f, "</TR>\n");
                    377:            }
                    378:        }
                    379:     }
                    380:   }
                    381:   for (b = 0; b<gNumReps; b++) {
                    382:     if ((R=gReps[b]) != NULL) {
                    383:        int shown = 0;
                    384: #define FSM_COLOR(s) (((s)==ST_OPENED)?"g":(((s)==ST_INITIAL)?"r":"y"))
                    385: #define PHYS_COLOR(s) (((s)==PHYS_STATE_UP)?"g":(((s)==PHYS_STATE_DOWN)?"r":"y"))
                    386:        int rows = (R->links[0]?1:0) + (R->links[1]?1:0);
                    387:        if (rows == 0)
                    388:            rows = 1;
                    389:        fprintf(f, "<TR>\n");
                    390:        fprintf(f, "<TD rowspan=\"%d\" colspan=6>Repeater</TD>\n", rows);
                    391:        fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?rep%%20%s&amp;show%%20repeater\">%s</a></TD>\n", 
                    392:             rows, R->p_up?"g":"r", R->name, R->name);
                    393:        for (l = 0; l < 2; l++) {
                    394:            if ((L=R->links[l]) != NULL) {
                    395:                if (shown)
                    396:                    fprintf(f, "<TR>\n");
                    397:                fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
                    398:                    PHYS_COLOR(L->state), L->name, L->name);
                    399:                fprintf(f, "<TD colspan=2></TD>\n");
                    400:                fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
                    401:                    PHYS_COLOR(L->state), L->name, L->type?L->type->name:"");
                    402:                fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
                    403:                    PHYS_COLOR(L->state), L->name, gPhysStateNames[L->state]);
                    404:                if (L->state != PHYS_STATE_DOWN) {
                    405:                    PhysGetPeerAddr(L, buf, sizeof(buf));
                    406:                    fprintf(f, "<TD>%s</TD>\n", buf);
                    407:                    if (L->bund != NULL)
                    408:                        fprintf(f, "<TD>%s</TD>\n", inet_ntoa(L->bund->ipcp.peer_addr));
                    409:                    else
                    410:                        fprintf(f, "<TD></TD>\n");
                    411:                    PhysGetCallingNum(L, buf, sizeof(buf));
                    412:                    PhysGetCalledNum(L, buf2, sizeof(buf2));
                    413:                    if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
                    414:                            fprintf(f, "<TD>%s</TD><TD><=</TD><TD>%s</TD>\n", 
                    415:                                buf2, buf);
                    416:                    } else {
                    417:                            fprintf(f, "<TD>%s</TD><TD>=></TD><TD>%s</TD>\n", 
                    418:                                buf, buf2);
                    419:                    }
                    420:                } else {
                    421:                        fprintf(f, "<TD></TD>\n");
                    422:                        fprintf(f, "<TD></TD>\n");
                    423:                        fprintf(f, "<TD colspan=3></TD>\n");
                    424:                }
                    425:                fprintf(f, "<TD></TD>\n");
                    426:                fprintf(f, "</TR>\n");
                    427:                
                    428:                shown = 1;
                    429:            }
                    430:        }
                    431:        if (!shown) {
                    432:            fprintf(f, "<TD colspan = \"11\"></TD>\n");
                    433:            fprintf(f, "</TR>\n");
                    434:        }
                    435:     }
                    436:   }
                    437:   fprintf(f, "</TABLE>\n");
                    438: }
                    439: 
                    440: static void 
                    441: WebRunBinCmd(FILE *f, const char *query, int priv)
                    442: {
                    443:     Console            c = &gConsole;
                    444:     struct console_session css;
                    445:     ConsoleSession     cs = &css;
                    446:     char               *buf;
                    447:     char               *tmp;
                    448:     int                        argc, k;
                    449:     char               *argv[MAX_CONSOLE_ARGS];
                    450:   
                    451:     memset(cs, 0, sizeof(*cs));
                    452: 
                    453:     cs->cookie = f;
                    454:     cs->console = c;
                    455:     cs->close = NULL;
                    456:     cs->write = WebConsoleSessionWrite;
                    457:     cs->writev = WebConsoleSessionWriteV;
                    458:     cs->prompt = WebConsoleSessionShowPrompt;
                    459:     cs->context.cs = cs;
                    460:     cs->context.priv = priv;
                    461: 
                    462:     tmp = buf = Mstrdup(MB_WEB, query);
                    463:     for (argc = 0; (argv[argc] = strsep(&tmp, "&")) != NULL;)
                    464:        if (argv[argc][0] != '\0')
                    465:            if (++argc >= MAX_CONSOLE_ARGS)
                    466:                break;
                    467: 
                    468:     for (k = 0; k < argc; k++) {
                    469:        int     ac, rtn;
                    470:        char    *av[MAX_CONSOLE_ARGS];
                    471:        char    *buf1;
                    472: 
                    473:        buf1 = Malloc(MB_WEB, strlen(argv[k]) + 1);
                    474:        http_request_url_decode(argv[k], buf1);
                    475:         Log2(LG_CONSOLE, ("[%s] WEB: %s", 
                    476:            cs->context.lnk ? cs->context.lnk->name :
                    477:                (cs->context.bund? cs->context.bund->name : ""), 
                    478:            buf1));
                    479:        ac = ParseLine(buf1, av, sizeof(av) / sizeof(*av), 0);
                    480:        cs->context.errmsg[0] = 0;
                    481:        rtn = DoCommandTab(&cs->context, gCommands, ac, av);
                    482:        Freee(buf1);
                    483:        fprintf(f, "RESULT: %d %s\n", rtn, cs->context.errmsg);
                    484:     }
                    485:     Freee(buf);
                    486:     RESETREF(cs->context.lnk, NULL);
                    487:     RESETREF(cs->context.bund, NULL);
                    488:     RESETREF(cs->context.rep, NULL);
                    489: }
                    490: 
                    491: static void 
                    492: WebRunCmd(FILE *f, const char *query, int priv)
                    493: {
                    494:     Console            c = &gConsole;
                    495:     struct console_session css;
                    496:     ConsoleSession     cs = &css;
                    497:     char               *buf;
                    498:     char               *tmp;
                    499:     int                        argc, k;
                    500:     char               *argv[MAX_CONSOLE_ARGS];
                    501:   
                    502:     memset(cs, 0, sizeof(*cs));
                    503: 
                    504:     cs->cookie = f;
                    505:     cs->console = c;
                    506:     cs->close = NULL;
                    507:     cs->write = WebConsoleSessionWrite;
                    508:     cs->writev = WebConsoleSessionWriteV;
                    509:     cs->prompt = WebConsoleSessionShowPrompt;
                    510:     cs->context.cs = cs;
                    511:     cs->context.priv = priv;
                    512: 
                    513:     tmp = buf = Mstrdup(MB_WEB, query);
                    514:     for (argc = 0; (argv[argc] = strsep(&tmp, "&")) != NULL;)
                    515:        if (argv[argc][0] != '\0')
                    516:            if (++argc >= MAX_CONSOLE_ARGS)
                    517:                break;
                    518: 
                    519:     fprintf(f, "<P><A href=\"/\"><< Back</A></P>\n");
                    520: 
                    521:     if (argc == 0) {
                    522:        fprintf(f, "<P>No command cpecified!</P>\n");
                    523:        goto done;
                    524:     }
                    525: 
                    526:     fprintf(f, "<PRE>\n");
                    527:     for (k = 0; k < argc; k++) {
                    528:        int     ac;
                    529:        char    *av[MAX_CONSOLE_ARGS];
                    530:        char    *buf1;
                    531: 
                    532:        buf1 = Malloc(MB_WEB, strlen(argv[k]) + 1);
                    533:        http_request_url_decode(argv[k], buf1);
                    534:         Log2(LG_CONSOLE, ("[%s] WEB: %s", 
                    535:            cs->context.lnk ? cs->context.lnk->name :
                    536:                (cs->context.bund? cs->context.bund->name : ""), 
                    537:            buf1));
                    538: 
                    539:        cs->prompt(cs);
                    540:        cs->write(cs, "%s\n", buf1);
                    541:     
                    542:        ac = ParseLine(buf1, av, sizeof(av) / sizeof(*av), 0);
                    543:        DoCommand(&cs->context, ac, av, NULL, 0);
                    544:        Freee(buf1);
                    545:     }
                    546:     fprintf(f, "</PRE>\n");
                    547: done:
                    548:     Freee(buf);
                    549:     fprintf(f, "<P><A href=\"/\"><< Back</A></P>\n");
                    550:     RESETREF(cs->context.lnk, NULL);
                    551:     RESETREF(cs->context.bund, NULL);
                    552:     RESETREF(cs->context.rep, NULL);
                    553: }
                    554: 
                    555: static void
                    556: WebServletRunCleanup(void *cookie) {
                    557:     GIANT_MUTEX_UNLOCK();
                    558: }
                    559: 
                    560: static int     
                    561: WebServletRun(struct http_servlet *servlet,
                    562:                          struct http_request *req, struct http_response *resp)
                    563: {
                    564:     FILE *f;
                    565:     const char *path;
                    566:     const char *query;
                    567:     int priv = 0;
                    568:     
                    569:     if (Enabled(&gWeb.options, WEB_AUTH)) {
                    570:        const char *username;
                    571:        const char *password;
                    572:        ConsoleUser             u;
                    573:        struct console_user     iu;
                    574: 
                    575:        /* Get username and password */
                    576:        if ((username = http_request_get_username(req)) == NULL)
                    577:            username = "";
                    578:        if ((password = http_request_get_password(req)) == NULL)
                    579:            password = "";
                    580: 
                    581:        strlcpy(iu.username, username, sizeof(iu.username));
                    582:        RWLOCK_RDLOCK(gUsersLock);
                    583:        u = ghash_get(gUsers, &iu);
                    584:        RWLOCK_UNLOCK(gUsersLock);
                    585: 
                    586:        if ((u == NULL) || strcmp(u->password, password)) {
                    587:                http_response_send_basic_auth(resp, "Access Restricted");
                    588:                return (1);
                    589:        }
                    590:        priv = u->priv;
                    591:     }
                    592: 
                    593:     if (!(f = http_response_get_output(resp, 1))) {
                    594:        return 0;
                    595:     }
                    596:     if (!(path = http_request_get_path(req)))
                    597:        return 0;
                    598:     if (!(query = http_request_get_query_string(req)))
                    599:        return 0;
                    600: 
                    601:     if (!strcmp(path,"/mpd.css")) {
                    602:        http_response_set_header(resp, 0, "Content-Type", "text/css");
                    603:        WebShowCSS(f);
                    604:     } else if (!strcmp(path,"/bincmd")) {
                    605:        http_response_set_header(resp, 0, "Content-Type", "text/plain");
                    606:        http_response_set_header(resp, 1, "Pragma", "no-cache");
                    607:        http_response_set_header(resp, 1, "Cache-Control", "no-cache, must-revalidate");
                    608:        
                    609:        pthread_cleanup_push(WebServletRunCleanup, NULL);
                    610:        GIANT_MUTEX_LOCK();
                    611:        WebRunBinCmd(f, query, priv);
                    612:        GIANT_MUTEX_UNLOCK();
                    613:        pthread_cleanup_pop(0);
                    614:     } else if (!strcmp(path,"/") || !strcmp(path,"/cmd")) {
                    615:        http_response_set_header(resp, 0, "Content-Type", "text/html");
                    616:        http_response_set_header(resp, 1, "Pragma", "no-cache");
                    617:        http_response_set_header(resp, 1, "Cache-Control", "no-cache, must-revalidate");
                    618:        
                    619:        pthread_cleanup_push(WebServletRunCleanup, NULL);
                    620:        GIANT_MUTEX_LOCK();
                    621:        fprintf(f, "<!DOCTYPE HTML "
                    622:            "PUBLIC \"-//W3C//DTD HTML 4.01//EN\" "
                    623:            "\"http://www.w3.org/TR/html4/strict.dtd\">\n");
                    624:        fprintf(f, "<HTML>\n");
                    625:        fprintf(f, "<HEAD><TITLE>Multi-link PPP Daemon for FreeBSD (mpd)</TITLE>\n");
                    626:        fprintf(f, "<LINK rel='stylesheet' href='/mpd.css' type='text/css'>\n");
                    627:        fprintf(f, "</HEAD>\n<BODY>\n");
                    628:        fprintf(f, "<H1>Multi-link PPP Daemon for FreeBSD</H1>\n");
                    629:     
                    630:        if (!strcmp(path,"/"))
                    631:            WebShowSummary(f, priv);
                    632:        else if (!strcmp(path,"/cmd"))
                    633:            WebRunCmd(f, query, priv);
                    634:            
                    635:        GIANT_MUTEX_UNLOCK();
                    636:        pthread_cleanup_pop(0);
                    637:        
                    638:        fprintf(f, "</BODY>\n</HTML>\n");
                    639:     } else {
                    640:        http_response_send_error(resp, 404, NULL);
                    641:     }
                    642:     return 1;
                    643: }
                    644: 
                    645: static void    
                    646: WebServletDestroy(struct http_servlet *servlet)
                    647: {
                    648: }
                    649: 
                    650: static void
                    651: WebLogger(int sev, const char *fmt, ...)
                    652: {
                    653:   va_list       args;
                    654: 
                    655:   va_start(args, fmt);
                    656:   vLogPrintf(fmt, args);
                    657:   va_end(args);
                    658: }
                    659: 
                    660: /*
                    661:  * WebSetCommand()
                    662:  */
                    663: 
                    664: static int
                    665: WebSetCommand(Context ctx, int ac, char *av[], void *arg) 
                    666: {
                    667:   Web                  w = &gWeb;
                    668:   int                  port;
                    669: 
                    670:   switch ((intptr_t)arg) {
                    671: 
                    672:     case SET_OPEN:
                    673:       WebOpen(w);
                    674:       break;
                    675: 
                    676:     case SET_CLOSE:
                    677:       WebClose(w);
                    678:       break;
                    679: 
                    680:     case SET_ENABLE:
                    681:        EnableCommand(ac, av, &w->options, gConfList);
                    682:       break;
                    683: 
                    684:     case SET_DISABLE:
                    685:        DisableCommand(ac, av, &w->options, gConfList);
                    686:       break;
                    687: 
                    688:     case SET_SELF:
                    689:       if (ac < 1 || ac > 2)
                    690:        return(-1);
                    691: 
                    692:       if (!ParseAddr(av[0],&w->addr, ALLOW_IPV4)) 
                    693:        Error("Bogus IP address given %s", av[0]);
                    694: 
                    695:       if (ac == 2) {
                    696:         port =  strtol(av[1], NULL, 10);
                    697:         if (port < 1 || port > 65535)
                    698:            Error("Bogus port given %s", av[1]);
                    699:         w->port=port;
                    700:       }
                    701:       break;
                    702: 
                    703:     default:
                    704:       return(-1);
                    705: 
                    706:   }
                    707: 
                    708:   return 0;
                    709: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>