Beispiel #1
0
static void
delete_find_items_cb (GnomeKeyringResult result, GList *list, gpointer user_data)
{
	KeyringCall *call = user_data;
	Request *r = call->r;
	GList *iter;
	GError *error = NULL;

	r->keyring_calls = g_slist_remove (r->keyring_calls, call);
	if (r->canceled) {
		/* Callback already called by NM or dispose */
		request_free (r);
		return;
	}

	if ((result == GNOME_KEYRING_RESULT_OK) || (result == GNOME_KEYRING_RESULT_NO_MATCH)) {
		for (iter = list; iter != NULL; iter = g_list_next (iter)) {
			GnomeKeyringFound *found = (GnomeKeyringFound *) iter->data;

			gnome_keyring_item_delete (found->keyring, found->item_id, keyring_delete_cb, NULL, NULL);
		}
	} else {
		error = g_error_new (NM_SECRET_AGENT_ERROR,
		                     NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
		                     "The request could not be completed.  Keyring result: %d",
		                     result);
	}

	r->delete_callback (r->agent, r->connection, error, r->callback_data);
	request_free (r);
}
Beispiel #2
0
void read_handler(aeEventLoop *el, int fd, void *privdata, int mask)
{
	int err;
	int nread;
	(void) mask;
	char buf[BUF_SIZE]={0};
	struct request *req = (struct request*)privdata;

	nread = read(fd, buf, BUF_SIZE);

	if (nread < 1) {
		request_free(req);
		aeDeleteFileEvent(el, fd, AE_WRITABLE);
		aeDeleteFileEvent(el, fd, AE_READABLE);
		close(fd);
		_clicount--;
		return;
	} else {
		request_append(req, buf, nread);
		err = request_parse(req);
		if (err == -1) {
			request_free(req);
			aeDeleteFileEvent(el, fd, AE_WRITABLE);
			aeDeleteFileEvent(el, fd, AE_READABLE);
			close(fd);
			_clicount--;
			return;
		}

		if (err == 1) {
			_process_cmd(fd, req);
			request_clean(req);
		}
	}
}
static void
delete_find_items_cb (GObject *source,
                      GAsyncResult *result,
                      gpointer user_data)
{
	Request *r = user_data;
	GError *secret_error = NULL;
	GError *error = NULL;

	r->keyring_calls--;
	if (g_cancellable_is_cancelled (r->cancellable)) {
		/* Callback already called by NM or dispose */
		request_free (r);
		return;
	}

	secret_password_clear_finish (result, &secret_error);
	if (secret_error != NULL) {
		error = g_error_new (NM_SECRET_AGENT_ERROR,
		                     NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
		                     "The request could not be completed (%s)",
		                     secret_error->message);
		g_error_free (secret_error);
	}

	r->delete_callback (r->agent, r->connection, error, r->callback_data);
	request_free (r);
}
Beispiel #4
0
gboolean net_io_download_file(GtkWidget *parent, settings_t *settings,
			      char *url, char *filename, const char *title) {
  net_io_request_t *request = g_new0(net_io_request_t, 1);

  printf("net_io: download %s to file %s\n", url, filename);
  request->type = NET_IO_DL_FILE;
  request->url = g_strdup(url);
  request->filename = g_strdup(filename);
  if(settings && settings->proxy)
    request->proxy = settings->proxy;

  gboolean result = net_io_do(parent, request, title);
  if(!result) {

    /* remove the file that may have been written by now. the kernel */
    /* should cope with the fact that the worker thread may still have */
    /* an open reference to this and might thus still write to this file. */
    /* letting the worker delete the file is worse since it may take the */
    /* worker some time to come to the point to delete this file. If the */
    /* user has restarted the download by then, the worker will erase that */
    /* newly written file */

    printf("request failed, deleting %s\n", filename);
    g_remove(filename);
  } else
    printf("request ok\n");

  request_free(request);
  return result;
}
Beispiel #5
0
void request_send(struct fuse_conn *fc, struct fuse_in *in,
		  struct fuse_out *out)
{
	struct fuse_req *req;

	out->h.error = -ERESTARTSYS;
	if(down_interruptible(&fc->outstanding))
		return;

	out->h.error = -ENOMEM;
	req = request_new();
	if(!req)
		return;

	req->in = in;
	req->out = out;
	req->issync = 1;

	spin_lock(&fuse_lock);
	out->h.error = -ENOTCONN;
	if(fc->file) {
		in->h.unique = get_unique(fc);		
		list_add_tail(&req->list, &fc->pending);
		wake_up(&fc->waitq);
		request_wait_answer(req);
		list_del(&req->list);
	}
	spin_unlock(&fuse_lock);
	request_free(req);

	up(&fc->outstanding);
}
Beispiel #6
0
/**
 * here is the heart of SoftGREd/service
 */
