Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
2.6 KiB

  1. #!/usr/bin/perl -w
  2. use IO::Socket::INET;
  3. use Sys::Hostname;
  4. use Data::Dumper;
  5. use Getopt::Long;
  6. use Pod::Usage;
  7. use strict;
  8. use constant VMPI_PROTOCOL_VERSION => 5;
  9. use constant VMPI_MESSAGE_BASE => 71;
  10. use constant VMPI_PING_REQUEST => VMPI_MESSAGE_BASE+2;
  11. use constant VMPI_PING_RESPONSE => VMPI_MESSAGE_BASE+3;
  12. use constant VMPI_FORCE_PASSWORD_CHANGE => VMPI_MESSAGE_BASE+11;
  13. use constant VMPI_PASSWORD_OVERRIDE => -111;
  14. use constant VMPI_SERVICE_PORT => 23397;
  15. use constant VMPI_LAST_SERVICE_PORT => VMPI_SERVICE_PORT + 15;
  16. my $list = undef;
  17. my $pass = "";
  18. my $help = 0;
  19. my $man = 0;
  20. GetOptions("file=s" => \$list,
  21. "pass=s" => \$pass,
  22. "help|?" => \$help,
  23. "man" => \$man) or pod2usage(1);
  24. pod2usage(2) if $help;
  25. pod2usage(-exitstatus=>0, -verbose=>2) if $man;
  26. my @machines = @ARGV;
  27. if ($list) {
  28. if (open(my $listfh, $list)) {
  29. while(my $line = <$listfh>) {
  30. chomp($line);
  31. next unless $line =~ /\S/;
  32. push @machines, $line;
  33. }
  34. }
  35. }
  36. if (!@machines) {
  37. warn "No machines specified\n";
  38. pod2usage(3);
  39. }
  40. my $message = BuildMessage(VMPI_PROTOCOL_VERSION, VMPI_FORCE_PASSWORD_CHANGE);
  41. $message .= pack("Z*", $pass);
  42. my $length = length($message);
  43. my $socket = CreateSocket();
  44. # send the message 3 times to make sure it gets it
  45. for (1..3) {
  46. for my $host (@machines) {
  47. SendMessage($socket, $host, $message);
  48. }
  49. sleep(1);
  50. }
  51. sub CreateSocket {
  52. return IO::Socket::INET->new(Proto=>'udp');
  53. }
  54. sub BuildMessage {
  55. my $ver = shift;
  56. my $type = shift;
  57. my $message = pack("CcCC", $ver, VMPI_PASSWORD_OVERRIDE, 0, $type);
  58. return $message;
  59. }
  60. sub SendMessage {
  61. my $socket = shift;
  62. my $host = shift;
  63. my $message = shift;
  64. my $ip = gethostbyname($host);
  65. if (!$ip) {
  66. warn "Can't resolve: $host\n";
  67. return;
  68. }
  69. for my $port (VMPI_SERVICE_PORT..VMPI_LAST_SERVICE_PORT) {
  70. my $ipaddr = sockaddr_in($port, $ip);
  71. defined(send($socket, $message, 0, $ipaddr)) || warn("SEND: $!\n");
  72. }
  73. }
  74. __END__
  75. =head1 NAME
  76. vmpi_chpass.pl - Sets the VMPI password on a set of machines
  77. =head1 SYNOPSIS
  78. vmpi_chpass.pl [-pass <password>] [-help|-?] [-man]
  79. -file <host file> | <host> ...
  80. Options:
  81. -file A file that contains the names of machines to use
  82. -pass Password to set
  83. -help|-? Display command line usage
  84. -man Display full documentation
  85. =head1 DESCRIPTION
  86. B<vmpi_chpass.pl> sets the password on the given list of machines. The
  87. machines can be given as separate arguments on the command line or as
  88. a list in a text file. If the password is not given, the password is
  89. removed from the machines, opening them up for general use.
  90. =cut