srctree

Gregory Mullen parent 23a42b26 6350974f
fix auth for local system

inlinesplit
src/auth.zig added: 83, removed: 61, total 22
@@ -8,18 +8,11 @@ const User = @import("types.zig").User;
 
const Auth = @This();
 
pub const Method = enum {
pub const MethodType = enum {
none,
unknown,
invalid,
mtls,
 
pub fn valid(m: Method) bool {
return switch (m) {
.mtls => true,
else => false,
};
}
};
 
const Reason = enum {
@@ -30,9 +23,25 @@ const MTLSPayload = struct {
status: []const u8,
fingerprint: []const u8,
cert: []const u8,
 
pub fn valid(m: MTLSPayload) bool {
var buffer: [0xffff]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buffer);
const a = fba.allocator();
const user = User.findMTLSFingerprint(a, m.fingerprint) catch |err| {
std.debug.print("Auth failure {}\n", .{err});
return false;
};
const time = std.time.timestamp();
if (user.not_before <= time and user.not_after >= time) {
return true;
} else {
return false;
}
}
};
 
const Payload = union(Method) {
const Method = union(MethodType) {
none: void,
unknown: void,
invalid: Reason,
@@ -40,7 +49,6 @@ const Payload = union(Method) {
};
 
method: Method,
payload: Payload,
 
pub fn init(h: HeaderList) Auth {
var status: ?[]const u8 = null;
@@ -60,14 +68,11 @@ pub fn init(h: HeaderList) Auth {
if (fingerprint) |f| {
if (cert) |c| {
return .{
.method = .mtls,
.payload = .{
.mtls = .{
.status = s,
.fingerprint = f,
.cert = c,
},
},
.method = .{ .mtls = .{
.status = s,
.fingerprint = f,
.cert = c,
} },
};
}
}
@@ -75,22 +80,24 @@ pub fn init(h: HeaderList) Auth {
 
return .{
.method = .none,
.payload = .unknown,
};
}
 
pub fn valid(auth: Auth) bool {
return auth.method.valid();
return switch (auth.method) {
.mtls => |m| m.valid(),
else => false,
};
}
 
pub fn validOrError(auth: Auth) !void {
if (!auth.valid()) return error.Unauthenticated;
}
 
pub fn user(auth: Auth, a: Allocator) !User {
pub fn currentUser(auth: Auth, a: Allocator) !User {
switch (auth.method) {
.mtls => {
return try User.findMTLSFingerprint(a, auth.payload.mtls.fingerprint);
.mtls => |m| {
return try User.findMTLSFingerprint(a, m.fingerprint);
},
else => return error.NotImplemted,
}
 
src/endpoints/gist.zig added: 83, removed: 61, total 22
@@ -57,7 +57,7 @@ fn post(ctx: *Context) Error!void {
 
if (udata.file_name.len != udata.file_blob.len) return error.BadData;
const username = if (ctx.auth.valid())
(ctx.auth.user(ctx.alloc) catch unreachable).username
(ctx.auth.currentUser(ctx.alloc) catch unreachable).username
else
"public";
 
 
src/endpoints/repos/diffs.zig added: 83, removed: 61, total 22
@@ -184,7 +184,7 @@ fn createDiff(ctx: *Context) Error!void {
udata.title,
udata.desc,
if (ctx.auth.valid())
(ctx.auth.user(ctx.alloc) catch unreachable).username
(ctx.auth.currentUser(ctx.alloc) catch unreachable).username
else
try allocPrint(ctx.alloc, "REMOTE_ADDR {s}", .{remote_addr}),
) catch unreachable;
@@ -221,7 +221,7 @@ fn newComment(ctx: *Context) Error!void {
 
var delta = Delta.open(ctx.alloc, rd.name, delta_index) catch unreachable orelse return error.Unrouteable;
const username = if (ctx.auth.valid())
(ctx.auth.user(ctx.alloc) catch unreachable).username
(ctx.auth.currentUser(ctx.alloc) catch unreachable).username
else
"public";
const c = Comment.new(username, msg.value) catch unreachable;
@@ -731,7 +731,7 @@ fn view(ctx: *Context) Error!void {
}
 
const username = if (ctx.auth.valid())
(ctx.auth.user(ctx.alloc) catch unreachable).username
(ctx.auth.currentUser(ctx.alloc) catch unreachable).username
else
"public";
 
 
src/endpoints/repos/issues.zig added: 83, removed: 61, total 22
@@ -78,7 +78,7 @@ fn newPost(ctx: *Context) Error!void {
valid.title,
valid.desc,
if (ctx.auth.valid())
(ctx.auth.user(ctx.alloc) catch unreachable).username
(ctx.auth.currentUser(ctx.alloc) catch unreachable).username
else
try allocPrint(ctx.alloc, "remote_address", .{}),
) catch unreachable;
@@ -109,7 +109,7 @@ fn newComment(ctx: *Context) Error!void {
) catch unreachable orelse return error.Unrouteable;
_ = delta.loadThread(ctx.alloc) catch unreachable;
const username = if (ctx.auth.valid())
(ctx.auth.user(ctx.alloc) catch unreachable).username
(ctx.auth.currentUser(ctx.alloc) catch unreachable).username
else
"public";
const c = Comment.new(username, msg.value) catch unreachable;
 
src/types/delta.zig added: 83, removed: 61, total 22
@@ -251,7 +251,7 @@ pub fn raze(_: Delta, _: std.mem.Allocator) void {
fn currMaxSet(repo: []const u8, count: usize) !void {
var buf: [2048]u8 = undefined;
const filename = try std.fmt.bufPrint(&buf, "_{s}_count", .{repo});
var cnt_file = try datad.createFile(filename, .{});
var cnt_file = try datad.createFile(filename, .{ .truncate = false });
defer cnt_file.close();
var writer = cnt_file.writer();
_ = try writer.writeInt(usize, count, endian);
@@ -302,7 +302,7 @@ fn openFile(repo: []const u8) !std.fs.File {
const max: usize = currMax(repo) catch 0;
var buf: [2048]u8 = undefined;
const filename = try std.fmt.bufPrint(&buf, "{s}.{x}.delta", .{ repo, max + 1 });
return try datad.createFile(filename, .{ .read = true });
return try datad.openFile(filename, .{ .mode = .read_write });
}
 
pub fn new(repo: []const u8, title: []const u8, msg: []const u8, author: []const u8) !Delta {
 
src/types/diff.zig added: 83, removed: 61, total 22
@@ -123,7 +123,7 @@ pub fn raze(self: Diff, a: std.mem.Allocator) void {
}
 
fn currMaxSet(count: usize) !void {
var cnt_file = try datad.createFile("_count", .{});
var cnt_file = try datad.createFile("_count", .{ .truncate = false });
defer cnt_file.close();
var writer = cnt_file.writer();
_ = try writer.writeIntNative(usize, count);
 
src/types/issue.zig added: 83, removed: 61, total 22
@@ -129,7 +129,7 @@ pub fn raze(self: Issue, a: std.mem.Allocator) void {
}
 
fn currMaxSet(count: usize) !void {
var cnt_file = try datad.createFile("_count", .{});
var cnt_file = try datad.createFile("_count", .{ .truncate = false });
defer cnt_file.close();
var writer = cnt_file.writer();
_ = try writer.writeIntNative(usize, count);
 
src/types/user.zig added: 83, removed: 61, total 22
@@ -8,7 +8,7 @@ const Types = @import("../types.zig");
pub const User = @This();
 
pub const TYPE_PREFIX = "users";
const USER_VERSION: usize = 0;
const USER_VERSION: usize = 1;
 
var datad: std.fs.Dir = undefined;
pub fn init(_: []const u8) !void {}
@@ -16,13 +16,39 @@ pub fn initType(stor: Types.Storage) !void {
datad = stor;
}
 
pub fn readVersioned(a: Allocator, file: std.fs.File) !User {
mtls_fp: [40]u8 = .{0} ** 40,
not_before: i64,
not_after: i64,
username: []const u8,
 
pub fn findMTLSFingerprint(a: Allocator, fp: []const u8) !User {
if (fp.len != 40) return error.InvalidFingerprint;
const file = try openFile(fp);
return readFile(a, file);
}
 
pub fn open(a: Allocator, username: []const u8) !User {
for (username) |c| if (!std.ascii.isLower(c)) return error.InvalidUsername;
 
const ufile = try openFile(username);
return try readFile(a, ufile);
}
 
pub fn commit(self: User) !User {
const file = try openFile(self.mtls_fp);
const w = file.writer().any();
try self.writeOut(w);
}
 
fn readVersioned(a: Allocator, file: std.fs.File) !User {
var reader = file.reader();
const ver: usize = try reader.readInt(usize, endian);
switch (ver) {
0 => {
return User{
.mtls_fp = try reader.readBytesNoEof(40),
.not_before = std.math.minInt(i64),
.not_after = std.math.maxInt(i64),
.username = try reader.readUntilDelimiterAlloc(a, 0, 0xFFF),
};
},
@@ -30,10 +56,13 @@ pub fn readVersioned(a: Allocator, file: std.fs.File) !User {
}
}
 
mtls_fp: [40]u8 = .{0} ** 40,
username: []const u8,
fn openFile(fp: []const u8) !std.fs.File {
var buf: [2048]u8 = undefined;
const filename = try std.fmt.bufPrint(&buf, "{s}.fp", .{fp});
return try datad.createFile(filename, .{ .read = true, .truncate = false });
}
 
pub fn readFile(a: Allocator, file: std.fs.File) !User {
fn readFile(a: Allocator, file: std.fs.File) !User {
defer file.close();
return readVersioned(a, file);
}
@@ -47,20 +76,6 @@ pub fn writeOut(_: User) !void {
}
 
pub fn new() !User {
// TODO implement ln username -> fp
return error.NotImplemnted;
}
 
pub fn findMTLSFingerprint(a: Allocator, fp: []const u8) !User {
if (fp.len != 40) return error.InvalidFingerprint;
var fpfbuf: [43]u8 = undefined;
const fname = try std.fmt.bufPrint(&fpfbuf, "{s}.fp", .{fp});
const file = datad.openFile(fname, .{}) catch return error.UserNotFound;
return User.readFile(a, file);
}
 
pub fn open(a: Allocator, username: []const u8) !User {
for (username) |c| if (!std.ascii.isLower(c)) return error.InvalidUsername;
 
const ufile = datad.openFile(username, .{}) catch return error.UserNotFound;
return try User.readFile(a, ufile);
}