static void *
thread_handler(void *arg)
{
    struct request *req = arg;

#if 0
    const char *host = inet_ntoa(req->saddr.sin_addr);

    D_DEBUG0("[fd=%d] handling request from %s\n", req->fd, host);

    int i = 0;
    for (i=0; i < req->argc; i++)
        D_DEBUG2("argv[%d]='%s'\n", i, req->argv[i]);
#endif

    if (!service_cmd_handler(req))
        request_appendf(req, "The command '%s' is invalid, try 'HELP'\n", req->argv[0]);

    // end request
    if (req)
        request_free(req);

    // bye
    pthread_exit(0);
    return NULL;
}
inline NSAPIEnvironment::~NSAPIEnvironment()
{
    // Tidy up the thread-specific "globals" for the next caller
    conf_reset_thread_globals();

    // Discard the request
    if (rq)
        request_free(rq);

    // Discard the session
    if (sn) {
        if (sn->csd && sn->csd_open)
            PR_Close(sn->csd);
        sn->csd_open = 0;
        session_free(sn);
    }

    // Restore the caller's pool.  session_free() set it to NULL
    if (poolCaller)
        systhread_setdata(keyPool, poolCaller);

    // This may have been a request thread.  If it was, we need to restore the
    // HttpRequest* for the thread-specific "globals".
    if (hrq) {
        HttpRequest::SetCurrentRequest(hrq);
        conf_set_thread_globals(hrq);
    }
    else {
        conf_set_thread_globals(threadHrq, threadVS);
    }
}
Beispiel #8
0
static inline void destroy_request(struct fuse_conn *fc, struct fuse_req *req)
{
	if(req) {
		int i;

		for(i = 0; i < req->in->numargs; i++)
			kfree(req->in->args[i].value);
		kfree(req->in);
		request_free(req);
	}
}
static void
save_request_try_complete (Request *r)
{
	/* Only call the SaveSecrets callback and free the request when all the
	 * secrets have been saved to the keyring.
	 */
	if (r->keyring_calls == 0) {
		if (!g_cancellable_is_cancelled (r->cancellable))
			r->save_callback (NM_SECRET_AGENT (r->agent), r->connection, NULL, r->callback_data);
		request_free (r);
	}
}
Beispiel #10
0
gboolean net_io_download(GtkWidget *parent, char *url, char **mem) {
  net_io_request_t *request = g_new0(net_io_request_t, 1);

  request->proxy = proxy_config_get();
  request->url = g_strdup(url);

  gboolean result = net_io_do(parent, request);
  if(result) 
    *mem = request->result.data.ptr;
  
  request_free(request);
  return result;
}
Beispiel #11
0
static gboolean
request_try_free (Request *request)
{
    if (!g_cancellable_is_cancelled (request->cancellable))
        g_cancellable_cancel (request->cancellable);

    if (request->idle_funcs == 0)
        request_free (request);
    else
        g_idle_add ((GSourceFunc) request_try_free, request);

    return FALSE;
}
Beispiel #12
0
static void clear(struct mwService *srvc) {
  struct mwServiceStorage *srvc_stor;
  GList *l;

  srvc_stor = (struct mwServiceStorage *) srvc;

  for(l = srvc_stor->pending; l; l = l->next)
    request_free(l->data);

  g_list_free(srvc_stor->pending);
  srvc_stor->pending = NULL;

  srvc_stor->id_counter = 0;
}
Beispiel #13
0
static void
save_request_try_complete (Request *r, KeyringCall *call)
{
	/* Only call the SaveSecrets callback and free the request when all the
	 * secrets have been saved to the keyring.
	 */
	if (call)
		r->keyring_calls = g_slist_remove (r->keyring_calls, call);

	if (g_slist_length (r->keyring_calls) == 0) {
		if (r->canceled == FALSE)
			r->save_callback (NM_SECRET_AGENT (r->agent), r->connection, NULL, r->callback_data);
		request_free (r);
	}
}
Beispiel #14
0
gboolean net_io_download_mem(GtkWidget *parent, settings_t *settings,
			     char *url, char **mem) {
  net_io_request_t *request = g_new0(net_io_request_t, 1);

  printf("net_io: download %s to memory\n", url);
  request->type = NET_IO_DL_MEM;
  request->url = g_strdup(url);
  if(settings && settings->proxy)
    request->proxy = settings->proxy;

  gboolean result = net_io_do(parent, request, NULL);
  if(result) {
    printf("ptr = %p, len = %d\n", request->mem.ptr, request->mem.len);
    *mem = request->mem.ptr;
  }

  request_free(request);
  return result;
}
Beispiel #15
0
static void stop(struct mwService *srvc) {

  struct mwServiceStorage *srvc_store;
  GList *l;

  g_return_if_fail(srvc != NULL);
  srvc_store = (struct mwServiceStorage *) srvc;

  if(srvc_store->channel) {
    mwChannel_destroy(srvc_store->channel, ERR_SUCCESS, NULL);
    srvc_store->channel = NULL;
  }

#if 1
  /* the new way */
  /* remove pending requests. Sometimes we can crash the storage
     service, and when that happens, we end up resending the killer
     request over and over again, and the service never stays up */
  for(l = srvc_store->pending; l; l = l->next)
    request_free(l->data);

  g_list_free(srvc_store->pending);
  srvc_store->pending = NULL;

  srvc_store->id_counter = 0;

#else
  /* the old way */
  /* reset all of the started requests to their unstarted states */
  for(l = srvc_store->pending; l; l = l->next) {
    struct mwStorageReq *req = l->data;

    if(req->action == action_loaded) {
      req->action = action_load;
    } else if(req->action == action_saved) {
      req->action = action_save;
    }
  }
#endif

  mwService_stopped(srvc);
}
Beispiel #16
0
static gboolean net_io_idle_cb(gpointer data) {
  net_io_request_t *request = (net_io_request_t *)data;

  /* the http connection itself may have failed */
  if(request->res != 0) {
    request->result.code = 2;
    printf("Download failed with message: %s\n", request->buffer);
  } else  if(request->response != 200) {
    /* a valid http connection may have returned an error */
    request->result.code = 3;
    printf("Download failed with code %ld: %s\n", 
	   request->response, http_message(request->response));
  }

  /* call application callback */
  if(request->cb)
    request->cb(&request->result, request->data);

  request_free(request);

  return FALSE;
}
static void
get_secrets_cb (AppletAgent *self,
                GHashTable *secrets,
                GError *error,
                gpointer user_data)
{
	Request *r = user_data;

	/* 'secrets' shouldn't be valid if there was an error */
	if (error) {
		g_warn_if_fail (secrets == NULL);
		secrets = NULL;
	}

	if (!g_cancellable_is_cancelled (r->cancellable)) {
		/* Save updated secrets as long as user-interaction was allowed; otherwise
		 * we'd be saving secrets we just pulled out of the keyring which is somewhat
		 * redundant.
		 */
		if (secrets && (r->flags != NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE)) {
			NMConnection *dupl;
			GHashTableIter iter;
			const char *setting_name;

			/* Copy the existing connection and update its secrets */
			dupl = nm_connection_duplicate (r->connection);
			g_hash_table_iter_init (&iter, secrets);
			while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, NULL))
				nm_connection_update_secrets (dupl, setting_name, secrets, NULL);

			/* And save updated secrets to the keyring */
			nm_secret_agent_save_secrets (NM_SECRET_AGENT (self), dupl, get_save_cb, NULL);
			g_object_unref (dupl);
		}

		r->get_callback (NM_SECRET_AGENT (r->agent), r->connection, secrets, error, r->callback_data);
	}
	request_free (r);
}
Beispiel #18
0
/*
 *	Free a REQUEST struct.
 */
void request_free(REQUEST **request_ptr)
{
	REQUEST *request;

	if (!request_ptr || !*request_ptr) {
		return;
	}

	request = *request_ptr;

	rad_assert(!request->in_request_hash);
#ifdef WITH_PROXY
	rad_assert(!request->in_proxy_hash);
#endif
	rad_assert(!request->ev);

#ifdef WITH_COA
	if (request->coa) {
		request->coa->parent = NULL;
		request_free(&request->coa);
	}

	if (request->parent && (request->parent->coa == request)) {
		request->parent->coa = NULL;
	}
#endif

#ifndef NDEBUG
	request->magic = 0x01020304;	/* set the request to be nonsense */
#endif
	request->client = NULL;
#ifdef WITH_PROXY
	request->home_server = NULL;
#endif
	talloc_free(request);
	*request_ptr = NULL;

	VERIFY_ALL_TALLOC;
}
Beispiel #19
0
REQUEST *request_alloc_coa(REQUEST *request)
{
	if (!request || request->coa) return NULL;

	/*
	 *	Originate CoA requests only when necessary.
	 */
	if ((request->packet->code != PW_AUTHENTICATION_REQUEST) &&
	    (request->packet->code != PW_ACCOUNTING_REQUEST)) return NULL;

	request->coa = request_alloc_fake(request);
	if (!request->coa) return NULL;

	request->coa->packet->code = 0; /* unknown, as of yet */
	request->coa->child_state = REQUEST_RUNNING;
	request->coa->proxy = rad_alloc(request->coa, 0);
	if (!request->coa->proxy) {
		request_free(&request->coa);
		return NULL;
	}

	return request->coa;
}
Beispiel #20
0
/* This one is currently only used for sending FORGET and RELEASE,
   which are kernel initiated request.  So the outstanding semaphore
   is not used.  */
