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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
|
.Dd August 12, 2020
.Dt STERNENBLOG.CGI 1
.Os
.Sh NAME
.Nm sternenblog.cgi
.Nd file based CGI blog software
.Sh SYNOPSIS
.Nm sternenblog.cgi
.Sh DESCRIPTION
The
.Nm
CGI script implements a blog application based on a directory containing blog
entries in HTML format.
It serves both an index page listing all available entries and single pages for
every individual entry.
.Pp
The Request URL
.Ql /sternenblog.cgi
results in the index page being served,
.Ql /sternenblog.cgi/rss.xml
returns a RSS feed with the same contents as the index page and
.Ql /sternenblog.cgi/my-entry
serves the single entry page for
.Pa /path/to/entry/directory/my-entry .
.Pp
Every entry is a regular file in the configured entry directory that meets
certain criteria (see
.Sx "SECURITY CONSIDERATIONS"
for details) and should contain a HTML snippet which is passed to the
used template by
.Nm
to generate a complete HTML page.
To determine the “publication” datetime of an entry and to sort the index
page, the modification time of the underlying file is used.
To backdate an entry (for example after a minor edit)
.Xr touch 1
can be used to (re)set the modification time.
.Ss CONFIGURATION
.Nm
is configured statically by changing
.Pa config.h
before (re)compiling it.
If no custom config header is provided at compile time,
it is generated from the default one,
.Pa config.example.h ,
which also may serve as a starting point for a custom configuration.
.Bl -tag -width Ds
.It Sy BLOG_DIR
The directory blog entries are stored in.
See
.Sx "SECURITY CONSIDERATIONS"
for information on which files in that directory are processed by
.Nm .
It is recommended to use a dedicated directory owned by the webserver's
user and group which only contains the blog entries without a (sub)directory
structure.
.Pp
Must either start with
.Ql ./
or
.Ql /
although the latter, i. e. an absolute path, is recommended.
.Pp
Default value is
.Pa /srv/sternenblog/ .
.It Sy BLOG_TITLE
Title of the blog to serve, used in the RSS feed and the default template.
.Pp
Default value is
.Ql my blog .
.It Sy BLOG_DESCRIPTION
Used to set the
.Ql description
element of the RSS feed.
.Pp
Default value is
.Ql my personal blog .
.It Sy BLOG_SERVER_URL
Public URL of the root of the server, i. e. public address or hostname and used
protocol.
This is used to construct global URLs to the entries for the RSS
feed.
.Pp
Default value is
.Ql http://localhost .
.It Sy BLOG_RSS_TTL
Used to set the
.Ql ttl
element of the RSS feed.
The value (in minutes) can be used by feed readers to
determine how often to refresh the RSS feed.
.Pp
Default value is
.Ql 60 .
.It Sy BLOG_CSS
Absolute path from the web root to the CSS stylesheet to be used by the default
template.
See
.Sx FILES
for the location of the installed default stylesheet.
.Pp
This value is optional: If not set, no stylesheet is included.
.Pp
Default value is
.Ql /sternenblog.css
.El
.Pp
It is also possible to add additional values to
.Pa config.h
to be used in a custom template.
.Pp
The template can be changed in
.Pa config.mk
by changing the
.Ql TEMPLATE
variable to the path to the template file without its extension.
For details
refer to section
.Sx TEMPLATING .
.Ss BUILDING
.Nm
is built using
.Xr make 1 .
.Pp
The default target compiles
.Nm
using
.Sy CC
and the
.Sy CFLAGS
set in
.Pa config.mk
and generates
.Pa config.h
from
.Pa config.example.h
beforehand if it is missing.
.Pp
In most, if not all, cases it is required to provide a custom
.Pa config.h
or to change
.Pa config.example.h
prior to compiling for
.Nm
to work properly.
For details refer to the previous section
.Sx CONFIGURATION .
.Pp
The
.Ql doc
target builds developer documentation about templating, provided helper
libraries and
.Nm
internals using
.Xr doxygen 1 .
The output can be found in
.Pa doc/html
and
.Pa doc/man/man3
in HTML and man page format respectively.
.Pp
The
.Ql install
target installs
documentation and files necessary for serving
.Nm sternenblog.cgi
to
.Pa /usr/local .
If
.Pa assets/favicon.ico
is missing, a default one is generated using
.Xr convert 1 .
All files intended to be served by a web server are
installed to
.Pa /usr/local/share/sternenblog .
For a listing of files installed apart from
documentation and the CGI script itself see section
.Sx FILES .
All installation paths can be adjusted in
.Pa config.mk
\".Ss WEBSERVER CONFIGURATION TODO
.
.Ss TEMPLATING
See
.Xr template.h 3
.
.Sh ENVIRONMENT
.Nm
expects a subset of the CGI 1.1 environment as specified in
.Lk https://tools.ietf.org/html/rfc3875 RFC3876 .
The expected variables to be set are:
.Bl -tag -width Ds
.It Ev SCRIPT_NAME
Expected to be the script name as an absolute path from the webroot, i. e\.
.Ql <a href="$SCRIPT_NAME">index</a>
is expected to link to the script itself, so
.Ev PATH_INFO
is empty and the index page is served.
.It Ev PATH_INFO
Is expected to be the URL part after
.Ev SCRIPT_NAME ,
i. e. the path to a subpage of the script.
This is interpreted as a path to an entry and must start with a leading
.Ql / .
.El
.Pp
Most likely these will be set correctly by your favorite web server without
any special configuration.
.Sh FILES AND DIRECTORIES
Below is a listing of files and directories used and installed by default.
It is possible to configure
.Nm
to use different locations instead as described in section
.Sx CONFIGURATION .
.Bl -tag -width Ds
.It Pa /srv/sternenblog
Default directory for entries used by
.Nm .
Controlled by
.Ql BLOG_DIR
in
.Pa config.h .
Not created by the installation process.
.It Pa /usr/share/sternenblog/sternenblog.css
Default CSS the default template of
.Nm
uses.
If used, must be served at
.Pa /sternenblog.css
by the used web server.
Controlled by
.Ql BLOG_CSS
in
.Pa config.h .
.It Pa /usr/share/sternenblog/favicon.ico
Default favicon of
.Nm .
Can optionally be served at
.Pa /favicon.ico
by the used web server.
.El
.Sh EXIT STATUS
.Nm
always returns 0.
Errors are reported via the HTTP
.Ql Status
header.
.Sh SEE ALSO
.Xr cgiutil.h 3 ,
.Xr config.example.h 3 ,
.Xr core.h 3 ,
.Xr entry.h 3 ,
.Xr index.h 3 and
.Xr main.c 3 .
.Xr template.h 3 ,
.Xr xml.h 3 ,
.Sh AUTHORS
.An sternenseemann <sternenseemann@systemli.org>
.\" .Sh LIMITATIONS TODO
.Sh "SECURITY CONSIDERATIONS"
.Nm
hasn't been tested thoroughly in production yet and, as it is a one person
project, no second pair of eyes has reviewed the code.
There may well be issues that haven't been discovered yet.
.Pp
User input comes from two avenues: The first one is trusted:
blog entries stored in the configured directory.
The second one is arbitrary user input from third parties via
.Ev PATH_INFO .
.Pp
.Ev PATH_INFO
is validated to prevent
.Nm
from accessing dotfiles and escaping from the configured directory by using
.Ql .. .
Although the latter usually is already mitigated by the web server's
processing of the request URL.
.Pp
While accessing files,
.Nm
will only process regular files (e. g. not follow symlinks) and make sure that
the file is either owned by the group or the user it is running as (which will
usually be the webserver's user and group).
The check is made using the effective UID and GID which are determined using
.Xr geteuid 2 and
.Xr getegid 2 .
The idea here is that
.Xr chown 1
has to be used actively for the entry files to be processed by
.Nm .
.Pp
.Nm
will process files in subdirectories of the configured directory if they are
addressed directly.
They will however not be part of any indices or listings.
This behavior might be subject to change in the future.
|