imapext-2007
diff APOPtools/apopcall.c @ 4:d741b3ecc917
imapext-2007f
author | HIROSE Yuuji <yuuji@gentei.org> |
---|---|
date | Thu, 30 Oct 2014 00:03:05 +0900 |
parents | 28a55bc1110c |
children |
line diff
1.1 --- a/APOPtools/apopcall.c Mon Sep 14 19:23:11 2009 +0900 1.2 +++ b/APOPtools/apopcall.c Thu Oct 30 00:03:05 2014 +0900 1.3 @@ -524,3 +524,529 @@ 1.4 printf("このユーティリティはSSL接続時のみ有効です.<br>\n"); 1.5 } 1.6 } 1.7 +#include <stdio.h> 1.8 +#include <stdlib.h> 1.9 +#include <string.h> 1.10 +#include <unistd.h> 1.11 +#include <sys/types.h> 1.12 +#include <sys/wait.h> 1.13 +#include <sys/stat.h> 1.14 +#include <pwd.h> 1.15 +#ifdef SHADOW_PASSWD 1.16 +#include <shadow.h> 1.17 +#endif 1.18 + 1.19 +#ifndef APOPPASSWD 1.20 +#define APOPPASSWD "/usr/local/bin/apoppasswd" 1.21 +#endif 1.22 +#ifndef APOPFILEBASE 1.23 +#define APOPFILEBASE ".apop" 1.24 +#endif 1.25 +#ifndef XADDR_DELIM 1.26 +#define XADDR_DELIM ('-') 1.27 +#endif 1.28 + 1.29 +char *myname; 1.30 + 1.31 +int ishexa(int c) { 1.32 + strchr("0123456789ABCDFabcdef", c) ? 1 : 0; 1.33 +} 1.34 + 1.35 +put_form(email, pass, new, new2, suffix, hidden, auth, force) 1.36 + char *email, *pass, *new, *new2, *suffix; 1.37 + int hidden, auth, force; 1.38 + /* auth = 0: old password 1.39 + 1: base addresse's mail password 1.40 + 2: unix password */ 1.41 +{ 1.42 + char *authtype[] = {"old", "base", "unix"}; 1.43 + char *var[] = {"email", "pass", "new", "new2", "auth", ""}; 1.44 + char *val[] = {email, pass, new, new2, authtype[auth]}; 1.45 + char *prm[] = {"", /* "ユーザ名", */ 1.46 + auth ? 1.47 + ((auth==1) 1.48 + ? "基本メイルアドレス用パスワード<br>Password for Basic Mail address" 1.49 + : "UNIXログインパスワード<br>UNIX login Password") 1.50 + : "古いメイルパスワード<br>Old Mail Password", 1.51 + "新しいメイルパスワード<br>New Mail Password", 1.52 + "新パスワードをもう一回(確認)<br>New Mail Password Again", 1.53 + ""}; 1.54 + int h=0, i; 1.55 + 1.56 + printf("<form method=POST action\"./%s\">\n", myname); 1.57 + printf(" <table border=1>\n"); 1.58 + for (i=0; var[i][0]; i++) { 1.59 + h = hidden || strstr("email,suffix,auth", var[i]); 1.60 + if (prm[i][0]) { 1.61 + printf("<tr><td>%s</td><td>", prm[i]); 1.62 + } else { 1.63 + } 1.64 + printf("<input name=%s %svalue=\"%s\" length=40 maxlength=40>\n", 1.65 + var[i], 1.66 + h ? "type=hidden " 1.67 + : (strstr(prm[i], "パスワード") ? "type=password " : "<br>"), 1.68 + val[i]); 1.69 + if (!strcmp(var[i], "suffix")) { 1.70 + /* ここでは suffix を入れさせない方がいいかも */ 1.71 + /* 表向きのメイルアドレスを表示しておく */ 1.72 + printf("%s", email); 1.73 + /* if (suffix[0]) { 1.74 + printf("-%s", suffix); 1.75 + } */ 1.76 + if (auth) 1.77 + printf("<br>(新規作成:New Account)"); 1.78 + } 1.79 + if (prm[i][0]) 1.80 + printf("</td></tr>"); 1.81 + printf("\n"); 1.82 + } 1.83 + 1.84 + printf("</table>\n"); 1.85 + if (force) 1.86 + printf("<input name=force type=hidden value=ON>\n"); 1.87 + if (auth) { 1.88 + char *a[] = {"basic", "unix"}; 1.89 + printf("<input type=hidden name=auth value=\"%s\">\n", a[auth-1]); 1.90 + } 1.91 + printf("<input name=OK value=OK type=submit>\n"); 1.92 + printf("<input name=RESET value=RESET type=reset>\n"); 1.93 + printf("</form>\n"); 1.94 + fflush(stdout); 1.95 +} 1.96 + 1.97 +char *decode(char *code) { 1.98 + int l=1+strlen(code); 1.99 + int i, c, d; 1.100 + char *ret = (char*)malloc(l*sizeof(char)); 1.101 + char *p = code; 1.102 + memset(ret, 0, l); 1.103 + for (i=0; i<strlen(code); i++) { 1.104 + if (code[i] == '+') code[i] = ' '; 1.105 + } 1.106 + while (code[0] && (p=strchr(code, '%')) 1.107 + && ishexa(*(p+1)) && ishexa(*(p+2))) { 1.108 + *(p++) = '\0'; 1.109 + strncat(ret, code, l); 1.110 + c = (islower(*p) ? toupper(*p) : *p) - '0'; 1.111 + p++; 1.112 + d = (islower(*p) ? toupper(*p) : *p) - '0'; 1.113 + if (c > 9) c -= ('A'-'9'-1); 1.114 + if (d > 9) d -= ('A'-'9'-1); 1.115 + ret[strlen(ret)] = c*16+d; 1.116 + code = p+1; 1.117 + } 1.118 + if (code[0]) strncat(ret, code, l); 1.119 + return ret; 1.120 +} 1.121 + 1.122 +#define BSIZE 8192 1.123 +char **decode_post() { 1.124 + char *buf = (char*)malloc(BSIZE*sizeof(char)); 1.125 + char **post, *p = buf; 1.126 + int n=0, i; 1.127 + post = (char**)calloc(1, sizeof(char*)); 1.128 + *buf = '\0'; 1.129 + fgets(buf, BSIZE, stdin); 1.130 + if (strchr("\n\r", buf[strlen(buf)-1])) /* chop */ 1.131 + buf[strlen(buf)-1] = '\0'; 1.132 + while (buf[0] && NULL != (p=strchr(buf, '&'))) { 1.133 + *p = '\0'; 1.134 + post[n] = (char*)malloc((p-buf+1)*sizeof(char)); 1.135 + strcpy(post[n], buf); 1.136 + n++; 1.137 + post = (char**)realloc(post, (1+n)*sizeof(char*)); 1.138 + buf = 1+p; 1.139 + } 1.140 + if (buf[0]) post[n++] = buf; 1.141 + /* decode URL encoded */ 1.142 + for (i=0; i < n; i++) { 1.143 + char *p; 1.144 + p=post[i]; 1.145 + post[i] = decode(p); 1.146 + } 1.147 + post[i] = ""; /* terminator */ 1.148 + return post; 1.149 +} 1.150 + 1.151 +void footer() { 1.152 + puts("</body>\n</html>"); 1.153 + fflush(stdout); 1.154 +} 1.155 + 1.156 +void fail() { 1.157 + printf("パスワード更新に失敗しました<br>\n"); 1.158 + printf("<a href=\"./\">やり直し</a><br>\n"); 1.159 + footer(); 1.160 + exit(1); 1.161 +} 1.162 +void success(char *email) { 1.163 + printf("<hr>メイルアカウント %s 用のパスワード更新は完了しました。<br>\n", 1.164 + email); 1.165 + footer(); 1.166 + exit(0); 1.167 +} 1.168 + 1.169 +int apopfile_existp(char *home, char *suffix, uid_t uid) { 1.170 + struct stat st; 1.171 + int s; 1.172 + int len = strlen(home) + 1 1.173 + + strlen(APOPFILEBASE) + strlen(suffix) + 3; 1.174 + char *apopfile = (char*)malloc(len); 1.175 + if (suffix[0]) { 1.176 + snprintf(apopfile, len, "%s/%s%c%s%c", 1.177 + home, APOPFILEBASE, XADDR_DELIM, suffix, 0); 1.178 + } else { 1.179 + snprintf(apopfile, len, "%s/%s%c", home, APOPFILEBASE, 0); 1.180 + } 1.181 + seteuid(uid); 1.182 + s = stat(apopfile, &st); 1.183 + seteuid(0); 1.184 + memset(apopfile, '\0', strlen(apopfile)); 1.185 + free(apopfile); 1.186 + return !s; 1.187 +} 1.188 + 1.189 +#ifndef QMAILCONTROL 1.190 +# define QMAILCONTROL "/var/qmail/control" 1.191 +#endif 1.192 +#ifndef MAILTMPLEN 1.193 +# define MAILTMPLEN 1024 1.194 +#endif 1.195 + 1.196 +/* Convert virtual domain user 1.197 + */ 1.198 +char* conv_virtualdomain(char *account) { 1.199 + char *dom = strchr(account, '@'), *p; 1.200 + char vd[MAILTMPLEN+1], rewrite[MAILTMPLEN+1], previous[MAILTMPLEN+1]; 1.201 + FILE *vdfd; 1.202 + int match=0; 1.203 + char buf[MAILTMPLEN+1], *s; 1.204 + snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "virtualdomains"); 1.205 + if (NULL == dom) return account; 1.206 + dom++; /* set position of domain part beginning */ 1.207 + if (dom && NULL != (vdfd = fopen (vd, "r"))) { 1.208 + int l = strlen(dom); 1.209 + int L = strlen(account); 1.210 + while ((s=fgets(buf, MAILTMPLEN, vdfd))) { 1.211 + if (p=strchr(s, '#')) 1.212 + *p = '\0'; /* zap comments */ 1.213 + if (!strchr(buf, ':')) 1.214 + continue; 1.215 + while (s && (strrchr(s, '\n') || strrchr(s, '\r') || strrchr(s, ' '))) 1.216 + s[strlen(s)-1] = '\0'; 1.217 + if (!strncmp(account, s, L) && s[L] == ':' && s[L+1]) { /* user matches */ 1.218 + match = 3; 1.219 + snprintf(rewrite, MAILTMPLEN, "%s-%s", s+L+1, account); 1.220 + break; 1.221 + } 1.222 + if (!strncmp(dom, s, l) && s[l] == ':' && s[l+1]) { /* domain matches */ 1.223 + match = 2; 1.224 + snprintf(rewrite, MAILTMPLEN, "%s%c%s", s+l+1, XADDR_DELIM, account); 1.225 + continue; 1.226 + } 1.227 + if (match < 2 && s[0] == '.') { /* if domain described in wildcard */ 1.228 + if (p=strchr(s, ':')) { 1.229 + *p = '\0'; 1.230 + if (!strcmp(dom+(strlen(dom)-strlen(s)), s)) { 1.231 + if (match == 0 1.232 + || strlen(previous) < strlen(s)) { 1.233 + match = 1; 1.234 + strncpy(previous, s, MAILTMPLEN); 1.235 + snprintf(rewrite, MAILTMPLEN, "%s%c%s", p+1, XADDR_DELIM, account); 1.236 + } 1.237 + } 1.238 + } 1.239 + } 1.240 + } 1.241 + fclose(vdfd); 1.242 + if (match) { 1.243 + p = strchr(rewrite, '@'); 1.244 + /* fprintf(stderr, "m=%d, rwr=[%s]\n", match, rewrite); */ 1.245 + if (p) { 1.246 + *p = '\0'; 1.247 + } 1.248 + /* fprintf(stderr, "rwr=[%s]\n", rewrite); */ 1.249 + s = malloc(strlen(rewrite)+1); 1.250 + strncpy(s, rewrite, strlen(rewrite)+1); 1.251 + memset(vd, 0, sizeof(vd)); 1.252 + memset(rewrite, 0, sizeof(rewrite)); 1.253 + memset(previous, 0, sizeof(previous)); 1.254 + return s; 1.255 + } 1.256 + } 1.257 + /* Then, compare with locals */ 1.258 + snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "locals"); 1.259 + if (NULL != (vdfd=fopen(vd, "r"))) { 1.260 + while (s=fgets(buf, MAILTMPLEN, vdfd)) { 1.261 + if (p=strchr(s, '#')) *p = '\0'; /* zap after comment mark # */ 1.262 + while (*s && (strrchr(s, '\r')||strrchr(s, '\n') 1.263 + ||strrchr(s, ' ')||strrchr(s, '\t'))) { 1.264 + *(s+strlen(s)-1) = '\0'; 1.265 + } 1.266 + while (*s && (*s == '\t' || *s == ' ')) s++; 1.267 + if (!strncmp(s, dom, strlen(s))) { /* matches with local domain */ 1.268 + int len = dom-account-1; 1.269 + p = (char*)malloc(len+1); 1.270 + memset(p, '\0', len+1); 1.271 + strncpy(p, account, len); 1.272 + return p; 1.273 + } 1.274 + } 1.275 + } 1.276 + return NULL; /* invalid domain */ 1.277 + /* return account; return itself */ 1.278 +} 1.279 + 1.280 +void apopcall(char **args) { 1.281 + int i=0, sc=0; 1.282 + pid_t pid; 1.283 + char *email="", *suffix="", *pass="", *new="", *new2 = "", *home=""; 1.284 + char buf[BUFSIZ], auth, *user; 1.285 + FILE *child, *result; 1.286 + while (args[i][0]) { 1.287 + /* printf("[%s]<br>\n", args[i]); */ 1.288 + if (!strncmp("email=", args[i], 6)) { 1.289 + email = args[i]+6; 1.290 + } else if (!strncmp("suffix=", args[i], 7)) { 1.291 + suffix = args[i]+7; 1.292 + } else if (!strncmp("pass=", args[i], 5)) { 1.293 + pass = args[i]+5; 1.294 + } else if (!strncmp("new=", args[i], 4)) { 1.295 + new = args[i]+4; 1.296 + } else if (!strncmp("new2=", args[i], 5)) { 1.297 + new2 = args[i]+5; 1.298 + } else if (!strncmp("auth=", args[i], 5)) { 1.299 + /* "this" or "base" or "unix" */ 1.300 + auth = args[i][5]; 1.301 + } 1.302 + i++; 1.303 + } 1.304 + /* Make a backup of original e-mail address */ 1.305 + /* user = (char*)malloc(1+strlen(email)); 1.306 + strcpy(user, email); 1.307 + */ 1.308 + user = conv_virtualdomain(email); 1.309 + if (NULL == user) { 1.310 + printf("そのようなドメインは無効です(%s)<br>\n", strchr(email, '@')); 1.311 + printf("入力したメイルアドレスを確認してやり直してください.<br>\n"); 1.312 + fail(); 1.313 + } 1.314 + if (strchr(user, XADDR_DELIM)) { 1.315 + char *p = malloc(1+strlen(user)); 1.316 + char *q = NULL; 1.317 + struct passwd *pwd; 1.318 + /* printf("user=[%s]<br>\n", user); */ 1.319 + 1.320 + memset(p, '\0', 1+strlen(user)); 1.321 + strcpy(p, user); 1.322 + while (!(pwd=getpwnam(p)) && (q=strrchr(p, XADDR_DELIM))) { 1.323 + fflush(stdout); 1.324 + *q = '\0'; 1.325 + } 1.326 + if (pwd && q) { 1.327 + q = user+(q-p)+1; 1.328 + user=p; 1.329 + suffix=q; 1.330 + } 1.331 + } 1.332 + if (user[0] && new[0] && new2[0]) { 1.333 + int tochild[2], toparent[2]; 1.334 + pid_t pid; 1.335 + int argc=0; 1.336 + char **argv; 1.337 + struct passwd *pswd; 1.338 + char *pstr; 1.339 + 1.340 + if (!(pswd=getpwnam(user))) { 1.341 + printf("Unkown user %s.\n", user); 1.342 + fflush(stdout); 1.343 + fail(); 1.344 + } 1.345 + pstr = pswd->pw_passwd; 1.346 +#ifdef SHADOW_PASSWD 1.347 + { struct spwd *ss = getspnam(user); 1.348 + pstr = (char*)ss->sp_pwdp; 1.349 + } 1.350 +#endif 1.351 + home=pswd->pw_dir; 1.352 + argv = (char**)calloc(4, sizeof(char*)); 1.353 + argv[argc++] = "apoppasswd"; 1.354 + argv[argc++] = "-s"; 1.355 + argv[argc++] = "-c"; 1.356 + /* if old password does not exist, 1.357 + then check UNIX password */ 1.358 +#if 0 1.359 + if (apopfile_existp(home, suffix, pswd->pw_uid)) { /* no apop-ext exists */ 1.360 + /* そのまま */ 1.361 + } else if (apopfile_existp(home, "", pswd->pw_uid)) {/* check base mail password */ 1.362 + argv = (char**)realloc(argv, (argc+2)*sizeof(char*)); 1.363 + argv[argc++] = "-b"; 1.364 + } 1.365 +#endif 1.366 + switch (auth) { 1.367 + case 'b': case 'B': 1.368 + if (apopfile_existp(home, "", pswd->pw_uid)) { 1.369 + argv = (char**)realloc(argv, (argc+2)*sizeof(char*)); 1.370 + argv[argc++] = "-b"; 1.371 + } else { 1.372 + printf("基本アドレスのパスワードファイルがありません<br>\n"); 1.373 + fail(); 1.374 + } 1.375 + break; 1.376 + case 'u': case 'U': 1.377 + if (strcmp(pstr, (char*)crypt(pass, pstr))) { 1.378 + printf("UNIX Password not correct.<br>\n"); 1.379 + /* printf("[%s]vs.[%s]<br>\n", 1.380 + pswd->pw_passwd, crypt(pass, pswd->pw_passwd)); */ 1.381 + printf("UNIXパスワードと一致しません.<br>\n"); 1.382 + fflush(stdout); 1.383 + fail(); 1.384 + } 1.385 + } 1.386 + 1.387 + if (strlen(new) < 8 || strlen(new2) < 8) { 1.388 + printf("New mail password must be more than 7 characters.<br>\n"); 1.389 + printf("メイルパスワードは8文字以上にしてください。<br>\n"); 1.390 + fflush(stdout); 1.391 + fail(); 1.392 + } 1.393 + if (suffix[0]) { 1.394 + argv = (char**)realloc(argv, (argc+3)*sizeof(char*)); 1.395 + argv[argc++] = "-e"; 1.396 + argv[argc++] = suffix; 1.397 + 1.398 + } 1.399 + argv[argc++] = NULL; 1.400 + if (setgid(pswd->pw_gid) || 0 != setuid(pswd->pw_uid)) { 1.401 + printf("Cannot switch to %s\n", user); 1.402 + printf("uid=%d, gid=%d<br>\n", pswd->pw_gid, pswd->pw_uid); 1.403 + printf("メイルパスワード変更サーバの設定不良の可能性があるので<br>\n"); 1.404 + printf("お手数ですがこの画面のコピーを添えてシステム管理者"); 1.405 + printf("まで御連絡下さい。<br>\n"); 1.406 + fflush(stdout); 1.407 + fail(); 1.408 + } 1.409 + 1.410 + /* OK, start apopasswd */ 1.411 + if (pipe(tochild)+pipe(toparent)) { 1.412 + printf("Cannot create pipe\n"); 1.413 + fail(); 1.414 + } 1.415 + if ((pid=fork()) > 0) { 1.416 + FILE *child = fdopen(tochild[1], "w"); 1.417 + close(tochild[0]); 1.418 + close(toparent[1]); 1.419 + fprintf(child, "PASS %s\nNEW %s\nNEW2 %s\n", 1.420 + pass, new, new2); 1.421 + fflush(child); 1.422 + fclose(child); 1.423 + 1.424 + } else if (pid == -1) { 1.425 + printf("Cannot fork\n"); 1.426 + fail(); 1.427 + } else { 1.428 + char *pe = malloc(6+strlen(pswd->pw_dir)); 1.429 + close(tochild[1]); 1.430 + close(toparent[0]); 1.431 + dup2(tochild[0], 0); 1.432 + dup2(toparent[1], 1); 1.433 + 1.434 + /* setuid section */ 1.435 + 1.436 + strcpy(pe, "HOME="); 1.437 + strcat(pe, pswd->pw_dir); 1.438 + if (putenv(pe)) { 1.439 + puts("ga-n! arichan gakkari<br>"); 1.440 + } 1.441 + execv(APOPPASSWD, argv); 1.442 + 1.443 + /* setuid section ends */ 1.444 + fprintf(stderr, "Cannot exec %s\n", APOPPASSWD); 1.445 + fail(); 1.446 + } 1.447 + result = fdopen(toparent[0], "r"); 1.448 + while (fgets(buf, BUFSIZ, result)) { 1.449 + printf("%s<br>", buf); 1.450 + fflush(stdout); 1.451 + if (strstr(buf, "Success!")) { 1.452 + printf("<br>Mail Password changed successfully!<br>\n"); 1.453 + sc++; 1.454 + break; 1.455 + } else if (strstr(buf, "mismatch")) { 1.456 + printf("二個入れた新パスワードが一致しません.<br>\n"); 1.457 + break; 1.458 + } else if (strstr(buf, "Illegal")) { 1.459 + printf("照合用パスワードが違います.<br>--\n"); 1.460 + break; 1.461 + } else if (strstr(buf, "does not exist")) { 1.462 + /* try_overwrite(user, pass, new, new2, suffix); */ 1.463 + if (suffix[0]) { 1.464 + printf("%s-%s", user, suffix); 1.465 + } else { 1.466 + printf("%s", user); 1.467 + } 1.468 + /* ここは来ないことになった(のはず) */ 1.469 + printf("というメイルアカウントは未作成です<br>\n"); 1.470 + printf("新規に作る場合はOKボタンをクリック\n"); 1.471 + put_form(email, pass, new, new2, suffix, 1, 0, 1); 1.472 + fflush(stdout); 1.473 + } 1.474 + } 1.475 + fclose(result); 1.476 + while (wait(0) != pid) {sleep(1);fputc('.', stderr);} 1.477 + if (sc) success(email); else fail(); 1.478 + } else if (user[0]) { 1.479 + struct passwd *pw = getpwnam(user); 1.480 + int auth=0; 1.481 + if (!pw) { 1.482 + printf("そのようなユーザはいません %s<br>\n", user); 1.483 + fail(); 1.484 + } 1.485 + home=pw->pw_dir; 1.486 + 1.487 + printf("%s というメイルアドレスの<br>\n", email); 1.488 + printf("メイル専用パスワードを変更します.<br>\n"); 1.489 + printf("メイルパスワードとUNIXパスワードの違いに気をつけてください.<br>\n"); 1.490 + printf("新パスワードは8文字以上にしてください.<br>\n"); 1.491 + printf("New password must be more than or equal to 8 characters.<br>\n"); 1.492 + if (apopfile_existp(home, suffix, pw->pw_uid)) { 1.493 + auth = 0; /* this password file */ 1.494 + printf("「古いメイルパスワード」には、現在<br>\n"); 1.495 + printf("<tt>%s</tt><br>\n", email); 1.496 + printf("を読むために指定しているパスワードを入力します。"); 1.497 + } else if (apopfile_existp(home, "", pw->pw_uid)) { 1.498 + auth = 1; /* basic mail address password */ 1.499 + printf("今回は本人認証として基本メイルアドレスのパスワードを"); 1.500 + printf("入力しますが、新しくパスワードを設定するのは<br>\n"); 1.501 + printf("<tt>%s</tt><br>\n", email); 1.502 + printf("用のパスワードです。基本メイルアドレスのパスワードは"); 1.503 + printf("変わりませんので注意してください。"); 1.504 + } else { 1.505 + auth = 2; /* UNIX login */ 1.506 + } 1.507 + put_form(email, "", "", "", suffix, 0, auth, 0); 1.508 + footer(); 1.509 + exit(0); 1.510 + } 1.511 + printf("user=[%s]\n", user); 1.512 +} 1.513 + 1.514 +int main(int argc, char* argv[]) { 1.515 + char *method = getenv("REQUEST_METHOD"); 1.516 + char **args; 1.517 + myname = argv[0]; 1.518 + if (method && strcmp(method, "POST") != 0) { 1.519 + printf("This program should be used in method:POST.\n"); 1.520 + fail(); 1.521 + } 1.522 + printf("Content-type: text/html; charset=EUC-JP\n\n"); 1.523 + printf("<html>\n<head><title>Change Password</title></head>\n"); 1.524 + printf("<body style=\"background: #f0ffff;\">\n"); 1.525 + if (getenv("SSL_CIPHER") && getenv("SSL_PROTOCOL")) { 1.526 + args = decode_post(); 1.527 + apopcall(args); 1.528 + } else { 1.529 + printf("This program can be used only via SSL connection.<br>\n"); 1.530 + printf("このユーティリティはSSL接続時のみ有効です.<br>\n"); 1.531 + } 1.532 +}