int request_send_noreply(struct fuse_conn *fc, struct fuse_in *in)
{
	struct fuse_req *req;

	req = request_new();
	if(!req)
		return -ENOMEM;

	req->in = in;
	req->issync = 0;

	spin_lock(&fuse_lock);
	if(!fc->file) {
		spin_unlock(&fuse_lock);
		request_free(req);
		return -ENOTCONN;
	}

	list_add_tail(&req->list, &fc->pending);
	wake_up(&fc->waitq);
	spin_unlock(&fuse_lock);
	return 0;
}
static int tls_socket_recv(rad_listen_t *listener)
{
	int doing_init = FALSE;
	ssize_t rcode;
	RADIUS_PACKET *packet;
	REQUEST *request;
	listen_socket_t *sock = listener->data;
	fr_tls_status_t status;
	RADCLIENT *client = sock->client;

	if (!sock->packet) {
		sock->packet = rad_alloc(0);
		if (!sock->packet) return 0;

		sock->packet->sockfd = listener->fd;
		sock->packet->src_ipaddr = sock->other_ipaddr;
		sock->packet->src_port = sock->other_port;
		sock->packet->dst_ipaddr = sock->my_ipaddr;
		sock->packet->dst_port = sock->my_port;

		if (sock->request) sock->request->packet = sock->packet;
	}

	/*
	 *	Allocate a REQUEST for debugging.
	 */
	if (!sock->request) {
		sock->request = request = request_alloc();
		if (!sock->request) {
			radlog(L_ERR, "Out of memory");
			return 0;
		}

		rad_assert(request->packet == NULL);
		rad_assert(sock->packet != NULL);
		request->packet = sock->packet;

		request->component = "<core>";
		request->component = "<tls-connect>";

		/*
		 *	Not sure if we should do this on every packet...
		 */
		request->reply = rad_alloc(0);
		if (!request->reply) return 0;

		request->options = RAD_REQUEST_OPTION_DEBUG2;

		rad_assert(sock->ssn == NULL);

		sock->ssn = tls_new_session(listener->tls, sock->request,
					    listener->tls->require_client_cert);
		if (!sock->ssn) {
			request_free(&sock->request);
			sock->packet = NULL;
			return 0;
		}

		SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_REQUEST, (void *)request);
		SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_CERTS, (void *)&request->packet->vps);

		doing_init = TRUE;
	}

	rad_assert(sock->request != NULL);
	rad_assert(sock->request->packet != NULL);
	rad_assert(sock->packet != NULL);
	rad_assert(sock->ssn != NULL);

	request = sock->request;

	RDEBUG3("Reading from socket %d", request->packet->sockfd);
	PTHREAD_MUTEX_LOCK(&sock->mutex);
	rcode = read(request->packet->sockfd,
		     sock->ssn->dirty_in.data,
		     sizeof(sock->ssn->dirty_in.data));
	if ((rcode < 0) && (errno == ECONNRESET)) {
	do_close:
		PTHREAD_MUTEX_UNLOCK(&sock->mutex);
		tls_socket_close(listener);
		return 0;
	}
	
	if (rcode < 0) {
		RDEBUG("Error reading TLS socket: %s", strerror(errno));
		goto do_close;
	}

	/*
	 *	Normal socket close.
	 */
	if (rcode == 0) goto do_close;
	
	sock->ssn->dirty_in.used = rcode;
	memset(sock->ssn->dirty_in.data + sock->ssn->dirty_in.used,
	       0, 16);

	dump_hex("READ FROM SSL", sock->ssn->dirty_in.data, sock->ssn->dirty_in.used);

	/*
	 *	Catch attempts to use non-SSL.
	 */
	if (doing_init && (sock->ssn->dirty_in.data[0] != handshake)) {
		RDEBUG("Non-TLS data sent to TLS socket: closing");
		goto do_close;
	}
	
	/*
	 *	Skip ahead to reading application data.
	 */
	if (SSL_is_init_finished(sock->ssn->ssl)) goto app;

	if (!tls_handshake_recv(request, sock->ssn)) {
		RDEBUG("FAILED in TLS handshake receive");
		goto do_close;
	}
	
	if (sock->ssn->dirty_out.used > 0) {
		tls_socket_write(listener, request);
		PTHREAD_MUTEX_UNLOCK(&sock->mutex);
		return 0;
	}

app:
	/*
	 *	FIXME: Run the packet through a virtual server in
	 *	order to see if we like the certificate presented by
	 *	the client.
	 */

	status = tls_application_data(sock->ssn, request);
	RDEBUG("Application data status %d", status);

	if (status == FR_TLS_MORE_FRAGMENTS) {
		PTHREAD_MUTEX_UNLOCK(&sock->mutex);
		return 0;
	}

	if (sock->ssn->clean_out.used == 0) {
		PTHREAD_MUTEX_UNLOCK(&sock->mutex);
		return 0;
	}

	dump_hex("TUNNELED DATA", sock->ssn->clean_out.data, sock->ssn->clean_out.used);

	/*
	 *	If the packet is a complete RADIUS packet, return it to
	 *	the caller.  Otherwise...
	 */
	if ((sock->ssn->clean_out.used < 20) ||
	    (((sock->ssn->clean_out.data[2] << 8) | sock->ssn->clean_out.data[3]) != (int) sock->ssn->clean_out.used)) {
		RDEBUG("Received bad packet: Length %d contents %d",
		       sock->ssn->clean_out.used,
		       (sock->ssn->clean_out.data[2] << 8) | sock->ssn->clean_out.data[3]);
		goto do_close;
	}

	packet = sock->packet;
	packet->data = rad_malloc(sock->ssn->clean_out.used);
	packet->data_len = sock->ssn->clean_out.used;
	sock->ssn->record_minus(&sock->ssn->clean_out, packet->data, packet->data_len);
	packet->vps = NULL;
	PTHREAD_MUTEX_UNLOCK(&sock->mutex);

	if (!rad_packet_ok(packet, 0)) {
		RDEBUG("Received bad packet: %s", fr_strerror());
		tls_socket_close(listener);
		return 0;	/* do_close unlocks the mutex */
	}

	/*
	 *	Copied from src/lib/radius.c, rad_recv();
	 */
	if (fr_debug_flag) {
		char host_ipaddr[128];

		if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) {
			RDEBUG("tls_recv: %s packet from host %s port %d, id=%d, length=%d",
			       fr_packet_codes[packet->code],
			       inet_ntop(packet->src_ipaddr.af,
					 &packet->src_ipaddr.ipaddr,
					 host_ipaddr, sizeof(host_ipaddr)),
			       packet->src_port,
			       packet->id, (int) packet->data_len);
		} else {
			RDEBUG("tls_recv: Packet from host %s port %d code=%d, id=%d, length=%d",
			       inet_ntop(packet->src_ipaddr.af,
					 &packet->src_ipaddr.ipaddr,
					 host_ipaddr, sizeof(host_ipaddr)),
			       packet->src_port,
			       packet->code,
			       packet->id, (int) packet->data_len);
		}
	}

	FR_STATS_INC(auth, total_requests);

	return 1;
}
Beispiel #22
0
/*
 * Fetches the resource denoted by |uri|.
 */
