Пример #1
0
// Use the global passwords file, if specified by auth_gpass option,
// or search for .htpasswd in the requested directory.
static FILE *open_auth_file(struct mg_connection *conn, const char *path) {
  char name[PATH_MAX];
  const char *p, *e, *gpass = conn->ctx->config[GLOBAL_PASSWORDS_FILE];
  struct file file = STRUCT_FILE_INITIALIZER;
  FILE *fp = NULL;

  if (gpass != NULL) {
    // Use global passwords file
    fp = mg_fopen(gpass, "r");
    // Important: using local struct file to test path for is_directory flag.
    // If filep is used, mg_stat() makes it appear as if auth file was opened.
  } else if (mg_stat(path, &file) && file.is_directory) {
    mg_snprintf(name, sizeof(name), "%s%c%s",
                path, '/', PASSWORDS_FILE_NAME);
    fp = mg_fopen(name, "r");
  } else {
     // Try to find .htpasswd in requested directory.
    for (p = path, e = p + strlen(p) - 1; e > p; e--)
      if (e[0] == '/')
        break;
    mg_snprintf(name, sizeof(name), "%.*s%c%s",
                (int) (e - p), p, '/', PASSWORDS_FILE_NAME);
    fp = mg_fopen(name, "r");
  }

  return fp;
}
Пример #2
0
static int handle_lsp_request(struct mg_connection *conn, const char *path,
                               struct file *filep, struct lua_State *ls) {
  void *p = NULL;
  lua_State *L = NULL;
  FILE *fp = NULL;
  int error = 1;

  // We need both mg_stat to get file size, and mg_fopen to get fd
  if (!mg_stat(path, filep) || (fp = mg_fopen(path, "r")) == NULL) {
    lsp_send_err(conn, ls, "File [%s] not found", path);
  } else if ((p = mmap(NULL, (size_t) filep->size, PROT_READ, MAP_PRIVATE,
                       fileno(fp), 0)) == MAP_FAILED) {
    lsp_send_err(conn, ls, "mmap(%s, %zu, %d): %s", path, (size_t) filep->size,
              fileno(fp), strerror(errno));
  } else if ((L = ls != NULL ? ls : luaL_newstate()) == NULL) {
    send_http_error(conn, 500, http_500_error, "%s", "luaL_newstate failed");
  } else {
    // We're not sending HTTP headers here, Lua page must do it.
    if (ls == NULL) {
      prepare_lua_environment(conn, L);
    }
    error = lsp(conn, path, p, filep->size, L);
  }

  if (L != NULL && ls == NULL) lua_close(L);
  if (p != NULL) munmap(p, filep->size);
  fclose(fp);

  return error;
}
Пример #3
0
static void edit_config_file(struct mg_context *ctx) {
  const char **names, *value;
  FILE *fp;
  int i;
  char cmd[200];

  // Create config file if it is not present yet
  if ((fp = mg_fopen(config_file, "r")) != NULL) {
    mg_fclose(fp);
  } else if ((fp = fopen(config_file, "a+")) != NULL) {
    fprintf(fp,
            "# Mongoose web server configuration file.\n"
            "# Lines starting with '#' and empty lines are ignored.\n"
            "# For detailed description of every option, visit\n"
            "# http://code.google.com/p/mongoose/wiki/MongooseManual\n\n");
    names = mg_get_valid_option_names();
    for (i = 0; names[i] != NULL; i += MG_ENTRIES_PER_CONFIG_OPTION) {
      value = mg_get_option(ctx, names[i + 1]);
      fprintf(fp, "# %s %s\n", names[i + 1], *value ? value : "<value>");
    }
    mg_fclose(fp);
  }

  snprintf(cmd, sizeof(cmd), "notepad.exe %s", config_file);
  WinExec(cmd, SW_SHOW);
}
Пример #4
0
// Return 1 if request is authorised, 0 otherwise.
static int check_authorization(struct mg_connection *conn, const char *path) {
  char fname[PATH_MAX];
  struct vec uri_vec, filename_vec;
  const char *list;
  FILE *fp = NULL;
  int authorized = 1;

  list = conn->ctx->config[PROTECT_URI];
  while ((list = next_option(list, &uri_vec, &filename_vec)) != NULL) {
    if (!memcmp(conn->request_info.uri, uri_vec.ptr, uri_vec.len)) {
      mg_snprintf(fname, sizeof(fname), "%.*s",
                  (int) filename_vec.len, filename_vec.ptr);
      fp = mg_fopen(fname, "r");
      break;
    }
  }

  if (fp == NULL) {
    fp = open_auth_file(conn, path);
  }

  if (fp != NULL) {
    authorized = authorize(conn, fp);
    fclose(fp);
  }

  return authorized;
}
Пример #5
0
REPLACE_STATIC void handle_lsp_request(struct mg_connection *conn, const char *path,
                               struct file *filep) {
  void *p = NULL;
  lua_State *L = NULL;

  if (!mg_fopen(conn, path, "r", filep)) {
    send_http_error(conn, 404, "Not Found", "%s", "File not found");
  } else if (filep->membuf == NULL &&
             (p = mmap(NULL, filep->size, PROT_READ, MAP_PRIVATE,
                       fileno(filep->fp), 0)) == MAP_FAILED) {
    send_http_error(conn, 500, http_500_error, "%s", "x");
  } else if ((L = luaL_newstate()) == NULL) {
    send_http_error(conn, 500, http_500_error, "%s", "y");
  } else {
    mg_printf(conn, "%s", "HTTP/1.1 200 OK\r\n"
              "Content-Type: text/html\r\nConnection: close\r\n\r\n");
    prepare_lua_environment(conn, L);
    conn->request_info.ev_data = L;
    call_user(conn, MG_INIT_LUA);
    lsp(conn, filep->membuf == NULL ? p : filep->membuf, filep->size, L);
  }

  if (L) lua_close(L);
  if (p) munmap(p, filep->size);
  mg_fclose(filep);
}
Пример #6
0
static int is_authorized_for_put(struct mg_connection *conn) {
  const char *passfile = conn->ctx->config[PUT_DELETE_PASSWORDS_FILE];
  FILE *fp;
  int ret = 0;

  if (passfile != NULL && (fp = mg_fopen(passfile, "r")) != NULL) {
    ret = authorize(conn, fp);
    fclose(fp);
  }

  return ret;
}
Пример #7
0
void mg_hexdump_connection(struct mg_connection *nc, const char *path,
                           const void *buf, int num_bytes, int ev) {
  FILE *fp = NULL;
  char src[60], dst[60];
  const char *tag = NULL;
  switch (ev) {
    case MG_EV_RECV:
      tag = "<-";
      break;
    case MG_EV_SEND:
      tag = "->";
      break;
    case MG_EV_ACCEPT:
      tag = "<A";
      break;
    case MG_EV_CONNECT:
      tag = "C>";
      break;
    case MG_EV_CLOSE:
      tag = "XX";
      break;
  }
  if (tag == NULL) return; /* Don't log MG_EV_TIMER, etc */

  if (strcmp(path, "-") == 0) {
    fp = stdout;
  } else if (strcmp(path, "--") == 0) {
    fp = stderr;
#if MG_ENABLE_FILESYSTEM
  } else {
    fp = mg_fopen(path, "a");
#endif
  }
  if (fp == NULL) return;

  mg_conn_addr_to_str(nc, src, sizeof(src),
                      MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
  mg_conn_addr_to_str(nc, dst, sizeof(dst), MG_SOCK_STRINGIFY_IP |
                                                MG_SOCK_STRINGIFY_PORT |
                                                MG_SOCK_STRINGIFY_REMOTE);
  fprintf(fp, "%lu %p %s %s %s %d\n", (unsigned long) mg_time(), (void *) nc,
          src, tag, dst, (int) num_bytes);
  if (num_bytes > 0) {
    mg_hexdumpf(fp, buf, num_bytes);
  }
  if (fp != stdout && fp != stderr) fclose(fp);
}
Пример #8
0
static void process_command_line_arguments(char *argv[], char **options) {
  char line[MAX_CONF_FILE_LINE_SIZE], opt[sizeof(line)], val[sizeof(line)], *p;
  FILE *fp = NULL;
  size_t i;
  int cmd_line_opts_start = 1;
  int line_no = 0;

  options[0] = NULL;

  // Should we use a config file ?
  if (argv[1] != NULL && argv[2] == NULL) {
    snprintf(config_file, sizeof(config_file), "%s", argv[1]);
    cmd_line_opts_start = 2;
  } else if ((p = strrchr(argv[0], DIRSEP)) == NULL) {
    // No command line flags specified. Look where binary lives
    snprintf(config_file, sizeof(config_file), "%s", CONFIG_FILE);
  } else {
    snprintf(config_file, sizeof(config_file), "%.*s%c%s",
             (int) (p - argv[0]), argv[0], DIRSEP, CONFIG_FILE);
  }

  fp = mg_fopen(config_file, "r");

  // If config file was set in command line and open failed, exit
  if (argv[1] != NULL && argv[2] == NULL && fp == NULL) {
    die("Cannot open config file %s: %s", config_file, mg_strerror(ERRNO));
  }

  // use the default values for starters (so that all options have a known reasonable value):
  for (i = 0; default_options[i]; i += 2) {
    set_option(options, default_options[i], default_options[i+1]);
  }

  // Load config file settings first
  if (fp != NULL) {
    fprintf(stderr, "Loading config file %s\n", config_file);

    // Loop over the lines in config file
    while (fgets(line, sizeof(line), fp) != NULL) {

      if (!line_no && !memcmp(line,"\xEF\xBB\xBF", 3)) {
        // strip UTF-8 BOM
        p = line+3;
      } else {
        p = line;
      }

      line_no++;

      // Ignore empty lines (with optional, ignored, whitespace) and comments
      if (line[0] == '#')
        continue;

      // MS sscanf() says: The return value is EOF for an error or if the end of the string is reached before the first conversion.
      // Hence we make sure we don't feed it an empty line --> -1 will only have one meaning then.
      if (line[strspn(line, " \t\r\n")] == 0)
        continue;

      if (2 == sscanf(line, "%s %[^\r\n#]", opt, val)) {
        set_option(options, opt, val);
        continue;
      } else {
        die("%s: line %d is invalid", config_file, line_no);
        break;
      }
    }

    (void) mg_fclose(fp);
  }

  // Handle command line flags. They override config file and default settings.
  for (i = cmd_line_opts_start; argv[i] != NULL; i += 2) {
    if (argv[i][0] != '-' || argv[i + 1] == NULL) {
      show_usage_and_exit(ctx);
    }
    set_option(options, &argv[i][1], argv[i + 1]);
  }
}