miniroon

Simplistic macaroon-based authorization for Unix systems
git clone https://ccx.te2000.cz/git/miniroon
Log | Files | Refs | README

miniroon_spec.html (14229B)


      1 <!DOCTYPE html>
      2 <html><head><style type="text/css">
      3 	table.code_doc { border-collapse: collapse; border: 0px; }
      4 	table.code_doc code { white-space: pre; }
      5 	table.code_doc tr { vertical-align: top; }
      6 	table.code_doc td:hover { background-color: #3331; }
      7 </style></head><body><table class="code_doc">
      8 <tr><td>1</td><td><code>:- module(miniroon_spec,</code></td><td rowspan="13"></td></tr>
      9 <tr><td>2</td><td><code>	[ dcgappend/3</code></td></tr>
     10 <tr><td>3</td><td><code>	, netstring_prefix_for_payload/3</code></td></tr>
     11 <tr><td>4</td><td><code>	, netstring_bytes/3</code></td></tr>
     12 <tr><td>5</td><td><code>	, netstring_maplist_dcg/4</code></td></tr>
     13 <tr><td>6</td><td><code>	, phrase_length/4</code></td></tr>
     14 <tr><td>7</td><td><code>	, netstring_call_dcg/3</code></td></tr>
     15 <tr><td>8</td><td><code>	, miniroon_encoding/2</code></td></tr>
     16 <tr><td>9</td><td><code>	, miniroon_header/3</code></td></tr>
     17 <tr><td>10</td><td><code>	, miniroon_v0_caveat_list/3</code></td></tr>
     18 <tr><td>11</td><td><code>	]).</code></td></tr>
     19 <tr><td>12</td><td><code>:- use_module(library(debug), [assertion/1]).</code></td></tr>
     20 <tr><td>13</td><td><code>:- use_module(library(dcg/basics), [digits/3]).</code></td></tr>
     21 <tr><td>14</td><td><code></code></td><td rowspan="4"></td></tr>
     22 <tr><td>15</td><td><code>% pack_install(delay). =&gt; https://storage.googleapis.com/packs.ndrix.com/delay/delay-0.3.3.zip</code></td></tr>
     23 <tr><td>16</td><td><code>% Also at: https://github.com/mndrix/delay</code></td></tr>
     24 <tr><td>17</td><td><code>:- use_module(library(delay), [delay/1]).</code></td></tr>
     25 <tr><td>18</td><td><code></code></td><td rowspan="2"></td></tr>
     26 <tr><td>19</td><td><code>:- multifile delay:mode/1.</code></td></tr>
     27 <tr><td>20</td><td><code></code></td><td rowspan="3"></td></tr>
     28 <tr><td>21</td><td><code>delay:mode(lists:append(ground,_)).</code></td></tr>
     29 <tr><td>22</td><td><code>delay:mode(lists:append(_,ground)).</code></td></tr>
     30 <tr><td>23</td><td><code></code></td><td rowspan="3"></td></tr>
     31 <tr><td>24</td><td><code>delay:mode(system:string_bytes(ground,_,ground)).</code></td></tr>
     32 <tr><td>25</td><td><code>delay:mode(system:string_bytes(_,ground,ground)).</code></td></tr>
     33 <tr><td>26</td><td><code></code></td><td rowspan="3"></td></tr>
     34 <tr><td>27</td><td><code>%delay:mode(system:number_codes(ground,_)).</code></td></tr>
     35 <tr><td>28</td><td><code>%delay:mode(system:number_codes(_,ground)).</code></td></tr>
     36 <tr><td>29</td><td><code></code></td><td rowspan="3"></td></tr>
     37 <tr><td>30</td><td><code>%delay:mode(system:length(_,ground)).</code></td></tr>
     38 <tr><td>31</td><td><code>%delay:mode(system:length(list,_)).</code></td></tr>
     39 <tr><td>32</td><td><code></code></td><td rowspan="3"></td></tr>
     40 <tr><td>33</td><td><code>delay:mode(miniroon_spec:netstring_prefix_digits(list, _, _)).</code></td></tr>
     41 <tr><td>34</td><td><code>delay:mode(miniroon_spec:netstring_prefix_digits(_, list, _)).</code></td></tr>
     42 <tr><td>35</td><td><code></code></td><td rowspan="3"></td></tr>
     43 <tr><td>36</td><td><code>delay:mode(miniroon_spec:miniroon_v0_action(ground, _)).</code></td></tr>
     44 <tr><td>37</td><td><code>delay:mode(miniroon_spec:miniroon_v0_action(_, list)).</code></td></tr>
     45 <tr><td>38</td><td><code></code></td><td rowspan="3"></td></tr>
     46 <tr><td>39</td><td><code>delay:mode(miniroon_spec:phrase_length(nonvar, ground, _, _)).</code></td></tr>
     47 <tr><td>40</td><td><code>delay:mode(miniroon_spec:phrase_length(ground, _, _, _)).</code></td></tr>
     48 <tr><td>41</td><td><code></code></td><td rowspan="3"></td></tr>
     49 <tr><td>42</td><td><code>:- op(950, xfx, will_be).  %&lt; Shorthand operator for type and value checking</code></td></tr>
     50 <tr><td>43</td><td><code>:- op(800, fx, ~).  %&lt; Shorthand operator for delayed goal</code></td></tr>
     51 <tr><td>44</td><td><code></code></td><td rowspan="2"></td></tr>
     52 <tr><td>45</td><td><code>~(Goal) :- delay(Goal).</code></td></tr>
     53 <tr><td>46</td><td><code></code></td><td rowspan="2"></td></tr>
     54 <tr><td>47</td><td><code>%%% Helpers for DCGs:</code></td></tr>
     55 <tr><td>48</td><td><code></code></td><td rowspan="6"></td></tr>
     56 <tr><td>49</td><td><code>% swapped arguments append for use in DCGs</code></td></tr>
     57 <tr><td>50</td><td><code>% when called with instanced list as first argument it unifies it's content with DCG.</code></td></tr>
     58 <tr><td>51</td><td><code>dcgappend([], L, L) :- !.</code></td></tr>
     59 <tr><td>52</td><td><code>dcgappend([H|T], [H|R], L) :-</code></td></tr>
     60 <tr><td>53</td><td><code>	dcgappend(T, R, L).</code></td></tr>
     61 <tr><td>54</td><td><code></code></td><td rowspan="3"></td></tr>
     62 <tr><td>55</td><td><code>% Non-cutting variant:</code></td></tr>
     63 <tr><td>56</td><td><code>%dcgappend(List, L0, L1) :- append(List, L1, L0).</code></td></tr>
     64 <tr><td>57</td><td><code></code></td><td rowspan="9"></td></tr>
     65 <tr><td>58</td><td><code>phrase_length_agg(List, Terminator, CurrentDepth, Length) :-</code></td></tr>
     66 <tr><td>59</td><td><code>	(  List == Terminator</code></td></tr>
     67 <tr><td>60</td><td><code>	-&gt; CurrentDepth = Length</code></td></tr>
     68 <tr><td>61</td><td><code>	;  NextDepth is CurrentDepth + 1,</code></td></tr>
     69 <tr><td>62</td><td><code>	   assertion(compound(List)),</code></td></tr>
     70 <tr><td>63</td><td><code>	   List = [_|NextList],</code></td></tr>
     71 <tr><td>64</td><td><code>	   phrase_length_agg(NextList, Terminator, NextDepth, Length)</code></td></tr>
     72 <tr><td>65</td><td><code>	).</code></td></tr>
     73 <tr><td>66</td><td><code></code></td><td rowspan="5"></td></tr>
     74 <tr><td>67</td><td><code>phrase_length(DCGBody, List, Rest, Length) :-</code></td></tr>
     75 <tr><td>68</td><td><code>	phrase(DCGBody, List, Terminator),</code></td></tr>
     76 <tr><td>69</td><td><code>	phrase_length_agg(List, Terminator, 0, Length),</code></td></tr>
     77 <tr><td>70</td><td><code>	Terminator = Rest.</code></td></tr>
     78 <tr><td>71</td><td><code></code></td><td rowspan="2"></td></tr>
     79 <tr><td>72</td><td><code>%%% Helpers for type and value checking:</code></td></tr>
     80 <tr><td>73</td><td><code></code></td><td rowspan="4"></td></tr>
     81 <tr><td>74</td><td><code>% apply check to value when bound</code></td></tr>
     82 <tr><td>75</td><td><code>will_be(Value, Goal) :-</code></td></tr>
     83 <tr><td>76</td><td><code>	freeze(Value, assertion(call(Goal, Value))).</code></td></tr>
     84 <tr><td>77</td><td><code></code></td><td rowspan="2"></td></tr>
     85 <tr><td>78</td><td><code>byte(Value) :- must_be(between(0, 255), Value).</code></td></tr>
     86 <tr><td>79</td><td><code></code></td><td rowspan="2"></td></tr>
     87 <tr><td>80</td><td><code>nonnegative_integer(Value) :- must_be(nonneg, Value).</code></td></tr>
     88 <tr><td>81</td><td><code></code></td><td rowspan="5"></td></tr>
     89 <tr><td>82</td><td><code>sequence_of_bytes([]).</code></td></tr>
     90 <tr><td>83</td><td><code>sequence_of_bytes([First|Rest]) :-</code></td></tr>
     91 <tr><td>84</td><td><code>	First will_be byte,</code></td></tr>
     92 <tr><td>85</td><td><code>	Rest will_be sequence_of_bytes.</code></td></tr>
     93 <tr><td>86</td><td><code></code></td><td rowspan="2"></td></tr>
     94 <tr><td>87</td><td><code>%%% Generic grammar definitions:</code></td></tr>
     95 <tr><td>88</td><td><code></code></td><td rowspan="5"></td></tr>
     96 <tr><td>89</td><td><code>nonzero_digit(Code) --&gt;</code></td></tr>
     97 <tr><td>90</td><td><code>	[Code],</code></td></tr>
     98 <tr><td>91</td><td><code>	{ assertion(ground(Code)) },</code></td></tr>
     99 <tr><td>92</td><td><code>	{ member(Code, `123456789`) }.</code></td></tr>
    100 <tr><td>93</td><td><code></code></td><td rowspan="2"></td></tr>
    101 <tr><td>94</td><td><code>%%% Netstring definitions:</code></td></tr>
    102 <tr><td>95</td><td><code></code></td><td rowspan="1"></td></tr>
    103 <tr><td>96</td><td><code>netstring_bytes(PayloadBytes) --&gt;  </code></td><td rowspan="2">Netstring is a sequence of bytes.</td></tr>
    104 <tr><td>97</td><td><code>	{ PayloadBytes will_be sequence_of_bytes },</code></td></tr>
    105 <tr><td>98</td><td><code>	netstring_prefix_for_payload(PayloadBytes),  </code></td><td rowspan="1">It consists of prefix,</td></tr>
    106 <tr><td>99</td><td><code>	PayloadBytes, </code></td><td rowspan="1">payload,</td></tr>
    107 <tr><td>100</td><td><code>	`,`.  </code></td><td rowspan="1">and terminator. Terminator is single ASCII comma `,`.</td></tr>
    108 <tr><td>101</td><td><code></code></td><td rowspan="4"></td></tr>
    109 <tr><td>102</td><td><code>netstring_string(PayloadString) --&gt;</code></td></tr>
    110 <tr><td>103</td><td><code>	{ ~ string_bytes(PayloadString, PayloadBytes, octet) },</code></td></tr>
    111 <tr><td>104</td><td><code>	netstring_bytes(PayloadBytes).</code></td></tr>
    112 <tr><td>105</td><td><code></code></td><td rowspan="1"></td></tr>
    113 <tr><td>106</td><td><code></code></td><td rowspan="8">Netstring prefix is the shortest ASCII decimal representation for length of
    114 payload in bytes, followed by ASCII colon `:`.
    115 That is number starting with non-zero digit unless payload is empty,
    116 in which case it's `0`.</td></tr>
    117 <tr><td>107</td><td><code></code></td></tr>
    118 <tr><td>108</td><td><code></code></td></tr>
    119 <tr><td>109</td><td><code></code></td></tr>
    120 <tr><td>110</td><td><code>netstring_prefix_for_payload(PayloadBytes, A, B) :-</code></td></tr>
    121 <tr><td>111</td><td><code>	~ netstring_prefix_digits(Prefix, A, B),</code></td></tr>
    122 <tr><td>112</td><td><code>	~ number_codes(PayloadLength, Prefix),</code></td></tr>
    123 <tr><td>113</td><td><code>	length(PayloadBytes, PayloadLength).</code></td></tr>
    124 <tr><td>114</td><td><code></code></td><td rowspan="7"></td></tr>
    125 <tr><td>115</td><td><code>netstring_prefix_digits(`0`) --&gt; `0:`, !.</code></td></tr>
    126 <tr><td>116</td><td><code>netstring_prefix_digits([C|Cs]) --&gt;</code></td></tr>
    127 <tr><td>117</td><td><code>	nonzero_digit(C),</code></td></tr>
    128 <tr><td>118</td><td><code>	!,</code></td></tr>
    129 <tr><td>119</td><td><code>	digits(Cs),</code></td></tr>
    130 <tr><td>120</td><td><code>	`:`.</code></td></tr>
    131 <tr><td>121</td><td><code></code></td><td rowspan="5"></td></tr>
    132 <tr><td>122</td><td><code>netstring_call_dcg(DCGBody, L0, Rest) :-</code></td></tr>
    133 <tr><td>123</td><td><code>	~ phrase_length(DCGBody,Payload,[44|Rest],PayloadLength),</code></td></tr>
    134 <tr><td>124</td><td><code>	~ number_codes(PayloadLength, PrefixDigits),</code></td></tr>
    135 <tr><td>125</td><td><code>	netstring_prefix_digits(PrefixDigits, L0, Payload).</code></td></tr>
    136 <tr><td>126</td><td><code></code></td><td rowspan="5"></td></tr>
    137 <tr><td>127</td><td><code>netstring_maplist_dcg(_, []) --&gt; {true}.</code></td></tr>
    138 <tr><td>128</td><td><code>netstring_maplist_dcg(DCGBody, [Item|Rest]) --&gt;</code></td></tr>
    139 <tr><td>129</td><td><code>	netstring_call_dcg(call(DCGBody, Item)),</code></td></tr>
    140 <tr><td>130</td><td><code>	netstring_maplist_dcg(DCGBody, Rest).</code></td></tr>
    141 <tr><td>131</td><td><code></code></td><td rowspan="2"></td></tr>
    142 <tr><td>132</td><td><code>%%% Miniroon definitions:</code></td></tr>
    143 <tr><td>133</td><td><code></code></td><td rowspan="7"></td></tr>
    144 <tr><td>134</td><td><code>% Miniroon is a netstring whose payload is concatenation of three parts: header, caveat list and signature.</code></td></tr>
    145 <tr><td>135</td><td><code>miniroon_content(miniroon_v0(Identifier, Action, Caveats, Signature)) --&gt;</code></td></tr>
    146 <tr><td>136</td><td><code>	netstring_call_dcg(miniroon_header(header_v0(Identifier, Action))),</code></td></tr>
    147 <tr><td>137</td><td><code>	%netstring_call_dcg(miniroon_v0_caveat_list(Caveats)),</code></td></tr>
    148 <tr><td>138</td><td><code>	netstring_call_dcg(netstring_maplist_dcg(miniroon_v0_caveat, Caveats)),</code></td></tr>
    149 <tr><td>139</td><td><code>	netstring_bytes(Signature).</code></td></tr>
    150 <tr><td>140</td><td><code></code></td><td rowspan="3"></td></tr>
    151 <tr><td>141</td><td><code>miniroon_encoding(Miniroon, Bytes) :-</code></td></tr>
    152 <tr><td>142</td><td><code>	phrase(netstring_call_dcg(miniroon_content(Miniroon)), Bytes).</code></td></tr>
    153 <tr><td>143</td><td><code></code></td><td rowspan="4"></td></tr>
    154 <tr><td>144</td><td><code>miniroon_v0_action(revoke) --&gt; `revoke`.</code></td></tr>
    155 <tr><td>145</td><td><code>miniroon_v0_action(invoke) --&gt; `invoke`.</code></td></tr>
    156 <tr><td>146</td><td><code>miniroon_v0_action(invoke_once) --&gt; `invoke-once`.</code></td></tr>
    157 <tr><td>147</td><td><code></code></td><td rowspan="7"></td></tr>
    158 <tr><td>148</td><td><code>miniroon_header(header_v0(Identifier, Action)) --&gt;</code></td></tr>
    159 <tr><td>149</td><td><code>	netstring_bytes(`capv0`),</code></td></tr>
    160 <tr><td>150</td><td><code>	netstring_bytes(Identifier),</code></td></tr>
    161 <tr><td>151</td><td><code>	netstring_call_dcg(miniroon_v0_action(Action)).</code></td></tr>
    162 <tr><td>152</td><td><code>%	{ ~ miniroon_v0_action(Action, ActionBytes) },</code></td></tr>
    163 <tr><td>153</td><td><code>%	netstring_bytes(ActionBytes).</code></td></tr>
    164 <tr><td>154</td><td><code></code></td><td rowspan="16"></td></tr>
    165 <tr><td>155</td><td><code>miniroon_v0_caveat(caveat_v0_env_is(VarName, Value)) --&gt;</code></td></tr>
    166 <tr><td>156</td><td><code>	netstring_bytes(`env-is`),</code></td></tr>
    167 <tr><td>157</td><td><code>	netstring_string(VarName),</code></td></tr>
    168 <tr><td>158</td><td><code>	netstring_string(Value).</code></td></tr>
    169 <tr><td>159</td><td><code>miniroon_v0_caveat(caveat_v0_env_absent(VarName)) --&gt;</code></td></tr>
    170 <tr><td>160</td><td><code>	netstring_bytes(`env-absent`),</code></td></tr>
    171 <tr><td>161</td><td><code>	netstring_string(VarName).</code></td></tr>
    172 <tr><td>162</td><td><code>miniroon_v0_caveat(caveat_v0_env_regmatch(VarName, Pattern)) --&gt;</code></td></tr>
    173 <tr><td>163</td><td><code>	netstring_bytes(`env-re`),</code></td></tr>
    174 <tr><td>164</td><td><code>	netstring_string(VarName),</code></td></tr>
    175 <tr><td>165</td><td><code>	netstring_string(Pattern).</code></td></tr>
    176 <tr><td>166</td><td><code>miniroon_v0_caveat(caveat_v0_env_glob(VarName, Pattern)) --&gt;</code></td></tr>
    177 <tr><td>167</td><td><code>	netstring_bytes(`env-glob`),</code></td></tr>
    178 <tr><td>168</td><td><code>	netstring_string(VarName),</code></td></tr>
    179 <tr><td>169</td><td><code>	netstring_string(Pattern).</code></td></tr>
    180 <tr><td>170</td><td><code></code></td><td rowspan="5"></td></tr>
    181 <tr><td>171</td><td><code>miniroon_v0_caveat_list([]) --&gt; {true}.</code></td></tr>
    182 <tr><td>172</td><td><code>miniroon_v0_caveat_list([Caveat|Rest]) --&gt;</code></td></tr>
    183 <tr><td>173</td><td><code>	netstring_call_dcg(miniroon_v0_caveat(Caveat)),</code></td></tr>
    184 <tr><td>174</td><td><code>	miniroon_v0_caveat_list(Rest).</code></td></tr>
    185 </table></body></html>