Beispiel #1
0
void handle_request(void* data, struct pk_chunk *chunk) {
  char buffer[4096];
  char *hi = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello World\n";
  struct pk_conn* pkc = data;
  int bytes;

  pk_log_chunk(chunk);
  if (chunk->ping) {
    bytes = pk_format_pong(buffer);
    pkc_write(pkc, buffer, bytes);
  }
  else if (chunk->sid) {
    if (chunk->eof) {
      /* Ignored, for now */
    }
    else if (!chunk->noop) {

      /* Send a reply, and close this channel right away */
      bytes = pk_format_reply(buffer, chunk->sid, strlen(hi), hi);
      pkc_write(pkc, buffer, bytes);

      bytes = pk_format_eof(buffer, chunk->sid, PK_EOF);
      pkc_write(pkc, buffer, bytes);
    }
  }
  else {
    /* Weirdness ... */
  }
}
Beispiel #2
0
void pkr_relay_incoming(int result, void* void_data) {
  struct incoming_conn_state* ics = (struct incoming_conn_state*) void_data;

  PK_TRACE_FUNCTION;

  if (ics->parse_state == PARSE_FAILED) {
    pk_log(PK_LOG_TUNNEL_DATA|PK_LOG_ERROR,
           "pkr_relay_incoming() invoked for dead ics");
    return; /* Should never happen */
  }

  if (result == PARSE_WANT_MORE_DATA) {
    if (pk_time() - ics->created > 5) {
      /* We don't wait forever for more data; that would make resource
       * exhaustion DOS attacks against the server trivially easy. */
      _pkr_close(ics, 0, "Timed out");
    }
    else {
      /* Slow down a tiny bit, unless there are jobs in the queue waiting
       * for us to finish. */
      if (ics->pkm->blocking_jobs.count < 1) sleep_ms(100);
      _pkr_process_readable(ics);
    }
  }
  else {
    /* If we get this far, then the request has been parsed and we have
     * in ics details about what needs to be done. So we do it! :)
     */

    if (ics->parsed_as == PROTO_PAGEKITE) {
      char* response = NULL;
      struct pke_event* ev = pke_post_blocking_event(NULL,
        PK_EV_TUNNEL_REQUEST, 0, ics->unparsed_data, NULL, &response);

      int rlen = 0;
      if (response && *response) {
        rlen = strlen(response);
        pkc_write(&(ics->pkb->conn), response, rlen);
      }

      int result_ok = rlen && ev && (ev->response_code & PK_EV_RESPOND_TRUE);
      if (result_ok) {
        /* FIXME: Upgrade this connection to a tunnel */

        int flying = 0;
        struct pk_kite_request* pkr = pk_parse_pagekite_response(
          response, rlen + 1, NULL, NULL);
        if (pkr != NULL) {
          struct pk_kite_request* p;
          for (p = pkr; p->status != PK_KITE_UNKNOWN; p++) {
            if (p->status == PK_KITE_FLYING) {
              /* FIXME: Record kite->tunnel mapping */
              pk_log(PK_LOG_MANAGER_DEBUG, "Accepted kite: %s://%s:%d",
                                           p->kite->protocol,
                                           p->kite->public_domain,
                                           p->kite->public_port);
              flying++;
            }
            else {
              pk_log(PK_LOG_MANAGER_DEBUG, "Rejected kite: %s://%s:%d (%d)",
                                           p->kite->protocol,
                                           p->kite->public_domain,
                                           p->kite->public_port,
                                           p->status);
            }
          }
          free(pkr);

          /* FIXME: Add to event loop */
        }

        if (!flying) result_ok = 0;
      }

      if (ev) pke_free_event(NULL, ev->event_code);
      if (response) free(response);
      if (!result_ok) _pkr_close(ics, 0, "Rejected");
    }
    else {
      _pkr_close(ics, 0, "FIXME");
    }
  }
}
Beispiel #3
0
static gpg_error_t
write_extended_private_key (char *fname, estream_t fp,
                            const void *buf, size_t len)
{
  gpg_error_t err;
  pkc_t pk = NULL;
  gcry_sexp_t key = NULL;
  int remove = 0;
  int line;

  err = pkc_parse (&pk, &line, fp);
  if (err)
    {
      log_error ("error parsing '%s' line %d: %s\n",
                 fname, line, gpg_strerror (err));
      goto leave;
    }

  err = gcry_sexp_sscan (&key, NULL, buf, len);
  if (err)
    goto leave;

  err = pkc_set_private_key (pk, key);
  if (err)
    goto leave;

  err = es_fseek (fp, 0, SEEK_SET);
  if (err)
    goto leave;

  err = pkc_write (pk, fp);
  if (err)
    {
      log_error ("error writing '%s': %s\n", fname, gpg_strerror (err));
      remove = 1;
      goto leave;
    }

  if (ftruncate (es_fileno (fp), es_ftello (fp)))
    {
      err = gpg_error_from_syserror ();
      log_error ("error truncating '%s': %s\n", fname, gpg_strerror (err));
      remove = 1;
      goto leave;
    }

  if (es_fclose (fp))
    {
      err = gpg_error_from_syserror ();
      log_error ("error closing '%s': %s\n", fname, gpg_strerror (err));
      remove = 1;
      goto leave;
    }
  else
    fp = NULL;

  bump_key_eventcounter ();

 leave:
  if (fp)
    es_fclose (fp);
  if (remove)
    gnupg_remove (fname);
  xfree (fname);
  gcry_sexp_release (key);
  pkc_release (pk);
  return err;
}