forked from zeromq/clrzmq4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ZCertStore.cs
158 lines (147 loc) · 5.91 KB
/
ZCertStore.cs
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace ZeroMQ
{
/// <summary>
/// This class is a port of zcertstore.c provided in CZMQ, http://czmq.zeromq.org.
///
/// To authenticate new clients using the ZeroMQ CURVE security mechanism,
/// we have to check that the client's public key matches a key we know and
/// accept.There are numerous ways to store accepted client public keys.
/// The mechanism CZMQ implements is "certificates" (plain text files) held
/// in a "certificate store" (a disk directory). This class works with such
/// certificate stores, and lets you easily load them from disk, and check
/// if a given client public key is known or not. The ZCert class does the
/// work of managing a single certificate.
/// </summary>
/// <remarks>
/// The certificate store can be memory-only, in which case you can load it
/// yourself by inserting certificate objects one by one, or it can be loaded
/// from disk, in which case you can add, modify, or remove certificates on
/// disk at any time, and the store will detect such changes and refresh
/// itself automatically.In most applications you won't use this class
/// directly but through the ZAuth class, which provides a high-level API for
/// authentication(and manages certificate stores for you). To actually
/// create certificates on disk, use the ZCert class in code or any text editor.
/// The format of a certificate file is defined in the ZCert man page of CZMQ.
/// </remarks>
class ZCertStore
{
// a dictionary with public keys (in text) and their certificates.
Dictionary<string, ZCert> certs = new Dictionary<string, ZCert>();
FileSystemWatcher watcher = new FileSystemWatcher();
/// <summary>
/// The path to the certificate store (e.g. ".curve") or null if in memory only.
/// </summary>
string Location { get; set; }
/// <summary>
/// Certificate store in memory constructor,
/// </summary>
public ZCertStore() : this(null)
{
}
/// <summary>
/// Create a new certificate store, loading and indexing all certificates.
/// Specifying the location argument will setup the directory loader for this
/// ZCertStore instance. The directory itself may be absent, and created later,
/// or modified at any time. The certificate store is automatically refreshed.
/// If the location is specified as NULL, creates a pure-memory store,
/// which you can work with by inserting certificates at runtime.
/// </summary>
/// <param name="location">The location of the certificate store. May be null if a pure in memory store should be used.</param>
public ZCertStore(string location)
{
if (location != null)
{
Location = location;
watcher.Path = location;
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.FileName | NotifyFilters.LastAccess;
watcher.Filter = "*.*";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
Load(location);
}
else
{
Location = null;
}
}
/// <summary>
/// Lookup a certificate by the public key. Null is returned if the certificate isn't found.
/// </summary>
/// <param name="publicTxt">Public key if certificate to search for.</param>
/// <returns>Return the found certificate or null if it isn't found.</returns>
public ZCert Lookup(string publicTxt)
{
lock (certs)
{
if (certs.ContainsKey(publicTxt))
{
return certs[publicTxt];
}
}
return null;
}
/// <summary>
/// Insert a certificate to this ZCertStore. Note that this will override any existing certificate in the store
/// which has the same public key.
/// </summary>
/// <param name="cert">Certificate to store in ZCertStore.</param>
public void Insert(ZCert cert)
{
lock (certs)
{
certs[cert.PublicTxt] = cert;
}
}
/// <summary>
/// Clear this certificate store from all certificates.
/// </summary>
public void Clear()
{
lock (certs)
{
certs.Clear();
}
}
/// <summary>
/// Get a list with all certificates in this ZCertStore.
/// </summary>
/// <returns></returns>
public List<ZCert> Certs()
{
lock (certs)
{
return certs.Values.ToList();
}
}
private void OnChanged(object sender, FileSystemEventArgs e)
{
Load(Location);
}
private void Load(string path)
{
lock (certs)
{
certs.Clear();
if (Directory.Exists(path))
{
string[] files = Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly);
foreach (var filename in files)
{
ZCert cert = ZCert.Load(Path.Combine(filename));
if (cert != null && (filename.EndsWith("_secret") || !certs.ContainsKey(cert.PublicTxt)))
{
certs[cert.PublicTxt] = cert;
}
}
}
}
}
}
}