static void fetch_uri(const struct URI *uri)
{
  spdylay_session_callbacks callbacks;
  int fd;
  SSL_CTX *ssl_ctx;
  SSL *ssl;
  struct Request req;
  struct Connection connection;
  int rv;
  nfds_t npollfds = 1;
  struct pollfd pollfds[1];
  uint16_t spdy_proto_version;

  request_init(&req, uri);

  setup_spdylay_callbacks(&callbacks);

  /* Establish connection and setup SSL */
  fd = connect_to(req.host, req.port);
  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
  if(ssl_ctx == NULL) {
    dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL));
  }
  init_ssl_ctx(ssl_ctx, &spdy_proto_version);
  ssl = SSL_new(ssl_ctx);
  if(ssl == NULL) {
    dief("SSL_new", ERR_error_string(ERR_get_error(), NULL));
  }
  /* To simplify the program, we perform SSL/TLS handshake in blocking
     I/O. */
  ssl_handshake(ssl, fd);

  connection.ssl = ssl;
  connection.want_io = IO_NONE;

  /* Here make file descriptor non-block */
  make_non_block(fd);
  set_tcp_nodelay(fd);

  printf("[INFO] SPDY protocol version = %d\n", spdy_proto_version);
  rv = spdylay_session_client_new(&connection.session, spdy_proto_version,
                                  &callbacks, &connection);
  if(rv != 0) {
    diec("spdylay_session_client_new", rv);
  }

  /* Submit the HTTP request to the outbound queue. */
  submit_request(&connection, &req);

  pollfds[0].fd = fd;
  ctl_poll(pollfds, &connection);

  /* Event loop */
  while(spdylay_session_want_read(connection.session) ||
        spdylay_session_want_write(connection.session)) {
    int nfds = poll(pollfds, npollfds, -1);
    if(nfds == -1) {
      dief("poll", strerror(errno));
    }
    if(pollfds[0].revents & (POLLIN | POLLOUT)) {
      exec_io(&connection);
    }
    if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) {
      die("Connection error");
    }
    ctl_poll(pollfds, &connection);
  }

  /* Resource cleanup */
  spdylay_session_del(connection.session);
  SSL_shutdown(ssl);
  SSL_free(ssl);
  SSL_CTX_free(ssl_ctx);
  shutdown(fd, SHUT_WR);
  close(fd);
  request_free(&req);
}
Beispiel #23
0
/*
 *	Free a request.
 */
