Exemplo n.º 1
0
int
handle_logout_command(struct thread_data_t * datum, char * args)
{
  int i, len;
  char buffer[MAX_COMMAND_LENGTH];

  /* Logout command takes no arguments */
  #ifndef NDEBUG
  if (*args != '\0') {
    fprintf(stderr,
            "[thread %lu] WARNING: ignoring '%s' (argument residue)\n",
            datum->id, args);
  }
  #endif

  /* Prepare a reply dependent on our state */
  memset(buffer, '\0', MAX_COMMAND_LENGTH);
  if (datum->credentials.userlength) {
    snprintf(buffer, MAX_COMMAND_LENGTH, "Goodbye, %s!",
             datum->credentials.username);
  } else {
    snprintf(buffer, MAX_COMMAND_LENGTH, "LOGOUT ERROR");
  }
  salt_and_pepper(buffer, NULL, &datum->buffet);
  encrypt_message(&datum->buffet, datum->credentials.key);
  /* Clear the credential bits from the key */
  if (datum->credentials.userlength) {
    len = datum->credentials.userlength;
    for (i = 0; i < AUTH_KEY_LENGTH; ++i) {
      datum->credentials.key[i] ^=
       datum->credentials.username[i % len];
    }
    memset(&datum->credentials.username, '\0', MAX_COMMAND_LENGTH);
    datum->credentials.userlength = 0;
  }
  send_message(&datum->buffet, datum->sock);

  /* Handle verification (should fail) */
  recv_message(&datum->buffet, datum->sock);
  decrypt_message(&datum->buffet, datum->credentials.key);
  for (i = 0; i < MAX_COMMAND_LENGTH; ++i) {
    datum->buffet.pbuffer[i] =
     datum->buffet.tbuffer[MAX_COMMAND_LENGTH - 1 - i];
  }
  encrypt_message(&datum->buffet, datum->credentials.key);
  send_message(&datum->buffet, datum->sock);

  return BANKING_SUCCESS;
}
Exemplo n.º 2
0
int
handle_balance_command(struct thread_data_t * datum, char * args)
{
  long int balance;
  char buffer[MAX_COMMAND_LENGTH];

  /* Balance command takes no arguments */
  #ifndef NDEBUG
  if (*args != '\0') {
    fprintf(stderr,
            "[thread %lu] WARNING: ignoring '%s' (argument residue)\n",
            datum->id, args);
  }
  #endif

  /* Formulate a response */
  memset(buffer, '\0', MAX_COMMAND_LENGTH);
  /* If we have a username, try to do a lookup */
  if (datum->credentials.userlength
   && do_lookup(session_data.db_conn, NULL,
                datum->credentials.username,
                datum->credentials.userlength,
                &balance) == BANKING_SUCCESS) {
    snprintf(buffer, MAX_COMMAND_LENGTH,
             "%s, your balance is $%li.",
             datum->credentials.username, balance);
  } else {
    snprintf(buffer, MAX_COMMAND_LENGTH, "BALANCE ERROR");
  }
  /* Send the results */
  salt_and_pepper(buffer, NULL, &datum->buffet);
  encrypt_message(&datum->buffet, datum->credentials.key);
  send_message(&datum->buffet, datum->sock);
  return BANKING_SUCCESS;
}
int encrypt(unsigned char* ciphertext, size_t* ciphertext_length, unsigned char* key) {
	unsigned char message[] = MESSAGE;
	printf("Message (%lu Bytes):\n%s\n\n", sizeof(message), message);

	//create random nonce
	unsigned char nonce[crypto_secretbox_NONCEBYTES];
	randombytes_buf(nonce, crypto_secretbox_NONCEBYTES);

	//print nonce
	printf("Nonce (%i Bytes):\n", crypto_secretbox_NONCEBYTES);
	print_hex(nonce, crypto_secretbox_NONCEBYTES, 30);
	putchar('\n');

	const unsigned char header[] = HEADER;
	printf("Header (%lu Bytes):\n%s\n\n", sizeof(header), header);

	int status = encrypt_message(
			ciphertext,
			ciphertext_length,
			message,
			sizeof(message),
			header,
			sizeof(header),
			nonce,
			key);
	sodium_memzero(message, sizeof(message));
	return status;
}
Exemplo n.º 4
0
static PyObject* authGSSWinRMEncryptMessage(PyObject* self, PyObject* args)
{
    char *input = NULL;
    char *header = NULL;
    int header_len = 0;
    char *enc_output = NULL;
    int enc_output_len = 0;
    PyObject *pystate = NULL;
    gss_client_state *state = NULL;
    int result = 0;
    PyObject *pyresult = NULL;

    // NB: use et so we get a copy of the string (since gss_wrap_iov mutates it), and so we're certain it's always
    // a UTF8 byte string
    if (! PyArg_ParseTuple(args, "Oet", &pystate, "UTF-8", &input)) {
        pyresult = NULL;
        goto end;
    }

    if (!PyCheck(pystate)) {
        PyErr_SetString(PyExc_TypeError, "Expected a context object");
        pyresult = NULL;
        goto end;
    }

    state = PyGet(pystate, gss_client_state);
    if (state == NULL) {
        pyresult = NULL;
        goto end;
    }

    result = encrypt_message(state, input, &header, &header_len, &enc_output, &enc_output_len);

    if (result == AUTH_GSS_ERROR) {
        pyresult = NULL;
        goto end;
    }

#if PY_MAJOR_VERSION >= 3
    pyresult = Py_BuildValue("y# y#", enc_output, enc_output_len, header, header_len);
#else
    pyresult = Py_BuildValue("s# s#", enc_output, enc_output_len, header, header_len);
#endif

end:
    if (input) {
        PyMem_Free(input);
    }
    if (header) {
        free(header);
    }
    if (enc_output) {
        free(enc_output);
    }

    return pyresult;
}
Exemplo n.º 5
0
int
handle_transfer_command(struct thread_data_t * datum, char * args)
{
  long amount, balance;
  char * user, buffer[MAX_COMMAND_LENGTH];

  #ifndef NDEBUG
  if (*args == '\0') {
    fprintf(stderr,
            "[thread %lu] WARNING: [%s] arguments empty\n",
            datum->id, "transfer");
  } else {
    fprintf(stderr,
            "[thread %lu] INFO: [%s] '%s' (arguments)\n",
            datum->id, "transfer", args);
  }
  #endif
  amount = strtol(args, &args, 10);
  user = ++args;

  if (amount <= 0 || amount > MAX_TRANSACTION) {
    snprintf(buffer, MAX_COMMAND_LENGTH, "Invalid transfer amount.");
  } else if (datum->credentials.userlength
   && do_lookup(session_data.db_conn, NULL,
                datum->credentials.username,
                datum->credentials.userlength,
                &balance) == BANKING_SUCCESS) {
    if (balance < amount) {
      snprintf(buffer, MAX_COMMAND_LENGTH, "Insufficient funds.");
    } else if (do_update(session_data.db_conn, NULL,
               datum->credentials.username,
               datum->credentials.userlength,
               balance - amount)
            || do_lookup(session_data.db_conn, NULL,
               user, strnlen(user, MAX_COMMAND_LENGTH),
               &balance)
            || do_update(session_data.db_conn, NULL,
               user, strnlen(user, MAX_COMMAND_LENGTH),
               balance + amount)) {
      /* TODO atomic operation? */
      snprintf(buffer, MAX_COMMAND_LENGTH, "Cannot complete transfer.");
    } else {
      snprintf(buffer, MAX_COMMAND_LENGTH, "Transfered $%li to %s",
                                           amount, user);
    }
  } else {
    snprintf(buffer, MAX_COMMAND_LENGTH, "TRANSFER ERROR");
  }
  salt_and_pepper(buffer, NULL, &datum->buffet);
  encrypt_message(&datum->buffet, datum->credentials.key);
  send_message(&datum->buffet, datum->sock);

  return BANKING_SUCCESS;
}
Exemplo n.º 6
0
        void out_thread(master_post_office* o)
        try
        {
            REQUIRE(o);

            std::string last_address;

            while(!o->_done)
            try
            {
                //get message from queue
                message m;
                if(!o->_out.pop(m, true))
                    continue;

                REQUIRE_GREATER_EQUAL(m.meta.from.size(), 1);
                REQUIRE_GREATER_EQUAL(m.meta.to.size(), 1);

                const std::string outside_queue_address = m.meta.to.front();
                last_address = outside_queue_address;

                //encode, compress, and encrypt message
                auto data = u::encode(m);
                data = u::compress(data);

                encrypt_message(
                        data, 
                        m, 
                        outside_queue_address,
                        *o->_encrypted_channels);

                //send message over wire
                o->_connections.send(outside_queue_address, data, m.meta.robust);

                if(o->_outside_stats.on) o->_outside_stats.out_pop_count++;
            }
            catch(std::exception& e)
            {
                LOG << "error sending message to " << last_address << ": " << e.what() << std::endl;
            }
            catch(...)
            {
                LOG << "error sending message to " << last_address << ": unknown error." << std::endl;
            }
            u::sleep_thread(QUIT_SLEEP);
        }
        catch(...)
        {
            LOG << "exit: master_post::out_thread" << std::endl;
        }
Exemplo n.º 7
0
int
handle_withdraw_command(struct thread_data_t * datum, char * args)
{
  long balance, amount;
  char buffer[MAX_COMMAND_LENGTH];

  #ifndef NDEBUG
  if (*args == '\0') {
    fprintf(stderr,
            "[thread %lu] WARNING: [%s] arguments empty\n",
            datum->id, "withdraw");
  } else {
    fprintf(stderr,
            "[thread %lu] INFO: [%s] '%s' (arguments)\n",
            datum->id, "withdraw", args);
  }
  #endif
  amount = strtol(args, &args, 10);

  if (amount <= 0 || amount > MAX_TRANSACTION) {
    snprintf(buffer, MAX_COMMAND_LENGTH, "Invalid withdrawal amount.");
  } else if (datum->credentials.userlength
   && do_lookup(session_data.db_conn, NULL,
                datum->credentials.username,
                datum->credentials.userlength,
                &balance) == BANKING_SUCCESS) {
    if (balance < amount) {
      snprintf(buffer, MAX_COMMAND_LENGTH, "Insufficient funds.");
    } else if (do_update(session_data.db_conn, NULL,
               datum->credentials.username,
               datum->credentials.userlength,
               balance - amount)) {
      snprintf(buffer, MAX_COMMAND_LENGTH, "Cannot complete withdrawal.");
    } else {
      snprintf(buffer, MAX_COMMAND_LENGTH, "Withdrew $%li", amount);
    }
  } else {
    snprintf(buffer, MAX_COMMAND_LENGTH, "WITHDRAW ERROR");
  }
  salt_and_pepper(buffer, NULL, &datum->buffet);
  encrypt_message(&datum->buffet, datum->credentials.key);
  send_message(&datum->buffet, datum->sock);

  return BANKING_SUCCESS;
}
Exemplo n.º 8
0
void *
handle_client(void * arg)
{
  struct thread_data_t * datum = (struct thread_data_t *)(arg);
  /* Fetch the ID from the argument */
  #ifndef NDEBUG
  fprintf(stderr, "[thread %lu] INFO: worker started\n", datum->id);
  #endif

  /* Worker thread signal handling is unique */
  sigaction(SIGUSR1, datum->signal_action, NULL);
  sigaction(SIGUSR2, datum->signal_action, NULL);

  /* As long as possible, grab up whatever connection is available */
  while (!session_data.caught_signal && !datum->caught_signal) {
    /* Ensure only one worker accepts the next client */
    gcry_pthread_mutex_lock((void **)(&session_data.accept_mutex));
    datum->sock = accept(session_data.sock,
                         (struct sockaddr *)(&datum->remote_addr),
                         &datum->remote_addr_len);
    gcry_pthread_mutex_unlock((void **)(&session_data.accept_mutex));
    if (datum->sock >= 0) {
      #ifndef NDEBUG
      fprintf(stderr,
              "[thread %lu] INFO: worker connected to client\n",
              datum->id);
      #endif
      /* Receive a "hello" message from the client */
      recv_message(&datum->buffet, datum->sock);
      /* Decrypt it with the default key */
      decrypt_message(&datum->buffet, keystore.key);
      /* Verify it is an authentication request */
      if (strncmp(datum->buffet.tbuffer,
                  AUTH_CHECK_MSG, sizeof(AUTH_CHECK_MSG))) {
        /* Respond with nonce (misdirection) */
        gcry_create_nonce(datum->buffet.pbuffer, MAX_COMMAND_LENGTH);
        encrypt_message(&datum->buffet, keystore.key);
        send_message(&datum->buffet, datum->sock);
      } else {
        /* Request a session key */
        gcry_pthread_mutex_lock((void **)(&session_data.keystore_mutex));
        #ifndef NDEBUG
        print_keystore(stderr, "before request");
        #endif
        request_key(&datum->credentials.key);
        #ifndef NDEBUG
        print_keystore(stderr, "after request");
        #endif
        gcry_pthread_mutex_unlock((void **)(&session_data.keystore_mutex));
        /* Encrypted it using the default key */
        salt_and_pepper((char *)(datum->credentials.key), NULL,
                        &datum->buffet);
        encrypt_message(&datum->buffet, keystore.key);
        send_message(&datum->buffet, datum->sock);
        clear_buffet(&datum->buffet);
        /* Repeatedly poll for message streams */
        while (handle_stream(datum) == BANKING_SUCCESS);
        /* Revoke the session key */
        gcry_pthread_mutex_lock((void **)(&session_data.keystore_mutex));
        #ifndef NDEBUG
        print_keystore(stderr, "before revoke");
        #endif
        revoke_key(&datum->credentials.key);
        #ifndef NDEBUG
        print_keystore(stderr, "after revoke");
        #endif
        gcry_pthread_mutex_unlock((void **)(&session_data.keystore_mutex));
      }
      /* Cleanup (disconnect) */
      #ifndef NDEBUG
      fprintf(stderr,
              "[thread %lu] INFO: worker disconnected from client\n",
              datum->id);
      #endif
      clear_buffet(&datum->buffet);
      destroy_socket(datum->sock);
      datum->sock = BANKING_FAILURE;
    } else {
      fprintf(stderr,
              "[thread %lu] ERROR: worker unable to connect\n",
              datum->id);
    }
  }

  /* Teardown */
  handle_interruption(0);
  return NULL;
}
Exemplo n.º 9
0
/*! \brief Handle a message stream from a client */
int
handle_stream(struct thread_data_t * datum) {
  int i;
  handle_t hdl;
  char msg[MAX_COMMAND_LENGTH], * args;

  /* The initial message is always an authentication request */
  recv_message(&datum->buffet, datum->sock);
  decrypt_message(&datum->buffet, datum->credentials.key);
  if (strncmp(datum->buffet.tbuffer,
              AUTH_CHECK_MSG, sizeof(AUTH_CHECK_MSG))) {
    #ifndef NDEBUG
    fprintf(stderr,
            "[thread %lu] INFO: malformed authentication message\n",
            datum->id);
    #endif
    /* Respond with a "mumble" (nonce) */
    gcry_create_nonce(datum->buffet.pbuffer, MAX_COMMAND_LENGTH);
    encrypt_message(&datum->buffet, datum->credentials.key);
    send_message(&datum->buffet, datum->sock);
    return BANKING_FAILURE;
  }
  /* Turn around the buffer and toss it back */
  for (i = 0; i < MAX_COMMAND_LENGTH; ++i) {
    datum->buffet.pbuffer[i] =
     datum->buffet.tbuffer[MAX_COMMAND_LENGTH - 1 - i];
  }
  encrypt_message(&datum->buffet, datum->credentials.key);
  send_message(&datum->buffet, datum->sock);
  clear_buffet(&datum->buffet);
  #ifndef NDEBUG
  fprintf(stderr,
          "[thread %lu] INFO: authentication successful\n",
          datum->id);
  #endif

  /* Read the actual command */
  recv_message(&datum->buffet, datum->sock);
  decrypt_message(&datum->buffet, datum->credentials.key);
  /* Copy the command into a buffer so more can be received */
  strncpy(msg, datum->buffet.tbuffer, MAX_COMMAND_LENGTH);
  #ifndef NDEBUG
  /* Local echo for all received messages */
  fprintf(stderr,
          "[thread %lu] INFO: worker received message:\n",
          datum->id);
  hexdump(stderr, (unsigned char *)(msg), MAX_COMMAND_LENGTH);
  #endif
  
  /* Disconnect from any client that issues malformed commands */
  if (fetch_handle(msg, &hdl, &args)) {
    /* Respond with a "mumble" (nonce) */
    gcry_create_nonce(datum->buffet.pbuffer, MAX_COMMAND_LENGTH);
    encrypt_message(&datum->buffet, datum->credentials.key);
    send_message(&datum->buffet, datum->sock);
    clear_buffet(&datum->buffet);
    return BANKING_FAILURE;
  }
  /* We are signaled by failed handlers */
  datum->caught_signal = hdl(datum, args);
  clear_buffet(&datum->buffet);

  return BANKING_SUCCESS;
}
Exemplo n.º 10
0
int
handle_login_command(struct thread_data_t * datum, char * args)
{
  size_t i, len;
  char buffer[MAX_COMMAND_LENGTH];

  /* The login argument takes one argument */
  #ifndef NDEBUG
  if (*args == '\0') {
    fprintf(stderr,
            "[thread %lu] WARNING: [%s] arguments empty\n",
            datum->id, "login");
  } else {
    fprintf(stderr,
            "[thread %lu] INFO: [%s] '%s' (arguments)\n",
            datum->id, "login", args);
  }
  #endif
  /* TODO verify they're an actual user of the system */

  /* Modify the key using bits from the username */
  len = strnlen(args, MAX_COMMAND_LENGTH);
  for (i = 0; i < AUTH_KEY_LENGTH; ++i) {
    datum->credentials.key[i] ^= args[i % len];
  }
  /* Turn around the message */
  for (i = 0; i < MAX_COMMAND_LENGTH; ++i) {
    datum->buffet.pbuffer[i] =
     datum->buffet.tbuffer[MAX_COMMAND_LENGTH - 1 - i];
  }
  /* Echo this message with the modified key */
  encrypt_message(&datum->buffet, datum->credentials.key);
  send_message(&datum->buffet, datum->sock);

  /* Receive the PIN */
  recv_message(&datum->buffet, datum->sock);
  decrypt_message(&datum->buffet, datum->credentials.key);
  /* Copy the args backward TODO better auth, use pin as salt */
  memset(buffer, '\0', MAX_COMMAND_LENGTH);
  for (i = 0; i < len; ++i) {
    buffer[i] = args[len - i - 1];
  }

  /* Check the buffer matches the args */
  if (strncmp(buffer, datum->buffet.tbuffer, len)
   || do_lookup(session_data.db_conn, NULL, args, len, NULL)) {
    snprintf(buffer, MAX_COMMAND_LENGTH, "LOGIN ERROR");
    /* Remove the previously added bits */
    for (i = 0; i < AUTH_KEY_LENGTH; ++i) {
      datum->credentials.key[i] ^= args[i % len];
    }
  } else {
    snprintf(buffer, MAX_COMMAND_LENGTH, "%s, %s!", AUTH_LOGIN_MSG, args);
    /* We have now authenticated the user */
    memset(datum->credentials.username, '\0', MAX_COMMAND_LENGTH);
    strncpy(datum->credentials.username, args, len);
    datum->credentials.userlength = len;
  }
  salt_and_pepper(buffer, NULL, &datum->buffet);
  encrypt_message(&datum->buffet, datum->credentials.key);
  send_message(&datum->buffet, datum->sock);

  /* Catch authentication check */
  recv_message(&datum->buffet, datum->sock);
  decrypt_message(&datum->buffet, datum->credentials.key);
  /* Turn around the message */
  for (i = 0; i < MAX_COMMAND_LENGTH; ++i) {
    datum->buffet.pbuffer[i] =
     datum->buffet.tbuffer[MAX_COMMAND_LENGTH - 1 - i];
  }
  encrypt_message(&datum->buffet, datum->credentials.key);
  send_message(&datum->buffet, datum->sock);

  return BANKING_SUCCESS;
}