public SubscribedForwardDestination(Growl.Daemon.Subscriber subscriber, int ttl) : this(subscriber.Name, true, subscriber.IPAddress, subscriber.Port, subscriber.Key.Password, KnownDestinationPlatformType.FromString(subscriber.PlatformName), ttl) { base.Key = subscriber.ID; this.hashAlgorithm = subscriber.Key.HashAlgorithm; this.encryptionAlgorithm = subscriber.Key.EncryptionAlgorithm; }
/// <summary> /// 接続先を詳細に指定してGrowlに接続する場合のコンストラクタ /// </summary> /// <param name="password">Growlへ接続をする際に使うパスワード</param> /// <param name="hostname">接続ホスト名 or 接続先のIPアドレス</param> /// <param name="port">接続するポート番号</param> /// <param name="encryptionAlgorithm"> /// 通知メッセージの暗号化タイプを指定。 /// デフォルトは「plaintext」 /// </param> public GrowlManagerBase(string password, string hostname, int port, Cryptography.SymmetricAlgorithmType encryptionAlgorithm = Cryptography.SymmetricAlgorithmType.PlainText) { Connector = new GrowlConnector(password, hostname, port) { EncryptionAlgorithm = encryptionAlgorithm }; }
/// <summary> /// Creates a new instance of the Key class. /// </summary> /// <param name="password">The user-supplied password to use as the basis for the key</param> /// <param name="hashAlgorithm">The <see cref="Cryptography.HashAlgorithmType"/> used when hashing values</param> /// <param name="encryptionAlgorithm">The <see cref="Cryptography.SymmetricAlgorithmType"/> used when encrypting values</param> protected Key(string password, Cryptography.HashAlgorithmType hashAlgorithm, Cryptography.SymmetricAlgorithmType encryptionAlgorithm) { if (!String.IsNullOrEmpty(password)) { this.password = password; this.hashAlgorithm = hashAlgorithm; this.encryptionAlgorithm = encryptionAlgorithm; byte[] saltBytes = Cryptography.GenerateBytes(8); this.salt = Cryptography.HexEncode(saltBytes); byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password); byte[] keyBasis = new byte[passwordBytes.Length + saltBytes.Length]; Array.Copy(passwordBytes, 0, keyBasis, 0, passwordBytes.Length); Array.Copy(saltBytes, 0, keyBasis, passwordBytes.Length, saltBytes.Length); byte[] keyBytes = Cryptography.ComputeHash(keyBasis, hashAlgorithm); this.encryptionKey = keyBytes; byte[] keyHashBytes = Cryptography.ComputeHash(keyBytes, hashAlgorithm); this.keyHash = Cryptography.HexEncode(keyHashBytes); } else { InitializeEmptyKey(); } }
/// <summary> /// Creates a new instance of the Key class. /// </summary> /// <param name="password">The user-supplied password to use as the basis for the key</param> /// <param name="hashAlgorithm">The <see cref="Cryptography.HashAlgorithmType"/> used when hashing values</param> /// <param name="encryptionAlgorithm">The <see cref="Cryptography.SymmetricAlgorithmType"/> used when encrypting values</param> protected Key(string password, Cryptography.HashAlgorithmType hashAlgorithm, Cryptography.SymmetricAlgorithmType encryptionAlgorithm) { if (!String.IsNullOrEmpty(password)) { this.password = password; this.hashAlgorithm = hashAlgorithm; this.encryptionAlgorithm = encryptionAlgorithm; byte[] saltBytes = Cryptography.GenerateBytes(8); this.salt = Cryptography.HexEncode(saltBytes); byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password); byte[] keyBasis = new byte[passwordBytes.Length + saltBytes.Length]; Array.Copy(passwordBytes, 0, keyBasis, 0, passwordBytes.Length); Array.Copy(saltBytes, 0, keyBasis, passwordBytes.Length, saltBytes.Length); byte[] keyBytes = Cryptography.ComputeHash(keyBasis, hashAlgorithm); this.encryptionKey = keyBytes; byte[] keyHashBytes = Cryptography.ComputeHash(keyBytes, hashAlgorithm); this.keyHash = Cryptography.HexEncode(keyHashBytes); } else InitializeEmptyKey(); }
public static int Main(string[] args) { if (args == null || args.Length == 0) { Console.WriteLine("Invalid arguments. See /? for usage."); return(-1); } if (args[0] == "/?") { Console.WriteLine(); string usage = global::growlnotify.Properties.Resources.usage; Console.WriteLine(usage); return(0); } // parse parameters Dictionary <string, Parameter> parameters = new Dictionary <string, Parameter>(); try { foreach (string arg in args) { Parameter p = GetParameterValue(arg); parameters.Add(p.Argument, p); } } catch (Exception ex) { Console.WriteLine("Bad arguments : " + ex.Message); return(-1); } // set default values string messageText = ""; string title = "growlnotify"; string id = ""; string coalescingid = null; bool sticky = false; int priorityInt = 0; string iconFile = null; string applicationName = "growlnotify"; string appIconFile = null; string[] notificationTypesToRegister = null; string notificationType = "General Notification"; string callbackUrl = null; string protocol = "GNTP"; string host = "localhost"; string password = null; Cryptography.SymmetricAlgorithmType encryptionAlgorithm = Cryptography.SymmetricAlgorithmType.PlainText; Cryptography.HashAlgorithmType hashAlgorithm = Cryptography.HashAlgorithmType.MD5; int port = GrowlConnector.TCP_PORT; // validate required parameters if (!parameters.ContainsKey("messagetext")) { Console.WriteLine("Missing 'messagetext' argument. See /? for usage"); return(-1); } else { messageText = parameters["messagetext"].Value; } if (parameters.ContainsKey("/t")) { title = parameters["/t"].Value; } if (parameters.ContainsKey("/id")) { id = parameters["/id"].Value; } if (parameters.ContainsKey("/s")) { string s = parameters["/s"].Value.ToLower(); if (s == "true") { sticky = true; } } if (parameters.ContainsKey("/p")) { priorityInt = Convert.ToInt32(parameters["/p"].Value); } if (parameters.ContainsKey("/i")) { iconFile = parameters["/i"].Value; if (iconFile.StartsWith(".")) { string root = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); iconFile = System.IO.Path.Combine(root, iconFile); } } if (parameters.ContainsKey("/c")) { coalescingid = parameters["/c"].Value; } if (parameters.ContainsKey("/a")) { applicationName = parameters["/a"].Value; } if (parameters.ContainsKey("/ai")) { appIconFile = parameters["/ai"].Value; if (appIconFile.StartsWith(".")) { string root = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); appIconFile = System.IO.Path.Combine(root, iconFile); } } if (parameters.ContainsKey("/r")) { string[] parts = parameters["/r"].Value.Split(','); if (parts != null && parts.Length > 0) { notificationTypesToRegister = new string[parts.Length]; for (int p = 0; p < parts.Length; p++) { string val = parts[p]; if (val.StartsWith("\"")) { val = val.Substring(1, val.Length - 1); } if (val.EndsWith("\"")) { val = val.Substring(0, val.Length - 1); } notificationTypesToRegister[p] = val; } } } if (parameters.ContainsKey("/n")) { notificationType = parameters["/n"].Value; } if (parameters.ContainsKey("/cu")) { callbackUrl = parameters["/cu"].Value; } if (parameters.ContainsKey("/protocol")) { protocol = parameters["/protocol"].Value; } if (parameters.ContainsKey("/host")) { host = parameters["/host"].Value; } if (parameters.ContainsKey("/port")) { port = Convert.ToInt32(parameters["/port"].Value); } else { if (protocol == "UDP") { port = 9887; } } if (parameters.ContainsKey("/pass")) { password = parameters["/pass"].Value; } if (parameters.ContainsKey("/enc")) { switch (parameters["/enc"].Value.ToUpper()) { case "DES": encryptionAlgorithm = Cryptography.SymmetricAlgorithmType.DES; break; case "3DES": encryptionAlgorithm = Cryptography.SymmetricAlgorithmType.TripleDES; break; case "AES": encryptionAlgorithm = Cryptography.SymmetricAlgorithmType.AES; break; default: encryptionAlgorithm = Cryptography.SymmetricAlgorithmType.PlainText; break; } } if (parameters.ContainsKey("/hash")) { switch (parameters["/hash"].Value.ToUpper()) { case "SHA1": hashAlgorithm = Cryptography.HashAlgorithmType.SHA1; break; case "SHA256": hashAlgorithm = Cryptography.HashAlgorithmType.SHA256; break; case "SHA512": hashAlgorithm = Cryptography.HashAlgorithmType.SHA512; break; default: hashAlgorithm = Cryptography.HashAlgorithmType.MD5; break; } } if (parameters.ContainsKey("/silent")) { string s = parameters["/silent"].Value.ToLower(); if (s == "true") { silent = true; } } // set up a waithandle so we can wait for responses ewh = new EventWaitHandle(false, EventResetMode.ManualReset); // set up growl connector growl = new GrowlConnector(password, host, port); growl.EncryptionAlgorithm = encryptionAlgorithm; growl.KeyHashAlgorithm = hashAlgorithm; growl.OKResponse += new GrowlConnector.ResponseEventHandler(growl_Response); growl.ErrorResponse += new GrowlConnector.ResponseEventHandler(growl_Response); // do any registration first if (notificationTypesToRegister != null || applicationName == "growlnotify") { Growl.CoreLibrary.Resource appIcon = null; if (!String.IsNullOrEmpty(appIconFile)) { Uri uri = new Uri(appIconFile); if (uri.IsFile && System.IO.File.Exists(uri.LocalPath)) { appIcon = Growl.CoreLibrary.ImageConverter.ImageFromUrl(uri.LocalPath); } else { appIcon = appIconFile; } } if (notificationTypesToRegister == null) { notificationTypesToRegister = new string[] { "General Notification" }; } NotificationType[] types = new NotificationType[notificationTypesToRegister.Length]; for (int t = 0; t < types.Length; t++) { string nttr = notificationTypesToRegister[t]; NotificationType type = new NotificationType(nttr); types[t] = type; } Application application = new Application(applicationName); application.Icon = appIcon; growl.Register(application, types); ewh.WaitOne(); // wait just to be sure the registration gets there first } // handle any callback information CallbackContext callback = null; if (!String.IsNullOrEmpty(callbackUrl)) { callback = new CallbackContext(callbackUrl); } ewh.Reset(); // handle icons (local icons will be sent as binary data, url-based icons will be sent as urls) Growl.CoreLibrary.Resource icon = null; if (!String.IsNullOrEmpty(iconFile)) { Uri uri = new Uri(iconFile); if (uri.IsFile && System.IO.File.Exists(uri.LocalPath)) { icon = Growl.CoreLibrary.ImageConverter.ImageFromUrl(uri.LocalPath); } else { icon = iconFile; } } // send the notification Priority priority = (Enum.IsDefined(typeof(Priority), priorityInt) ? (Priority)priorityInt : Priority.Normal); Notification notification = new Notification(applicationName, notificationType, id, title, messageText, icon, sticky, priority, coalescingid); growl.Notify(notification, callback); ewh.WaitOne(); Console.WriteLine(); return(r); }
/// <summary> /// Compares the provides keyHash and salt to the supplied password to see if they are a match. /// </summary> /// <param name="password">The password to compare to.</param> /// <param name="keyHash">The hex-encoded key hash</param> /// <param name="salt">The hex-encoded salt value</param> /// <param name="hashAlgorithm">The <see cref="Cryptography.HashAlgorithmType"/> used to generate the key hash</param> /// <param name="encryptionAlgorithm">The <see cref="Cryptography.SymmetricAlgorithmType"/> used by this key to do encryption/decryption</param> /// <param name="matchingKey">If a match is found, returns the matching <see cref="Key"/>;if no match is found, returns <c>null</c>.</param> /// <returns> /// <c>true</c> if the key hash and salt match the password; /// <c>false</c> otherwise /// </returns> public static bool Compare(string password, string keyHash, string salt, Cryptography.HashAlgorithmType hashAlgorithm, Cryptography.SymmetricAlgorithmType encryptionAlgorithm, out Key matchingKey) { matchingKey = null; if (!String.IsNullOrEmpty(password)) { byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password); byte[] saltBytes = Cryptography.HexUnencode(salt); byte[] keyBasis = new byte[passwordBytes.Length + saltBytes.Length]; Array.Copy(passwordBytes, 0, keyBasis, 0, passwordBytes.Length); Array.Copy(saltBytes, 0, keyBasis, passwordBytes.Length, saltBytes.Length); byte[] keyBytes = Cryptography.ComputeHash(keyBasis, hashAlgorithm); byte[] keyHashBytes = Cryptography.ComputeHash(keyBytes, hashAlgorithm); string actualKeyHash = Cryptography.HexEncode(keyHashBytes); if (keyHash == actualKeyHash) { matchingKey = new Key(); matchingKey.password = password; matchingKey.salt = salt; matchingKey.keyHash = keyHash; matchingKey.hashAlgorithm = hashAlgorithm; matchingKey.encryptionKey = keyBytes; matchingKey.encryptionAlgorithm = encryptionAlgorithm; return(true); } } return(false); }
/// <summary> /// Generates a <see cref="Key"/> based on the supplied password and algorithms. /// </summary> /// <param name="password">The password to use as the basis for the key.</param> /// <param name="hashAlgorithm">The <see cref="Cryptography.HashAlgorithmType"/> used when hashing values</param> /// <param name="encryptionAlgorithm">The <see cref="Cryptography.SymmetricAlgorithmType"/> used when encrypting values</param> /// <returns><see cref="Key"/></returns> public static Key GenerateKey(string password, Cryptography.HashAlgorithmType hashAlgorithm, Cryptography.SymmetricAlgorithmType encryptionAlgorithm) { if (String.IsNullOrEmpty(password)) { return(Key.None); } else { return(new Key(password, hashAlgorithm, encryptionAlgorithm)); } }
private void ProcessBuffer() { try { Data data = new Data(buffer.ToArray()); string s = data.ToString(); alreadyReceived.Append(s); if (tag == START_TAG) { // start looking for GNTP header tag = GNTP_IDENTIFIER_TAG; ContinueProcessing(); } else if (tag == GNTP_IDENTIFIER_TAG) { string line = s; Match match = ParseGNTPHeaderLine(line, this.passwordRequired); if (match.Success) { this.version = match.Groups["Version"].Value; if (version == MessageParser.GNTP_SUPPORTED_VERSION) { string d = match.Groups["Directive"].Value; if (Enum.IsDefined(typeof(RequestType), d)) { this.directive = (RequestType)Enum.Parse(typeof(RequestType), d); // check for supported but not allowed requests if (this.directive == RequestType.SUBSCRIBE && !this.allowSubscriptions) { OnError(ErrorCode.NOT_AUTHORIZED, ErrorDescription.SUBSCRIPTIONS_NOT_ALLOWED); } else { this.encryptionAlgorithm = Cryptography.GetEncryptionType(match.Groups["EncryptionAlgorithm"].Value); this.ivHex = (match.Groups["IV"] != null ? match.Groups["IV"].Value : null); if (!String.IsNullOrEmpty(this.ivHex)) { this.iv = Cryptography.HexUnencode(this.ivHex); } string keyHash = match.Groups["KeyHash"].Value.ToUpper(); bool authorized = false; // Any of the following criteria require a password: // 1. the request did not originate on the local machine or LAN // 2. the request came from the LAN, but LAN passwords are required // 2. it is a SUBSCRIBE request (all subscriptions require a password) // 3. the user's preferences require even local requests to supply a password // Additionally, even if a password is not required, it will be validated if the // sending appplication includes one string errorDescription = ErrorDescription.INVALID_KEY; if (this.passwordRequired || this.directive == RequestType.SUBSCRIBE || !String.IsNullOrEmpty(keyHash)) { if (String.IsNullOrEmpty(keyHash)) { errorDescription = ErrorDescription.MISSING_KEY; } else { string keyHashAlgorithmType = match.Groups["KeyHashAlgorithm"].Value; this.keyHashAlgorithm = Cryptography.GetKeyHashType(keyHashAlgorithmType); string salt = match.Groups["Salt"].Value.ToUpper(); authorized = this.passwordManager.IsValid(keyHash, salt, this.keyHashAlgorithm, this.encryptionAlgorithm, out this.key); } } else { authorized = true; this.key = Key.None; } if (authorized) { if (this.encryptionAlgorithm == Cryptography.SymmetricAlgorithmType.PlainText) { tag = HEADER_TAG; ContinueProcessing(); } else { tag = ENCRYPTED_HEADERS_TAG; ContinueProcessing(); } } else { OnError(ErrorCode.NOT_AUTHORIZED, errorDescription); } } } else { OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.UNSUPPORTED_DIRECTIVE, d); } } else { OnError(ErrorCode.UNKNOWN_PROTOCOL_VERSION, ErrorDescription.UNSUPPORTED_VERSION, version); } } else { OnError(ErrorCode.UNKNOWN_PROTOCOL, ErrorDescription.MALFORMED_REQUEST); } } else if (tag == HEADER_TAG) { if (s == MessageParser.BLANK_LINE) { // if this is a REGISTER message, check Notifications-Count value // to see how many notification sections to expect if (this.directive == RequestType.REGISTER) { if (this.expectedNotifications > 0) { tag = NOTIFICATION_TYPE_TAG; ContinueProcessing(); } else { // a REGISTER request with no notifications is not valid OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.NO_NOTIFICATIONS_REGISTERED); } } else { // otherwise, check the number of resource pointers we got and start reading those this.pointersExpected = GetNumberOfPointers(); if (this.pointersExpected > 0) { this.pointersExpectedRemaining = this.pointersExpected; this.currentPointer = 1; tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } else { OnMessageParsed(); } } } else { Header header = Header.ParseHeader(s); if (header != null) { bool addHeader = true; if (header.Name == Header.APPLICATION_NAME) { this.applicationName = header.Value; } if (header.Name == Header.NOTIFICATIONS_COUNT) { this.expectedNotifications = Convert.ToInt32(header.Value); this.expectedNotificationsRemaining = this.expectedNotifications; this.currentNotification = 1; } if (header.Name == Header.NOTIFICATION_CALLBACK_CONTEXT) { this.callbackData = header.Value; } if (header.Name == Header.NOTIFICATION_CALLBACK_CONTEXT_TYPE) { this.callbackDataType = header.Value; } if (header.Name == Header.NOTIFICATION_CALLBACK_TARGET || header.Name == Header.NOTIFICATION_CALLBACK_CONTEXT_TARGET) // left in for compatibility { this.callbackUrl = header.Value; } if (header.Name == Header.RECEIVED) { this.requestInfo.PreviousReceivedHeaders.Add(header); addHeader = false; } if (addHeader) { this.headers.AddHeader(header); } } tag = HEADER_TAG; ContinueProcessing(); } } else if (tag == NOTIFICATION_TYPE_TAG) { if (s == MessageParser.BLANK_LINE) { this.expectedNotificationsRemaining--; if (this.expectedNotificationsRemaining > 0) { this.currentNotification++; tag = NOTIFICATION_TYPE_TAG; ContinueProcessing(); } else { // otherwise, check the number of resource pointers we got and start reading those this.pointersExpected = GetNumberOfPointers(); if (this.pointersExpected > 0) { this.pointersExpectedRemaining = this.pointersExpected; this.currentPointer = 1; tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } else { OnMessageParsed(); } } } else { if (this.notificationsToBeRegistered.Count < this.currentNotification) { this.notificationsToBeRegistered.Add(new HeaderCollection()); } Header header = Header.ParseHeader(s); this.notificationsToBeRegistered[this.currentNotification - 1].AddHeader(header); tag = NOTIFICATION_TYPE_TAG; ContinueProcessing(); } } else if (tag == RESOURCE_HEADER_TAG) { if (s == MessageParser.BLANK_LINE) { // we should have found an Identifier header and Length header, or we are just starting a new section Pointer p = this.pointers[this.currentPointer - 1]; if (p.Identifier != null && p.Length > 0) { // read #of bytes int length = this.pointers[this.currentPointer - 1].Length; tag = RESOURCE_TAG; ContinueProcessing(); } else { tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } } else { Header header = Header.ParseHeader(s); // should be Identifer or Length if (header != null) { bool validHeader = false; if (header.Name == Header.RESOURCE_IDENTIFIER) { this.pointers[this.currentPointer - 1].Identifier = header.Value; validHeader = true; } else if (header.Name == Header.RESOURCE_LENGTH) { this.pointers[this.currentPointer - 1].Length = Convert.ToInt32(header.Value); validHeader = true; } else { OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.UNRECOGNIZED_RESOURCE_HEADER, header.Name); } if (validHeader) { tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } } else { OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.UNRECOGNIZED_RESOURCE_HEADER); } } } else if (tag == RESOURCE_TAG) { // deal with data bytes byte[] bytes = this.key.Decrypt(data.ByteArray, this.iv); Pointer pointer = this.pointers[this.currentPointer - 1]; pointer.ByteArray = bytes; BinaryData binaryData = new BinaryData(pointer.Identifier, pointer.ByteArray); ResourceCache.Add(this.applicationName, binaryData); this.pointersExpectedRemaining--; if (this.pointersExpectedRemaining > 0) { this.currentPointer++; tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } else { OnMessageParsed(); } } else if (tag == ENCRYPTED_HEADERS_TAG) { // see if a length was specified (the original spec did not require the main encrypted headers portion to specify a length) if (s.StartsWith(Header.RESOURCE_LENGTH)) { Header header = Header.ParseHeader(s); if (header != null) { int len = Convert.ToInt32(header.Value); tag = ENCRYPTED_HEADERS_TAG; ContinueProcessing(); } } ParseEncryptedMessage(data.ByteArray); if (this.pointersExpected > 0) { tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } else { OnMessageParsed(); } } else { OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST); } } catch (GrowlException gEx) { OnError(gEx.ErrorCode, gEx.Message, gEx.AdditionalInfo); } catch (Exception ex) { OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST, ex.Message); } }
private void Test_Register(string testName, Growl.Connector.Application app, List <NotificationType> types, Cryptography.SymmetricAlgorithmType ea, Cryptography.HashAlgorithmType ha) { GrowlConnector g = new GrowlConnector(this.textBox2.Text); g.EncryptionAlgorithm = ea; g.KeyHashAlgorithm = ha; //string r = g.Register(app, types.ToArray()); //WriteTestRequest(r); }
public GrowlManager(string password, string hostname, int port, Cryptography.SymmetricAlgorithmType encryptionAlgorithm = Cryptography.SymmetricAlgorithmType.PlainText) : base(password, hostname, port, encryptionAlgorithm) { }
public GrowlManager(string password, Cryptography.SymmetricAlgorithmType encryptionAlgorithm = Cryptography.SymmetricAlgorithmType.PlainText) : base(password, encryptionAlgorithm) { }
public GrowlManager(Cryptography.SymmetricAlgorithmType encryptionAlgorithm = Cryptography.SymmetricAlgorithmType.PlainText) : base(encryptionAlgorithm) { }
/// <summary> /// Checks the supplied <paramref name="keyHash"/> against all of the stored passwords to /// see if the hash is valid, and retuns the matching <see cref="Key"/> if a match is found. /// </summary> /// <param name="keyHash">The hex-encoded hash to validate</param> /// <param name="salt">The hex-encoded salt value</param> /// <param name="hashAlgorithm">The <see cref="Cryptography.HashAlgorithmType"/> used to generate the hash</param> /// <param name="encryptionAlgorithm">The <see cref="Cryptography.SymmetricAlgorithmType"/> used by this key to do encryption/decryption</param> /// <param name="matchingKey">Contains the matching <see cref="Key"/> if a match is found</param> /// <returns> /// <c>true</c> if the hash matches one of the stored password/key values; /// <c>false</c> if no match is found /// If no match is found, <paramref name="matchingKey"/> will return <c>null</c>. /// </returns> public bool IsValid(string keyHash, string salt, Cryptography.HashAlgorithmType hashAlgorithm, Cryptography.SymmetricAlgorithmType encryptionAlgorithm, out Key matchingKey) { matchingKey = null; if (String.IsNullOrEmpty(keyHash)) { return(false); } keyHash = keyHash.ToUpper(); foreach (Password password in this.passwords.Values) { bool match = Key.Compare(password.ActualPassword, keyHash, salt, hashAlgorithm, encryptionAlgorithm, out matchingKey); if (match) { return(true); } } return(false); }
public static int Main(string[] args) { if (args == null || args.Length == 0) { Console.WriteLine("Invalid arguments. See /? for usage."); return(-1); } else if (args[0] == "/?") { Console.WriteLine(); Console.WriteLine(Resources.usage); return(0); } else { Dictionary <string, Program.Parameter> dictionary = new Dictionary <string, Program.Parameter>(); try { foreach (string str in args) { Program.Parameter parameterValue = Program.GetParameterValue(str); dictionary.Add(parameterValue.Argument, parameterValue); } } catch (Exception ex) { Console.WriteLine("Bad arguments : " + ex.Message); return(-1); } string title = "growlnotify"; string id = ""; string coalescingID = (string)null; bool sticky = false; int num = 0; string str1 = (string)null; string str2 = "growlnotify"; string uriString = (string)null; string[] strArray1 = (string[])null; string notificationName = "General Notification"; string url = (string)null; string str3 = "GNTP"; string hostname = "localhost"; string password = (string)null; Cryptography.SymmetricAlgorithmType symmetricAlgorithmType = Cryptography.SymmetricAlgorithmType.PlainText; Cryptography.HashAlgorithmType hashAlgorithmType = Cryptography.HashAlgorithmType.MD5; int port = 23053; if (!dictionary.ContainsKey("messagetext")) { Console.WriteLine("Missing 'messagetext' argument. See /? for usage"); return(-1); } else { string text = dictionary["messagetext"].Value; if (dictionary.ContainsKey("/t")) { title = dictionary["/t"].Value; } if (dictionary.ContainsKey("/id")) { id = dictionary["/id"].Value; } if (dictionary.ContainsKey("/s") && dictionary["/s"].Value.ToLower() == "true") { sticky = true; } if (dictionary.ContainsKey("/p")) { num = Convert.ToInt32(dictionary["/p"].Value); } if (dictionary.ContainsKey("/i")) { str1 = dictionary["/i"].Value; if (str1.StartsWith(".")) { str1 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), str1); } } if (dictionary.ContainsKey("/c")) { coalescingID = dictionary["/c"].Value; } if (dictionary.ContainsKey("/a")) { str2 = dictionary["/a"].Value; } if (dictionary.ContainsKey("/ai")) { uriString = dictionary["/ai"].Value; if (uriString.StartsWith(".")) { uriString = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), str1); } } if (dictionary.ContainsKey("/r")) { string[] strArray2 = dictionary["/r"].Value.Split(new char[1] { ',' }); if (strArray2 != null && strArray2.Length > 0) { strArray1 = new string[strArray2.Length]; for (int index = 0; index < strArray2.Length; ++index) { string str4 = strArray2[index]; if (str4.StartsWith("\"")) { str4 = str4.Substring(1, str4.Length - 1); } if (str4.EndsWith("\"")) { str4 = str4.Substring(0, str4.Length - 1); } strArray1[index] = str4; } } } if (dictionary.ContainsKey("/n")) { notificationName = dictionary["/n"].Value; } if (dictionary.ContainsKey("/cu")) { url = dictionary["/cu"].Value; } if (dictionary.ContainsKey("/protocol")) { str3 = dictionary["/protocol"].Value; } if (dictionary.ContainsKey("/host")) { hostname = dictionary["/host"].Value; } if (dictionary.ContainsKey("/port")) { port = Convert.ToInt32(dictionary["/port"].Value); } else if (str3 == "UDP") { port = 9887; } if (dictionary.ContainsKey("/pass")) { password = dictionary["/pass"].Value; } if (dictionary.ContainsKey("/enc")) { switch (dictionary["/enc"].Value.ToUpper()) { case "DES": symmetricAlgorithmType = Cryptography.SymmetricAlgorithmType.DES; break; case "3DES": symmetricAlgorithmType = Cryptography.SymmetricAlgorithmType.TripleDES; break; case "AES": symmetricAlgorithmType = Cryptography.SymmetricAlgorithmType.AES; break; default: symmetricAlgorithmType = Cryptography.SymmetricAlgorithmType.PlainText; break; } } if (dictionary.ContainsKey("/hash")) { switch (dictionary["/hash"].Value.ToUpper()) { case "SHA1": hashAlgorithmType = Cryptography.HashAlgorithmType.SHA1; break; case "SHA256": hashAlgorithmType = Cryptography.HashAlgorithmType.SHA256; break; case "SHA512": hashAlgorithmType = Cryptography.HashAlgorithmType.SHA512; break; default: hashAlgorithmType = Cryptography.HashAlgorithmType.MD5; break; } } if (dictionary.ContainsKey("/silent") && dictionary["/silent"].Value.ToLower() == "true") { Program.silent = true; } Program.ewh = new EventWaitHandle(false, EventResetMode.ManualReset); Program.growl = new GrowlConnector(password, hostname, port); Program.growl.EncryptionAlgorithm = symmetricAlgorithmType; Program.growl.KeyHashAlgorithm = hashAlgorithmType; Program.growl.OKResponse += new GrowlConnector.ResponseEventHandler(Program.growl_Response); Program.growl.ErrorResponse += new GrowlConnector.ResponseEventHandler(Program.growl_Response); if (strArray1 != null || str2 == "growlnotify") { Resource resource = (Resource)null; if (!string.IsNullOrEmpty(uriString)) { Uri uri = new Uri(uriString); resource = !uri.IsFile || !File.Exists(uri.LocalPath) ? (Resource)uriString : (Resource)ImageConverter.ImageFromUrl(uri.LocalPath); } if (strArray1 == null) { strArray1 = new string[1] { "General Notification" } } ; NotificationType[] notificationTypes = new NotificationType[strArray1.Length]; for (int index = 0; index < notificationTypes.Length; ++index) { NotificationType notificationType = new NotificationType(strArray1[index]); notificationTypes[index] = notificationType; } Program.growl.Register(new Application(str2) { Icon = resource }, notificationTypes); Program.ewh.WaitOne(); } CallbackContext callbackContext = (CallbackContext)null; if (!string.IsNullOrEmpty(url)) { callbackContext = new CallbackContext(url); } Program.ewh.Reset(); Resource icon = (Resource)null; if (!string.IsNullOrEmpty(str1)) { Uri uri = new Uri(str1); icon = !uri.IsFile || !File.Exists(uri.LocalPath) ? (Resource)str1 : (Resource)ImageConverter.ImageFromUrl(uri.LocalPath); } Priority priority = Enum.IsDefined(typeof(Priority), (object)num) ? (Priority)num : Priority.Normal; Notification notification = new Notification(str2, notificationName, id, title, text, icon, sticky, priority, coalescingID); Program.growl.Notify(notification, callbackContext); Program.ewh.WaitOne(); Console.WriteLine(); return(Program.r); } } }
/// <summary> /// Initializes a new instance of the <see cref="SubscriberKey"/> class. /// </summary> /// <param name="key">The <see cref="Key"/> to base this key upon.</param> /// <param name="subscriberID">The unique subscriber ID</param> /// <param name="hashAlgorithm">The <see cref="Cryptography.HashAlgorithmType"/> used when hashing values</param> /// <param name="encryptionAlgorithm">The <see cref="Cryptography.SymmetricAlgorithmType"/> used when encrypting values</param> public SubscriberKey(Key key, string subscriberID, Cryptography.HashAlgorithmType hashAlgorithm, Cryptography.SymmetricAlgorithmType encryptionAlgorithm) : base(key.Password + subscriberID, hashAlgorithm, encryptionAlgorithm) { }
private void ProcessBuffer() { try { Data data = new Data(buffer.ToArray()); string s = data.ToString(); alreadyReceived.Append(s); if (tag == START_TAG) { // start looking for GNTP header tag = GNTP_IDENTIFIER_TAG; ContinueProcessing(); } else if (tag == GNTP_IDENTIFIER_TAG) { string line = s; Match match = ParseGNTPHeaderLine(line, this.passwordRequired); if (match.Success) { this.version = match.Groups["Version"].Value; if (version == MessageParser.GNTP_SUPPORTED_VERSION) { string d = match.Groups["Directive"].Value; if (Enum.IsDefined(typeof(RequestType), d)) { this.directive = (RequestType)Enum.Parse(typeof(RequestType), d); // check for supported but not allowed requests if (this.directive == RequestType.SUBSCRIBE && !this.allowSubscriptions) { OnError(ErrorCode.NOT_AUTHORIZED, ErrorDescription.SUBSCRIPTIONS_NOT_ALLOWED); } else { this.encryptionAlgorithm = Cryptography.GetEncryptionType(match.Groups["EncryptionAlgorithm"].Value); this.ivHex = (match.Groups["IV"] != null ? match.Groups["IV"].Value : null); if (!String.IsNullOrEmpty(this.ivHex)) this.iv = Cryptography.HexUnencode(this.ivHex); string keyHash = match.Groups["KeyHash"].Value.ToUpper(); bool authorized = false; // Any of the following criteria require a password: // 1. the request did not originate on the local machine or LAN // 2. the request came from the LAN, but LAN passwords are required // 2. it is a SUBSCRIBE request (all subscriptions require a password) // 3. the user's preferences require even local requests to supply a password // Additionally, even if a password is not required, it will be validated if the // sending appplication includes one string errorDescription = ErrorDescription.INVALID_KEY; if (this.passwordRequired || this.directive == RequestType.SUBSCRIBE || !String.IsNullOrEmpty(keyHash)) { if (String.IsNullOrEmpty(keyHash)) { errorDescription = ErrorDescription.MISSING_KEY; } else { string keyHashAlgorithmType = match.Groups["KeyHashAlgorithm"].Value; this.keyHashAlgorithm = Cryptography.GetKeyHashType(keyHashAlgorithmType); string salt = match.Groups["Salt"].Value.ToUpper(); authorized = this.passwordManager.IsValid(keyHash, salt, this.keyHashAlgorithm, this.encryptionAlgorithm, out this.key); } } else { authorized = true; this.key = Key.None; } if (authorized) { if (this.encryptionAlgorithm == Cryptography.SymmetricAlgorithmType.PlainText) { tag = HEADER_TAG; ContinueProcessing(); } else { tag = ENCRYPTED_HEADERS_TAG; ContinueProcessing(); } } else { OnError(ErrorCode.NOT_AUTHORIZED, errorDescription); } } } else { OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.UNSUPPORTED_DIRECTIVE, d); } } else { OnError(ErrorCode.UNKNOWN_PROTOCOL_VERSION, ErrorDescription.UNSUPPORTED_VERSION, version); } } else { OnError(ErrorCode.UNKNOWN_PROTOCOL, ErrorDescription.MALFORMED_REQUEST); } } else if (tag == HEADER_TAG) { if (s == MessageParser.BLANK_LINE) { // if this is a REGISTER message, check Notifications-Count value // to see how many notification sections to expect if (this.directive == RequestType.REGISTER) { if (this.expectedNotifications > 0) { tag = NOTIFICATION_TYPE_TAG; ContinueProcessing(); } else { // a REGISTER request with no notifications is not valid OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.NO_NOTIFICATIONS_REGISTERED); } } else { // otherwise, check the number of resource pointers we got and start reading those this.pointersExpected = GetNumberOfPointers(); if (this.pointersExpected > 0) { this.pointersExpectedRemaining = this.pointersExpected; this.currentPointer = 1; tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } else { OnMessageParsed(); } } } else { Header header = Header.ParseHeader(s); if (header != null) { bool addHeader = true; if (header.Name == Header.APPLICATION_NAME) { this.applicationName = header.Value; } if (header.Name == Header.NOTIFICATIONS_COUNT) { this.expectedNotifications = Convert.ToInt32(header.Value); this.expectedNotificationsRemaining = this.expectedNotifications; this.currentNotification = 1; } if (header.Name == Header.NOTIFICATION_CALLBACK_CONTEXT) { this.callbackData = header.Value; } if (header.Name == Header.NOTIFICATION_CALLBACK_CONTEXT_TYPE) { this.callbackDataType = header.Value; } if (header.Name == Header.NOTIFICATION_CALLBACK_TARGET || header.Name == Header.NOTIFICATION_CALLBACK_CONTEXT_TARGET) // left in for compatibility { this.callbackUrl = header.Value; } if (header.Name == Header.RECEIVED) { this.requestInfo.PreviousReceivedHeaders.Add(header); addHeader = false; } if (addHeader) this.headers.AddHeader(header); } tag = HEADER_TAG; ContinueProcessing(); } } else if (tag == NOTIFICATION_TYPE_TAG) { if (s == MessageParser.BLANK_LINE) { this.expectedNotificationsRemaining--; if (this.expectedNotificationsRemaining > 0) { this.currentNotification++; tag = NOTIFICATION_TYPE_TAG; ContinueProcessing(); } else { // otherwise, check the number of resource pointers we got and start reading those this.pointersExpected = GetNumberOfPointers(); if (this.pointersExpected > 0) { this.pointersExpectedRemaining = this.pointersExpected; this.currentPointer = 1; tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } else { OnMessageParsed(); } } } else { if (this.notificationsToBeRegistered.Count < this.currentNotification) { this.notificationsToBeRegistered.Add(new HeaderCollection()); } Header header = Header.ParseHeader(s); this.notificationsToBeRegistered[this.currentNotification - 1].AddHeader(header); tag = NOTIFICATION_TYPE_TAG; ContinueProcessing(); } } else if (tag == RESOURCE_HEADER_TAG) { if (s == MessageParser.BLANK_LINE) { // we should have found an Identifier header and Length header, or we are just starting a new section Pointer p = this.pointers[this.currentPointer - 1]; if (p.Identifier != null && p.Length > 0) { // read #of bytes int length = this.pointers[this.currentPointer - 1].Length; tag = RESOURCE_TAG; ContinueProcessing(); } else { tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } } else { Header header = Header.ParseHeader(s); // should be Identifer or Length if (header != null) { bool validHeader = false; if (header.Name == Header.RESOURCE_IDENTIFIER) { this.pointers[this.currentPointer - 1].Identifier = header.Value; validHeader = true; } else if (header.Name == Header.RESOURCE_LENGTH) { this.pointers[this.currentPointer - 1].Length = Convert.ToInt32(header.Value); validHeader = true; } else { OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.UNRECOGNIZED_RESOURCE_HEADER, header.Name); } if (validHeader) { tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } } else { OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.UNRECOGNIZED_RESOURCE_HEADER); } } } else if (tag == RESOURCE_TAG) { // deal with data bytes byte[] bytes = this.key.Decrypt(data.ByteArray, this.iv); Pointer pointer = this.pointers[this.currentPointer - 1]; pointer.ByteArray = bytes; BinaryData binaryData = new BinaryData(pointer.Identifier, pointer.ByteArray); ResourceCache.Add(this.applicationName, binaryData); this.pointersExpectedRemaining--; if (this.pointersExpectedRemaining > 0) { this.currentPointer++; tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } else { OnMessageParsed(); } } else if (tag == ENCRYPTED_HEADERS_TAG) { // see if a length was specified (the original spec did not require the main encrypted headers portion to specify a length) if (s.StartsWith(Header.RESOURCE_LENGTH)) { Header header = Header.ParseHeader(s); if (header != null) { int len = Convert.ToInt32(header.Value); tag = ENCRYPTED_HEADERS_TAG; ContinueProcessing(); } } ParseEncryptedMessage(data.ByteArray); if (this.pointersExpected > 0) { tag = RESOURCE_HEADER_TAG; ContinueProcessing(); } else { OnMessageParsed(); } } else { OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST); } } catch (GrowlException gEx) { OnError(gEx.ErrorCode, gEx.Message, gEx.AdditionalInfo); } catch (Exception ex) { OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST, ex.Message); } }
/// <summary> /// デフォルトコンストラクタ /// </summary> /// <param name="encryptionAlgorithm"> /// 通知メッセージの暗号化タイプを指定。 /// デフォルトは「plaintext」 /// </param> public GrowlManagerBase(Cryptography.SymmetricAlgorithmType encryptionAlgorithm = Cryptography.SymmetricAlgorithmType.PlainText) : this("", encryptionAlgorithm) { }