Exemplo n.º 1
0
int srv_check_authtoken(const SRV_LISTENER_CFG_T *pListenCfg, const HTTP_REQ_T *pReq, int allowcomma) {
  int rc = 0;
  const char *parg = NULL;
  char buf[KEYVAL_MAXLEN];
  const char *p;

  if(pListenCfg->pAuthTokenId && pListenCfg->pAuthTokenId[0] != '\0') {
    if(!((parg = conf_find_keyval(pReq->uriPairs, VSX_URI_TOKEN_QUERY_PARAM)))) {
      rc = -1;
    } else if(allowcomma && (p = strchr(parg, ','))) {
      memset(buf, 0, sizeof(buf));
      strncpy(buf, parg, MIN(sizeof(buf), p - parg));
      parg = buf;
    }

    if(rc >= 0 && strcmp(pListenCfg->pAuthTokenId, parg)) {
      rc = -1;
    }
  }

  if(rc < 0) {
    LOG(X_WARNING("Missing or invalid HTTP security token for '%s'"), pReq->url);
  }
  return rc;
}
Exemplo n.º 2
0
static int get_ts(HTTPLIVE_CLIENT_T *pClient, const char *puri) {
  int rc = 0;
  HTTP_PARSE_CTXT_T hdrCtxt;
  HTTP_RESP_T httpResp;
  const char *p = NULL;
  unsigned char *pdata;
  unsigned int contentLen = 0;
  char fulluri[256];
  unsigned char buf[RTP_JTBUF_PKT_BUFSZ_LOCAL + SOCKET_LIST_PREBUF_SZ];

  //LOG(X_DEBUG("Retrieving TS chunk '%s'"), puri);

  if(pClient->uriprefix[0] != '\0') {
    snprintf(fulluri, sizeof(fulluri), "%s%s", pClient->uriprefix, puri);
    puri = fulluri;
  }

  memset(&hdrCtxt, 0, sizeof(hdrCtxt));
  memset(&httpResp, 0, sizeof(httpResp));
  hdrCtxt.pnetsock = &pClient->netsock;
  hdrCtxt.pbuf = (char *) buf;
  hdrCtxt.szbuf = sizeof(buf);
  hdrCtxt.tmtms = 0;

  if((httpcli_gethdrs(&hdrCtxt, &httpResp, &pClient->sa, puri,
          http_getConnTypeStr(HTTP_CONN_TYPE_KEEPALIVE), 0, 0, pClient->hostbuf, NULL)) < 0) {
    return -1;
  }

  if(!(p = conf_find_keyval(httpResp.hdrPairs, HTTP_HDR_CONTENT_TYPE))) {
    LOG(X_ERROR("No "HTTP_HDR_CONTENT_TYPE" found in response"));
    return -1;
  } else if(!(strncasecmp(p, CONTENT_TYPE_MP2TS, strlen(CONTENT_TYPE_MP2TS)) &&
              strncasecmp(p, CONTENT_TYPE_OCTET_STREAM, strlen(CONTENT_TYPE_OCTET_STREAM)))) {
    LOG(X_ERROR("Unsupported %s: %s received in response for %s"),
               HTTP_HDR_CONTENT_TYPE, (p ? p : "<Not Found>"), puri);
    rc = -1;
  }

  if(!(pdata = http_get_contentlen_start(&httpResp, &hdrCtxt, buf, sizeof(buf), 
                                    0, &contentLen))) {
    rc = -1;
  }

  //fprintf(stderr, "TS contentlen:%d pdata:0x%x idxb:%d hdrslen:%d\n", contentLen, pdata, hdrCtxt.idxbuf, hdrCtxt.hdrslen);  

  if(rc >= 0 && pClient->pCfg->running == 0) {
    rc = http_recvloop(pClient->pCfg, &pClient->netsock, &pClient->sa, 
                       pClient->pStreamsOut, pClient->pStream, 
                       hdrCtxt.hdrslen, hdrCtxt.idxbuf - hdrCtxt.hdrslen, 
                       contentLen,
                       buf, sizeof(buf));
  }

  //fprintf(stderr, "TS DONE w rc:%d\n", rc);

  return rc;
}
Exemplo n.º 3
0
unsigned char *http_get_contentlen_start(HTTP_RESP_T *pHttpResp, 
                                    HTTP_PARSE_CTXT_T *pHdrCtxt,
                                    unsigned char *pbuf, unsigned int szbuf,
                                    int verifybufsz,
                                    unsigned int *pcontentLen) {
  const char *p;
  int contentLen = 0;
  unsigned int consumed = 0;
  unsigned char *pdata = NULL;

  if((p = conf_find_keyval(pHttpResp->hdrPairs, HTTP_HDR_CONTENT_LEN))) {
    contentLen = atoi(p);
  }

  if(contentLen <= 0) {
    LOG(X_ERROR("%s not found in response"), HTTP_HDR_CONTENT_LEN);
  } else if(verifybufsz && (unsigned int) contentLen >= szbuf) {
    LOG(X_ERROR("Input buffer size too small %d / %d"), szbuf, contentLen);
  } else if(pHdrCtxt->idxbuf > pHdrCtxt->hdrslen) {

    if((consumed = pHdrCtxt->idxbuf - pHdrCtxt->hdrslen) < szbuf) {
      if((char *) pbuf != pHdrCtxt->pbuf) {
        memcpy(pbuf, &pHdrCtxt->pbuf[pHdrCtxt->hdrslen], consumed);
        pdata = pbuf;
      } else {
        pdata = &pbuf[pHdrCtxt->hdrslen];
      }
    } else {
      LOG(X_ERROR("Input buffer size too small %d / %d"), szbuf, contentLen);
    }

  } else if(pHdrCtxt->idxbuf == pHdrCtxt->hdrslen) {
    pdata = pbuf;
  }

  if(pdata && pcontentLen) {
    *pcontentLen = contentLen;
  }

  return pdata;
}
Exemplo n.º 4
0
int rtmp_auth_parse_req(const char *url, RTMP_AUTH_PARSE_CTXT_T *pParseCtxt) {
  int rc = 0;
  const char *p = NULL;

  if(!url|| !pParseCtxt) {
    return -1;
  }

  if(!(p = strchr(url, '?'))) {
    return rc;
  }
  p++;

  rc = strutil_parse_delimeted_str(cbparse_authmod_descr_params, &pParseCtxt->authList, p, '&');

  if((p = conf_find_keyval(&pParseCtxt->authList.list[0], "authmod"))) {
    strncpy(pParseCtxt->authmodStr, p, sizeof(pParseCtxt->authmodStr) - 1);
  }

  return rc;
}
Exemplo n.º 5
0
int srv_ctrl_pip(CLIENT_CONN_T *pConn) {
  int rc = 0; 
  int rcTmp;
  enum HTTP_STATUS statusCode = HTTP_STATUS_OK;
  const char *parg;
  PIP_CFG_T pipCfg;
  IXCODE_VIDEO_CROP_T crop;
  IXCODE_PIP_MOTION_T *pipMotion = NULL;
  int idx = 0;
  int pip_id = 0;
  int do_stop = 0;
  int do_start = 0;
  int do_update = 0;
  int do_status = 0;
  int do_crop = 0;
  STUN_POLICY_T stunPolicy;
  int activePipIds[MAX_PIPS];
  const char *do_pipconf = NULL;
  unsigned int idxResp;
  char tmp[128];
  char buf[1024];
  char respExtra[512];
  STREAMER_CFG_T *pCfg = NULL;
  char *strxcodebuf = NULL;

  LOG(X_DEBUG("Received PIP command %s%s from %s:%d"), pConn->httpReq.puri,  
      http_req_dump_uri(&pConn->httpReq, buf, sizeof(buf)), FORMAT_NETADDR(pConn->sd.sa, tmp, sizeof(tmp)), 
      htons(INET_PORT(pConn->sd.sa)));

  buf[0] = '\0';
  respExtra[0] = '\0';

  if(pConn->pStreamerCfg0 && pConn->pStreamerCfg0->running >= 0) {
    pCfg = (STREAMER_CFG_T *) pConn->pStreamerCfg0;
  } else if(pConn->pStreamerCfg1 && pConn->pStreamerCfg1->running >= 0) {
    pCfg = (STREAMER_CFG_T *) pConn->pStreamerCfg1;
  }

  if(pCfg) {

    memset(&crop, 0, sizeof(crop));

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, PIP_KEY_PAD_TOP))) {
      crop.padTop = atoi(parg);
      do_crop = 1;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, PIP_KEY_PAD_BOTTOM))) {
      crop.padBottom = atoi(parg);
      do_crop = 1;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, PIP_KEY_PAD_LEFT))) {
      crop.padLeft = atoi(parg);
      do_crop = 1;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, PIP_KEY_PAD_RGB))) {
      strutil_read_rgb(parg, crop.padRGB);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, PIP_KEY_PAD_RIGHT))) {
      crop.padRight = atoi(parg);
      do_crop = 1;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, PIP_KEY_CROP_TOP))) {
      crop.cropTop = atoi(parg);
      do_crop = 1;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, PIP_KEY_CROP_BOTTOM))) {
      crop.cropBottom = atoi(parg);
      do_crop = 1;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, PIP_KEY_CROP_LEFT))) {
      crop.cropLeft = atoi(parg);
      do_crop = 1;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, PIP_KEY_CROP_RIGHT))) {
      crop.cropRight = atoi(parg);
      do_crop = 1;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, PIP_KEY_PAD_ASPECT_RATIO))) {
      crop.padAspectR = atoi(parg);
      do_crop = 1;
    }

    if(do_crop) {
      if((rc = xcode_set_crop_pad(&crop, &pCfg->xcode.vid.out[0], crop.padAspectR, 
                                  pCfg->xcode.vid.out[0].resOutH, pCfg->xcode.vid.out[0].resOutV, 0, 0)) < 0) {
        LOG(X_ERROR("Invalid picture pad / crop dimensions"));
      } else {
        //TODO: updating these params does not work via xcode ipc
        //TODO: this should be atomic w/ respect to xcoder 
        memcpy(&pCfg->xcode.vid.out[0].crop, &crop, sizeof(pCfg->xcode.vid.out[0].crop));
      }
    }

    memset(&pipCfg, 0, sizeof(pipCfg));
    pipCfg.rtpPktzMode = -1;
    pipCfg.dtls_handshake_server = -1;

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipstatus"))) {
      do_status = 1;
      pip_id = atoi(parg);
    } else if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipstop"))) {
      do_stop = 1;
      pip_id = atoi(parg);
    } else if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipstart"))) {
      if(atoi(parg) > 0) {
        do_start = 1;
      }
    } else if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipupdate"))) {
      // start a PIP which was previously started with 'delaystart' parameter
      if((pip_id = atoi(parg)) > 0) {
        do_update = 1;
      }
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipconf"))) {
      do_pipconf = parg;
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipxcode")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "xcode"))) {
      pipCfg.strxcode = parg;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pip")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "in")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "input"))) {
      pipCfg.input = parg;
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "out")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "output"))) {
      pipCfg.output = parg;
//pipCfg.output="dtlssrtp://127.0.0.1:5000,5008";
//pipCfg.output="srtp://127.0.0.1:5000,5000";
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "tslive"))) {
      pipCfg.tsliveaddr = parg;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "rtppayloadtype"))) {
      pipCfg.output_rtpptstr = parg;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "rtpssrc"))) {
      pipCfg.output_rtpssrcsstr = parg;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "mtu"))) {
      pipCfg.mtu = atoi(parg);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "rtppktzmode"))) {
      pipCfg.rtpPktzMode = atoi(parg);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "rtcpports"))) {
      pipCfg.rtcpPorts = parg;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "srtpkey"))) {
      pipCfg.srtpKeysBase64 = parg;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "dtls"))) {
      pipCfg.use_dtls = atoi(parg);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "dtlssrtp"))) {
      pipCfg.use_dtls = pipCfg.use_srtp = atoi(parg);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "dtlsserver"))) {
      pipCfg.dtls_handshake_server = atoi(parg);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "dtlsclient"))) {
      pipCfg.dtls_handshake_server = !atoi(parg);
    }
    //if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "dtlsoutserverkey"))) {
    //  pipCfg.dtls_xmit_serverkey = atoi(parg);
   // }
    //if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "dtlsinserverkey")) ||
    //   (parg = conf_find_keyval(pConn->httpReq.uriPairs, "dtlsserverkey"))) {
    //  pipCfg.dtls_capture_serverkey = atoi(parg);
    //}
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "stunrespond"))) {
      if((stunPolicy = atoi(parg)) != STUN_POLICY_ENABLED) {
        stunPolicy = STUN_POLICY_NONE;
      }
      if((pipCfg.stunBindingResponse = stunPolicy) != STUN_POLICY_NONE) {
        pipCfg.stunRespUseSDPIceufrag = 1;
      }
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "stunrequestuser"))) {
      pipCfg.stunReqUsername = parg;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "stunrequestpass"))) {
      pipCfg.stunReqPass = parg;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "stunrequestrealm"))) {
      pipCfg.stunReqRealm = parg;
    }
    if(pipCfg.stunBindingRequest == STUN_POLICY_NONE && (pipCfg.stunReqUsername || pipCfg.stunReqPass || pipCfg.stunReqRealm)) {
      pipCfg.stunBindingRequest = STUN_POLICY_XMIT_IF_RCVD;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "stunrequest"))) {
      stunPolicy = atoi(parg);
      pipCfg.stunBindingRequest = stunPolicy;
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "turnuser"))) {
      pipCfg.turnCfg.turnUsername = parg; 
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "turnpass"))) {
      pipCfg.turnCfg.turnPass = parg; 
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "turnrealm"))) {
      pipCfg.turnCfg.turnRealm = parg; 
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "turnserver"))) {
      pipCfg.turnCfg.turnServer = parg; 
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "turnpeer"))) {
      pipCfg.turnCfg.turnPeerRelay = parg; 
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "turnsdp"))) {
      pipCfg.turnCfg.turnSdpOutPath = parg; 
    }

    //if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "turnout"))) {
    //  pipCfg.turnCfg.turnOutput = parg; 
    //} else if(pipCfg.turnCfg.turnServer) {
    //  pipCfg.turnCfg.turnOutput = pipCfg.turnCfg.turnServer;
    //}

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "delaystart"))) {
      pipCfg.delayed_output = atoi(parg);
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "abrself"))) {
      pipCfg.abrSelf = atoi(parg);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "abrauto")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "abr"))) {
      pipCfg.abrAuto = atoi(parg);
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "piplayout")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "layout"))) {
      pipCfg.layoutType = pip_str2layout(parg);
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipx")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipxleft")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipxright"))) {
      pipCfg.posx = atoi(parg);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipy")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipytop")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipybottom"))) {
      pipCfg.posy = atoi(parg);
    }

    // PIP_KEY_ZORDER "zorder"
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipzorder")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "zorder"))) {
      pipCfg.zorder = atoi(parg);
    }

    // PIP_KEY_NOAUDIO
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipnoaudio")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "noaud")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "noaudio"))) {
      pipCfg.noaud = 1;
    }

    // PIP_KEY_NOVIDEO
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipnovideo")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "novid")) ||
       (parg = conf_find_keyval(pConn->httpReq.uriPairs, "novideo"))) {
      pipCfg.novid = 1;
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "duplicate"))) {
      pipCfg.allowDuplicate = 1;
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "startchime"))) {
      pipCfg.startChimeFile = parg;
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "stopchime"))) {
      pipCfg.stopChimeFile = parg;
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "rtpretransmit"))) {
      pipCfg.nackRtpRetransmitVideo = atoi(parg);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "rembxmitmaxrate"))) {
      pipCfg.apprembRtcpSendVideoMaxRateBps =  (unsigned int) strutil_read_numeric(optarg, 0, 1000, 0);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "rembxmitminrate"))) {
      pipCfg.apprembRtcpSendVideoMinRateBps =  (unsigned int) strutil_read_numeric(optarg, 0, 1000, 0);
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "rembxmitforce"))) {
      pipCfg.apprembRtcpSendVideoForceAdjustment = atoi(parg);
    }

    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipalphamax"))) {
      pipCfg.alphamax_min1 = atoi(parg) + 1;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipalphamin"))) {
      pipCfg.alphamin_min1 = atoi(parg) + 1;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipbefore"))) {
      if(atoi(parg) > 0) {
        pipCfg.flags |= PIP_FLAGS_INSERT_BEFORE_SCALE;
      }
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipxright"))) {
      pipCfg.flags |= PIP_FLAGS_POSITION_RIGHT;
    }
    if((parg = conf_find_keyval(pConn->httpReq.uriPairs, "pipybottom"))) {
      pipCfg.flags |= PIP_FLAGS_POSITION_BOTTOM;
    }

    //
    // Read the PIP configuration from a fiel
    //
    if(do_pipconf) {
      pipCfg.cfgfile = do_pipconf;

      //if((idx = pip_getIndexById(pCfg,  pip_id, 1)) >= 0 && idx < MAX_PIPS && pCfg->pStorageBuf) {
      //  strxcodebuf = ((STREAM_STORAGE_T *) pCfg->pStorageBuf)->pipxcodeStrbuf[idx];

      if(pCfg->pStorageBuf) {
        //TODO: if we're all going to use the same buffer (temporarily) we need some locking here...
        strxcodebuf = ((STREAM_STORAGE_T *) pCfg->pStorageBuf)->pipxcodeStrbuf[0];
      }

      if((pipMotion = pip_read_conf(&pipCfg, pCfg->status.pathFile, strxcodebuf))) {
        do_start = 1;
        do_stop = 0;
      } else {

      }
    }

    if(do_status) {

      if(pip_id == -1) {
        if((rc = pip_getActiveIds(pCfg, activePipIds, 1)) > 0) {
          idxResp = 0;
          if((rcTmp = snprintf(respExtra, sizeof(respExtra), "&ids=")) > 0) {
            idxResp += rcTmp;
          }
          for(idx = 0; idx < rc; idx++) {
            if((rcTmp = snprintf(&respExtra[idxResp], sizeof(respExtra) - idxResp, "%s%d", 
                                 idx > 0 ? "," : "", activePipIds[idx])) > 0) { 
              idxResp += rcTmp;
            }
          }
        }
      } else if((idx = pip_getIndexById(pCfg, pip_id, 1)) >= 0) {
        rc = pip_id;
      } else {
        rc = -1;
      }

    } else if(do_update) {

      if((idx = pip_getIndexById(pCfg, pip_id, 1)) >= 0) {
        rc = pip_update(&pipCfg, pCfg, pip_id);
      } else {
        do_update = 0;
      }

    } else if(do_stop) {

      if((rc = pip_stop(pCfg, pip_id)) < 0) {
        LOG(X_ERROR("Failed to stop PIP[%d]"), pip_id);
      }

    } else if(do_start && rc >= 0) {

      rc = pip_start(&pipCfg, pCfg, pipMotion);

    }

    //
    // The html body response
    //
    snprintf(buf, sizeof(buf), "code=%d%s", rc, respExtra[0] != '\0' ? respExtra : ""); 

  } else {
    rc = -1;
  }
 
  if(rc < 0) {
    statusCode = HTTP_STATUS_SERVERERROR;
  }

  rc = http_resp_send(&pConn->sd, &pConn->httpReq, statusCode, (unsigned char *) buf, strlen(buf));

  LOG(X_DEBUG("Sent PIP response '%s' to %s:%d"), buf, FORMAT_NETADDR(pConn->sd.sa, tmp, sizeof(tmp)), 
                                                  htons(INET_PORT(pConn->sd.sa)));

  return rc;
}
Exemplo n.º 6
0
//TODO: move this to http files
int http_getpage(const char *addr, uint16_t port, const char *uri,
                 char *buf, unsigned int szbuf, unsigned int tmtms) {
  int rc = 0;
  NETIO_SOCK_T netsock;
  struct sockaddr_in sa;
  HTTP_PARSE_CTXT_T hdrCtxt;
  HTTP_RESP_T httpResp;
  unsigned int contentLen = 0;
  const char *p;
  unsigned int consumed = 0;
  struct timeval tv0, tv1;
  char hdr[1024];

  if(!addr || !buf || szbuf <= 0) {
    return -1;
  }
  if(!uri) {
    uri = "/";
  }

  memset(&netsock, 0, sizeof(netsock));
  if((NETIOSOCK_FD(netsock) = net_opensocket(SOCK_STREAM, 0, 0, NULL)) == INVALID_SOCKET) {
    return -1;
  }

  memset(&sa, 0, sizeof(sa));
  sa.sin_addr.s_addr = inet_addr(addr);
  sa.sin_port = htons(port);

  if((rc = net_connect(NETIOSOCK_FD(netsock), &sa)) != 0) {
    return rc;
  }

  gettimeofday(&tv0, NULL);

  memset(&hdrCtxt, 0, sizeof(hdrCtxt));
  memset(&httpResp, 0, sizeof(httpResp));
  hdrCtxt.pnetsock = &netsock;
  hdrCtxt.pbuf = hdr;
  hdrCtxt.szbuf = sizeof(hdr);
  hdrCtxt.tmtms = tmtms;

  VSX_DEBUG_MGR(LOG(X_DEBUG("MGR - Sending local status command: '%s' to: %d"), uri, htons(sa.sin_port)));

  if((httpcli_gethdrs(&hdrCtxt, &httpResp, &sa, uri, NULL, 0, 0, NULL, NULL)) < 0) {
    return -1;
  }

  if(rc >= 0 && (p = conf_find_keyval(httpResp.hdrPairs, HTTP_HDR_CONTENT_LEN))) {
    contentLen = atoi(p);  
  } 

  if(rc >= 0) {
    if(contentLen <= 0) {
      LOG(X_ERROR("Content-Length not found in response"));
      rc = -1;
    } else if(contentLen > szbuf) {
      LOG(X_ERROR("Input buffer size too small %d / %d"), szbuf, contentLen);
      rc = -1;
    } else if(hdrCtxt.idxbuf > hdrCtxt.hdrslen) {
      if((consumed = hdrCtxt.idxbuf - hdrCtxt.hdrslen) < szbuf) {
        memcpy(buf, &hdr[hdrCtxt.hdrslen], consumed);
      } else {
        LOG(X_ERROR("Input buffer size too small %d / %d"), szbuf, contentLen);
        rc = -1;
      }
    }
  }

  if(rc >= 0 && net_setsocknonblock(NETIOSOCK_FD(netsock), 1) < 0) {
    rc = -1;
  } 

    //fprintf(stderr, "GET PAGE OK idx:%d hdrs:%d conentlen:%d\n", hdrCtxt.idxbuf, hdrCtxt.hdrslen, contentLen);

  while(rc >= 0 && consumed < contentLen) {
    if((rc = netio_recvnb(&netsock, (unsigned char *) &buf[consumed], 
                          contentLen - consumed, 500)) > 0) {
      consumed += rc;
    } 

    gettimeofday(&tv1, NULL);
    if(tmtms > 0 && consumed < contentLen && TIME_TV_DIFF_MS(tv1, tv0) > tmtms) {
      LOG(X_WARNING("HTTP %s:%d%s timeout %d ms exceeded"), net_inet_ntoa(sa.sin_addr, hdr), 
           ntohs(sa.sin_port), uri, tmtms);
      break;
      rc = -1;
    }
  }

  if(contentLen > 0 && consumed >= contentLen) {
    rc = consumed;
  } else {
    rc = -1;
  }

  netio_closesocket(&netsock);

  return rc;
}
Exemplo n.º 7
0
int srvauth_authenticate(const AUTH_CREDENTIALS_STORE_T *pAuthStore, const HTTP_REQ_T *pReq, 
                         const char *nonce_srv, const char *opaque_srv, const char *realm_srv,
                         char *bufAuthHdr, unsigned int bufOutSz) {
  int rc = 0;
  int ok_auth = 0;
  int do_basic = 0;
  char bufAuth[1024];
  char tmpH1[KEYVAL_MAXLEN];
  char tmpH2[KEYVAL_MAXLEN];
  char tmpDigest[KEYVAL_MAXLEN];
  char tmps[6][KEYVAL_MAXLEN];
  char bufnonce[AUTH_NONCE_MAXLEN];
  const char *pAuthHdr = NULL;
  const char *enc = NULL;
  const char *realm = NULL;
  const char *uri_cli = NULL;
  const char *qop_cli = NULL;
  const char *nc_cli = NULL;
  const char *cnonce_cli = NULL;
  const char *nonce_cli = NULL;
  const char *resp_cli = NULL;
  AUTH_LIST_T authList;
  AUTH_CREDENTIALS_STORE_T authStore;

  if(!pAuthStore || !pReq) {
    return -1;
  }


  if(!IS_AUTH_CREDENTIALS_SET(pAuthStore)) {
    //
    // No username and password has been set
    //
    return 0;
  }

  if(!(realm = realm_srv)) {
    realm = pAuthStore->realm;
  }

  if(!realm || realm[0] == '\0') {
    realm = VSX_BINARY;
  }

  if(pAuthStore->authtype == HTTP_AUTH_TYPE_FORCE_BASIC) {
    do_basic = 1;
  }

  if(ok_auth >= 0 && 
     !(pAuthHdr = conf_find_keyval((const KEYVAL_PAIR_T *) &pReq->reqPairs, HTTP_HDR_AUTHORIZATION))) {
    LOG(X_WARNING("Client request doest not include "HTTP_HDR_AUTHORIZATION" header for %s %s"),
                pReq->method, pReq->url);
    ok_auth = -1;
  }

  if(ok_auth >= 0) {
    enc = pAuthHdr;
    MOVE_WHILE_SPACE(enc);
    if(!strncasecmp(AUTH_STR_BASIC, enc, strlen(AUTH_STR_BASIC))) {
      enc += strlen(AUTH_STR_BASIC);
      MOVE_WHILE_SPACE(enc);
      if(pAuthStore->authtype == HTTP_AUTH_TYPE_ALLOW_BASIC || pAuthStore->authtype == HTTP_AUTH_TYPE_FORCE_BASIC) {
        do_basic = 1;
      } else {
        LOG(X_WARNING("Client wants disabled Basic authentication for %s %s"), pReq->method, pReq->url);
        ok_auth = -1;
      }
    } else if(!strncasecmp(AUTH_STR_DIGEST, enc, strlen(AUTH_STR_DIGEST))) {
      enc += strlen(AUTH_STR_DIGEST);
      MOVE_WHILE_SPACE(enc);
    } else {
      LOG(X_WARNING("Client request contains unsupported "HTTP_HDR_AUTHORIZATION
                    " header type '%s' for %s %s"), pAuthHdr, pReq->method, pReq->url);
      ok_auth = -1;
    }
  }

  if(ok_auth >= 0 && do_basic) {

    //
    // Basic Auth 
    //

    memset(&authStore, 0, sizeof(authStore));

    //
    // Parse the header Authorization: Basic <Base64(username:password)>
    //
    if(ok_auth >= 0 &&
       auth_basic_decode(enc, authStore.username, sizeof(authStore.username), 
                         authStore.pass, sizeof(authStore.pass)) < 0) {
      LOG(X_WARNING("Client "HTTP_HDR_AUTHORIZATION" Basic Auth decode failed for '%s' for %s %s"),
                      enc, pReq->method, pReq->url);
      ok_auth = -1;
    }

    //
    // Verify the username and password
    //
    if(ok_auth >= 0) {
      if(((pAuthStore->username[0] != '\0' && !strcmp(pAuthStore->username, authStore.username)) &&
          (pAuthStore->pass[0] != '\0' && !strcmp(pAuthStore->pass, authStore.pass)))) {
        ok_auth = 1;
      } else {
        LOG(X_WARNING("Client "HTTP_HDR_AUTHORIZATION" incorrect Basic auth credentials for "
                      "'%s' for %s %s username: %s"), pAuthHdr, pReq->method, pReq->url, pAuthStore->username);
        ok_auth = -1;
      }
    }

  } else if(ok_auth >= 0) {

    //
    // Parse the Digest Authorization header
    //
    if(ok_auth  >= 0 && auth_digest_parse(enc, &authList) < 0) {
      LOG(X_WARNING("Failed to parse client "HTTP_HDR_AUTHORIZATION" '%s' for %s %s"), 
                    pAuthHdr, pReq->method, pReq->url);
      ok_auth = -1;
    } else if(ok_auth >= 0) {

      uri_cli = avc_dequote(conf_find_keyval(&authList.list[0], "uri"), tmps[0], sizeof(tmps[0]));
      qop_cli = avc_dequote(conf_find_keyval(&authList.list[0], "qop"), tmps[1], sizeof(tmps[1]));
      nc_cli = avc_dequote(conf_find_keyval(&authList.list[0], "nc"), tmps[2], sizeof(tmps[2]));
      cnonce_cli  = avc_dequote(conf_find_keyval(&authList.list[0], "cnonce"), tmps[3], sizeof(tmps[3]));
      nonce_cli = avc_dequote(conf_find_keyval(&authList.list[0], "nonce"), tmps[4], sizeof(tmps[4]));
      resp_cli = avc_dequote(conf_find_keyval(&authList.list[0], "response"), tmps[5], sizeof(tmps[5]));

      // 
      // If nonce_srv is supplied, we try to do nonce validation
      // (prior generated nonce should not be stored per-connection but globally with matching
      // client IP and creation time
      //

      if(ok_auth >= 0 && (!nonce_cli || (nonce_srv && strcmp(nonce_cli, nonce_srv)))) {
        LOG(X_WARNING("Invalid nonce from client: '%s', expected: '%s' for %s %s"), 
            nonce_cli, nonce_srv, pReq->method, pReq->url);
        ok_auth = -1;
      }

      if(ok_auth >= 0 && 
         (rc = auth_digest_getH1(pAuthStore->username, realm, pAuthStore->pass, tmpH1, sizeof(tmpH1))) < 0) {
        ok_auth = -1;
      }
      if(ok_auth >= 0 && (rc = auth_digest_getH2(pReq->method, uri_cli, tmpH2, sizeof(tmpH2))) < 0) {
        ok_auth = -1;
      }
      if(ok_auth >= 0 && 
         (rc = auth_digest_getDigest(tmpH1, nonce_srv ? nonce_srv : nonce_cli, tmpH2, nc_cli, cnonce_cli,
                                     qop_cli, tmpDigest, sizeof(tmpDigest))) < 0) {
        ok_auth = -1;
      }
      if(ok_auth >= 0 && resp_cli  && !strcmp(tmpDigest, resp_cli)) {
        ok_auth = 1;
      } else {
        LOG(X_WARNING("Client "HTTP_HDR_AUTHORIZATION" incorrect Digest auth credentials for '%s' "
                      "for %s %s username: %s"), pAuthHdr, pReq->method, pReq->url, pAuthStore->username);
        ok_auth = -1;
      }
    }

  }

  if(ok_auth > 0) {
    LOG(X_DEBUG("Succesful %s authentication for %s %s username: %s"), 
                do_basic ? "Basic" : "Digest", pReq->method, pReq->url, pAuthStore->username);
  } else if(ok_auth <= 0 && bufAuthHdr && bufOutSz > 0) {

    if(do_basic == 1) {
      //
      // Basic Auth unauthorized resposne
      //
      if((rc = snprintf(bufAuthHdr, bufOutSz, "%s: %s realm=\"%s\"\r\n",
                        HTTP_HDR_WWW_AUTHENTICATE, AUTH_STR_BASIC, realm)) < 0) {

        return -1;
      }

    } else {
      //
      // Digest Auth RFC 2069 / RFC 2617 unauthorized response
      //

      memset(&authList, 0, sizeof(authList));
      if(nonce_srv && nonce_srv[0] == '\0') {
        auth_digest_gethexrandom(16, (char *) nonce_srv, AUTH_NONCE_MAXLEN);
      } else {
        auth_digest_gethexrandom(16, (char *) bufnonce, AUTH_NONCE_MAXLEN);
      }
      if(opaque_srv && opaque_srv[0] == '\0') {
        auth_digest_gethexrandom(16, (char *) opaque_srv, AUTH_OPAQUE_MAXLEN);
      }

      //auth_digest_additem(&authList, "qop", "auth", 1);
      auth_digest_additem(&authList, "realm", realm, 1);
      auth_digest_additem(&authList, "nonce", nonce_srv ? nonce_srv : bufnonce, 1);
      if(opaque_srv) {
        auth_digest_additem(&authList, "opaque", opaque_srv, 1);
      }

      if((rc = auth_digest_write(&authList, bufAuth, sizeof(bufAuth))) < 0) {
        return -1;
      }

      if((rc = snprintf(bufAuthHdr, bufOutSz, "%s: %s\r\n", HTTP_HDR_WWW_AUTHENTICATE, bufAuth)) < 0) {
        return -1;
      }
    }

    //if(rtsp_resp_sendhdr(pRtsp->pSd, statusCode, pReq->cseq,
    //                     pRtsp->pSession, 0, NULL, bufAuthHdr) < 0) {
    //  rc = -1;
    //}
  }

  return ok_auth > 0 ? 0 : -1;
}