int request_opaque_free(REQUEST *request)
{
	request_free(&request);

	return 0;
}
Beispiel #24
0
static REQUEST *request_setup(FILE *fp)
{
	VALUE_PAIR *vp;
	REQUEST *request;
	vp_cursor_t cursor;

	/*
	 *	Create and initialize the new request.
	 */
	request = request_alloc(NULL);

	request->packet = rad_alloc(request, 0);
	if (!request->packet) {
		ERROR("No memory");
		request_free(&request);
		return NULL;
	}

	request->reply = rad_alloc(request, 0);
	if (!request->reply) {
		ERROR("No memory");
		request_free(&request);
		return NULL;
	}

	request->listener = listen_alloc(request);
	request->client = client_alloc(request);

	request->number = 0;

	request->master_state = REQUEST_ACTIVE;
	request->child_state = REQUEST_RUNNING;
	request->handle = NULL;
	request->server = talloc_typed_strdup(request, "default");

	request->root = &mainconfig;

	/*
	 *	Read packet from fp
	 */
	request->packet->vps = readvp2(request->packet, fp, &filedone, "radiusd:");
	if (!request->packet->vps) {
		talloc_free(request);
		return NULL;
	}

	/*
	 *	Set the defaults for IPs, etc.
	 */
	request->packet->code = PW_CODE_AUTHENTICATION_REQUEST;

	request->packet->src_ipaddr.af = AF_INET;
	request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->src_port = 18120;

	request->packet->dst_ipaddr.af = AF_INET;
	request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->dst_port = 1812;

	/*
	 *	Copied from radclient
	 */
#if 1
	/*
	 *	Fix up Digest-Attributes issues
	 */
	for (vp = fr_cursor_init(&cursor, &request->packet->vps);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
		/*
		 *	Double quoted strings get marked up as xlat expansions,
		 *	but we don't support that here.
		 */
		if (vp->type == VT_XLAT) {
			vp->vp_strvalue = vp->value.xlat;
			vp->value.xlat = NULL;
			vp->type = VT_DATA;
		}

		if (!vp->da->vendor) switch (vp->da->attr) {
			default:
				break;

				/*
				 *	Allow it to set the packet type in
				 *	the attributes read from the file.
				 */
			case PW_PACKET_TYPE:
				request->packet->code = vp->vp_integer;
				break;

			case PW_PACKET_DST_PORT:
				request->packet->dst_port = (vp->vp_integer & 0xffff);
				break;

			case PW_PACKET_DST_IP_ADDRESS:
				request->packet->dst_ipaddr.af = AF_INET;
				request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
				break;

			case PW_PACKET_DST_IPV6_ADDRESS:
				request->packet->dst_ipaddr.af = AF_INET6;
				request->packet->dst_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
				break;

			case PW_PACKET_SRC_PORT:
				request->packet->src_port = (vp->vp_integer & 0xffff);
				break;

			case PW_PACKET_SRC_IP_ADDRESS:
				request->packet->src_ipaddr.af = AF_INET;
				request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
				break;

			case PW_PACKET_SRC_IPV6_ADDRESS:
				request->packet->src_ipaddr.af = AF_INET6;
				request->packet->src_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
				break;

			case PW_CHAP_PASSWORD: {
				int i, already_hex = 0;

				/*
				 *	If it's 17 octets, it *might* be already encoded.
				 *	Or, it might just be a 17-character password (maybe UTF-8)
				 *	Check it for non-printable characters.  The odds of ALL
				 *	of the characters being 32..255 is (1-7/8)^17, or (1/8)^17,
				 *	or 1/(2^51), which is pretty much zero.
				 */
				if (vp->length == 17) {
					for (i = 0; i < 17; i++) {
						if (vp->vp_octets[i] < 32) {
							already_hex = 1;
							break;
						}
					}
				}

				/*
				 *	Allow the user to specify ASCII or hex CHAP-Password
				 */
				if (!already_hex) {
					uint8_t *p;
					size_t len, len2;

					len = len2 = vp->length;
					if (len2 < 17) len2 = 17;

					p = talloc_zero_array(vp, uint8_t, len2);

					memcpy(p, vp->vp_strvalue, len);

					rad_chap_encode(request->packet,
							p,
							fr_rand() & 0xff, vp);
					vp->vp_octets = p;
					vp->length = 17;
				}
			}
				break;

			case PW_DIGEST_REALM:
			case PW_DIGEST_NONCE:
			case PW_DIGEST_METHOD:
			case PW_DIGEST_URI:
			case PW_DIGEST_QOP:
			case PW_DIGEST_ALGORITHM:
			case PW_DIGEST_BODY_DIGEST:
			case PW_DIGEST_CNONCE:
			case PW_DIGEST_NONCE_COUNT:
			case PW_DIGEST_USER_NAME:
				/* overlapping! */
			{
				DICT_ATTR const *da;
				uint8_t *p, *q;

				p = talloc_array(vp, uint8_t, vp->length + 2);

				memcpy(p + 2, vp->vp_octets, vp->length);
				p[0] = vp->da->attr - PW_DIGEST_REALM + 1;
				vp->length += 2;
				p[1] = vp->length;

				da = dict_attrbyvalue(PW_DIGEST_ATTRIBUTES, 0);
				rad_assert(da != NULL);
				vp->da = da;

				/*
				 *	Re-do pairmemsteal ourselves,
				 *	because we play games with
				 *	vp->da, and pairmemsteal goes
				 *	to GREAT lengths to sanitize
				 *	and fix and change and
				 *	double-check the various
				 *	fields.
				 */
				memcpy(&q, &vp->vp_octets, sizeof(q));
				talloc_free(q);

				vp->vp_octets = talloc_steal(vp, p);
				vp->type = VT_DATA;

				VERIFY_VP(vp);
			}

			break;
			}
	} /* loop over the VP's we read in */
#endif

	if (debug_flag) {
		for (vp = fr_cursor_init(&cursor, &request->packet->vps);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			/*
			 *	Take this opportunity to verify all the VALUE_PAIRs are still valid.
			 */
			if (!talloc_get_type(vp, VALUE_PAIR)) {
				ERROR("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp));

				log_talloc_report(vp);
				rad_assert(0);
			}

			vp_print(fr_log_fp, vp);
		}
		fflush(fr_log_fp);
	}

	/*
	 *	FIXME: set IPs, etc.
	 */
	request->packet->code = PW_CODE_AUTHENTICATION_REQUEST;

	request->packet->src_ipaddr.af = AF_INET;
	request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->src_port = 18120;

	request->packet->dst_ipaddr.af = AF_INET;
	request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->dst_port = 1812;

	/*
	 *	Build the reply template from the request.
	 */
	request->reply->sockfd = request->packet->sockfd;
	request->reply->dst_ipaddr = request->packet->src_ipaddr;
	request->reply->src_ipaddr = request->packet->dst_ipaddr;
	request->reply->dst_port = request->packet->src_port;
	request->reply->src_port = request->packet->dst_port;
	request->reply->id = request->packet->id;
	request->reply->code = 0; /* UNKNOWN code */
	memcpy(request->reply->vector, request->packet->vector,
	       sizeof(request->reply->vector));
	request->reply->vps = NULL;
	request->reply->data = NULL;
	request->reply->data_len = 0;

	/*
	 *	Debugging
	 */
	request->options = debug_flag;
	request->radlog = vradlog_request;

	request->username = pairfind(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);
	request->password = pairfind(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY);

	return request;
}
static REQUEST *request_setup(FILE *fp)
{	
	REQUEST *request;

	/*
	 *	Create and initialize the new request.
	 */
	request = request_alloc(NULL);

	request->packet = rad_alloc(request, 0);
	if (!request->packet) {
		ERROR("No memory");
		request_free(&request);
		return NULL;
	}

	request->reply = rad_alloc(request, 0);
	if (!request->reply) {
		ERROR("No memory");
		request_free(&request);
		return NULL;
	}

	request->listener = listen_alloc(request);
	request->client = client_alloc(request);

	request->number = 0;

	request->master_state = REQUEST_ACTIVE;
	request->child_state = REQUEST_ACTIVE;
	request->handle = NULL;
	request->server = talloc_strdup(request, "default");

	request->root = &mainconfig;

	/*
	 *	Read packet from fp
	 */
	request->packet->vps = readvp2(request->packet, fp, &filedone, "radiusd:");
	if (!request->packet->vps) {
		talloc_free(request);
		return NULL;
	}

	/*
	 *	FIXME: set IPs, etc.
	 */
	request->packet->code = PW_CODE_AUTHENTICATION_REQUEST;

	request->packet->src_ipaddr.af = AF_INET;
	request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->src_port = 18120;

	request->packet->dst_ipaddr.af = AF_INET;
	request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->dst_port = 1812;

	/*
	 *	Build the reply template from the request.
	 */
	request->reply->sockfd = request->packet->sockfd;
	request->reply->dst_ipaddr = request->packet->src_ipaddr;
	request->reply->src_ipaddr = request->packet->dst_ipaddr;
	request->reply->dst_port = request->packet->src_port;
	request->reply->src_port = request->packet->dst_port;
	request->reply->id = request->packet->id;
	request->reply->code = 0; /* UNKNOWN code */
	memcpy(request->reply->vector, request->packet->vector,
	       sizeof(request->reply->vector));
	request->reply->vps = NULL;
	request->reply->data = NULL;
	request->reply->data_len = 0;

	/*
	 *	Debugging
	 */
	request->options = debug_flag;
	request->radlog = radlog_request;

	request->username = pairfind(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);
	request->password = pairfind(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY);

	return request;
}
Beispiel #26
0
static int
mod_authenticate (void *arg, eap_handler_t *handler)
{
    pwd_session_t *pwd_session;
    pwd_hdr *hdr;
    pwd_id_packet *id;
    eap_packet_t *response;
    REQUEST *request, *fake;
    VALUE_PAIR *pw, *vp;
    EAP_DS *eap_ds;
    int len, ret = 0;
    eap_pwd_t *inst = (eap_pwd_t *)arg;
    uint16_t offset;
    uint8_t exch, *buf, *ptr, msk[MSK_EMSK_LEN], emsk[MSK_EMSK_LEN];
    uint8_t peer_confirm[SHA256_DIGEST_LENGTH];
    BIGNUM *x = NULL, *y = NULL;

    if ((!handler) ||
	((eap_ds = handler->eap_ds) == NULL) ||
	(!inst)) {
	return 0;
    }
    pwd_session = (pwd_session_t *)handler->opaque;
    request = handler->request;
    response = handler->eap_ds->response;
    hdr = (pwd_hdr *)response->type.data;

    buf = hdr->data;
    len = response->type.length - sizeof(pwd_hdr);

    /*
     * see if we're fragmenting, if so continue until we're done
     */
    if (pwd_session->out_buf_pos) {
	if (len) {
	    RDEBUG2("pwd got something more than an ACK for a fragment");
	}
	return send_pwd_request(pwd_session, eap_ds);
    }

    /*
     * the first fragment will have a total length, make a
     * buffer to hold all the fragments
     */
    if (EAP_PWD_GET_LENGTH_BIT(hdr)) {
	if (pwd_session->in_buf) {
	    RDEBUG2("pwd already alloced buffer for fragments");
	    return 0;
	}
	pwd_session->in_buf_len = ntohs(buf[0] * 256 | buf[1]);
	if ((pwd_session->in_buf = talloc_zero_array(pwd_session, uint8_t,
						     pwd_session->in_buf_len)) == NULL) {
	    RDEBUG2("pwd cannot allocate %d buffer to hold fragments",
		    pwd_session->in_buf_len);
	    return 0;
	}
	memset(pwd_session->in_buf, 0, pwd_session->in_buf_len);
	pwd_session->in_buf_pos = 0;
	buf += sizeof(uint16_t);
	len -= sizeof(uint16_t);
    }

    /*
     * all fragments, including the 1st will have the M(ore) bit set,
     * buffer those fragments!
     */
    if (EAP_PWD_GET_MORE_BIT(hdr)) {
	rad_assert(pwd_session->in_buf != NULL);
	if ((pwd_session->in_buf_pos + len) > pwd_session->in_buf_len) {
	    RDEBUG2("pwd will not overflow a fragment buffer. Nope, not prudent.");
	    return 0;
	}
	memcpy(pwd_session->in_buf + pwd_session->in_buf_pos, buf, len);
	pwd_session->in_buf_pos += len;

	/*
	 * send back an ACK for this fragment
	 */
	exch = EAP_PWD_GET_EXCHANGE(hdr);
	eap_ds->request->code = PW_EAP_REQUEST;
	eap_ds->request->type.num = PW_EAP_PWD;
	eap_ds->request->type.length = sizeof(pwd_hdr);
	if ((eap_ds->request->type.data = talloc_array(eap_ds->request,
						       uint8_t, sizeof(pwd_hdr))) == NULL) {
	    return 0;
	}
	hdr = (pwd_hdr *)eap_ds->request->type.data;
	EAP_PWD_SET_EXCHANGE(hdr, exch);
	return 1;

    }

    if (pwd_session->in_buf) {
	/*
	 * the last fragment...
	 */
	if ((pwd_session->in_buf_pos + len) > pwd_session->in_buf_len) {
	    RDEBUG2("pwd will not overflow a fragment buffer. Nope, not prudent.");
	    return 0;
	}
	memcpy(pwd_session->in_buf + pwd_session->in_buf_pos, buf, len);
	buf = pwd_session->in_buf;
	len = pwd_session->in_buf_len;
    }

    switch (pwd_session->state) {
	case PWD_STATE_ID_REQ:
	    if (EAP_PWD_GET_EXCHANGE(hdr) != EAP_PWD_EXCH_ID) {
		RDEBUG2("pwd exchange is incorrect: not ID");
		return 0;
	    }
	    id = (pwd_id_packet *)buf;
	    if ((id->prf != EAP_PWD_DEF_PRF) ||
		(id->random_function != EAP_PWD_DEF_RAND_FUN) ||
		(id->prep != EAP_PWD_PREP_NONE) ||
		(memcmp(id->token, (char *)&pwd_session->token, 4)) ||
		(id->group_num != ntohs(pwd_session->group_num))) {
		RDEBUG2("pwd id response is invalid");
		return 0;
	    }
	    /*
	     * we've agreed on the ciphersuite, record it...
	     */
	    ptr = (uint8_t *)&pwd_session->ciphersuite;
	    memcpy(ptr, (char *)&id->group_num, sizeof(uint16_t));
	    ptr += sizeof(uint16_t);
	    *ptr = EAP_PWD_DEF_RAND_FUN;
	    ptr += sizeof(uint8_t);
	    *ptr = EAP_PWD_DEF_PRF;

	    pwd_session->peer_id_len = len - sizeof(pwd_id_packet);
	    if (pwd_session->peer_id_len >= sizeof(pwd_session->peer_id)) {
		RDEBUG2("pwd id response is malformed");
		return 0;
	    }
	    memcpy(pwd_session->peer_id, id->identity,
		    pwd_session->peer_id_len);
	    pwd_session->peer_id[pwd_session->peer_id_len] = '\0';

	    /*
	     * make fake request to get the password for the usable ID
	     */
	    if ((fake = request_alloc_fake(handler->request)) == NULL) {
		RDEBUG("pwd unable to create fake request!");
		return 0;
	    }
	    fake->username = pairmake_packet("User-Name", "", T_OP_EQ);
	    if (!fake->username) {
		RDEBUG("pwd unanable to create value pair for username!");
		request_free(&fake);
		return 0;
	    }
	    memcpy(fake->username->vp_strvalue, pwd_session->peer_id,
		   pwd_session->peer_id_len);
	    fake->username->length = pwd_session->peer_id_len;
	    fake->username->vp_strvalue[fake->username->length] = 0;

	    if ((vp = pairfind(request->config_items, PW_VIRTUAL_SERVER, 0, TAG_ANY)) != NULL) {
		    fake->server = vp->vp_strvalue;
		
	    } else if (inst->conf->virtual_server) {
		    fake->server = inst->conf->virtual_server;
		
	    } /* else fake->server == request->server */
	
	    if ((debug_flag > 0) && fr_log_fp) {
		    RDEBUG("Sending tunneled request");
		
		    debug_pair_list(fake->packet->vps);
		
		    fprintf(fr_log_fp, "server %s {\n",
			    (!fake->server) ? "" : fake->server);
	    }
	
	    /*
	     *	Call authorization recursively, which will
	     *	get the password.
	     */
	    process_authorize(0, fake);
	
	    /*
	     *	Note that we don't do *anything* with the reply
	     *	attributes.
	     */
	    if ((debug_flag > 0) && fr_log_fp) {
		    fprintf(fr_log_fp, "} # server %s\n",
			    (!fake->server) ? "" : fake->server);
		
		    RDEBUG("Got tunneled reply code %d", fake->reply->code);
		
		    debug_pair_list(fake->reply->vps);
	    }

	    if ((pw = pairfind(fake->config_items, PW_CLEARTEXT_PASSWORD, 0, TAG_ANY)) == NULL) {
		DEBUG2("failed to find password for %s to do pwd authentication",
		       pwd_session->peer_id);
		request_free(&fake);
		return 0;
	    }

	    if (compute_password_element(pwd_session, pwd_session->group_num,
					 pw->data.strvalue, strlen(pw->data.strvalue),
					 inst->conf->server_id, strlen(inst->conf->server_id),
					 pwd_session->peer_id, strlen(pwd_session->peer_id),
					 &pwd_session->token)) {
		DEBUG2("failed to obtain password element :-(");
		request_free(&fake);
		return 0;
	    }
	    request_free(&fake);

	    /*
	     * compute our scalar and element
	     */
	    if (compute_scalar_element(pwd_session, inst->bnctx)) {
		DEBUG2("failed to compute server's scalar and element");
		return 0;
	    }
	    if (((x = BN_new()) == NULL) ||
		((y = BN_new()) == NULL)) {
		DEBUG2("server point allocation failed");
		return 0;
	    }
	    /*
	     * element is a point, get both coordinates: x and y
	     */
	    if (!EC_POINT_get_affine_coordinates_GFp(pwd_session->group,
						     pwd_session->my_element, x, y,
						     inst->bnctx)) {
		DEBUG2("server point assignment failed");
		BN_free(x);
		BN_free(y);
		return 0;
	    }
	    /*
	     * construct request
	     */
	    pwd_session->out_buf_len = BN_num_bytes(pwd_session->order) +
		(2 * BN_num_bytes(pwd_session->prime));
	    if ((pwd_session->out_buf = talloc_array(pwd_session, uint8_t,
						     pwd_session->out_buf_len)) == NULL) {
		return 0;
	    }
	    memset(pwd_session->out_buf, 0, pwd_session->out_buf_len);

	    ptr = pwd_session->out_buf;
	    offset = BN_num_bytes(pwd_session->prime) - BN_num_bytes(x);
	    BN_bn2bin(x, ptr + offset);

	    ptr += BN_num_bytes(pwd_session->prime);
	    offset = BN_num_bytes(pwd_session->prime) - BN_num_bytes(y);
	    BN_bn2bin(y, ptr + offset);

	    ptr += BN_num_bytes(pwd_session->prime);
	    offset = BN_num_bytes(pwd_session->order) - BN_num_bytes(pwd_session->my_scalar);
	    BN_bn2bin(pwd_session->my_scalar, ptr + offset);

	    pwd_session->state = PWD_STATE_COMMIT;
	    ret = send_pwd_request(pwd_session, eap_ds);
	    break;
	case PWD_STATE_COMMIT:
	    if (EAP_PWD_GET_EXCHANGE(hdr) != EAP_PWD_EXCH_COMMIT) {
		RDEBUG2("pwd exchange is incorrect: not commit!");
		return 0;
	    }
	    /*
	     * process the peer's commit and generate the shared key, k
	     */
	    if (process_peer_commit(pwd_session, buf, inst->bnctx)) {
		RDEBUG2("failed to process peer's commit");
		return 0;
	    }

	    /*
	     * compute our confirm blob
	     */
	    if (compute_server_confirm(pwd_session, pwd_session->my_confirm, inst->bnctx)) {
		ERROR("rlm_eap_pwd: failed to compute confirm!");
		return 0;
	    }
	    /*
	     * construct a response...which is just our confirm blob
	     */
	    pwd_session->out_buf_len = SHA256_DIGEST_LENGTH;
	    if ((pwd_session->out_buf = talloc_array(pwd_session, uint8_t,
						     pwd_session->out_buf_len)) == NULL) {
		return 0;
	    }
	    memset(pwd_session->out_buf, 0, pwd_session->out_buf_len);
	    memcpy(pwd_session->out_buf, pwd_session->my_confirm, SHA256_DIGEST_LENGTH);

	    pwd_session->state = PWD_STATE_CONFIRM;
	    ret = send_pwd_request(pwd_session, eap_ds);
	    break;
	case PWD_STATE_CONFIRM:
	    if (EAP_PWD_GET_EXCHANGE(hdr) != EAP_PWD_EXCH_CONFIRM) {
		RDEBUG2("pwd exchange is incorrect: not commit!");
		return 0;
	    }
	    if (compute_peer_confirm(pwd_session, peer_confirm, inst->bnctx)) {
		RDEBUG2("pwd exchange cannot compute peer's confirm");
		return 0;
	    }
	    if (memcmp(peer_confirm, buf, SHA256_DIGEST_LENGTH)) {
		RDEBUG2("pwd exchange fails: peer confirm is incorrect!");
		return 0;
	    }
	    if (compute_keys(pwd_session, peer_confirm, msk, emsk)) {
		RDEBUG2("pwd exchange cannot generate (E)MSK!");
		return 0;
	    }
	    eap_ds->request->code = PW_EAP_SUCCESS;
	    /*
	     * return the MSK (in halves)
	     */
	    eap_add_reply(handler->request,
			  "MS-MPPE-Recv-Key", msk, MPPE_KEY_LEN);
	    eap_add_reply(handler->request,
			  "MS-MPPE-Send-Key", msk+MPPE_KEY_LEN, MPPE_KEY_LEN);
	    ret = 1;
	    break;
	default:
	    RDEBUG2("unknown PWD state");
	    return 0;
    }

    /*
     * we processed the buffered fragments, get rid of them
     */
    if (pwd_session->in_buf) {
	    talloc_free(pwd_session->in_buf);
	    pwd_session->in_buf = NULL;
    }

    return ret;
}
/*
 *	Do authentication, by letting EAP-TLS do most of the work.
 */
static int CC_HINT(nonnull) mod_authenticate(void *type_arg, eap_handler_t *handler)
{
	fr_tls_status_t	status;
	tls_session_t *tls_session = (tls_session_t *) handler->opaque;
	REQUEST *request = handler->request;
	rlm_eap_tls_t *inst;

	inst = type_arg;

	RDEBUG2("Authenticate");

	status = eaptls_process(handler);
	RDEBUG2("eaptls_process returned %d\n", status);
	switch (status) {
		/*
		 *	EAP-TLS handshake was successful, return an
		 *	EAP-TLS-Success packet here.
		 *
		 *	If a virtual server was configured, check that
		 *	it accepts the certificates, too.
		 */
	case FR_TLS_SUCCESS:
		if (inst->virtual_server) {
			VALUE_PAIR *vp;
			REQUEST *fake;

			/* create a fake request */
			fake = request_alloc_fake(request);
			rad_assert(!fake->packet->vps);

			fake->packet->vps = paircopy(fake->packet, request->packet->vps);

			/* set the virtual server to use */
			if ((vp = pairfind(request->config_items, PW_VIRTUAL_SERVER, 0, TAG_ANY)) != NULL) {
				fake->server = vp->vp_strvalue;
			} else {
				fake->server = inst->virtual_server;
			}

			RDEBUG("Processing EAP-TLS Certificate check:");
			debug_pair_list(fake->packet->vps);

			RDEBUG("server %s {", fake->server);

			rad_virtual_server(fake);

			RDEBUG("} # server %s", fake->server);

			/* copy the reply vps back to our reply */
			pairfilter(request->reply, &request->reply->vps,
				  &fake->reply->vps, 0, 0, TAG_ANY);

			/* reject if virtual server didn't return accept */
			if (fake->reply->code != PW_CODE_AUTHENTICATION_ACK) {
				RDEBUG2("Certificates were rejected by the virtual server");
				request_free(&fake);
				eaptls_fail(handler, 0);
				return 0;
			}

			request_free(&fake);
			/* success */
		}
		break;

		/*
		 *	The TLS code is still working on the TLS
		 *	exchange, and it's a valid TLS request.
		 *	do nothing.
		 */
	case FR_TLS_HANDLED:
		return 1;

		/*
		 *	Handshake is done, proceed with decoding tunneled
		 *	data.
		 */
	case FR_TLS_OK:
		RDEBUG2("Received unexpected tunneled data after successful handshake");
#ifndef NDEBUG
		if ((debug_flag > 2) && fr_log_fp) {
			unsigned int i;
			unsigned int data_len;
			unsigned char buffer[1024];

			data_len = (tls_session->record_minus)(&tls_session->dirty_in,
						buffer, sizeof(buffer));
			DEBUG("  Tunneled data (%u bytes)", data_len);
			for (i = 0; i < data_len; i++) {
				if ((i & 0x0f) == 0x00) fprintf(fr_log_fp, "  %x: ", i);
				if ((i & 0x0f) == 0x0f) fprintf(fr_log_fp, "\n");

				fprintf(fr_log_fp, "%02x ", buffer[i]);
			}
			fprintf(fr_log_fp, "\n");
		}
#endif

		eaptls_fail(handler, 0);
		return 0;
		break;

		/*
		 *	Anything else: fail.
		 *
		 *	Also, remove the session from the cache so that
		 *	the client can't re-use it.
		 */
	default:
		tls_fail(tls_session);

		return 0;
	}

	/*
	 *	Success: Automatically return MPPE keys.
	 */
	return eaptls_success(handler, 0);
}
int main(int argc, char const *argv[])
{
    list_t * colaboradores = NULL;
    list_t * retiradas = NULL;
    list_t * relatorio = list_blank_list();
    node_t * node = NULL;
    colaborador_t * colaborador = NULL;
    retirada_t * retirada = NULL;
    char buffer[500];
    unsigned int colaborador_id = 0;
    char * tipo_relatorio = NULL;
    request_t * request = NULL;
    response_t * response = response_empty(NULL);
    var_t * var = NULL;
    error_t error = ERROR_NULL;
    unsigned int user_id;
    unsigned char user_level;

    request_process(&request);

    login_info(request, &user_id, &user_level);

    if (user_level > ANONYMOUS)
    {
        node = request->GET->first;
        while (node != NULL)
        {
            var = (var_t *) node->data;

            if (strcmp(var->name, "por") == 0)
            {
                tipo_relatorio = var->value;
            }

            if (strcmp(var->name, "colaboradorid") == 0)
            {
                colaborador_id = atoi(var->value);
            }

            node = node->next;
        }

        colaboradores_load(&colaboradores, NULL);
        retiradas_load(&retiradas, NULL);

        if (strcmp(tipo_relatorio, "item") == 0)
        {
            process_report(&relatorio, retiradas, 0);

            login_refresh_session(&response, user_id, user_level);
            response_write_template(&response, "templates/header.html");
            response_write_template(&response, "templates/relatorios_item.html");

            if (relatorio->first == NULL)
            {
                response_write(&response, "<p>Não existe informações para serem exibidas</p>");
            }
            else
            {
                response_write(&response, "<table class=\"table table-bordered table-striped\">"
                               "<tr><th>Item</th><th>Retirado por</th><th>Data da última retirada</th>"
                               "<th>Quantidade restante</th></tr>");
                node = relatorio->first;
                while (node != NULL)
                {
                    retirada = (retirada_t *) node->data;
                    sprintf(buffer,
                            "<tr><td>%s</td><td>%s</td><td>%s</td><td class=\"quantidade\">%u</td></tr>",
                            retirada->item->nome,
                            retirada->colaborador->nome,
                            retirada->data,
                            retirada->item->quantidade);
                    response_write(&response, buffer);
                    retirada_free(&retirada);
                    node = node->next;
                }
                response_write(&response, "</table>");
            }

            response_write(&response, "<script src=\"/js/relatorios.js\"></script>");
            response_write_template(&response, "templates/footer.html");
        }
        else if (strcmp(tipo_relatorio, "colaborador") == 0)
        {
            if (colaborador_id > 0)
            {
                process_report(&relatorio, retiradas, colaborador_id);
            }

            login_refresh_session(&response, user_id, user_level);
            response_write_template(&response, "templates/header.html");
            response_write_template(&response, "templates/relatorios_colaborador.html");

            if (colaborador_id > 0)
            {
                if (relatorio->first == NULL)
                {
                    response_write(&response, "<p>Não existe informações para serem exibidas</p>");
                }
                else
                {
                    response_write(&response, "<table class=\"table table-bordered table-striped\">"
                                   "<tr><th>Item</th><th>Retirado por</th><th>Data da última retirada</th>"
                                   "<th>Quantidade restante</th></tr>");
                    node = relatorio->first;
                    while (node != NULL)
                    {
                        retirada = (retirada_t *) node->data;
                        sprintf(buffer,
                                "<tr><td>%s</td><td>%s</td><td>%s</td><td class=\"quantidade\">%u</td></tr>",
                                retirada->item->nome,
                                retirada->colaborador->nome,
                                retirada->data,
                                retirada->item->quantidade);
                        response_write(&response, buffer);
                        retirada_free(&retirada);
                        node = node->next;
                    }
                    response_write(&response, "</table>");
                }
            }
            else
            {
                response_write(&response, "<p id=\"message\">Para ver o relatório selecione um colaborador acima e aperte \"Ver relatório\"</p>");
            }

            response_write(&response, "<script>var colaboradores = [");

            node = colaboradores->first;
            while (node != NULL)
            {
                colaborador = (colaborador_t *) node->data;
                sprintf(buffer,
                        "{ id: %u, nome: \"%s\" },",
                        colaborador->id,
                        colaborador->nome);
                response_write(&response, buffer);
                colaborador_free(&colaborador);
                node = node->next;
            }

            response_write(&response, "];</script>");

            response_write(&response, "<script src=\"/js/relatorios.js\"></script>");
            response_write(&response, "<script src=\"/js/relatorios_colaborador.js\"></script>");
            response_write_template(&response, "templates/footer.html");
        }
        else
        {
            error = ERROR_RELATORIO_INVALIDO;
        }

        if (error != ERROR_NULL)
        {
            if (error == ERROR_RELATORIO_INVALIDO)
            {
                sprintf(buffer, "/cgi-bin/relatorios?por=item");
            }
            else
            {
                sprintf(buffer, "/cgi-bin/relatorios?por=%s", tipo_relatorio);
            }

            error_page(&response, error, buffer);
        }
    }
    else
    {
        error_page(&response, ERROR_LOGIN_REQUIRED, "/");
    }

    response_send(response);

    request_free(request);

    return 0;
}
Beispiel #29
0
/*
 *	Create a new REQUEST, based on an old one.
 *
 *	This function allows modules to inject fake requests
 *	into the server, for tunneled protocols like TTLS & PEAP.
 */
REQUEST *request_alloc_fake(REQUEST *request)
{
  REQUEST *fake;

  fake = request_alloc();

  fake->number = request->number;
#ifdef HAVE_PTHREAD_H
  fake->child_pid = request->child_pid;
#endif
  fake->parent = request;
  fake->root = request->root;
  fake->client = request->client;

  /*
   *	For new server support.
   *
   *	FIXME: Key instead off of a "virtual server" data structure.
   *
   *	FIXME: Permit different servers for inner && outer sessions?
   */
  fake->server = request->server;

  fake->packet = rad_alloc(request, 1);
  if (!fake->packet) {
	  request_free(&fake);
	  return NULL;
  }

  fake->reply = rad_alloc(request, 0);
  if (!fake->reply) {
	  request_free(&fake);
	  return NULL;
  }

  fake->master_state = REQUEST_ACTIVE;
  fake->child_state = REQUEST_RUNNING;

  /*
   *	Fill in the fake request.
   */
  fake->packet->sockfd = -1;
  fake->packet->src_ipaddr = request->packet->src_ipaddr;
  fake->packet->src_port = request->packet->src_port;
  fake->packet->dst_ipaddr = request->packet->dst_ipaddr;
  fake->packet->dst_port = 0;

  /*
   *	This isn't STRICTLY required, as the fake request MUST NEVER
   *	be put into the request list.  However, it's still reasonable
   *	practice.
   */
  fake->packet->id = fake->number & 0xff;
  fake->packet->code = request->packet->code;
  fake->timestamp = request->timestamp;
 
  /*
   *	Required for new identity support
   */
  fake->listener = request->listener;

  /*
   *	Fill in the fake reply, based on the fake request.
   */
  fake->reply->sockfd = fake->packet->sockfd;
  fake->reply->src_ipaddr = fake->packet->dst_ipaddr;
  fake->reply->src_port = fake->packet->dst_port;
  fake->reply->dst_ipaddr = fake->packet->src_ipaddr;
  fake->reply->dst_port = fake->packet->src_port;
  fake->reply->id = fake->packet->id;
  fake->reply->code = 0; /* UNKNOWN code */

  /*
   *	Copy debug information.
   */
  fake->options = request->options;
  fake->radlog = request->radlog;

  return fake;
}
Beispiel #30
0
/*
 *	Free a REQUEST struct.
 */
void request_free(REQUEST **request_ptr)
{
	REQUEST *request;

	if (!request_ptr || !*request_ptr) {
		return;
	}

	request = *request_ptr;

	rad_assert(!request->in_request_hash);
#ifdef WITH_PROXY
	rad_assert(!request->in_proxy_hash);
#endif
	rad_assert(!request->ev);

	if (request->packet)
		rad_free(&request->packet);

#ifdef WITH_PROXY
	if (request->proxy)
		rad_free(&request->proxy);
#endif

	if (request->reply)
		rad_free(&request->reply);

#ifdef WITH_PROXY
	if (request->proxy_reply)
		rad_free(&request->proxy_reply);
#endif

	if (request->config_items)
		pairfree(&request->config_items);

	request->username = NULL;
	request->password = NULL;

	if (request->data) {
		request_data_t *this, *next;

		for (this = request->data; this != NULL; this = next) {
			next = this->next;
			if (this->opaque && /* free it, if necessary */
			    this->free_opaque)
				this->free_opaque(this->opaque);
			free(this);
		}
		request->data = NULL;
	}

	if (request->root &&
	    (request->root->refcount > 0)) {
		request->root->refcount--;
		request->root = NULL;
	}

#ifdef WITH_COA
	if (request->coa) {
		request->coa->parent = NULL;
		rad_assert(request->coa->ev == NULL);
		request_free(&request->coa);
	}

	if (request->parent && (request->parent->coa == request)) {
		request->parent->coa = NULL;
	}
#endif

#ifndef NDEBUG
	request->magic = 0x01020304;	/* set the request to be nonsense */
#endif
	request->client = NULL;
#ifdef WITH_PROXY
	request->home_server = NULL;
#endif
	talloc_free(request);
	*request_ptr = NULL;
}