📄 negotiate.c
字号:
/* PKCIPE - public key based configuration tool for CIPE negotiate.c - ciped option and invocation handling Copyright 2000 Olaf Titz <olaf@bigred.inka.de> This program 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 2 of the License, or (at your option) any later version.*//* $Id: negotiate.c,v 1.12 2002/05/10 17:31:15 olaf Exp $ */#include <errno.h>#include <fcntl.h>#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/mman.h>#include <sys/wait.h>#include "pkcipe.h"#ifndef OPTDIR#define OPTDIR "/var/run/cipe/%s"#endif#ifndef CIPED#define CIPED "/usr/local/sbin/ciped-cb"#endifint cipeSocket=-1;#define OPTNAMMAX 16#define OPTVALMAX 64typedef struct _optlist { struct _optlist *next; char nam[OPTNAMMAX]; char val[OPTVALMAX]; char oflag;} optlist;static optlist *opts=NULL;void setOption(const char *n, const char *v, char oflag){ optlist *p; for (p=opts; p; p=p->next) if (!strcmp(n, p->nam)) break; if (!p) { if (!(p=malloc(sizeof(*p)))) { Log(LOG_ERR, "setOption: malloc: %m"); return; /* XX handle this */ } memset(p, 0, sizeof(*p)); if (mlock(p, sizeof(*p))<0) Log(LOG_ERR, "setOption: mlock: %m"); /* not fatal */ p->next=opts; opts=p; } strncpy(p->nam, n, OPTNAMMAX-1); if (v) strncpy(p->val, v, OPTVALMAX-1); else p->val[0]='\0'; p->oflag=oflag;}/* get value (and flag) for option */const char* getOption(const char* n, char* oflag){ optlist* p; for (p=opts; p; p=p->next) if (!strcmp(p->nam, n)) { if (oflag) *oflag=p->oflag; return p->val; } return NULL;}#if 0 /* not used by now */void unsetOption(const char *n){ optlist *p, *q; for (p=opts; p; p=q->next) { q=p; if (!strcmp(n, p->nam)) break; } if (!p) return; if (q==opts) opts=p->next; else q->next=p->next; free(p);}#endif/* don't use stdio here because of secret keys which shouldn't go through buffers */static void printOptions(int fd){ optlist *p; for (p=opts; p; p=p->next) { if (p->oflag==OF_REJECT) continue; xwrite(fd, p->nam, strlen(p->nam)); if (*p->val) { xwrite(fd, "=", 1); xwrite(fd, p->val, strlen(p->val)); } xwrite(fd, "\n", 1); }}void readOptions(FILE *f){ char buf[256]; char *p, *q; char c; while (fgets(buf, sizeof(buf), f)) { c=OF_DEFAULT; for (p=buf; isspace(*p); ++p); switch (*p) { case 0: case '\n': case '#': continue; case OF_REQUIRE: case OF_REQVAL: case OF_REJECT: case OF_MIN: case OF_MAX: case OF_IGNORE: c=*p; ++p; } parseopt(p, &p, &q); if (!strcasecmp(p, "key")) { /* sanity check */ Log(LOG_WARNING, "attempt to use static key ignored"); continue; } setOption(p, q, c); }}pState negotiate(int fd, unsigned char *pkt, int len){ debug((DEB_PROTO, "negotiate: %s", pkt+1)); if (*pkt!=PKT_OPT_REQ) goto err; if (!strncmp(pkt+1, "me=", 3)) { setOption("peer", pkt+4, OF_DEFAULT); /**/ return ready(fd); } err: { char buf[32]; int i=snprintf(buf, sizeof(buf), "%cunimplemented option", PKT_ERROR); packetSend(fd, buf, i); return Serr; }}pState ready(int fd){ char buf[PKTMAXLEN]; int i; alarm(0); /* ?? */ lockMaster(); /* when this routine returns error, don't unlock; we then expect the program to exit soon */ if ((i=fork())<0) { i=snprintf(buf, sizeof(buf), "%cfork failed: %s", PKT_ERROR, strerror(errno)); packetSend(fd, buf, i); Log(LOG_ERR, "ready: %s", buf+1); return Serr; } if (i) { /* we have exactly one child, wait till it daemonizes */ int r; char *p; Log(LOG_NOTICE, "starting %s for peer %s", CIPED, peerIdentity); wait(&r); p=retstatus(r); if (!p) { r=snprintf(buf, sizeof(buf), "%cstarted ciped", PKT_READY); packetSend(fd, buf, r); unlockMaster(); return Sready; } i=snprintf(buf, sizeof(buf), "%cciped %s", PKT_ERROR, p); packetSend(fd, buf, i); Log(LOG_ERR, "ready: %s", buf+1); return Serr; } /* child */ setOption("arg", peerIdentity, OF_REQVAL); snprintf(buf, sizeof(buf), OPTDIR, peerIdentity); if ((i=open(buf, O_WRONLY|O_CREAT|O_TRUNC, 0600))<0) exit(98); printOptions(i); close(i); close(fd); closelog(); { char ba[16]; char *na[]={CIPED, "-o", buf, "-s", ba, NULL}; if (cipeSocket>=0) { snprintf(ba, sizeof(ba), "%d", cipeSocket); } else { /* should not happen */ Log(LOG_ERR, "internal cipeSocket<0"); na[3]=NULL; } execv(CIPED, na); } exit(99);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -