Exemplo n.º 1
0
static void
read_peer_id (CcnetHandshake *handshake, ccnet_packet *packet)
{
    uint16_t len;
    char *id;

    /* get id */
    len = packet->header.length;
    id = g_malloc (len + 1);
    memcpy (id, packet->data, len);
    id[len] = '\0';
    handshake->id = id;

    if (handshake->state == INIT) {
        /* we are the slave */
        ccnet_debug ("[Conn] Incoming: Read peer id %.8s\n", id);
        send_handshake_message (handshake);
        handshake->state = ID_RECEIVED;
    } else if (handshake->state == ID_SENT) {
        /* we are the master */
        ccnet_debug ("[Conn] Outgoing: Read peer %s id %.8s\n",
                     handshake->peer->name, id);
        send_ack (handshake);
        ccnet_handshake_done (handshake, TRUE);
    } else
        g_assert (0);
}
Exemplo n.º 2
0
CcnetHandshake*
ccnet_handshake_new (CcnetSession     *session,
                     CcnetPeer        *peer,
                     CcnetPacketIO    *io,
                     handshakeDoneCB   doneCB,
                     void             *doneUserData)
{
    CcnetHandshake * handshake;

    handshake = g_new0 (CcnetHandshake, 1);
    handshake->peer = peer;
    if (peer)
        g_object_ref (peer);
    handshake->io = io;
    handshake->doneCB = doneCB;
    handshake->doneUserData = doneUserData;
    handshake->session = session;

    ccnet_packet_io_set_timeout_secs (io, HANDSHAKE_TIMEOUT);
    ccnet_packet_io_set_iofuncs (handshake->io, canRead, NULL,
                                 gotError, handshake);

    if (ccnet_packet_io_is_incoming (handshake->io))
        handshake->state = INIT;
    else {
        send_handshake_message (handshake);
        handshake->state = ID_SENT;
    }

    return handshake;
}
Exemplo n.º 3
0
static int send_finished( int connection, 
                          TLSParameters *parameters )
{
  unsigned char verify_data[ VERIFY_DATA_LEN ];
  
  compute_verify_data( "client finished", parameters, verify_data );
  send_handshake_message( connection, finished, verify_data, VERIFY_DATA_LEN,
    parameters );

  return 1;
}
Exemplo n.º 4
0
status_t
Shell::_Spawn(int row, int col, const ShellParameters& parameters)
{
	const char** argv = (const char**)parameters.Arguments();
	int argc = parameters.ArgumentCount();
	const char* defaultArgs[3] = {kDefaultShell, "-l", NULL};
	struct passwd passwdStruct;
	struct passwd *passwdResult;
	char stringBuffer[256];

	if (argv == NULL || argc == 0) {
		if (!getpwuid_r(getuid(), &passwdStruct, stringBuffer,
				sizeof(stringBuffer), &passwdResult)) {
			defaultArgs[0] = passwdStruct.pw_shell;
		}

		argv = defaultArgs;
		argc = 2;

		fShellInfo.SetDefaultShell(true);
	} else
		fShellInfo.SetDefaultShell(false);

	fShellInfo.SetEncoding(parameters.Encoding());

	signal(SIGTTOU, SIG_IGN);

	// get a pseudo-tty
	int master = posix_openpt(O_RDWR | O_NOCTTY);
	const char *ttyName;

	if (master < 0) {
		fprintf(stderr, "Didn't find any available pseudo ttys.");
		return errno;
	}

	if (grantpt(master) != 0 || unlockpt(master) != 0
		|| (ttyName = ptsname(master)) == NULL) {
		close(master);
		fprintf(stderr, "Failed to init pseudo tty.");
		return errno;
	}

	/*
	 * Get the modes of the current terminal. We will duplicates these
	 * on the pseudo terminal.
	 */

	thread_id terminalThread = find_thread(NULL);

	/* Fork a child process. */
	fShellInfo.SetProcessID(fork());
	if (fShellInfo.ProcessID() < 0) {
		close(master);
		return B_ERROR;
	}

	handshake_t handshake;

	if (fShellInfo.ProcessID() == 0) {
		// Now in child process.

		// close the PTY master side
		close(master);

		/*
		 * Make our controlling tty the pseudo tty. This hapens because
		 * we cleared our original controlling terminal above.
		 */

		/* Set process session leader */
		if (setsid() < 0) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				"could not set session leader.");
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		/* open slave pty */
		int slave = -1;
		if ((slave = open(ttyName, O_RDWR)) < 0) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				"can't open tty (%s).", ttyName);
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		/* set signal default */
		signal(SIGCHLD, SIG_DFL);
		signal(SIGHUP, SIG_DFL);
		signal(SIGQUIT, SIG_DFL);
		signal(SIGTERM, SIG_DFL);
		signal(SIGINT, SIG_DFL);
		signal(SIGTTOU, SIG_DFL);

		struct termios tio;
		/* get tty termios (not necessary).
		 * TODO: so why are we doing it ?
		 */
		tcgetattr(slave, &tio);

		initialize_termios(tio);

		/*
		 * change control tty.
		 */

		dup2(slave, 0);
		dup2(slave, 1);
		dup2(slave, 2);

		/* close old slave fd. */
		if (slave > 2)
			close(slave);

		/*
		 * set terminal interface.
		 */
		if (tcsetattr(0, TCSANOW, &tio) == -1) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				"failed set terminal interface (TERMIOS).");
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		/*
		 * set window size.
		 */

		handshake.status = PTY_WS;
		send_handshake_message(terminalThread, handshake);
		receive_handshake_message(handshake);

		if (handshake.status != PTY_WS) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				"mismatch handshake.");
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		struct winsize ws = { handshake.row, handshake.col };

		ioctl(0, TIOCSWINSZ, &ws);

		tcsetpgrp(0, getpgrp());
			// set this process group ID as the controlling terminal
		set_thread_priority(find_thread(NULL), B_NORMAL_PRIORITY);

		/* pty open and set termios successful. */
		handshake.status = PTY_OK;
		send_handshake_message(terminalThread, handshake);

		/*
		 * setenv TERM and TTY.
		 */
		setenv("TERM", kTerminalType, true);
		setenv("TTY", ttyName, true);
		setenv("TTYPE", fShellInfo.EncodingName(), true);

		// set the current working directory, if one is given
		if (parameters.CurrentDirectory().Length() > 0)
			chdir(parameters.CurrentDirectory().String());

		execve(argv[0], (char * const *)argv, environ);

		// Exec failed.
		// TODO: This doesn't belong here.

		sleep(1);

		BString alertCommand = "alert --stop '";
		alertCommand += B_TRANSLATE("Cannot execute \"%command\":\n\t%error");
		alertCommand += "' '";
		alertCommand += B_TRANSLATE("Use default shell");
		alertCommand += "' '";
		alertCommand += B_TRANSLATE("Abort");
		alertCommand += "'";
		alertCommand.ReplaceFirst("%command", argv[0]);
		alertCommand.ReplaceFirst("%error", strerror(errno));

		int returnValue = system(alertCommand.String());
		if (returnValue == 0) {
			execl(kDefaultShell, kDefaultShell,
				"-l", NULL);
		}

		exit(1);
	}

	/*
	 * In parent Process, Set up the input and output file pointers so
	 * that they can write and read the pseudo terminal.
	 */

	/*
	 * close parent control tty.
	 */

	int done = 0;
	while (!done) {
		receive_handshake_message(handshake);

		switch (handshake.status) {
			case PTY_OK:
				done = 1;
				break;

			case PTY_NG:
				fprintf(stderr, "%s\n", handshake.msg);
				done = -1;
				break;

			case PTY_WS:
				handshake.row = row;
				handshake.col = col;
				handshake.status = PTY_WS;
				send_handshake_message(fShellInfo.ProcessID(), handshake);
				break;
		}
	}

	if (done <= 0)
		return B_ERROR;

	fFd = master;

	return B_OK;
}
Exemplo n.º 5
0
/**
 * Send the client key exchange message, as detailed in section 7.4.7
 * Use the server's public key (if it has one) to encrypt a key. (or DH?)
 * Return true if this succeeded, false otherwise.
 */ 
static int send_client_key_exchange( int connection, TLSParameters *parameters )
{   
  unsigned char *key_exchange_message;
  int key_exchange_message_len;
  unsigned char *premaster_secret;
  int premaster_secret_len;

  switch ( parameters->pending_send_parameters.suite ) {
    case TLS_NULL_WITH_NULL_NULL:
      // XXX this is an error, exit here
      break;
    case TLS_RSA_WITH_NULL_MD5:
    case TLS_RSA_WITH_NULL_SHA:
    case TLS_RSA_EXPORT_WITH_RC4_40_MD5:
    case TLS_RSA_WITH_RC4_128_MD5:
    case TLS_RSA_WITH_RC4_128_SHA:
    case TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
    case TLS_RSA_WITH_IDEA_CBC_SHA:
    case TLS_RSA_EXPORT_WITH_DES40_CBC_SHA:
    case TLS_RSA_WITH_DES_CBC_SHA:
    case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_RSA_WITH_AES_128_CBC_SHA:
    case TLS_RSA_WITH_AES_256_CBC_SHA:
      premaster_secret_len = MASTER_SECRET_LENGTH;
      premaster_secret = malloc( premaster_secret_len );
      key_exchange_message_len = rsa_key_exchange( 
        &parameters->server_public_key.rsa_public_key,
        premaster_secret, &key_exchange_message );
      break;
    case TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
    case TLS_DH_DSS_WITH_DES_CBC_SHA:
    case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
    case TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
    case TLS_DH_RSA_WITH_DES_CBC_SHA:
    case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
    case TLS_DHE_DSS_WITH_DES_CBC_SHA:
    case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
    case TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
    case TLS_DHE_RSA_WITH_DES_CBC_SHA:
    case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
    case TLS_DH_anon_EXPORT_WITH_RC4_40_MD5:
    case TLS_DH_anon_WITH_RC4_128_MD5:
    case TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
    case TLS_DH_anon_WITH_DES_CBC_SHA:
    case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
    case TLS_DH_anon_WITH_AES_128_CBC_SHA:
    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
    case TLS_DH_anon_WITH_AES_256_CBC_SHA:
      premaster_secret_len = parameters->server_dh_key.p.size;
      premaster_secret = malloc( premaster_secret_len );
      key_exchange_message_len = dh_key_exchange( &parameters->server_dh_key,
        premaster_secret, &key_exchange_message );
      break;
    default:
      return 0;
  }

  if ( send_handshake_message( connection, client_key_exchange,
       key_exchange_message, key_exchange_message_len, parameters ) )
  {
    free( key_exchange_message );
    return 0;
  }

  free( key_exchange_message );

  // Now, turn the premaster secret into an actual master secret (the
  // server side will do this concurrently).
  compute_master_secret( premaster_secret, premaster_secret_len, parameters );

  // XXX - for security, should also "purge" the premaster secret from
  // memory.
  calculate_keys( parameters );

  free( premaster_secret );

  return 1;
}
Exemplo n.º 6
0
/**
 * Build and submit a TLS client hello handshake on the active
 * connection.  It is up to the caller of this function to wait
 * for the server reply.
 */
static int send_client_hello( int connection, TLSParameters *parameters )
{
  ClientHello       package;
  unsigned short    supported_suites[ 1 ];
  unsigned char     supported_compression_methods[ 1 ];
  int               send_buffer_size;
  char              *send_buffer;
  void              *write_buffer;
  time_t            local_time;
  int               status = 1;

  package.client_version.major = TLS_VERSION_MAJOR;
  package.client_version.minor = TLS_VERSION_MINOR;
  time( &local_time );
  package.random.gmt_unix_time = htonl( local_time );
  // TODO - actually make this random.
  // This is 28 bytes, but client random is 32 - the first four bytes of
  // "client random" are the GMT unix time computed above.
  memcpy( parameters->client_random, &package.random.gmt_unix_time, 4 );
  memcpy( package.random.random_bytes, parameters->client_random + 4, 28 );
  package.session_id_length = 0;
  package.session_id = NULL;
  // note that this is bytes, not count.
  package.cipher_suites_length = htons( 2 );
  supported_suites[ 0 ] = htons( TLS_RSA_WITH_3DES_EDE_CBC_SHA );
  package.cipher_suites = supported_suites;
  package.compression_methods_length = 1;
  supported_compression_methods[ 0 ] = 0;
  package.compression_methods = supported_compression_methods;

  // Compute the size of the ClientHello message after flattening.
  send_buffer_size = sizeof( ProtocolVersion ) + 
     sizeof( Random ) + 
     sizeof( unsigned char ) +
     ( sizeof( unsigned char ) * package.session_id_length ) +
     sizeof( unsigned short ) +
     ( sizeof( unsigned short ) * 1 ) +
     sizeof( unsigned char ) +
     sizeof( unsigned char );

  write_buffer = send_buffer = ( char * ) malloc( send_buffer_size );
  
  write_buffer = append_buffer( write_buffer, ( void * ) 
     &package.client_version.major, 1 );
  write_buffer = append_buffer( write_buffer, ( void * ) 
     &package.client_version.minor, 1 );
  write_buffer = append_buffer( write_buffer, ( void * )     
     &package.random.gmt_unix_time, 4 );
  write_buffer = append_buffer( write_buffer, ( void * ) 
     &package.random.random_bytes, 28 );
  write_buffer = append_buffer( write_buffer, ( void * )  
     &package.session_id_length, 1 );
  if ( package.session_id_length > 0 )
  {
    write_buffer = append_buffer( write_buffer, 
      ( void * )package.session_id,
      package.session_id_length );
  }
  write_buffer = append_buffer( write_buffer, 
     ( void * ) &package.cipher_suites_length, 2 );
  write_buffer = append_buffer( write_buffer, 
    ( void * ) package.cipher_suites, 2 );
  write_buffer = append_buffer( write_buffer, 
    ( void * ) &package.compression_methods_length, 1 );
  if ( package.compression_methods_length > 0 )
  {
    write_buffer = append_buffer( write_buffer, 
       ( void * ) package.compression_methods, 1 );
  }

  assert( ( ( char * ) write_buffer - send_buffer ) == send_buffer_size );

  status = send_handshake_message( connection, client_hello, send_buffer, 
     send_buffer_size, parameters );

  free( send_buffer );

  return status;
}
Exemplo n.º 7
0
status_t
Shell::_Spawn(int row, int col, const char *encoding, int argc, const char **argv)
{
	const char *kDefaultShellCommand[] = { "/bin/sh", "--login", NULL };

	if (argv == NULL || argc == 0) {
		argv = kDefaultShellCommand;
		argc = 2;
	}

	signal(SIGTTOU, SIG_IGN);

#ifdef __HAIKU__
	// get a pseudo-tty
	int master = posix_openpt(O_RDWR | O_NOCTTY);
	const char *ttyName;
#else /* __HAIKU__ */
	/*
	 * Get a pseudo-tty. We do this by cycling through files in the
	 * directory. The operating system will not allow us to open a master
	 * which is already in use, so we simply go until the open succeeds.
	 */
	char ttyName[B_PATH_NAME_LENGTH];
	int master = -1;
	DIR *dir = opendir("/dev/pt/");
	if (dir != NULL) {
		struct dirent *dirEntry;
		while ((dirEntry = readdir(dir)) != NULL) {
			// skip '.' and '..'
			if (dirEntry->d_name[0] == '.')
				continue;

			char ptyName[B_PATH_NAME_LENGTH];
			snprintf(ptyName, sizeof(ptyName), "/dev/pt/%s", dirEntry->d_name);

			master = open(ptyName, O_RDWR);
			if (master >= 0) {
				// Set the tty that corresponds to the pty we found
				snprintf(ttyName, sizeof(ttyName), "/dev/tt/%s", dirEntry->d_name);
				break;
			} else {
				// B_BUSY is a normal case
				if (errno != B_BUSY)
					fprintf(stderr, B_TRANSLATE("could not open %s: %s\n"),
						ptyName, strerror(errno));
			}
		}
		closedir(dir);
	}
#endif /* __HAIKU__ */

	if (master < 0) {
    	fprintf(stderr, B_TRANSLATE("Didn't find any available pseudo ttys."));
    	return errno;
	}

#ifdef __HAIKU__
	if (grantpt(master) != 0 || unlockpt(master) != 0
		|| (ttyName = ptsname(master)) == NULL) {
		close(master);
    	fprintf(stderr, B_TRANSLATE("Failed to init pseudo tty."));
		return errno;
	}
#endif /* __HAIKU__ */

	/*
	 * Get the modes of the current terminal. We will duplicates these
	 * on the pseudo terminal.
	 */

	thread_id terminalThread = find_thread(NULL);

	/* Fork a child process. */
	if ((fProcessID = fork()) < 0) {
		close(master);
		return B_ERROR;
	}

	handshake_t handshake;

	if (fProcessID == 0) {
		// Now in child process.

		// close the PTY master side
		close(master);

		/*
		 * Make our controlling tty the pseudo tty. This hapens because
		 * we cleared our original controlling terminal above.
		 */

		/* Set process session leader */
		if (setsid() < 0) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				B_TRANSLATE("could not set session leader."));
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		/* open slave pty */
		int slave = -1;
		if ((slave = open(ttyName, O_RDWR)) < 0) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				B_TRANSLATE("can't open tty (%s)."), ttyName);
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		/* set signal default */
		signal(SIGCHLD, SIG_DFL);
		signal(SIGHUP, SIG_DFL);
		signal(SIGQUIT, SIG_DFL);
		signal(SIGTERM, SIG_DFL);
		signal(SIGINT, SIG_DFL);
		signal(SIGTTOU, SIG_DFL);

		struct termios tio;
		/* get tty termios (not necessary).
		 * TODO: so why are we doing it ?
		 */
		tcgetattr(slave, &tio);

		initialize_termios(tio);

		/*
		 * change control tty.
		 */

		dup2(slave, 0);
		dup2(slave, 1);
		dup2(slave, 2);

		/* close old slave fd. */
		if (slave > 2)
			close(slave);

		/*
		 * set terminal interface.
		 */
		if (tcsetattr(0, TCSANOW, &tio) == -1) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				B_TRANSLATE("failed set terminal interface (TERMIOS)."));
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		/*
		 * set window size.
		 */

		handshake.status = PTY_WS;
		send_handshake_message(terminalThread, handshake);
		receive_handshake_message(handshake);

		if (handshake.status != PTY_WS) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				B_TRANSLATE("mismatch handshake."));
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		struct winsize ws = { handshake.row, handshake.col };

		ioctl(0, TIOCSWINSZ, &ws);

		tcsetpgrp(0, getpgrp());
			// set this process group ID as the controlling terminal
#ifndef __HAIKU__
		ioctl(0, 'pgid', getpid());
#endif
		set_thread_priority(find_thread(NULL), B_NORMAL_PRIORITY);

		/* pty open and set termios successful. */
		handshake.status = PTY_OK;
		send_handshake_message(terminalThread, handshake);

		/*
		 * setenv TERM and TTY.
		 */
		setenv("TERM", "xterm", true);
		setenv("TTY", ttyName, true);
		setenv("TTYPE", encoding, true);

		execve(argv[0], (char * const *)argv, environ);

		// Exec failed.
		// TODO: This doesn't belong here.

		sleep(1);

		BString alertCommand = "alert --stop '";
		alertCommand += B_TRANSLATE("Cannot execute \"%command\":\n\t%error");
		alertCommand += "' '";
		alertCommand += B_TRANSLATE("Use default shell");
		alertCommand += "' '";
		alertCommand += B_TRANSLATE("Abort");
		alertCommand += "'";
		alertCommand.ReplaceFirst("%command", argv[0]);
		alertCommand.ReplaceFirst("%error", strerror(errno));

		int returnValue = system(alertCommand.String());
		if (returnValue == 0) {
			execl(kDefaultShellCommand[0], kDefaultShellCommand[0],
				kDefaultShellCommand[1], NULL);
		}

		exit(1);
	}

	/*
	 * In parent Process, Set up the input and output file pointers so
	 * that they can write and read the pseudo terminal.
	 */

	/*
	 * close parent control tty.
	 */

	int done = 0;
	while (!done) {
		receive_handshake_message(handshake);

		switch (handshake.status) {
			case PTY_OK:
				done = 1;
				break;

			case PTY_NG:
				fprintf(stderr, "%s\n", handshake.msg);
				done = -1;
				break;

			case PTY_WS:
				handshake.row = row;
				handshake.col = col;
				handshake.status = PTY_WS;
				send_handshake_message(fProcessID, handshake);
				break;
		}
	}

	if (done <= 0)
		return B_ERROR;

	fFd = master;

	return B_OK;
}