1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
// Copyright 2006 Alp Toker <alp@atoker.com>
// This software is made available under the MIT License
// See COPYING for details
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
namespace NDesk.DBus.Authentication
{
enum ClientState
{
WaitingForData,
WaitingForOK,
WaitingForReject,
}
enum ServerState
{
WaitingForAuth,
WaitingForData,
WaitingForBegin,
}
class SaslClient
{
protected Connection conn;
protected SaslClient ()
{
}
public SaslClient (Connection conn)
{
this.conn = conn;
}
public void Run ()
{
StreamReader sr = new StreamReader (conn.Transport.Stream, Encoding.ASCII);
StreamWriter sw = new StreamWriter (conn.Transport.Stream, Encoding.ASCII);
sw.NewLine = "\r\n";
string str = conn.Transport.AuthString ();
byte[] bs = Encoding.ASCII.GetBytes (str);
string authStr = ToHex (bs);
sw.WriteLine ("AUTH EXTERNAL {0}", authStr);
sw.Flush ();
string ok_rep = sr.ReadLine ();
string[] parts;
parts = ok_rep.Split (' ');
if (parts.Length < 1 || parts[0] != "OK")
throw new Exception ("Authentication error: AUTH EXTERNAL was not OK: \"" + ok_rep + "\"");
/*
string guid = parts[1];
byte[] guidData = FromHex (guid);
uint unixTime = BitConverter.ToUInt32 (guidData, 0);
Console.Error.WriteLine ("guid: " + guid + ", " + "unixTime: " + unixTime + " (" + UnixToDateTime (unixTime) + ")");
*/
sw.WriteLine ("BEGIN");
sw.Flush ();
}
//From Mono.Unix.Native.NativeConvert
//should these methods use long or (u)int?
public static DateTime UnixToDateTime (long time)
{
DateTime LocalUnixEpoch = new DateTime (1970, 1, 1);
TimeSpan LocalUtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.UtcNow);
return LocalUnixEpoch.AddSeconds ((double) time + LocalUtcOffset.TotalSeconds);
}
public static long DateTimeToUnix (DateTime time)
{
DateTime LocalUnixEpoch = new DateTime (1970, 1, 1);
TimeSpan LocalUtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.UtcNow);
TimeSpan unixTime = time.Subtract (LocalUnixEpoch) - LocalUtcOffset;
return (long) unixTime.TotalSeconds;
}
//From Mono.Security.Cryptography
//Modified to output lowercase hex
static public string ToHex (byte[] input)
{
if (input == null)
return null;
StringBuilder sb = new StringBuilder (input.Length * 2);
foreach (byte b in input) {
sb.Append (b.ToString ("x2", CultureInfo.InvariantCulture));
}
return sb.ToString ();
}
//From Mono.Security.Cryptography
static private byte FromHexChar (char c)
{
if ((c >= 'a') && (c <= 'f'))
return (byte) (c - 'a' + 10);
if ((c >= 'A') && (c <= 'F'))
return (byte) (c - 'A' + 10);
if ((c >= '0') && (c <= '9'))
return (byte) (c - '0');
throw new ArgumentException ("Invalid hex char");
}
//From Mono.Security.Cryptography
static public byte[] FromHex (string hex)
{
if (hex == null)
return null;
if ((hex.Length & 0x1) == 0x1)
throw new ArgumentException ("Length must be a multiple of 2");
byte[] result = new byte [hex.Length >> 1];
int n = 0;
int i = 0;
while (n < result.Length) {
result [n] = (byte) (FromHexChar (hex [i++]) << 4);
result [n++] += FromHexChar (hex [i++]);
}
return result;
}
}
}
|