/* wydawca - automatic release submission daemon Copyright (C) 2007-2013 Sergey Poznyakoff Wydawca is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Wydawca is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with wydawca. If not, see . */ #include "wydawca.h" #include "sql.h" /* Return the length of the string without trailing whitespace */ size_t trim_length(const char *str) { size_t len; for (len = strlen(str); len > 0 && isspace(str[len - 1]); len--) ; return len; } /* Chop off any trailing whitespace. Return the length of the resulting string. */ size_t trim(char *str) { size_t len = trim_length(str); str[len] = 0; return len; } #define MSG_BEGIN_MARKER_STR "-----BEGIN PGP SIGNED MESSAGE-----\n" #define MSG_BEGIN_MARKER_LEN (sizeof (MSG_BEGIN_MARKER_STR) - 1) #define SIG_BEGIN_MARKER_STR "-----BEGIN PGP SIGNATURE-----\n" #define SIG_BEGIN_MARKER_LEN (sizeof (SIG_BEGIN_MARKER_STR) - 1) static int extract_plaintext(char *blurb) { char *start, *p; if (memcmp(blurb, MSG_BEGIN_MARKER_STR, MSG_BEGIN_MARKER_LEN)) return 1; p = blurb + MSG_BEGIN_MARKER_LEN; while (*p) { if (*p == '\n') { p++; break; } p = strchr(p, '\n'); if (!p) return 1; p++; } if (!*p) return 1; start = p; while (*p) { if (strncmp(p, SIG_BEGIN_MARKER_STR, SIG_BEGIN_MARKER_LEN) == 0) { *p++ = 0; memmove(blurb, start, p - start); return 0; } p = strchr(p, '\n'); if (!p) return 1; p++; } return 1; } int fill_project_name(struct wy_triplet *trp) { char *blurb; size_t size; FILE *fp; char *p; const char *directory; int rc; if (trp->blurb) return 0; size = trp->file[file_directive].sb.st_size; if (size <= MSG_BEGIN_MARKER_LEN) { wy_log(LOG_ERR, _("too small directive file %s"), trp->file[file_directive].name); return 1; } fp = fopen(trp->file[file_directive].name, "r"); if (!fp) { wy_log(LOG_ERR, _("cannot open file %s: %s"), trp->file[file_directive].name, strerror(errno)); return 1; } blurb = grecs_malloc(size + 1); rc = fread(blurb, size, 1, fp); fclose(fp); if (rc != 1) { wy_log(LOG_ERR, _("error reading file %s: %s"), trp->file[file_directive].name, strerror(errno)); free(blurb); return 1; } blurb[size] = 0; if (extract_plaintext(blurb)) { wy_log(LOG_ERR, _("%s: unrecognized format"), trp->file[file_directive].name); free(blurb); return 1; } trp->blurb = blurb; if (directive_parse(trp)) { free(blurb); trp->blurb = NULL; return 1; } if (directive_get_value(trp, "directory", &directory)) { wy_log(LOG_ERR, _("%s: missing `directory' directive"), trp->file[file_directive].name); return 1; } trp->relative_dir = safe_file_name(triplet_strdup(trp, directory)); if (!trp->relative_dir || trp->relative_dir[0] == '/') { wy_log(LOG_ERR, _("%s: invalid directory: %s"), trp->file[file_directive].name, directory); return 1; } p = strchr(trp->relative_dir, '/'); if (p) { size_t len = p - trp->relative_dir; if (len == 0) { wy_log(LOG_ERR, _("%s: empty `directory' directive"), trp->file[file_directive].name); return 1; } txtacc_grow(trp->acc, trp->relative_dir, len); txtacc_1grow(trp->acc, 0); trp->project = txtacc_finish(trp->acc, 0); } else trp->project = trp->relative_dir; return 0; } struct wy_user * uploader_find_frp(struct wy_user *list, const char *fpr) { for (; list; list = list->next) if (list->fpr && strcmp(list->fpr, fpr) == 0) break; return list; } int verify_directive_file(struct wy_triplet *trp, int noath) { if (!trp->file[file_directive].name) return 1; if (fill_project_name(trp)) return 1; if (!noath) { if (!wy_triplet_get_uploaders(trp)) return 1; if (verify_directive_signature(trp)) { /*FIXME: Update stats */ wy_log(LOG_ERR, _("invalid signature for %s"), trp->name ? trp->name : "[unknown]"); return 1; } else wy_debug(1, (_("%s: directive file signature OK"), trp->name)); } if (wy_debug_level > 1) { int i; for (i = 0; trp->directive[i]; i++) wy_log(LOG_DEBUG, "directive[%d] = %s", i, trp->directive[i]); } if (verify_directive_format(trp)) return 1; return 0; }