using System;
using System.Text;
using System.Management.Automation;
using System.Net;
using System.IO;
using System.Web;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Security;
namespace CustomCmdlets
{
[Cmdlet( VerbsCommunications.Send, "SMS", SupportsShouldProcess = true )]
public class SendSMS : PSCmdlet
{
private const string GOOGLE_VOICE_ADDRESS = "https://www.google.com/voice/";
private const string GOOGLE_VOICE_AUTHENTICATION_ADDRESS = "https://www.google.com/accounts/ServiceLoginAuth";
private const string GOOGLE_VOICE_SMS_ADDRESS = "https://www.google.com/voice/sms/send/";
private CookieCollection cookieCollection;
#region Parameters
private string googleUsername;
[ValidateNotNullOrEmpty]
public string GoogleUsername
{
get
{
return googleUsername;
}
set
{
googleUsername = value;
}
}
private SecureString googlePassword;
[ValidateNotNullOrEmpty]
public SecureString GooglePassword
{
get
{
return googlePassword;
}
set
{
googlePassword = value;
}
}
private string number;
[Parameter( Position = 0, Mandatory = true )]
[ValidateNotNullOrEmpty]
public string Number
{
get
{
return number;
}
set
{
number = value;
}
}
private string text;
[Parameter( Position = 1, Mandatory = true )]
public string Text
{
get
{
return text;
}
set
{
text = value;
}
}
#endregion
protected override void BeginProcessing()
{
if ( googleUsername == null )
{
googleUsername = (string)GetVariableValue( "GoogleUsername", null );
}
if ( googlePassword == null )
{
googlePassword = (SecureString)GetVariableValue( "GooglePassword", null );
}
if ( string.IsNullOrEmpty( googleUsername ) || googlePassword == null )
{
this.WriteError( new ErrorRecord(
new Exception( "You must provide a username and password." ),
"Send-SMS", ErrorCategory.PermissionDenied, this ) );
}
}
protected override void EndProcessing()
{
IntPtr bstr = Marshal.SecureStringToBSTR( googlePassword );
string plainGmailPassword = Marshal.PtrToStringAuto( bstr );
Marshal.ZeroFreeBSTR( bstr );
string postDataString = "&continue=" + HttpUtility.UrlEncode( GOOGLE_VOICE_ADDRESS ) +
"&Email=" + HttpUtility.UrlEncode( googleUsername ) +
"&Passwd=" + HttpUtility.UrlEncode( plainGmailPassword );
this.cookieCollection = new CookieCollection();
this.WriteVerbose( "Sending Google Voice login request..." );
MakeHttpWebRequest( GOOGLE_VOICE_AUTHENTICATION_ADDRESS, true, Encoding.UTF8.GetBytes( postDataString ) );
// if we don't have this cookie, something went wrong
if ( this.cookieCollection[ "GAUSR" ] == null )
{
this.WriteError( new ErrorRecord(
new Exception( "Could not log in to Gmail. Please check your username and password." ),
"Send-SMS", ErrorCategory.PermissionDenied, this ) );
}
else
{
this.WriteVerbose( "Sending Google Voice home page request..." );
string googleVoiceHomePage = MakeHttpWebRequest( GOOGLE_VOICE_ADDRESS, false, null );
Match rnrSeMatch = Regex.Match( googleVoiceHomePage, @"name=""_rnr_se"".*?value=""(?<Value>[^""]+)""" );
if ( rnrSeMatch.Success )
{
postDataString = "&_rnr_se=" + HttpUtility.UrlEncode( rnrSeMatch.Groups[ "Value" ].Value ) +
"&phoneNumber=" + HttpUtility.UrlEncode( number ) +
"&text=" + HttpUtility.UrlEncode( text );
this.WriteVerbose( "Sending Google Voice SMS request..." );
string sendResult = MakeHttpWebRequest( GOOGLE_VOICE_SMS_ADDRESS, true, Encoding.UTF8.GetBytes( postDataString ) );
Match resultMatch = Regex.Match( sendResult, @"\{""ok"":(?<Success>[^,]+),""data"":\{""code"":(?<Code>\d+)\}\}" );
if ( resultMatch.Success )
{
if ( bool.Parse( resultMatch.Groups[ "Success" ].Value ) )
{
this.WriteObject( "Your SMS has been sent." );
}
else
{
this.WriteError( new ErrorRecord(
new Exception( "Your SMS was not sent." ),
"Send-SMS", ErrorCategory.NotSpecified, this ) );
}
}
}
}
}
private string MakeHttpWebRequest( string requestUrl, bool post, byte[] postData )
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create( new Uri( requestUrl ) );
// we need to do this ourselves
webRequest.AllowAutoRedirect = false;
webRequest.KeepAlive = false;
webRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
webRequest.CookieContainer = new CookieContainer();
webRequest.CookieContainer.Add( this.cookieCollection );
if ( post )
{
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = postData.Length;
Stream requestStream = null;
try
{
requestStream = webRequest.GetRequestStream();
requestStream.Write( postData, 0, postData.Length );
}
catch ( Exception ex )
{
this.WriteError( new ErrorRecord( ex, "Send-SMS", ErrorCategory.InvalidData, this ) );
}
finally
{
if ( requestStream != null )
{
requestStream.Close();
}
}
}
else
{
webRequest.Method = "GET";
webRequest.ContentType = "text/html";
}
HttpWebResponse webResponse = null;
string responseString = "";
try
{
webResponse = (HttpWebResponse)webRequest.GetResponse();
cookieCollection.Add( webResponse.Cookies );
StreamReader streamReader = new StreamReader( webResponse.GetResponseStream() );
responseString = streamReader.ReadToEnd();
streamReader.Close();
// redirect if we have a Location header
if ( webResponse.Headers[ "Location" ] != null )
{
responseString = MakeHttpWebRequest( webResponse.Headers[ "Location" ], false, null );
}
}
catch ( Exception ex )
{
this.WriteError( new ErrorRecord( ex, "Send-SMS", ErrorCategory.InvalidResult, this ) );
}
finally
{
if ( webResponse != null )
{
webResponse.Close();
}
}
return responseString;
}
}
}