Exemple #1
0
int drop_privileges(wkr_t *w, scgi_t *scgi) {
  char *str;
  
  str = (char*) scgi_header_value_get(scgi, "USER");
  
  if(str && strlen(str) > 0) {
    struct passwd *user_info=NULL;
    user_info = getpwnam(str);
    // Check for user existence
    if(user_info) {
      w->tmp->uid = user_info->pw_uid; 
      w->tmp->gid = user_info->pw_gid;
    } else {
      scgi_body_add(w->ctl->scgi, "Application run_as_user is invalid. Application not started.", strlen("Application run_as_user is invalid. Application not started."));
      LOG_ERROR(SEVERE,"Application run_as_user is invalid. Application not started.");
      return FALSE;
    }
  } else {
    scgi_body_add(w->ctl->scgi, "Application run_as_user is missing. Application not started.", strlen("Application run_as_user is missing. Application not started."));
    LOG_ERROR(SEVERE,"Application run_as_user is missing. Application not started.");
    return FALSE;
  }
  
  change_log_file_owner(w->tmp->uid, w->tmp->gid);
  //setting read, effective, saved group and user id
  if(setgid(w->tmp->gid)!=0) {
    scgi_body_add(w->ctl->scgi, "setegid() failed", strlen("setegid() failed"));
    LOG_ERROR(SEVERE,"setegid() failed");
    return FALSE;
  }
  if(setuid(w->tmp->uid)!=0) {
    scgi_body_add(w->ctl->scgi, "seteuid() failed", strlen("seteuid() failed"));
    LOG_ERROR(SEVERE,"seteuid() failed");
    return FALSE;
  }
  
  LOG_DEBUG(DEBUG,"Passed userid=%d and groupid=%d",
            w->tmp->uid, w->tmp->gid);
  LOG_DEBUG(DEBUG,"effective userid=%d and groupid=%d",geteuid(),getegid());
#ifdef __linux__
  int rv = prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
  LOG_DEBUG(DEBUG,"prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) = %d", rv);
  if (rv < 0) {
    LOG_ERROR(SEVERE,"error setting prctl(PR_SET_DUMPABLE, 1, 0, 0, 0), errno = %d, desc = %s", errno, strerror(errno));
  }
#endif  
  return TRUE;
}
Exemple #2
0
void manipulate_environment_variable(wkr_t* w, scgi_t *scgi) {
  LOG_FUNCTION
  char *var, *str;
  int rv = 0;  
    
  str = (char*) scgi_header_value_get(scgi, "ENV_VAR");
  w->env_var = wr_string_list_new();  
  if(str){    
    var = strtok(str,"#");
    while(var){
      LOG_DEBUG(DEBUG,"Environment variable string = %s", var);
      wr_string_list_add(w->env_var, var, strlen(var));
       // TODO: see the security concerns     
      rv = putenv(w->env_var->rear->str.str);
      if (rv != 0) {
        LOG_ERROR(WARN, "putenv() failed, errno = %d, description = %s", errno, strerror(errno)); 
      } 
      var = strtok(NULL,"#");
    }
  }
}
Exemple #3
0
/** Reads the response from worker, deserialize it, render it to the Request. */
static void wr_resp_len_read_cb(struct ev_loop *loop, struct ev_io *w, int revents) {
  LOG_FUNCTION
  wr_req_t* req = (wr_req_t*) w->data;
  wr_wkr_t *worker = req->wkr;
  ssize_t read;

  LOG_DEBUG(DEBUG,"Request %d",req->id);

  if(!(revents & EV_READ))
    return;

  read = recv(w->fd,
              req->resp_buf + req->bytes_received,
              WR_RESP_BUF_SIZE - req->bytes_received,
              0);

  if(read <= 0) {
    ev_io_stop(loop,w);
    LOG_ERROR(WARN,"Error reading response:%s",strerror(errno));
    worker->state += (WR_WKR_ERROR + WR_WKR_HANG);
    wr_ctl_free(worker->ctl);
    return;
  }

  req->bytes_received =+ read;
  //worker responding
  LOG_DEBUG(DEBUG,"Idle watcher reset for worker %d", worker->id);
  LOG_DEBUG(DEBUG,"bytes read = %d", req->bytes_received);

  scgi_t* scgi = scgi_parse(req->resp_buf, req->bytes_received);

  if(scgi) {
    ev_io_stop(loop,w);
    const char *value = scgi_header_value_get(scgi, SCGI_CONTENT_LENGTH);
    // Set response length
    if(value)
      req->resp_buf_len = atoi(value);
    else
      req->resp_buf_len = 0;
    
    // Set rsponse code
    value = scgi_header_value_get(scgi, RESP_CODE);
    if(value)
      req->resp_code = atoi(value);
    else
      req->resp_code = 0;
    
    // Set content length
    value = scgi_header_value_get(scgi, RESP_CONTENT_LENGTH);
    if(value)
      req->resp_body_len = atoi(value);
    else
      req->resp_body_len = 0;
    
    LOG_DEBUG(DEBUG,"resp_code = %d, content len = %d, resp len = %d",
              req->resp_code,
              req->resp_body_len,
              req->resp_buf_len);
    // Response length should be greater than 0
    if(req->resp_buf_len == 0) {
      //TODO: Render 500 Internal Error, close Request, allocate worker to next Request
      LOG_ERROR(WARN,"Got response len 0");
      ev_io_stop(loop,w);
      worker->state += (WR_WKR_ERROR + WR_WKR_HANG);
      wr_ctl_free(worker->ctl);
      return;
    }

    if(!req->conn_err && req->app && req->app->svr->conf->server->flag & WR_SVR_ACCESS_LOG) {
      wr_access_log(req);
    }

    scgi_free(req->scgi);
    req->scgi = NULL;

    req->bytes_received = scgi->body_length;
    LOG_DEBUG(DEBUG,"wr_resp_len_read_cb() bytes read = %d", req->bytes_received);
    if(req->bytes_received > 0 && !req->conn_err) {
      wr_conn_resp_body_add(req->conn, scgi->body, scgi->body_length);
    }

    scgi_free(scgi);

    // Check for response length
    if(req->resp_buf_len == req->bytes_received) {
      LOG_DEBUG(DEBUG,"Idle watcher stopped for worker %d", worker->id);
      // worker is done with current Request
      worker->req = NULL;
      req->using_wkr = FALSE;
      worker->state &= (~224);
      ev_timer_stop(worker->loop,&worker->t_wait);
      // Close Request once complete response read
      wr_wkr_release(req);
    } else {
      LOG_DEBUG(DEBUG,"wr_resp_len_read_cb() Request %d, read %d/%d",
                req->id,
                req->bytes_received,
                req->resp_buf_len);
      ev_io_init(w,wr_resp_read_cb, w->fd,EV_READ);
      ev_io_start(loop,w);
      wr_wait_watcher_start(worker);
    }
  }
}
Exemple #4
0
void application_config_read_cb(wkr_t* w, scgi_t *scgi){
  LOG_FUNCTION
  char *str;
  /*w->ctl->scgi = scgi_new();
  
  if(w->ctl->scgi == NULL) {
    LOG_ERROR(SEVERE,"Cannot create SCGI Request");
    sigproc();
    return;
  } */ 
  
  if(w->tmp->is_static){

#ifdef W_ZLIB
    str = (char*) scgi_header_value_get(scgi, "LOWER_LIMIT");
    if(str){
      w->tmp->lower_limit = atol(str);
    }

    str = (char*) scgi_header_value_get(scgi, "UPPER_LIMIT");
    if(str){
      w->tmp->upper_limit = atol(str);
    }

#ifdef W_REGEX
    str = (char*) scgi_header_value_get(scgi, "CONTENT_TYPE");
    if(str){
      wr_string_new(w->tmp->r_content_type, str, strlen(str));
    }else {
      wr_string_new(w->tmp->r_content_type, DEFAULT_CONTENT_TYPE, strlen(DEFAULT_CONTENT_TYPE));
    }


    str = (char*) scgi_header_value_get(scgi, "USER_AGENT");
    if(str){
      wr_string_new(w->tmp->r_user_agent, str, strlen(str));
    }
#endif

#endif
  }else{
    if(drop_privileges(w, scgi) == FALSE) {
      wkr_tmp_free(&w->tmp);
      sigproc();
      return;
    }
    
    manipulate_environment_variable(w, scgi);
    str = (char*) scgi_header_value_get(scgi, "PATH");
    if(str){
      wr_string_new(w->tmp->path, str, strlen(str));
    }

    str = (char*) scgi_header_value_get(scgi, "ENV");
    if(str){
      wr_string_new(w->tmp->env, str, strlen(str));
    }

    str = (char*) scgi_header_value_get(scgi, "TYPE");
    if(str){
      wr_string_new(w->tmp->type, str, strlen(str));
    }

    str = (char*) scgi_header_value_get(scgi, "BASE_URI");
    if(str){
      wr_string_new(w->tmp->resolver, str, strlen(str));
    }

    str = (char*) scgi_header_value_get(scgi, "ANALYTICS");
    if(str && strcmp(str,"enabled")==0){
      w->tmp->profiler = 'y';
    }else{
      w->tmp->profiler = 'n'; 
    }
  }
  
  load_application(w);
}
Exemple #5
0
wr_ctl_msg_t* wr_ctl_msg_validate(scgi_t* request, wr_ctl_t* ctl) {
  LOG_FUNCTION
  wr_ctl_msg_t* ctl_msg = wr_malloc(wr_ctl_msg_t);
  char *val;
  char error[STR_SIZE64];

  ctl->type = WR_CTL_MSG_NONE;
  ctl->scgi = scgi_new();

  val = (char*) scgi_header_value_get(request,"COMPONENT");
  if(val == NULL) {
    memcpy(error,"COMPONENT missing.", strlen("COMPONENT missing.")+1);
    goto ctl_msg_err;
  }
  scgi_header_add(ctl->scgi, "COMPONENT", strlen("COMPONENT"), val, strlen(val));
  if(strcmp(val,"APPLICATION")==0) {
    val = (char*) scgi_header_value_get(request,"METHOD");
    if(val == NULL) {
      memcpy(error,"METHOD missing.", strlen("METHOD missing.")+1);
      goto ctl_msg_err;
    }

    scgi_header_add(ctl->scgi, "METHOD", strlen("METHOD"), val, strlen(val));
    
    ctl_msg->msg.app.app_name.str = (char*) scgi_header_value_get(request,"APP_NAME");
    if(ctl_msg->msg.app.app_name.str)
      ctl_msg->msg.app.app_name.len = strlen(ctl_msg->msg.app.app_name.str);
    if(ctl_msg->msg.app.app_name.str == NULL) {
      memcpy(error,"Application name is missing.", strlen("Application name is missing.")+1);
      goto ctl_msg_err;
    }

    // Application Add
    if(strcmp(val,"ADD")==0) {
      ctl->type = WR_CTL_MSG_APPLICATION_ADD;
    } else if(strcmp(val,"REMOVE")==0) {
      ctl->type = WR_CTL_MSG_APPLICATION_REMOVE;
    } else if(strcmp(val,"RELOAD")==0) {
      ctl->type = WR_CTL_MSG_APPLICATION_RELOAD;
    }else {
      memcpy(error, "Invalid METHOD.", strlen("Invalid METHOD.")+1);
      goto ctl_msg_err;
    }
  } else if(strcmp(val,"WORKER")==0) {
    val = (char*) scgi_header_value_get(request,"METHOD");
    if(val == NULL) {
      memcpy(error, "METHOD missing.", strlen("METHOD missing.")+1);
      goto ctl_msg_err;
    }

    if(strcmp(val,"ERROR")==0) {
      scgi_header_add(ctl->scgi, "METHOD", strlen("METHOD"), "ACK", strlen("ACK"));
    }else{
      scgi_header_add(ctl->scgi, "METHOD", strlen("METHOD"), val, strlen(val));
    }
    
    // Worker Add
    if(strcmp(val,"ADD")==0) {
      ctl->type = WR_CTL_MSG_WORKER_ADD;

      ctl_msg->msg.wkr.app_name.str  =   (char*) scgi_header_value_get(request,"APPLICATION");
      if(ctl_msg->msg.wkr.app_name.str)
        ctl_msg->msg.wkr.app_name.len = strlen(ctl_msg->msg.wkr.app_name.str);
      ctl_msg->msg.wkr.pid.str =   (char*) scgi_header_value_get(request,"PID");
      if(ctl_msg->msg.wkr.pid.str)
        ctl_msg->msg.wkr.pid.len = strlen(ctl_msg->msg.wkr.pid.str);
      ctl_msg->msg.wkr.port.str  =   (char*) scgi_header_value_get(request,"PORT");
      if(ctl_msg->msg.wkr.port.str)
        ctl_msg->msg.wkr.port.len = strlen(ctl_msg->msg.wkr.port.str);
      ctl_msg->msg.wkr.sock_path.str  =   (char*) scgi_header_value_get(request,"SOCK_PATH");
      if(ctl_msg->msg.wkr.sock_path.str)
        ctl_msg->msg.wkr.sock_path.len = strlen(ctl_msg->msg.wkr.sock_path.str);
      ctl_msg->msg.wkr.uds.str  =   (char*) scgi_header_value_get(request,"UDS");
      if(ctl_msg->msg.wkr.uds.str)
        ctl_msg->msg.wkr.uds.len = strlen(ctl_msg->msg.wkr.uds.str);

      if(ctl_msg->msg.wkr.app_name.str == NULL ||
          ctl_msg->msg.wkr.pid.str == NULL ||
          ctl_msg->msg.wkr.uds.str == NULL) {
        memcpy(error, "Missing some headers.", strlen("Missing some headers.")+1);
        goto ctl_msg_err;
      }

    } else if(strcmp(val,"REMOVE")==0) {
      ctl->type = WR_CTL_MSG_WORKER_REMOVE;
    } else if(strcmp(val,"PING") == 0) {
      ctl->type = WR_CTL_MSG_WORKER_PING;
    } else if(strcmp(val,"CONF_REQ") == 0){
      ctl->type = WR_CTL_MSG_WORKER_CONF_REQ;
      ctl_msg->msg.wkr.app_name.str  =   (char*) scgi_header_value_get(request,"APPLICATION");
      if(ctl_msg->msg.wkr.app_name.str)
        ctl_msg->msg.wkr.app_name.len = strlen(ctl_msg->msg.wkr.app_name.str);
    } else if(strcmp(val,"ERROR") == 0) {
      ctl->type = WR_CTL_MSG_WORKER_ADD_ERROR;
      ctl_msg->msg.wkr.app_name.str  =   (char*) scgi_header_value_get(request,"APPLICATION");
      if(ctl_msg->msg.wkr.app_name.str)
        ctl_msg->msg.wkr.app_name.len = strlen(ctl_msg->msg.wkr.app_name.str);
      ctl_msg->msg.wkr.pid.str =   (char*) scgi_header_value_get(request,"PID");
      if(ctl_msg->msg.wkr.pid.str)
        ctl_msg->msg.wkr.pid.len = strlen(ctl_msg->msg.wkr.pid.str);
      ctl_msg->msg.wkr.port.str  =   (char*) scgi_header_value_get(request,"PORT");
      if(ctl_msg->msg.wkr.port.str)
        ctl_msg->msg.wkr.port.len = strlen(ctl_msg->msg.wkr.port.str);
      ctl_msg->msg.wkr.sock_path.str  =   (char*) scgi_header_value_get(request,"SOCK_PATH");
      if(ctl_msg->msg.wkr.sock_path.str)
        ctl_msg->msg.wkr.sock_path.len = strlen(ctl_msg->msg.wkr.sock_path.str);
      ctl_msg->msg.wkr.uds.str  =   (char*) scgi_header_value_get(request,"UDS");
      if(ctl_msg->msg.wkr.uds.str)
        ctl_msg->msg.wkr.uds.len = strlen(ctl_msg->msg.wkr.uds.str);

      if(ctl_msg->msg.wkr.app_name.str == NULL ||
          ctl_msg->msg.wkr.pid.str == NULL ||
          ctl_msg->msg.wkr.uds.str == NULL) {
        memcpy(error, "Missing some headers.", strlen("Missing some headers.")+1);
        goto ctl_msg_err;
      }
    }else {
      memcpy(error,"Invalid METHOD.", strlen("Invalid METHOD.")+1);
      goto ctl_msg_err;
    }
  } else {
    memcpy(error,"Invalid COMPONENT.", strlen("Invalid COMPONENT.")+1);
    goto ctl_msg_err;
  }

  return ctl_msg;
ctl_msg_err:
  LOG_ERROR(WARN,"Error found in controller message");
  ctl->type = WR_CTL_MSG_TYPE_ERROR;
  scgi_body_add(ctl->scgi, error, strlen(error));
  scgi_header_add(ctl->scgi, "STATUS", strlen("STATUS"), "ERROR", strlen("ERROR"));
  return ctl_msg;
}