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 ... */ } }
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"); } } }
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; }